spikard 0.3.5 → 0.3.6
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 +4 -4
- data/LICENSE +1 -1
- data/README.md +659 -659
- data/ext/spikard_rb/Cargo.toml +17 -17
- data/ext/spikard_rb/extconf.rb +10 -10
- data/ext/spikard_rb/src/lib.rs +6 -6
- data/lib/spikard/app.rb +386 -386
- data/lib/spikard/background.rb +27 -27
- data/lib/spikard/config.rb +396 -396
- data/lib/spikard/converters.rb +13 -13
- data/lib/spikard/handler_wrapper.rb +113 -113
- data/lib/spikard/provide.rb +214 -214
- data/lib/spikard/response.rb +173 -173
- data/lib/spikard/schema.rb +243 -243
- data/lib/spikard/sse.rb +111 -111
- data/lib/spikard/streaming_response.rb +44 -44
- data/lib/spikard/testing.rb +221 -221
- data/lib/spikard/upload_file.rb +131 -131
- data/lib/spikard/version.rb +5 -5
- data/lib/spikard/websocket.rb +59 -59
- data/lib/spikard.rb +43 -43
- data/sig/spikard.rbs +366 -360
- data/vendor/crates/spikard-core/Cargo.toml +40 -40
- data/vendor/crates/spikard-core/src/bindings/mod.rs +3 -3
- data/vendor/crates/spikard-core/src/bindings/response.rs +133 -133
- data/vendor/crates/spikard-core/src/debug.rs +63 -63
- data/vendor/crates/spikard-core/src/di/container.rs +726 -726
- data/vendor/crates/spikard-core/src/di/dependency.rs +273 -273
- data/vendor/crates/spikard-core/src/di/error.rs +118 -118
- data/vendor/crates/spikard-core/src/di/factory.rs +538 -538
- data/vendor/crates/spikard-core/src/di/graph.rs +545 -545
- data/vendor/crates/spikard-core/src/di/mod.rs +192 -192
- data/vendor/crates/spikard-core/src/di/resolved.rs +411 -411
- data/vendor/crates/spikard-core/src/di/value.rs +283 -283
- data/vendor/crates/spikard-core/src/errors.rs +39 -39
- data/vendor/crates/spikard-core/src/http.rs +153 -153
- data/vendor/crates/spikard-core/src/lib.rs +29 -29
- data/vendor/crates/spikard-core/src/lifecycle.rs +422 -422
- data/vendor/crates/spikard-core/src/parameters.rs +722 -722
- data/vendor/crates/spikard-core/src/problem.rs +310 -310
- data/vendor/crates/spikard-core/src/request_data.rs +189 -189
- data/vendor/crates/spikard-core/src/router.rs +249 -249
- data/vendor/crates/spikard-core/src/schema_registry.rs +183 -183
- data/vendor/crates/spikard-core/src/type_hints.rs +304 -304
- data/vendor/crates/spikard-core/src/validation.rs +699 -699
- data/vendor/crates/spikard-http/Cargo.toml +68 -68
- data/vendor/crates/spikard-http/src/auth.rs +247 -247
- data/vendor/crates/spikard-http/src/background.rs +249 -249
- data/vendor/crates/spikard-http/src/bindings/mod.rs +3 -3
- data/vendor/crates/spikard-http/src/bindings/response.rs +1 -1
- data/vendor/crates/spikard-http/src/body_metadata.rs +8 -8
- data/vendor/crates/spikard-http/src/cors.rs +490 -490
- data/vendor/crates/spikard-http/src/debug.rs +63 -63
- data/vendor/crates/spikard-http/src/di_handler.rs +423 -423
- data/vendor/crates/spikard-http/src/handler_response.rs +190 -190
- data/vendor/crates/spikard-http/src/handler_trait.rs +228 -228
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +284 -284
- data/vendor/crates/spikard-http/src/lib.rs +529 -529
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +149 -149
- data/vendor/crates/spikard-http/src/lifecycle.rs +428 -428
- data/vendor/crates/spikard-http/src/middleware/mod.rs +285 -285
- data/vendor/crates/spikard-http/src/middleware/multipart.rs +86 -86
- data/vendor/crates/spikard-http/src/middleware/urlencoded.rs +147 -147
- data/vendor/crates/spikard-http/src/middleware/validation.rs +287 -287
- data/vendor/crates/spikard-http/src/openapi/mod.rs +309 -309
- data/vendor/crates/spikard-http/src/openapi/parameter_extraction.rs +190 -190
- data/vendor/crates/spikard-http/src/openapi/schema_conversion.rs +308 -308
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +195 -195
- data/vendor/crates/spikard-http/src/parameters.rs +1 -1
- data/vendor/crates/spikard-http/src/problem.rs +1 -1
- data/vendor/crates/spikard-http/src/query_parser.rs +369 -369
- data/vendor/crates/spikard-http/src/response.rs +399 -399
- data/vendor/crates/spikard-http/src/router.rs +1 -1
- data/vendor/crates/spikard-http/src/schema_registry.rs +1 -1
- data/vendor/crates/spikard-http/src/server/handler.rs +87 -87
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +98 -98
- data/vendor/crates/spikard-http/src/server/mod.rs +805 -805
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +119 -119
- data/vendor/crates/spikard-http/src/sse.rs +447 -447
- data/vendor/crates/spikard-http/src/testing/form.rs +14 -14
- data/vendor/crates/spikard-http/src/testing/multipart.rs +60 -60
- data/vendor/crates/spikard-http/src/testing/test_client.rs +285 -285
- data/vendor/crates/spikard-http/src/testing.rs +377 -377
- data/vendor/crates/spikard-http/src/type_hints.rs +1 -1
- data/vendor/crates/spikard-http/src/validation.rs +1 -1
- data/vendor/crates/spikard-http/src/websocket.rs +324 -324
- data/vendor/crates/spikard-rb/Cargo.toml +42 -42
- data/vendor/crates/spikard-rb/build.rs +8 -8
- data/vendor/crates/spikard-rb/src/background.rs +63 -63
- data/vendor/crates/spikard-rb/src/config.rs +294 -294
- data/vendor/crates/spikard-rb/src/conversion.rs +453 -453
- data/vendor/crates/spikard-rb/src/di.rs +409 -409
- data/vendor/crates/spikard-rb/src/handler.rs +625 -625
- data/vendor/crates/spikard-rb/src/lib.rs +2771 -2771
- data/vendor/crates/spikard-rb/src/lifecycle.rs +274 -274
- data/vendor/crates/spikard-rb/src/server.rs +283 -283
- data/vendor/crates/spikard-rb/src/sse.rs +231 -231
- data/vendor/crates/spikard-rb/src/test_client.rs +404 -404
- data/vendor/crates/spikard-rb/src/test_sse.rs +143 -143
- data/vendor/crates/spikard-rb/src/test_websocket.rs +221 -221
- data/vendor/crates/spikard-rb/src/websocket.rs +233 -233
- metadata +1 -1
data/lib/spikard/testing.rb
CHANGED
|
@@ -1,221 +1,221 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'json'
|
|
4
|
-
|
|
5
|
-
module Spikard
|
|
6
|
-
# Testing helpers that wrap the native Ruby extension.
|
|
7
|
-
module Testing
|
|
8
|
-
module_function
|
|
9
|
-
|
|
10
|
-
def create_test_client(app, config: nil)
|
|
11
|
-
unless defined?(Spikard::Native::TestClient)
|
|
12
|
-
raise LoadError, 'Spikard native test client is not available. Build the native extension before running tests.'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# Allow generated apps to stash a test config
|
|
16
|
-
if config.nil? && app.instance_variable_defined?(:@__spikard_test_config)
|
|
17
|
-
config = app.instance_variable_get(:@__spikard_test_config)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Use default config if none provided
|
|
21
|
-
config ||= Spikard::ServerConfig.new
|
|
22
|
-
|
|
23
|
-
routes_json = app.normalized_routes_json
|
|
24
|
-
handlers = app.handler_map.transform_keys(&:to_sym)
|
|
25
|
-
ws_handlers = app.websocket_handlers || {}
|
|
26
|
-
sse_producers = app.sse_producers || {}
|
|
27
|
-
dependencies = app.dependencies || {}
|
|
28
|
-
native = Spikard::Native::TestClient.new(routes_json, handlers, config, ws_handlers, sse_producers, dependencies)
|
|
29
|
-
TestClient.new(native)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# High level wrapper around the native test client.
|
|
33
|
-
class TestClient
|
|
34
|
-
def initialize(native)
|
|
35
|
-
@native = native
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Factory method for creating test client from an app
|
|
39
|
-
def self.new(app_or_native, config: nil)
|
|
40
|
-
# If passed a native client directly, use it
|
|
41
|
-
return super(app_or_native) if app_or_native.is_a?(Spikard::Native::TestClient)
|
|
42
|
-
|
|
43
|
-
# Otherwise, create test client from app
|
|
44
|
-
Spikard::Testing.create_test_client(app_or_native, config: config)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def request(method, path, **options)
|
|
48
|
-
payload = @native.request(method.to_s.upcase, path, options)
|
|
49
|
-
Response.new(payload)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def websocket(path)
|
|
53
|
-
native_ws = @native.websocket(path)
|
|
54
|
-
WebSocketTestConnection.new(native_ws)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def sse(path)
|
|
58
|
-
native_sse = @native.sse(path)
|
|
59
|
-
SseStream.new(native_sse)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def close
|
|
63
|
-
@native.close
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
%w[get post put patch delete head options trace].each do |verb|
|
|
67
|
-
define_method(verb) do |path, **options|
|
|
68
|
-
request(verb.upcase, path, **options)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# WebSocket test connection wrapper
|
|
74
|
-
class WebSocketTestConnection
|
|
75
|
-
def initialize(native_ws)
|
|
76
|
-
@native_ws = native_ws
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def send_text(text)
|
|
80
|
-
@native_ws.send_text(JSON.generate(text))
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def send_json(obj)
|
|
84
|
-
@native_ws.send_json(obj)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def receive_text
|
|
88
|
-
raw = @native_ws.receive_text
|
|
89
|
-
JSON.parse(raw)
|
|
90
|
-
rescue JSON::ParserError
|
|
91
|
-
raw
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def receive_json
|
|
95
|
-
@native_ws.receive_json
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def receive_bytes
|
|
99
|
-
receive_text
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def receive_message
|
|
103
|
-
native_msg = @native_ws.receive_message
|
|
104
|
-
WebSocketMessage.new(native_msg)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def close
|
|
108
|
-
@native_ws.close
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# WebSocket message wrapper
|
|
113
|
-
class WebSocketMessage
|
|
114
|
-
def initialize(native_msg)
|
|
115
|
-
@native_msg = native_msg
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def as_text
|
|
119
|
-
raw = @native_msg.as_text
|
|
120
|
-
return unless raw
|
|
121
|
-
|
|
122
|
-
JSON.parse(raw)
|
|
123
|
-
rescue JSON::ParserError
|
|
124
|
-
raw
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def as_json
|
|
128
|
-
@native_msg.as_json
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def as_binary
|
|
132
|
-
@native_msg.as_binary
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def close?
|
|
136
|
-
@native_msg.is_close
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
# SSE stream wrapper
|
|
141
|
-
class SseStream
|
|
142
|
-
def initialize(native_sse)
|
|
143
|
-
@native_sse = native_sse
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def body
|
|
147
|
-
@native_sse.body
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def events
|
|
151
|
-
parsed_chunks.map { |chunk| InlineSseEvent.new(chunk) }
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def events_as_json
|
|
155
|
-
parsed_chunks.filter_map do |chunk|
|
|
156
|
-
JSON.parse(chunk)
|
|
157
|
-
rescue JSON::ParserError
|
|
158
|
-
nil
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
private
|
|
163
|
-
|
|
164
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
165
|
-
def parsed_chunks
|
|
166
|
-
raw = body.to_s.gsub("\r\n", "\n")
|
|
167
|
-
events = []
|
|
168
|
-
current = []
|
|
169
|
-
|
|
170
|
-
raw.each_line do |line|
|
|
171
|
-
stripped = line.chomp
|
|
172
|
-
if stripped.start_with?('data:')
|
|
173
|
-
current << stripped[5..].strip
|
|
174
|
-
elsif stripped.empty?
|
|
175
|
-
unless current.empty?
|
|
176
|
-
data = current.join("\n").strip
|
|
177
|
-
events << data unless data.empty?
|
|
178
|
-
current = []
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
unless current.empty?
|
|
184
|
-
data = current.join("\n").strip
|
|
185
|
-
events << data unless data.empty?
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
events
|
|
189
|
-
end
|
|
190
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# SSE event wrapper
|
|
194
|
-
class SseEvent
|
|
195
|
-
def initialize(native_event)
|
|
196
|
-
@native_event = native_event
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def data
|
|
200
|
-
@native_event.data
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def as_json
|
|
204
|
-
@native_event.as_json
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
# Lightweight wrapper for parsed SSE events backed by strings.
|
|
209
|
-
class InlineSseEvent
|
|
210
|
-
attr_reader :data
|
|
211
|
-
|
|
212
|
-
def initialize(data)
|
|
213
|
-
@data = data
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def as_json
|
|
217
|
-
JSON.parse(@data)
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Spikard
|
|
6
|
+
# Testing helpers that wrap the native Ruby extension.
|
|
7
|
+
module Testing
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def create_test_client(app, config: nil)
|
|
11
|
+
unless defined?(Spikard::Native::TestClient)
|
|
12
|
+
raise LoadError, 'Spikard native test client is not available. Build the native extension before running tests.'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Allow generated apps to stash a test config
|
|
16
|
+
if config.nil? && app.instance_variable_defined?(:@__spikard_test_config)
|
|
17
|
+
config = app.instance_variable_get(:@__spikard_test_config)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Use default config if none provided
|
|
21
|
+
config ||= Spikard::ServerConfig.new
|
|
22
|
+
|
|
23
|
+
routes_json = app.normalized_routes_json
|
|
24
|
+
handlers = app.handler_map.transform_keys(&:to_sym)
|
|
25
|
+
ws_handlers = app.websocket_handlers || {}
|
|
26
|
+
sse_producers = app.sse_producers || {}
|
|
27
|
+
dependencies = app.dependencies || {}
|
|
28
|
+
native = Spikard::Native::TestClient.new(routes_json, handlers, config, ws_handlers, sse_producers, dependencies)
|
|
29
|
+
TestClient.new(native)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# High level wrapper around the native test client.
|
|
33
|
+
class TestClient
|
|
34
|
+
def initialize(native)
|
|
35
|
+
@native = native
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Factory method for creating test client from an app
|
|
39
|
+
def self.new(app_or_native, config: nil)
|
|
40
|
+
# If passed a native client directly, use it
|
|
41
|
+
return super(app_or_native) if app_or_native.is_a?(Spikard::Native::TestClient)
|
|
42
|
+
|
|
43
|
+
# Otherwise, create test client from app
|
|
44
|
+
Spikard::Testing.create_test_client(app_or_native, config: config)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def request(method, path, **options)
|
|
48
|
+
payload = @native.request(method.to_s.upcase, path, options)
|
|
49
|
+
Response.new(payload)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def websocket(path)
|
|
53
|
+
native_ws = @native.websocket(path)
|
|
54
|
+
WebSocketTestConnection.new(native_ws)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def sse(path)
|
|
58
|
+
native_sse = @native.sse(path)
|
|
59
|
+
SseStream.new(native_sse)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def close
|
|
63
|
+
@native.close
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
%w[get post put patch delete head options trace].each do |verb|
|
|
67
|
+
define_method(verb) do |path, **options|
|
|
68
|
+
request(verb.upcase, path, **options)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# WebSocket test connection wrapper
|
|
74
|
+
class WebSocketTestConnection
|
|
75
|
+
def initialize(native_ws)
|
|
76
|
+
@native_ws = native_ws
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def send_text(text)
|
|
80
|
+
@native_ws.send_text(JSON.generate(text))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def send_json(obj)
|
|
84
|
+
@native_ws.send_json(obj)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def receive_text
|
|
88
|
+
raw = @native_ws.receive_text
|
|
89
|
+
JSON.parse(raw)
|
|
90
|
+
rescue JSON::ParserError
|
|
91
|
+
raw
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def receive_json
|
|
95
|
+
@native_ws.receive_json
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def receive_bytes
|
|
99
|
+
receive_text
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def receive_message
|
|
103
|
+
native_msg = @native_ws.receive_message
|
|
104
|
+
WebSocketMessage.new(native_msg)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def close
|
|
108
|
+
@native_ws.close
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# WebSocket message wrapper
|
|
113
|
+
class WebSocketMessage
|
|
114
|
+
def initialize(native_msg)
|
|
115
|
+
@native_msg = native_msg
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def as_text
|
|
119
|
+
raw = @native_msg.as_text
|
|
120
|
+
return unless raw
|
|
121
|
+
|
|
122
|
+
JSON.parse(raw)
|
|
123
|
+
rescue JSON::ParserError
|
|
124
|
+
raw
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def as_json
|
|
128
|
+
@native_msg.as_json
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def as_binary
|
|
132
|
+
@native_msg.as_binary
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def close?
|
|
136
|
+
@native_msg.is_close
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# SSE stream wrapper
|
|
141
|
+
class SseStream
|
|
142
|
+
def initialize(native_sse)
|
|
143
|
+
@native_sse = native_sse
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def body
|
|
147
|
+
@native_sse.body
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def events
|
|
151
|
+
parsed_chunks.map { |chunk| InlineSseEvent.new(chunk) }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def events_as_json
|
|
155
|
+
parsed_chunks.filter_map do |chunk|
|
|
156
|
+
JSON.parse(chunk)
|
|
157
|
+
rescue JSON::ParserError
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
private
|
|
163
|
+
|
|
164
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
165
|
+
def parsed_chunks
|
|
166
|
+
raw = body.to_s.gsub("\r\n", "\n")
|
|
167
|
+
events = []
|
|
168
|
+
current = []
|
|
169
|
+
|
|
170
|
+
raw.each_line do |line|
|
|
171
|
+
stripped = line.chomp
|
|
172
|
+
if stripped.start_with?('data:')
|
|
173
|
+
current << stripped[5..].strip
|
|
174
|
+
elsif stripped.empty?
|
|
175
|
+
unless current.empty?
|
|
176
|
+
data = current.join("\n").strip
|
|
177
|
+
events << data unless data.empty?
|
|
178
|
+
current = []
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
unless current.empty?
|
|
184
|
+
data = current.join("\n").strip
|
|
185
|
+
events << data unless data.empty?
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
events
|
|
189
|
+
end
|
|
190
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# SSE event wrapper
|
|
194
|
+
class SseEvent
|
|
195
|
+
def initialize(native_event)
|
|
196
|
+
@native_event = native_event
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def data
|
|
200
|
+
@native_event.data
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def as_json
|
|
204
|
+
@native_event.as_json
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Lightweight wrapper for parsed SSE events backed by strings.
|
|
209
|
+
class InlineSseEvent
|
|
210
|
+
attr_reader :data
|
|
211
|
+
|
|
212
|
+
def initialize(data)
|
|
213
|
+
@data = data
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def as_json
|
|
217
|
+
JSON.parse(@data)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|