Class: TurboBoost::Commands::Runner
- Inherits:
-
Object
- Object
- TurboBoost::Commands::Runner
- Defined in:
- lib/turbo_boost/commands/runner.rb
Constant Summary collapse
- RESPONSE_HEADER =
"TurboBoost-Command"
- SUPPORTED_MEDIA_TYPES =
{ "text/html" => true, "text/vnd.turbo-boost.html" => true, "text/vnd.turbo-stream.html" => true }.freeze
Instance Attribute Summary collapse
-
#controller ⇒ Object
readonly
Returns the value of attribute controller.
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_state ⇒ Object
- #command_succeeded? ⇒ Boolean
- #command_valid? ⇒ Boolean
- #controller_action_allowed? ⇒ Boolean
- #controller_action_prevented? ⇒ Boolean
- #handle_command_event(*args) ⇒ Object
-
#initialize(controller) ⇒ Runner
constructor
A new instance of Runner.
- #message_verifier ⇒ Object
- #prevent_controller_action(error: nil) ⇒ Object
- #render_response(html: "", status: nil, status_header: nil) ⇒ Object
- #run ⇒ Object
- #should_prevent_controller_action? ⇒ Boolean
- #turbo_stream ⇒ Object
- #update_response ⇒ Object
Constructor Details
#initialize(controller) ⇒ Runner
Returns a new instance of Runner.
17 18 19 |
# File 'lib/turbo_boost/commands/runner.rb', line 17 def initialize(controller) @controller = controller end |
Instance Attribute Details
#controller ⇒ Object (readonly)
Returns the value of attribute controller.
15 16 17 |
# File 'lib/turbo_boost/commands/runner.rb', line 15 def controller @controller end |
Instance Method Details
#command_aborted? ⇒ Boolean
95 96 97 |
# File 'lib/turbo_boost/commands/runner.rb', line 95 def command_aborted? !!command_instance&.aborted? end |
#command_class ⇒ Object
85 86 87 |
# File 'lib/turbo_boost/commands/runner.rb', line 85 def command_class @command_class ||= command_class_name&.safe_constantize end |
#command_class_name ⇒ Object
72 73 74 75 76 77 |
# File 'lib/turbo_boost/commands/runner.rb', line 72 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
99 100 101 |
# File 'lib/turbo_boost/commands/runner.rb', line 99 def command_errored? !!command_instance&.errored? end |
#command_instance ⇒ Object
89 90 91 92 93 |
# File 'lib/turbo_boost/commands/runner.rb', line 89 def command_instance @command_instance ||= command_class&.new(controller, command_state, command_params).tap do |instance| instance&.add_observer self, :handle_command_event end end |
#command_method_name ⇒ Object
79 80 81 82 83 |
# File 'lib/turbo_boost/commands/runner.rb', line 79 def command_method_name return nil unless command_requested? return "perform" unless command_name.include?("#") command_name.split("#").last end |
#command_name ⇒ Object
67 68 69 70 |
# File 'lib/turbo_boost/commands/runner.rb', line 67 def command_name return nil unless command_requested? command_params[:name] end |
#command_params ⇒ Object
58 59 60 61 62 63 64 65 |
# File 'lib/turbo_boost/commands/runner.rb', line 58 def command_params return ActionController::Parameters.new unless command_requested? @command_params ||= begin payload = parsed_command_params.transform_keys(&:underscore) payload["element_attributes"]&.deep_transform_keys!(&:underscore) ActionController::Parameters.new(payload).permit! end end |
#command_performed? ⇒ Boolean
107 108 109 |
# File 'lib/turbo_boost/commands/runner.rb', line 107 def command_performed? !!command_instance&.performed? end |
#command_performing? ⇒ Boolean
103 104 105 |
# File 'lib/turbo_boost/commands/runner.rb', line 103 def command_performing? !!command_instance&.performing? end |
#command_requested? ⇒ Boolean
29 30 31 |
# File 'lib/turbo_boost/commands/runner.rb', line 29 def command_requested? controller.request.env.key?("turbo_boost_command") || controller.params.key?("turbo_boost_command") end |
#command_state ⇒ Object
21 22 23 24 25 26 27 |
# File 'lib/turbo_boost/commands/runner.rb', line 21 def command_state @command_state ||= begin sgid = command_params[:signed_state] value = TurboBoost::Commands::State.from_sgid_param(sgid) if sgid value || TurboBoost::Commands::State.new end end |
#command_succeeded? ⇒ Boolean
111 112 113 |
# File 'lib/turbo_boost/commands/runner.rb', line 111 def command_succeeded? !!command_instance&.succeeded? end |
#command_valid? ⇒ Boolean
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/turbo_boost/commands/runner.rb', line 33 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 ancestors = command_class.ancestors[0..command_class.ancestors.index(TurboBoost::Commands::Command) - 1] unless ancestors.any? { |a| a.public_instance_methods(false).any? command_method_name.to_sym } raise TurboBoost::Commands::InvalidMethodError, "`#{command_class_name}` does not define the public method `#{command_method_name}`!" end # validate csrf token unless valid_command_token? raise TurboBoost::Commands::InvalidTokenError, "Token mismatch! The token: #{client_command_token}` does not match the expected value of `#{server_command_token}`." end true end |
#controller_action_allowed? ⇒ Boolean
115 116 117 |
# File 'lib/turbo_boost/commands/runner.rb', line 115 def controller_action_allowed? !controller_action_prevented? end |
#controller_action_prevented? ⇒ Boolean
119 120 121 |
# File 'lib/turbo_boost/commands/runner.rb', line 119 def controller_action_prevented? !!@controller_action_prevented end |
#handle_command_event(*args) ⇒ Object
189 190 191 192 193 194 195 196 |
# File 'lib/turbo_boost/commands/runner.rb', line 189 def handle_command_event(*args) event = args.shift = args. case event when :aborted, :errored then prevent_controller_action error: [:error] when :performed then prevent_controller_action if should_prevent_controller_action? end end |
#message_verifier ⇒ Object
183 184 185 186 187 |
# File 'lib/turbo_boost/commands/runner.rb', line 183 def ActiveSupport::MessageVerifier.new Rails.application.secret_key_base, digest: "SHA256", url_safe: true rescue ActiveSupport::MessageVerifier.new Rails.application.secret_key_base, digest: "SHA256" end |
#prevent_controller_action(error: nil) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/turbo_boost/commands/runner.rb', line 139 def prevent_controller_action(error: nil) return if controller_action_prevented? @controller_action_prevented = true case error when nil render_response status: response_status append_success_to_response when TurboBoost::Commands::AbortError render_response status: error.http_status_code, status_header: error. append_streams_to_response_body when TurboBoost::Commands::PerformError render_response status: error.http_status_code, status_header: error. append_error_to_response error else render_response status: :internal_server_error, status_header: error. append_error_to_response error end append_command_state_to_response_body end |
#render_response(html: "", status: nil, status_header: nil) ⇒ Object
174 175 176 177 |
# File 'lib/turbo_boost/commands/runner.rb', line 174 def render_response(html: "", status: nil, status_header: nil) controller.render html: html, layout: false, status: status || response_status # unless controller.performed? append_to_response_headers status_header end |
#run ⇒ Object
128 129 130 131 132 133 134 135 136 137 |
# File 'lib/turbo_boost/commands/runner.rb', line 128 def run return unless command_valid? return if command_aborted? return if command_errored? return if command_performing? return if command_performed? command_instance.resolve_state command_params[:changed_state] command_instance.perform_with_callbacks command_method_name end |
#should_prevent_controller_action? ⇒ Boolean
123 124 125 126 |
# File 'lib/turbo_boost/commands/runner.rb', line 123 def should_prevent_controller_action? return false unless command_performed? command_instance.should_prevent_controller_action? command_method_name end |
#turbo_stream ⇒ Object
179 180 181 |
# File 'lib/turbo_boost/commands/runner.rb', line 179 def turbo_stream @turbo_stream ||= Turbo::Streams::TagBuilder.new(controller.view_context) end |
#update_response ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/turbo_boost/commands/runner.rb', line 161 def update_response return if @update_response_performed @update_response_performed = true return if controller_action_prevented? append_command_state_to_response_body append_to_response_headers if command_performed? append_success_to_response if command_succeeded? rescue => error Rails.logger.error "TurboBoost::Commands::Runner failed to update the response! #{error.}" end |