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
94 95 96 |
# File 'lib/turbo_boost/commands/runner.rb', line 94 def command_aborted? !!command_instance&.aborted? end |
#command_class ⇒ Object
84 85 86 |
# File 'lib/turbo_boost/commands/runner.rb', line 84 def command_class @command_class ||= command_class_name&.safe_constantize end |
#command_class_name ⇒ Object
71 72 73 74 75 76 |
# File 'lib/turbo_boost/commands/runner.rb', line 71 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
98 99 100 |
# File 'lib/turbo_boost/commands/runner.rb', line 98 def command_errored? !!command_instance&.errored? end |
#command_instance ⇒ Object
88 89 90 91 92 |
# File 'lib/turbo_boost/commands/runner.rb', line 88 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
78 79 80 81 82 |
# File 'lib/turbo_boost/commands/runner.rb', line 78 def command_method_name return nil unless command_requested? return "perform" unless command_name.include?("#") command_name.split("#").last end |
#command_name ⇒ Object
66 67 68 69 |
# File 'lib/turbo_boost/commands/runner.rb', line 66 def command_name return nil unless command_requested? command_params[:name] end |
#command_params ⇒ Object
57 58 59 60 61 62 63 64 |
# File 'lib/turbo_boost/commands/runner.rb', line 57 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
106 107 108 |
# File 'lib/turbo_boost/commands/runner.rb', line 106 def command_performed? !!command_instance&.performed? end |
#command_performing? ⇒ Boolean
102 103 104 |
# File 'lib/turbo_boost/commands/runner.rb', line 102 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
110 111 112 |
# File 'lib/turbo_boost/commands/runner.rb', line 110 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 |
# 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 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_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
114 115 116 |
# File 'lib/turbo_boost/commands/runner.rb', line 114 def controller_action_allowed? !controller_action_prevented? end |
#controller_action_prevented? ⇒ Boolean
118 119 120 |
# File 'lib/turbo_boost/commands/runner.rb', line 118 def controller_action_prevented? !!@controller_action_prevented end |
#handle_command_event(*args) ⇒ Object
188 189 190 191 192 193 194 195 |
# File 'lib/turbo_boost/commands/runner.rb', line 188 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
182 183 184 185 186 |
# File 'lib/turbo_boost/commands/runner.rb', line 182 def ActiveSupport::MessageVerifier.new "#{controller.request.session&.id}#{Rails.application.secret_key_base}", digest: "SHA256", url_safe: true rescue ActiveSupport::MessageVerifier.new "#{controller.request.session&.id}#{Rails.application.secret_key_base}", digest: "SHA256" end |
#prevent_controller_action(error: nil) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/turbo_boost/commands/runner.rb', line 138 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
173 174 175 176 |
# File 'lib/turbo_boost/commands/runner.rb', line 173 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
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/turbo_boost/commands/runner.rb', line 127 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
122 123 124 125 |
# File 'lib/turbo_boost/commands/runner.rb', line 122 def should_prevent_controller_action? return false unless command_performed? command_instance.should_prevent_controller_action? command_method_name end |
#turbo_stream ⇒ Object
178 179 180 |
# File 'lib/turbo_boost/commands/runner.rb', line 178 def turbo_stream @turbo_stream ||= Turbo::Streams::TagBuilder.new(controller.view_context) end |
#update_response ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/turbo_boost/commands/runner.rb', line 160 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 |