spikard 0.8.3 → 0.10.2
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/README.md +19 -10
- data/ext/spikard_rb/Cargo.lock +234 -162
- data/ext/spikard_rb/Cargo.toml +2 -2
- data/ext/spikard_rb/extconf.rb +4 -3
- data/lib/spikard/config.rb +88 -12
- data/lib/spikard/testing.rb +3 -1
- data/lib/spikard/version.rb +1 -1
- data/lib/spikard.rb +11 -0
- data/vendor/crates/spikard-bindings-shared/Cargo.toml +3 -6
- data/vendor/crates/spikard-bindings-shared/examples/config_extraction.rs +8 -8
- data/vendor/crates/spikard-bindings-shared/src/config_extractor.rs +2 -2
- data/vendor/crates/spikard-bindings-shared/src/conversion_traits.rs +4 -4
- data/vendor/crates/spikard-bindings-shared/src/di_traits.rs +10 -4
- data/vendor/crates/spikard-bindings-shared/src/error_response.rs +3 -3
- data/vendor/crates/spikard-bindings-shared/src/handler_base.rs +10 -5
- data/vendor/crates/spikard-bindings-shared/src/json_conversion.rs +829 -0
- data/vendor/crates/spikard-bindings-shared/src/lazy_cache.rs +587 -0
- data/vendor/crates/spikard-bindings-shared/src/lib.rs +7 -0
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_base.rs +11 -11
- data/vendor/crates/spikard-bindings-shared/src/lifecycle_executor.rs +9 -37
- data/vendor/crates/spikard-bindings-shared/src/response_builder.rs +436 -3
- data/vendor/crates/spikard-bindings-shared/src/response_interpreter.rs +944 -0
- data/vendor/crates/spikard-bindings-shared/src/test_client_base.rs +4 -4
- data/vendor/crates/spikard-bindings-shared/tests/config_extractor_behavior.rs +3 -2
- data/vendor/crates/spikard-bindings-shared/tests/error_response_edge_cases.rs +13 -13
- data/vendor/crates/spikard-bindings-shared/tests/{comprehensive_coverage.rs → full_coverage.rs} +10 -5
- data/vendor/crates/spikard-bindings-shared/tests/handler_base_integration.rs +14 -14
- data/vendor/crates/spikard-bindings-shared/tests/integration_tests.rs +669 -0
- data/vendor/crates/spikard-core/Cargo.toml +3 -3
- data/vendor/crates/spikard-core/src/di/container.rs +1 -1
- data/vendor/crates/spikard-core/src/di/factory.rs +2 -2
- data/vendor/crates/spikard-core/src/di/resolved.rs +2 -2
- data/vendor/crates/spikard-core/src/di/value.rs +1 -1
- data/vendor/crates/spikard-core/src/http.rs +75 -0
- data/vendor/crates/spikard-core/src/lifecycle.rs +43 -43
- data/vendor/crates/spikard-core/src/parameters.rs +14 -19
- data/vendor/crates/spikard-core/src/problem.rs +1 -1
- data/vendor/crates/spikard-core/src/request_data.rs +7 -16
- data/vendor/crates/spikard-core/src/router.rs +6 -0
- data/vendor/crates/spikard-core/src/schema_registry.rs +2 -3
- data/vendor/crates/spikard-core/src/type_hints.rs +3 -2
- data/vendor/crates/spikard-core/src/validation/error_mapper.rs +1 -1
- data/vendor/crates/spikard-core/src/validation/mod.rs +1 -1
- data/vendor/crates/spikard-core/tests/di_dependency_defaults.rs +1 -1
- data/vendor/crates/spikard-core/tests/error_mapper.rs +2 -2
- data/vendor/crates/spikard-core/tests/parameters_edge_cases.rs +1 -1
- data/vendor/crates/spikard-core/tests/parameters_full.rs +1 -1
- data/vendor/crates/spikard-core/tests/parameters_schema_and_formats.rs +1 -1
- data/vendor/crates/spikard-core/tests/validation_coverage.rs +4 -4
- data/vendor/crates/spikard-http/Cargo.toml +4 -2
- data/vendor/crates/spikard-http/src/cors.rs +32 -11
- data/vendor/crates/spikard-http/src/di_handler.rs +12 -8
- data/vendor/crates/spikard-http/src/grpc/framing.rs +469 -0
- data/vendor/crates/spikard-http/src/grpc/handler.rs +887 -25
- data/vendor/crates/spikard-http/src/grpc/mod.rs +114 -22
- data/vendor/crates/spikard-http/src/grpc/service.rs +232 -2
- data/vendor/crates/spikard-http/src/grpc/streaming.rs +80 -2
- data/vendor/crates/spikard-http/src/handler_trait.rs +204 -27
- data/vendor/crates/spikard-http/src/handler_trait_tests.rs +15 -15
- data/vendor/crates/spikard-http/src/jsonrpc/http_handler.rs +2 -2
- data/vendor/crates/spikard-http/src/jsonrpc/router.rs +2 -2
- data/vendor/crates/spikard-http/src/lib.rs +1 -1
- data/vendor/crates/spikard-http/src/lifecycle/adapter.rs +2 -2
- data/vendor/crates/spikard-http/src/lifecycle.rs +4 -4
- data/vendor/crates/spikard-http/src/openapi/spec_generation.rs +2 -0
- data/vendor/crates/spikard-http/src/server/fast_router.rs +186 -0
- data/vendor/crates/spikard-http/src/server/grpc_routing.rs +324 -23
- data/vendor/crates/spikard-http/src/server/handler.rs +33 -22
- data/vendor/crates/spikard-http/src/server/lifecycle_execution.rs +21 -2
- data/vendor/crates/spikard-http/src/server/mod.rs +125 -20
- data/vendor/crates/spikard-http/src/server/request_extraction.rs +126 -44
- data/vendor/crates/spikard-http/src/server/routing_factory.rs +80 -69
- data/vendor/crates/spikard-http/tests/common/handlers.rs +2 -2
- data/vendor/crates/spikard-http/tests/common/test_builders.rs +12 -12
- data/vendor/crates/spikard-http/tests/di_handler_error_responses.rs +2 -2
- data/vendor/crates/spikard-http/tests/di_integration.rs +6 -6
- data/vendor/crates/spikard-http/tests/grpc_bidirectional_streaming.rs +430 -0
- data/vendor/crates/spikard-http/tests/grpc_client_streaming.rs +738 -0
- data/vendor/crates/spikard-http/tests/grpc_integration_test.rs +13 -9
- data/vendor/crates/spikard-http/tests/grpc_server_streaming.rs +974 -0
- data/vendor/crates/spikard-http/tests/lifecycle_execution.rs +2 -2
- data/vendor/crates/spikard-http/tests/request_extraction_full.rs +4 -4
- data/vendor/crates/spikard-http/tests/server_config_builder.rs +2 -2
- data/vendor/crates/spikard-http/tests/server_cors_preflight.rs +1 -0
- data/vendor/crates/spikard-http/tests/server_openapi_jsonrpc_static.rs +140 -0
- data/vendor/crates/spikard-rb/Cargo.toml +3 -1
- data/vendor/crates/spikard-rb/src/conversion.rs +138 -4
- data/vendor/crates/spikard-rb/src/grpc/handler.rs +706 -229
- data/vendor/crates/spikard-rb/src/grpc/mod.rs +6 -2
- data/vendor/crates/spikard-rb/src/gvl.rs +2 -2
- data/vendor/crates/spikard-rb/src/handler.rs +169 -91
- data/vendor/crates/spikard-rb/src/lib.rs +444 -62
- data/vendor/crates/spikard-rb/src/lifecycle.rs +29 -1
- data/vendor/crates/spikard-rb/src/metadata/route_extraction.rs +108 -43
- data/vendor/crates/spikard-rb/src/request.rs +117 -20
- data/vendor/crates/spikard-rb/src/runtime/server_runner.rs +52 -25
- data/vendor/crates/spikard-rb/src/server.rs +23 -14
- data/vendor/crates/spikard-rb/src/testing/client.rs +5 -4
- data/vendor/crates/spikard-rb/src/testing/sse.rs +1 -36
- data/vendor/crates/spikard-rb/src/testing/websocket.rs +3 -38
- data/vendor/crates/spikard-rb/src/websocket.rs +32 -23
- data/vendor/crates/spikard-rb-macros/Cargo.toml +1 -1
- metadata +14 -4
- data/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/mise.toml +0 -5
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml +0 -2
|
@@ -119,17 +119,26 @@ pub fn run_server(
|
|
|
119
119
|
}
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
122
|
+
// Fast-path: if the route metadata declares a static_response, use StaticResponseHandler
|
|
123
|
+
if let Some(ref sr_value) = route_meta.static_response {
|
|
124
|
+
let status = sr_value.get("status").and_then(|v| v.as_u64()).unwrap_or(200) as u16;
|
|
125
|
+
let body = sr_value.get("body").and_then(|v| v.as_str()).unwrap_or("").to_string();
|
|
126
|
+
let content_type = sr_value.get("content_type").and_then(|v| v.as_str());
|
|
127
|
+
let static_handler = spikard_http::StaticResponseHandler::from_parts(status, body, content_type, vec![]);
|
|
128
|
+
routes_with_handlers.push((route, Arc::new(static_handler) as Arc<dyn Handler>));
|
|
129
|
+
} else {
|
|
130
|
+
let ruby_handler = RubyHandler::new_for_server(
|
|
131
|
+
ruby,
|
|
132
|
+
handler_value,
|
|
133
|
+
route_meta.handler_name.clone(),
|
|
134
|
+
route_meta.method.clone(),
|
|
135
|
+
route_meta.path.clone(),
|
|
136
|
+
json_module,
|
|
137
|
+
&route,
|
|
138
|
+
)?;
|
|
139
|
+
|
|
140
|
+
routes_with_handlers.push((route, Arc::new(ruby_handler) as Arc<dyn Handler>));
|
|
141
|
+
}
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
let lifecycle_hooks = if !hooks_value.is_nil() {
|
|
@@ -204,9 +213,9 @@ pub fn run_server(
|
|
|
204
213
|
.ok_or_else(|| Error::new(ruby.exception_arg_error(), "WebSocket handlers must be a Hash"))?;
|
|
205
214
|
|
|
206
215
|
ws_hash.foreach(|path: String, factory: Value| -> Result<ForEach, Error> {
|
|
207
|
-
let ws_state = crate::websocket::create_websocket_state(ruby, factory)
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
if let Some(ws_state) = crate::websocket::create_websocket_state(ruby, factory)? {
|
|
217
|
+
ws_endpoints.push((path, ws_state));
|
|
218
|
+
}
|
|
210
219
|
|
|
211
220
|
Ok(ForEach::Continue)
|
|
212
221
|
})?;
|
|
@@ -127,9 +127,10 @@ impl NativeTestClient {
|
|
|
127
127
|
let mut route_metadata_vec = Vec::with_capacity(metadata.len());
|
|
128
128
|
|
|
129
129
|
for meta in metadata.clone() {
|
|
130
|
-
|
|
130
|
+
crate::validate_route_metadata(ruby, &meta)?;
|
|
131
131
|
let route = Route::from_metadata(meta.clone(), &schema_registry)
|
|
132
132
|
.map_err(|err| Error::new(ruby.exception_runtime_error(), format!("Failed to build route: {err}")))?;
|
|
133
|
+
let handler_value = crate::conversion::fetch_handler(ruby, &handlers_hash, &meta.handler_name)?;
|
|
133
134
|
|
|
134
135
|
let handler = RubyHandler::new(&route, handler_value, json_module)?;
|
|
135
136
|
prepared_routes.push((route, Arc::new(handler.clone()) as Arc<dyn spikard_http::Handler>));
|
|
@@ -153,9 +154,9 @@ impl NativeTestClient {
|
|
|
153
154
|
|
|
154
155
|
ws_hash.foreach(
|
|
155
156
|
|path: String, factory: Value| -> Result<magnus::r_hash::ForEach, Error> {
|
|
156
|
-
let ws_state = crate::websocket::create_websocket_state(ruby, factory)
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
if let Some(ws_state) = crate::websocket::create_websocket_state(ruby, factory)? {
|
|
158
|
+
ws_endpoints.push((path, ws_state));
|
|
159
|
+
}
|
|
159
160
|
|
|
160
161
|
Ok(magnus::r_hash::ForEach::Continue)
|
|
161
162
|
},
|
|
@@ -88,42 +88,7 @@ pub fn sse_stream_from_response(ruby: &Ruby, response: &ResponseSnapshot) -> Res
|
|
|
88
88
|
|
|
89
89
|
/// Helper to convert JSON to Ruby object
|
|
90
90
|
fn json_to_ruby(ruby: &Ruby, value: &JsonValue) -> Result<Value, Error> {
|
|
91
|
-
|
|
92
|
-
JsonValue::Null => Ok(ruby.qnil().as_value()),
|
|
93
|
-
JsonValue::Bool(b) => Ok(if *b {
|
|
94
|
-
ruby.qtrue().as_value()
|
|
95
|
-
} else {
|
|
96
|
-
ruby.qfalse().as_value()
|
|
97
|
-
}),
|
|
98
|
-
JsonValue::Number(n) => {
|
|
99
|
-
if let Some(i) = n.as_i64() {
|
|
100
|
-
Ok(ruby.integer_from_i64(i).as_value())
|
|
101
|
-
} else if let Some(u) = n.as_u64() {
|
|
102
|
-
Ok(ruby.integer_from_i64(u as i64).as_value())
|
|
103
|
-
} else if let Some(f) = n.as_f64() {
|
|
104
|
-
Ok(ruby.float_from_f64(f).as_value())
|
|
105
|
-
} else {
|
|
106
|
-
Ok(ruby.qnil().as_value())
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
JsonValue::String(s) => Ok(ruby.str_new(s).as_value()),
|
|
110
|
-
JsonValue::Array(arr) => {
|
|
111
|
-
let ruby_arr = ruby.ary_new();
|
|
112
|
-
for item in arr {
|
|
113
|
-
let ruby_val = json_to_ruby(ruby, item)?;
|
|
114
|
-
ruby_arr.push(ruby_val)?;
|
|
115
|
-
}
|
|
116
|
-
Ok(ruby_arr.as_value())
|
|
117
|
-
}
|
|
118
|
-
JsonValue::Object(obj) => {
|
|
119
|
-
let ruby_hash = ruby.hash_new();
|
|
120
|
-
for (key, val) in obj {
|
|
121
|
-
let ruby_val = json_to_ruby(ruby, val)?;
|
|
122
|
-
ruby_hash.aset(ruby.str_new(key), ruby_val)?;
|
|
123
|
-
}
|
|
124
|
-
Ok(ruby_hash.as_value())
|
|
125
|
-
}
|
|
126
|
-
}
|
|
91
|
+
crate::conversion::json_to_ruby(ruby, value)
|
|
127
92
|
}
|
|
128
93
|
|
|
129
94
|
/// Initialize SSE test client bindings
|
|
@@ -11,14 +11,14 @@ use tungstenite::{Message, WebSocket};
|
|
|
11
11
|
use url::Url;
|
|
12
12
|
|
|
13
13
|
#[derive(Debug)]
|
|
14
|
-
pub
|
|
14
|
+
pub enum WebSocketIoError {
|
|
15
15
|
Timeout,
|
|
16
16
|
Closed,
|
|
17
17
|
Other(String),
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
#[derive(Debug)]
|
|
21
|
-
pub
|
|
21
|
+
pub struct WebSocketConnection {
|
|
22
22
|
stream: WebSocket<MaybeTlsStream<TcpStream>>,
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -547,42 +547,7 @@ fn ruby_to_json(ruby: &Ruby, value: Value) -> Result<JsonValue, Error> {
|
|
|
547
547
|
|
|
548
548
|
/// Helper to convert JSON to Ruby object
|
|
549
549
|
fn json_to_ruby(ruby: &Ruby, value: &JsonValue) -> Result<Value, Error> {
|
|
550
|
-
|
|
551
|
-
JsonValue::Null => Ok(ruby.qnil().as_value()),
|
|
552
|
-
JsonValue::Bool(b) => Ok(if *b {
|
|
553
|
-
ruby.qtrue().as_value()
|
|
554
|
-
} else {
|
|
555
|
-
ruby.qfalse().as_value()
|
|
556
|
-
}),
|
|
557
|
-
JsonValue::Number(n) => {
|
|
558
|
-
if let Some(i) = n.as_i64() {
|
|
559
|
-
Ok(ruby.integer_from_i64(i).as_value())
|
|
560
|
-
} else if let Some(u) = n.as_u64() {
|
|
561
|
-
Ok(ruby.integer_from_i64(u as i64).as_value())
|
|
562
|
-
} else if let Some(f) = n.as_f64() {
|
|
563
|
-
Ok(ruby.float_from_f64(f).as_value())
|
|
564
|
-
} else {
|
|
565
|
-
Ok(ruby.qnil().as_value())
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
JsonValue::String(s) => Ok(ruby.str_new(s).as_value()),
|
|
569
|
-
JsonValue::Array(arr) => {
|
|
570
|
-
let ruby_arr = ruby.ary_new();
|
|
571
|
-
for item in arr {
|
|
572
|
-
let ruby_val = json_to_ruby(ruby, item)?;
|
|
573
|
-
ruby_arr.push(ruby_val)?;
|
|
574
|
-
}
|
|
575
|
-
Ok(ruby_arr.as_value())
|
|
576
|
-
}
|
|
577
|
-
JsonValue::Object(obj) => {
|
|
578
|
-
let ruby_hash = ruby.hash_new();
|
|
579
|
-
for (key, val) in obj {
|
|
580
|
-
let ruby_val = json_to_ruby(ruby, val)?;
|
|
581
|
-
ruby_hash.aset(ruby.str_new(key), ruby_val)?;
|
|
582
|
-
}
|
|
583
|
-
Ok(ruby_hash.as_value())
|
|
584
|
-
}
|
|
585
|
-
}
|
|
550
|
+
crate::conversion::json_to_ruby(ruby, value)
|
|
586
551
|
}
|
|
587
552
|
|
|
588
553
|
/// Initialize WebSocket test client bindings
|
|
@@ -189,12 +189,11 @@ impl WebSocketHandler for RubyWebSocketHandler {
|
|
|
189
189
|
return None;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
let result =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
192
|
+
let result = if let Ok(result) = reply_rx.await {
|
|
193
|
+
result
|
|
194
|
+
} else {
|
|
195
|
+
error!("Ruby WebSocket handler '{}' response channel closed", self.name);
|
|
196
|
+
return None;
|
|
198
197
|
};
|
|
199
198
|
|
|
200
199
|
match result {
|
|
@@ -220,12 +219,11 @@ impl WebSocketHandler for RubyWebSocketHandler {
|
|
|
220
219
|
return;
|
|
221
220
|
}
|
|
222
221
|
|
|
223
|
-
let result =
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
222
|
+
let result = if let Ok(result) = reply_rx.await {
|
|
223
|
+
result
|
|
224
|
+
} else {
|
|
225
|
+
error!("Ruby WebSocket handler '{}' on_connect channel closed", self.name);
|
|
226
|
+
return;
|
|
229
227
|
};
|
|
230
228
|
|
|
231
229
|
if let Err(e) = result {
|
|
@@ -250,12 +248,11 @@ impl WebSocketHandler for RubyWebSocketHandler {
|
|
|
250
248
|
return;
|
|
251
249
|
}
|
|
252
250
|
|
|
253
|
-
let result =
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
251
|
+
let result = if let Ok(result) = reply_rx.await {
|
|
252
|
+
result
|
|
253
|
+
} else {
|
|
254
|
+
error!("Ruby WebSocket handler '{}' on_disconnect channel closed", self.name);
|
|
255
|
+
return;
|
|
259
256
|
};
|
|
260
257
|
|
|
261
258
|
if let Err(e) = result {
|
|
@@ -349,11 +346,13 @@ unsafe impl Sync for RubyWebSocketHandler {}
|
|
|
349
346
|
/// Create WebSocketState from Ruby handler object
|
|
350
347
|
///
|
|
351
348
|
/// This function is designed to be called from Ruby to register WebSocket handlers.
|
|
349
|
+
/// Returns None if the factory returns nil (no handler for this endpoint).
|
|
352
350
|
#[allow(dead_code)]
|
|
353
351
|
pub fn create_websocket_state(
|
|
354
352
|
ruby: &magnus::Ruby,
|
|
355
353
|
handler_factory: Value,
|
|
356
|
-
) -> Result<spikard_http::WebSocketState<RubyWebSocketHandler
|
|
354
|
+
) -> Result<Option<spikard_http::WebSocketState<RubyWebSocketHandler>>, magnus::Error> {
|
|
355
|
+
// Test the factory with an initial call to check if it returns nil
|
|
357
356
|
let handler_instance: Value = handler_factory.funcall("call", ()).map_err(|e| {
|
|
358
357
|
magnus::Error::new(
|
|
359
358
|
ruby.exception_runtime_error(),
|
|
@@ -361,6 +360,11 @@ pub fn create_websocket_state(
|
|
|
361
360
|
)
|
|
362
361
|
})?;
|
|
363
362
|
|
|
363
|
+
// If factory returns nil, skip creating a handler (return None)
|
|
364
|
+
if handler_instance.is_nil() {
|
|
365
|
+
return Ok(None);
|
|
366
|
+
}
|
|
367
|
+
|
|
364
368
|
let message_schema = handler_instance
|
|
365
369
|
.funcall::<_, _, Value>("instance_variable_get", (ruby.to_symbol("@_message_schema"),))
|
|
366
370
|
.ok()
|
|
@@ -383,6 +387,8 @@ pub fn create_websocket_state(
|
|
|
383
387
|
}
|
|
384
388
|
});
|
|
385
389
|
|
|
390
|
+
let (message_schema, response_schema) = (message_schema, response_schema);
|
|
391
|
+
|
|
386
392
|
let handler_factory = Opaque::from(handler_factory);
|
|
387
393
|
let (factory_tx, factory_rx) = mpsc::channel();
|
|
388
394
|
|
|
@@ -415,13 +421,15 @@ pub fn create_websocket_state(
|
|
|
415
421
|
}
|
|
416
422
|
};
|
|
417
423
|
|
|
418
|
-
if message_schema.is_some() || response_schema.is_some() {
|
|
424
|
+
let ws_state = if message_schema.is_some() || response_schema.is_some() {
|
|
419
425
|
spikard_http::WebSocketState::with_factory(handler_builder, message_schema, response_schema)
|
|
420
|
-
.map_err(|e| magnus::Error::new(ruby.exception_runtime_error(), e))
|
|
426
|
+
.map_err(|e| magnus::Error::new(ruby.exception_runtime_error(), e))?
|
|
421
427
|
} else {
|
|
422
428
|
spikard_http::WebSocketState::with_factory(handler_builder, None, None)
|
|
423
|
-
.map_err(|e| magnus::Error::new(ruby.exception_runtime_error(), e))
|
|
424
|
-
}
|
|
429
|
+
.map_err(|e| magnus::Error::new(ruby.exception_runtime_error(), e))?
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
Ok(Some(ws_state))
|
|
425
433
|
}
|
|
426
434
|
|
|
427
435
|
fn websocket_factory_worker_loop(
|
|
@@ -447,6 +455,7 @@ fn websocket_factory_worker_loop(
|
|
|
447
455
|
let handler_instance: Value = factory_value
|
|
448
456
|
.funcall("call", ())
|
|
449
457
|
.map_err(|e| format!("Failed to create WebSocket handler: {}", e))?;
|
|
458
|
+
|
|
450
459
|
RubyWebSocketHandler::from_handler(ruby, handler_instance).map_err(|e| e.to_string())
|
|
451
460
|
})();
|
|
452
461
|
let _ = reply.send(result);
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spikard
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Na'aman Hirschfeld
|
|
@@ -83,8 +83,6 @@ files:
|
|
|
83
83
|
- lib/spikard/version.rb
|
|
84
84
|
- lib/spikard/websocket.rb
|
|
85
85
|
- sig/spikard.rbs
|
|
86
|
-
- vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/mise.toml
|
|
87
|
-
- vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.10.0/build/buildkitd.toml
|
|
88
86
|
- vendor/crates/spikard-bindings-shared/Cargo.toml
|
|
89
87
|
- vendor/crates/spikard-bindings-shared/examples/config_extraction.rs
|
|
90
88
|
- vendor/crates/spikard-bindings-shared/src/config_extractor.rs
|
|
@@ -93,16 +91,20 @@ files:
|
|
|
93
91
|
- vendor/crates/spikard-bindings-shared/src/error_response.rs
|
|
94
92
|
- vendor/crates/spikard-bindings-shared/src/grpc_metadata.rs
|
|
95
93
|
- vendor/crates/spikard-bindings-shared/src/handler_base.rs
|
|
94
|
+
- vendor/crates/spikard-bindings-shared/src/json_conversion.rs
|
|
95
|
+
- vendor/crates/spikard-bindings-shared/src/lazy_cache.rs
|
|
96
96
|
- vendor/crates/spikard-bindings-shared/src/lib.rs
|
|
97
97
|
- vendor/crates/spikard-bindings-shared/src/lifecycle_base.rs
|
|
98
98
|
- vendor/crates/spikard-bindings-shared/src/lifecycle_executor.rs
|
|
99
99
|
- vendor/crates/spikard-bindings-shared/src/response_builder.rs
|
|
100
|
+
- vendor/crates/spikard-bindings-shared/src/response_interpreter.rs
|
|
100
101
|
- vendor/crates/spikard-bindings-shared/src/test_client_base.rs
|
|
101
102
|
- vendor/crates/spikard-bindings-shared/src/validation_helpers.rs
|
|
102
|
-
- vendor/crates/spikard-bindings-shared/tests/comprehensive_coverage.rs
|
|
103
103
|
- vendor/crates/spikard-bindings-shared/tests/config_extractor_behavior.rs
|
|
104
104
|
- vendor/crates/spikard-bindings-shared/tests/error_response_edge_cases.rs
|
|
105
|
+
- vendor/crates/spikard-bindings-shared/tests/full_coverage.rs
|
|
105
106
|
- vendor/crates/spikard-bindings-shared/tests/handler_base_integration.rs
|
|
107
|
+
- vendor/crates/spikard-bindings-shared/tests/integration_tests.rs
|
|
106
108
|
- vendor/crates/spikard-core/Cargo.toml
|
|
107
109
|
- vendor/crates/spikard-core/src/bindings/mod.rs
|
|
108
110
|
- vendor/crates/spikard-core/src/bindings/response.rs
|
|
@@ -148,6 +150,7 @@ files:
|
|
|
148
150
|
- vendor/crates/spikard-http/src/cors.rs
|
|
149
151
|
- vendor/crates/spikard-http/src/debug.rs
|
|
150
152
|
- vendor/crates/spikard-http/src/di_handler.rs
|
|
153
|
+
- vendor/crates/spikard-http/src/grpc/framing.rs
|
|
151
154
|
- vendor/crates/spikard-http/src/grpc/handler.rs
|
|
152
155
|
- vendor/crates/spikard-http/src/grpc/mod.rs
|
|
153
156
|
- vendor/crates/spikard-http/src/grpc/service.rs
|
|
@@ -173,6 +176,7 @@ files:
|
|
|
173
176
|
- vendor/crates/spikard-http/src/openapi/spec_generation.rs
|
|
174
177
|
- vendor/crates/spikard-http/src/query_parser.rs
|
|
175
178
|
- vendor/crates/spikard-http/src/response.rs
|
|
179
|
+
- vendor/crates/spikard-http/src/server/fast_router.rs
|
|
176
180
|
- vendor/crates/spikard-http/src/server/grpc_routing.rs
|
|
177
181
|
- vendor/crates/spikard-http/src/server/handler.rs
|
|
178
182
|
- vendor/crates/spikard-http/src/server/lifecycle_execution.rs
|
|
@@ -194,10 +198,13 @@ files:
|
|
|
194
198
|
- vendor/crates/spikard-http/tests/di_handler_error_responses.rs
|
|
195
199
|
- vendor/crates/spikard-http/tests/di_integration.rs
|
|
196
200
|
- vendor/crates/spikard-http/tests/doc_snippets.rs
|
|
201
|
+
- vendor/crates/spikard-http/tests/grpc_bidirectional_streaming.rs
|
|
202
|
+
- vendor/crates/spikard-http/tests/grpc_client_streaming.rs
|
|
197
203
|
- vendor/crates/spikard-http/tests/grpc_error_handling_test.rs
|
|
198
204
|
- vendor/crates/spikard-http/tests/grpc_integration_test.rs
|
|
199
205
|
- vendor/crates/spikard-http/tests/grpc_metadata_test.rs
|
|
200
206
|
- vendor/crates/spikard-http/tests/grpc_server_integration.rs
|
|
207
|
+
- vendor/crates/spikard-http/tests/grpc_server_streaming.rs
|
|
201
208
|
- vendor/crates/spikard-http/tests/lifecycle_execution.rs
|
|
202
209
|
- vendor/crates/spikard-http/tests/middleware_stack_integration.rs
|
|
203
210
|
- vendor/crates/spikard-http/tests/multipart_behavior.rs
|
|
@@ -271,6 +278,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
271
278
|
- - ">="
|
|
272
279
|
- !ruby/object:Gem::Version
|
|
273
280
|
version: 3.2.0
|
|
281
|
+
- - "<"
|
|
282
|
+
- !ruby/object:Gem::Version
|
|
283
|
+
version: '5.0'
|
|
274
284
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
275
285
|
requirements:
|
|
276
286
|
- - ">="
|