Class: Datastar::Dispatcher
- Inherits:
-
Object
- Object
- Datastar::Dispatcher
- Defined in:
- lib/datastar/dispatcher.rb
Overview
The Dispatcher encapsulates the logic of handling a request and building a response with streaming datastar messages. You’ll normally instantiate a Dispatcher in your controller action of Rack handler via Datastar.new.
Constant Summary collapse
- BLANK_BODY =
[].freeze
- SSE_CONTENT_TYPE =
'text/event-stream'- HTTP_ACCEPT =
'HTTP_ACCEPT'- HTTP1 =
'HTTP/1.1'
Instance Attribute Summary collapse
-
#request ⇒ Object
readonly
Returns the value of attribute request.
-
#response ⇒ Object
readonly
Returns the value of attribute response.
Instance Method Summary collapse
-
#execute_script(script, options = BLANK_OPTIONS) ⇒ Object
One-off execute script in the UI See data-star.dev/reference/sse_events#datastar-execute-script.
-
#initialize(request:, response: nil, view_context: nil, executor: Datastar.config.executor, error_callback: Datastar.config.error_callback, finalize: Datastar.config.finalize) ⇒ Dispatcher
constructor
A new instance of Dispatcher.
-
#merge_fragments(fragments, options = BLANK_OPTIONS) ⇒ Object
Send one-off fragments to the UI See data-star.dev/reference/sse_events#datastar-merge-fragments.
-
#merge_signals(signals, options = BLANK_OPTIONS) ⇒ Object
One-off merge signals in the UI See data-star.dev/reference/sse_events#datastar-merge-signals.
-
#on_client_disconnect(callable = nil, &block) ⇒ self
Register a callback for client disconnection Ex.
-
#on_connect(callable = nil) {|sse| ... } ⇒ self
Register an on-connect callback Triggered when the request is handled.
-
#on_error(callable = nil, &block) ⇒ self
Register a callback server-side exceptions Ex.
-
#on_server_disconnect(callable = nil, &block) ⇒ self
Register a callback for server disconnection Ex.
-
#redirect(url) ⇒ Object
Send an execute_script event to change window.location.
-
#remove_fragments(selector, options = BLANK_OPTIONS) ⇒ Object
One-off remove fragments from the UI See data-star.dev/reference/sse_events#datastar-remove-fragments.
-
#remove_signals(paths, options = BLANK_OPTIONS) ⇒ Object
One-off remove signals from the UI See data-star.dev/reference/sse_events#datastar-remove-signals.
-
#signals ⇒ Hash
Parse and returns Datastar signals sent by the client.
-
#sse? ⇒ Boolean
Check if the request accepts SSE responses.
-
#stream(streamer = nil) {|sse| ... } ⇒ Object
Start a streaming response A generator object is passed to the block The generator supports all the Datastar methods listed above (it’s the same type) But you can call them multiple times to send multiple messages down an open SSE connection.
Constructor Details
#initialize(request:, response: nil, view_context: nil, executor: Datastar.config.executor, error_callback: Datastar.config.error_callback, finalize: Datastar.config.finalize) ⇒ Dispatcher
Returns a new instance of Dispatcher.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/datastar/dispatcher.rb', line 38 def initialize( request:, response: nil, view_context: nil, executor: Datastar.config.executor, error_callback: Datastar.config.error_callback, finalize: Datastar.config.finalize ) @on_connect = [] @on_client_disconnect = [] @on_server_disconnect = [] @on_error = [error_callback] @finalize = finalize @streamers = [] @queue = nil @executor = executor @view_context = view_context @request = request @response = Rack::Response.new(BLANK_BODY, 200, response&.headers || {}) @response.content_type = SSE_CONTENT_TYPE @response.headers['Cache-Control'] = 'no-cache' @response.headers['Connection'] = 'keep-alive' if @request.env['SERVER_PROTOCOL'] == HTTP1 # Disable response buffering in NGinx and other proxies @response.headers['X-Accel-Buffering'] = 'no' @response.delete_header 'Content-Length' @executor.prepare(@response) end |
Instance Attribute Details
#request ⇒ Object (readonly)
Returns the value of attribute request.
30 31 32 |
# File 'lib/datastar/dispatcher.rb', line 30 def request @request end |
#response ⇒ Object (readonly)
Returns the value of attribute response.
30 31 32 |
# File 'lib/datastar/dispatcher.rb', line 30 def response @response end |
Instance Method Details
#execute_script(script, options = BLANK_OPTIONS) ⇒ Object
One-off execute script in the UI See data-star.dev/reference/sse_events#datastar-execute-script
182 183 184 185 186 |
# File 'lib/datastar/dispatcher.rb', line 182 def execute_script(script, = BLANK_OPTIONS) stream do |sse| sse.execute_script(script, ) end end |
#merge_fragments(fragments, options = BLANK_OPTIONS) ⇒ Object
Send one-off fragments to the UI See data-star.dev/reference/sse_events#datastar-merge-fragments
126 127 128 129 130 |
# File 'lib/datastar/dispatcher.rb', line 126 def merge_fragments(fragments, = BLANK_OPTIONS) stream do |sse| sse.merge_fragments(fragments, ) end end |
#merge_signals(signals, options = BLANK_OPTIONS) ⇒ Object
One-off merge signals in the UI See data-star.dev/reference/sse_events#datastar-merge-signals
154 155 156 157 158 |
# File 'lib/datastar/dispatcher.rb', line 154 def merge_signals(signals, = BLANK_OPTIONS) stream do |sse| sse.merge_signals(signals, ) end end |
#on_client_disconnect(callable = nil, &block) ⇒ self
Register a callback for client disconnection Ex. when the browser is closed mid-stream
86 87 88 89 |
# File 'lib/datastar/dispatcher.rb', line 86 def on_client_disconnect(callable = nil, &block) @on_client_disconnect << (callable || block) self end |
#on_connect(callable = nil) {|sse| ... } ⇒ self
Register an on-connect callback Triggered when the request is handled
77 78 79 80 |
# File 'lib/datastar/dispatcher.rb', line 77 def on_connect(callable = nil, &block) @on_connect << (callable || block) self end |
#on_error(callable = nil, &block) ⇒ self
Register a callback server-side exceptions Ex. when one of the server threads raises an exception
104 105 106 107 |
# File 'lib/datastar/dispatcher.rb', line 104 def on_error(callable = nil, &block) @on_error << (callable || block) self end |
#on_server_disconnect(callable = nil, &block) ⇒ self
Register a callback for server disconnection Ex. when the server finishes serving the request
95 96 97 98 |
# File 'lib/datastar/dispatcher.rb', line 95 def on_server_disconnect(callable = nil, &block) @on_server_disconnect << (callable || block) self end |
#redirect(url) ⇒ Object
Send an execute_script event to change window.location
192 193 194 195 196 |
# File 'lib/datastar/dispatcher.rb', line 192 def redirect(url) stream do |sse| sse.redirect(url) end end |
#remove_fragments(selector, options = BLANK_OPTIONS) ⇒ Object
One-off remove fragments from the UI See data-star.dev/reference/sse_events#datastar-remove-fragments
140 141 142 143 144 |
# File 'lib/datastar/dispatcher.rb', line 140 def remove_fragments(selector, = BLANK_OPTIONS) stream do |sse| sse.remove_fragments(selector, ) end end |
#remove_signals(paths, options = BLANK_OPTIONS) ⇒ Object
One-off remove signals from the UI See data-star.dev/reference/sse_events#datastar-remove-signals
168 169 170 171 172 |
# File 'lib/datastar/dispatcher.rb', line 168 def remove_signals(paths, = BLANK_OPTIONS) stream do |sse| sse.remove_signals(paths, ) end end |
#signals ⇒ Hash
Parse and returns Datastar signals sent by the client. See data-star.dev/guide/getting_started#data-signals
112 113 114 |
# File 'lib/datastar/dispatcher.rb', line 112 def signals @signals ||= parse_signals(request).freeze end |
#sse? ⇒ Boolean
Check if the request accepts SSE responses
68 69 70 |
# File 'lib/datastar/dispatcher.rb', line 68 def sse? @request.get_header(HTTP_ACCEPT) == SSE_CONTENT_TYPE end |
#stream(streamer = nil) {|sse| ... } ⇒ Object
Start a streaming response A generator object is passed to the block The generator supports all the Datastar methods listed above (it’s the same type) But you can call them multiple times to send multiple messages down an open SSE connection. This methods also captures exceptions raised in the block and triggers any error callbacks. Client disconnection errors trigger the @on_client_disconnect callbacks. Finally, when the block is done streaming, the @on_server_disconnect callbacks are triggered.
When multiple streams are scheduled this way, this SDK will spawn each block in separate threads (or fibers, depending on executor) and linearize their writes to the connection socket As a last step, the finalize callback is called with the view context and the response This is so that different frameworks can setup their responses correctly. By default, the built-in Rack finalzer just returns the resposne Array which can be used by any Rack handler. On Rails, the Rails controller response is set to this objects streaming response.
237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/datastar/dispatcher.rb', line 237 def stream(streamer = nil, &block) streamer ||= block @streamers << streamer body = if @streamers.size == 1 stream_one(streamer) else stream_many(streamer) end @response.body = body @finalize.call(@view_context, @response) end |