@@ -777,7 +777,7 @@ fn generate_request_response_enums(
777777 // Parameter-less handlers are dispatched directly in Phase 1, not through enum deserialization
778778 let request_variants = function_metadata
779779 . iter ( )
780- . filter ( |func| !func. params . is_empty ( ) ) // Only include handlers with parameters
780+ // .filter(|func| !func.params.is_empty()) // Only include handlers with parameters
781781 . map ( |func| {
782782 let variant_name = format_ident ! ( "{}" , & func. variant_name) ;
783783 generate_enum_variant ( & variant_name, & func. params )
@@ -827,7 +827,7 @@ fn generate_enum_variant(
827827 if params. is_empty ( ) {
828828 // Changed to a struct variant with no fields for functions with no parameters
829829 // This matches the JSON format {"VariantName": {}} sent by the client
830- quote ! { #variant_name{ } }
830+ quote ! { #variant_name }
831831 } else if params. len ( ) == 1 {
832832 // Simple tuple variant for single parameter
833833 let param_type = & params[ 0 ] ;
@@ -923,11 +923,25 @@ fn generate_response_handling(
923923 quote ! {
924924 // Instead of wrapping in HPMResponse enum, directly serialize the result
925925 let response_bytes = serde_json:: to_vec( & result) . unwrap( ) ;
926+
927+ // Get headers from APP_HELPERS if any are set
928+ let headers_opt = hyperware_app_common:: APP_HELPERS . with( |ctx| {
929+ let helpers = ctx. borrow( ) ;
930+ if helpers. response_headers. is_empty( ) {
931+ None
932+ } else {
933+ Some ( helpers. response_headers. clone( ) )
934+ }
935+ } ) ;
936+
926937 hyperware_process_lib:: http:: server:: send_response(
927938 hyperware_process_lib:: http:: StatusCode :: OK ,
928- None ,
939+ headers_opt ,
929940 response_bytes
930941 ) ;
942+
943+ // Clear headers after sending response
944+ hyperware_app_common:: clear_response_headers( ) ;
931945 }
932946 }
933947 }
@@ -1238,10 +1252,6 @@ fn generate_message_handlers(
12381252 format!( "Handler {} requires a request body" , stringify!( #fn_name) ) . into_bytes( )
12391253 ) ;
12401254 }
1241-
1242- hyperware_app_common:: APP_HELPERS . with( |ctx| {
1243- ctx. borrow_mut( ) . current_path = None ;
1244- } ) ;
12451255 return ;
12461256 }
12471257 }
@@ -1271,28 +1281,31 @@ fn generate_message_handlers(
12711281 return ;
12721282 }
12731283 } ;
1284+
1285+ // Get headers from APP_HELPERS if any are set
1286+ let headers_opt = hyperware_app_common:: APP_HELPERS . with( |ctx| {
1287+ let helpers = ctx. borrow( ) ;
1288+ if helpers. response_headers. is_empty( ) {
1289+ None
1290+ } else {
1291+ Some ( helpers. response_headers. clone( ) )
1292+ }
1293+ } ) ;
1294+
12741295 hyperware_process_lib:: http:: server:: send_response(
12751296 hyperware_process_lib:: http:: StatusCode :: OK ,
1276- None ,
1297+ headers_opt ,
12771298 response_bytes
12781299 ) ;
1300+
1301+ // Clear headers after sending response
1302+ hyperware_app_common:: clear_response_headers( ) ;
12791303 } ;
12801304
12811305 let handler_body = if handler. is_async {
12821306 quote ! {
1283- // Capture context values before async execution
1284- let current_path = hyperware_app_common:: get_path( ) ;
1285- let current_method = hyperware_app_common:: get_http_method( ) ;
1286-
12871307 let state_ptr: * mut #self_ty = state;
12881308 hyperware_app_common:: hyper! {
1289- // Restore context in the async task
1290- hyperware_app_common:: APP_HELPERS . with( |ctx| {
1291- let mut ctx_mut = ctx. borrow_mut( ) ;
1292- ctx_mut. current_path = current_path;
1293- ctx_mut. current_http_method = current_method;
1294- } ) ;
1295-
12961309 let result = unsafe { ( * state_ptr) . #fn_name( ) . await } ;
12971310 #response_handling
12981311 }
@@ -1312,9 +1325,6 @@ fn generate_message_handlers(
13121325 if #path_check && #method_check {
13131326 hyperware_process_lib:: logging:: debug!( "Matched parameter-less handler {} for {} {}" , stringify!( #fn_name) , http_method, current_path) ;
13141327 #handler_body
1315- hyperware_app_common:: APP_HELPERS . with( |ctx| {
1316- ctx. borrow_mut( ) . current_path = None ;
1317- } ) ;
13181328 return ;
13191329 }
13201330 }
@@ -1390,9 +1400,6 @@ fn generate_message_handlers(
13901400 #http_request_match_arms
13911401 hyperware_app_common:: maybe_save_state( & mut * state) ;
13921402 }
1393- hyperware_app_common:: APP_HELPERS . with( |ctx| {
1394- ctx. borrow_mut( ) . current_path = None ;
1395- } ) ;
13961403 return ;
13971404 } ,
13981405 Err ( e) => {
@@ -1418,9 +1425,6 @@ fn generate_message_handlers(
14181425 None ,
14191426 error_details. into_bytes( )
14201427 ) ;
1421- hyperware_app_common:: APP_HELPERS . with( |ctx| {
1422- ctx. borrow_mut( ) . current_path = None ;
1423- } ) ;
14241428 return ;
14251429 }
14261430 }
@@ -1438,9 +1442,6 @@ fn generate_message_handlers(
14381442 None ,
14391443 format!( "No handler found for {} {}" , http_method, current_path) . into_bytes( ) ,
14401444 ) ;
1441- hyperware_app_common:: APP_HELPERS . with( |ctx| {
1442- ctx. borrow_mut( ) . current_path = None ;
1443- } ) ;
14441445 } ,
14451446 hyperware_process_lib:: http:: server:: HttpServerRequest :: WebSocketPush { channel_id, message_type } => {
14461447 hyperware_process_lib:: logging:: debug!( "Received WebSocket message on channel {}, type: {:?}" , channel_id, message_type) ;
@@ -1581,7 +1582,7 @@ fn generate_component_impl(
15811582 // Extract values from args for use in the quote macro
15821583 let name = & args. name ;
15831584 let endpoints = & args. endpoints ;
1584- let _save_config = & args. save_config ;
1585+ let save_config = & args. save_config ;
15851586 let wit_world = & args. wit_world ;
15861587
15871588 let icon = match & args. icon {
@@ -1655,6 +1656,11 @@ fn generate_component_impl(
16551656 // Initialize our state
16561657 let mut state = hyperware_app_common:: initialize_state:: <#self_ty>( ) ;
16571658
1659+ // Set to persist state according to user setting
1660+ hyperware_app_common:: APP_CONTEXT . with( |ctx| {
1661+ ctx. borrow_mut( ) . hidden_state = Some ( hyperware_app_common:: HiddenState :: new( #save_config) ) ;
1662+ } ) ;
1663+
16581664 // Set up necessary components
16591665 let app_name = #name;
16601666 let app_icon = #icon;
@@ -1691,6 +1697,11 @@ fn generate_component_impl(
16911697 hyperware_app_common:: APP_HELPERS . with( |ctx| {
16921698 ctx. borrow_mut( ) . current_message = Some ( message. clone( ) ) ;
16931699 } ) ;
1700+
1701+ // Store old state if needed (for OnDiff save option)
1702+ // This only stores if old_state is None (first time or after a save)
1703+ hyperware_app_common:: store_old_state( & state) ;
1704+
16941705 match message {
16951706 hyperware_process_lib:: Message :: Response { body, context, .. } => {
16961707 let correlation_id = context
@@ -1706,6 +1717,12 @@ fn generate_component_impl(
17061717 hyperware_process_lib:: Message :: Request { .. } => {
17071718 if message. is_local( ) && message. source( ) . process == "http-server:distro:sys" {
17081719 handle_http_server_message( & mut state, message) ;
1720+ hyperware_app_common:: APP_HELPERS . with( |ctx| {
1721+ let mut ctx_mut = ctx. borrow_mut( ) ;
1722+ ctx_mut. current_path = None ;
1723+ ctx_mut. current_http_method = None ;
1724+ ctx_mut. response_headers = std:: collections:: HashMap :: new( ) ;
1725+ } ) ;
17091726 } else if message. is_local( ) {
17101727 handle_local_message( & mut state, message) ;
17111728 } else {
@@ -1773,15 +1790,15 @@ pub fn hyperprocess(attr: TokenStream, item: TokenStream) -> TokenStream {
17731790 let http_handlers_with_params: Vec < _ > = handlers
17741791 . http
17751792 . iter ( )
1776- . filter ( |h| !h. params . is_empty ( ) )
1793+ // .filter(|h| !h.params.is_empty())
17771794 . cloned ( )
17781795 . collect ( ) ;
17791796
17801797 // Collect all function metadata that will be represented in the HPMRequest enum.
17811798 // This includes all local and remote handlers, plus HTTP handlers that have parameters.
17821799 let metadata_for_enum: Vec < _ > = function_metadata
17831800 . iter ( )
1784- . filter ( |f| !f. is_http || !f. params . is_empty ( ) )
1801+ // .filter(|f| !f.is_http || !f.params.is_empty())
17851802 . cloned ( )
17861803 . collect ( ) ;
17871804
0 commit comments