@@ -25,12 +25,14 @@ const MSG_BRIDGE_RESPONSE: u8 = 0x06;
2525const MSG_STREAM_EVENT : u8 = 0x07 ;
2626const MSG_TERMINATE_EXECUTION : u8 = 0x08 ;
2727const MSG_WARM_SNAPSHOT : u8 = 0x09 ;
28+ const MSG_INIT : u8 = 0x0B ;
2829
2930// Rust → Host message type codes
3031const MSG_BRIDGE_CALL : u8 = 0x81 ;
3132const MSG_EXECUTION_RESULT : u8 = 0x82 ;
3233const MSG_LOG : u8 = 0x83 ;
3334const MSG_STREAM_CALLBACK : u8 = 0x84 ;
35+ const MSG_INIT_READY : u8 = 0x8C ;
3436
3537// ExecutionResult flags
3638const FLAG_HAS_EXPORTS : u8 = 0x01 ;
@@ -80,6 +82,13 @@ pub enum BinaryFrame {
8082 WarmSnapshot {
8183 bridge_code : String ,
8284 } ,
85+ Init {
86+ bridge_code : String ,
87+ warm_pool_size : u32 ,
88+ default_warm_heap_limit_mb : u32 ,
89+ default_warm_cpu_time_limit_ms : u32 ,
90+ wait_for_warm_pool : bool ,
91+ } ,
8392
8493 // Rust → Host
8594 BridgeCall {
@@ -104,6 +113,7 @@ pub enum BinaryFrame {
104113 callback_type : String ,
105114 payload : Vec < u8 > , // V8-serialized payload
106115 } ,
116+ InitReady ,
107117}
108118
109119/// Structured error in binary format.
@@ -176,7 +186,7 @@ pub fn extract_session_id(raw: &[u8]) -> io::Result<Option<&str>> {
176186 return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , "frame too short" ) ) ;
177187 }
178188 let msg_type = raw[ 0 ] ;
179- if msg_type == MSG_AUTHENTICATE || msg_type == MSG_WARM_SNAPSHOT {
189+ if msg_type == MSG_AUTHENTICATE || msg_type == MSG_WARM_SNAPSHOT || msg_type == MSG_INIT {
180190 return Ok ( None ) ;
181191 }
182192 let sid_len = raw[ 1 ] as usize ;
@@ -277,6 +287,23 @@ fn encode_body(buf: &mut Vec<u8>, frame: &BinaryFrame) -> io::Result<()> {
277287 buf. extend_from_slice ( & ( bc_bytes. len ( ) as u32 ) . to_be_bytes ( ) ) ;
278288 buf. extend_from_slice ( bc_bytes) ;
279289 }
290+ BinaryFrame :: Init {
291+ bridge_code,
292+ warm_pool_size,
293+ default_warm_heap_limit_mb,
294+ default_warm_cpu_time_limit_ms,
295+ wait_for_warm_pool,
296+ } => {
297+ buf. push ( MSG_INIT ) ;
298+ buf. push ( 0 ) ; // no session_id
299+ let bc_bytes = bridge_code. as_bytes ( ) ;
300+ buf. extend_from_slice ( & ( bc_bytes. len ( ) as u32 ) . to_be_bytes ( ) ) ;
301+ buf. extend_from_slice ( bc_bytes) ;
302+ buf. extend_from_slice ( & warm_pool_size. to_be_bytes ( ) ) ;
303+ buf. extend_from_slice ( & default_warm_heap_limit_mb. to_be_bytes ( ) ) ;
304+ buf. extend_from_slice ( & default_warm_cpu_time_limit_ms. to_be_bytes ( ) ) ;
305+ buf. push ( if * wait_for_warm_pool { 1 } else { 0 } ) ;
306+ }
280307 BinaryFrame :: BridgeCall {
281308 session_id,
282309 call_id,
@@ -337,6 +364,10 @@ fn encode_body(buf: &mut Vec<u8>, frame: &BinaryFrame) -> io::Result<()> {
337364 write_len_prefixed_u16 ( buf, callback_type) ?;
338365 buf. extend_from_slice ( payload) ;
339366 }
367+ BinaryFrame :: InitReady => {
368+ buf. push ( MSG_INIT_READY ) ;
369+ buf. push ( 0 ) ; // no session_id
370+ }
340371 }
341372 Ok ( ( ) )
342373}
@@ -423,6 +454,21 @@ fn decode_body(buf: &[u8]) -> io::Result<BinaryFrame> {
423454 let bridge_code = read_utf8 ( buf, & mut pos, bc_len) ?;
424455 Ok ( BinaryFrame :: WarmSnapshot { bridge_code } )
425456 }
457+ MSG_INIT => {
458+ let bc_len = read_u32 ( buf, & mut pos) ? as usize ;
459+ let bridge_code = read_utf8 ( buf, & mut pos, bc_len) ?;
460+ let warm_pool_size = read_u32 ( buf, & mut pos) ?;
461+ let default_warm_heap_limit_mb = read_u32 ( buf, & mut pos) ?;
462+ let default_warm_cpu_time_limit_ms = read_u32 ( buf, & mut pos) ?;
463+ let wait_flag = read_u8 ( buf, & mut pos) ?;
464+ Ok ( BinaryFrame :: Init {
465+ bridge_code,
466+ warm_pool_size,
467+ default_warm_heap_limit_mb,
468+ default_warm_cpu_time_limit_ms,
469+ wait_for_warm_pool : wait_flag != 0 ,
470+ } )
471+ }
426472 MSG_BRIDGE_CALL => {
427473 let call_id = read_u64 ( buf, & mut pos) ?;
428474 let m_len = read_u16 ( buf, & mut pos) ? as usize ;
@@ -486,6 +532,9 @@ fn decode_body(buf: &[u8]) -> io::Result<BinaryFrame> {
486532 payload,
487533 } )
488534 }
535+ MSG_INIT_READY => {
536+ Ok ( BinaryFrame :: InitReady )
537+ }
489538 _ => Err ( io:: Error :: new (
490539 io:: ErrorKind :: InvalidData ,
491540 format ! ( "unknown message type: 0x{msg_type:02x}" ) ,
@@ -841,6 +890,51 @@ mod tests {
841890 assert_eq ! ( result, None ) ;
842891 }
843892
893+ // -- Init / InitReady --
894+
895+ #[ test]
896+ fn roundtrip_init ( ) {
897+ roundtrip ( & BinaryFrame :: Init {
898+ bridge_code : "(function(){ /* bridge */ })()" . into ( ) ,
899+ warm_pool_size : 2 ,
900+ default_warm_heap_limit_mb : 128 ,
901+ default_warm_cpu_time_limit_ms : 5000 ,
902+ wait_for_warm_pool : true ,
903+ } ) ;
904+ }
905+
906+ #[ test]
907+ fn roundtrip_init_no_wait ( ) {
908+ roundtrip ( & BinaryFrame :: Init {
909+ bridge_code : "bridge()" . into ( ) ,
910+ warm_pool_size : 0 ,
911+ default_warm_heap_limit_mb : 0 ,
912+ default_warm_cpu_time_limit_ms : 0 ,
913+ wait_for_warm_pool : false ,
914+ } ) ;
915+ }
916+
917+ #[ test]
918+ fn roundtrip_init_ready ( ) {
919+ roundtrip ( & BinaryFrame :: InitReady ) ;
920+ }
921+
922+ #[ test]
923+ fn extract_session_id_init_returns_none ( ) {
924+ let frame = BinaryFrame :: Init {
925+ bridge_code : "bridge()" . into ( ) ,
926+ warm_pool_size : 2 ,
927+ default_warm_heap_limit_mb : 128 ,
928+ default_warm_cpu_time_limit_ms : 0 ,
929+ wait_for_warm_pool : true ,
930+ } ;
931+ let mut buf = Vec :: new ( ) ;
932+ write_frame ( & mut buf, & frame) . expect ( "write" ) ;
933+ let raw = & buf[ 4 ..] ;
934+ let result = extract_session_id ( raw) . expect ( "extract" ) ;
935+ assert_eq ! ( result, None ) ;
936+ }
937+
844938 // -- Edge cases --
845939
846940 #[ test]
@@ -1132,6 +1226,16 @@ mod tests {
11321226 } ,
11331227 0x09 ,
11341228 ) ,
1229+ (
1230+ BinaryFrame :: Init {
1231+ bridge_code: "b()" . into( ) ,
1232+ warm_pool_size: 2 ,
1233+ default_warm_heap_limit_mb: 128 ,
1234+ default_warm_cpu_time_limit_ms: 0 ,
1235+ wait_for_warm_pool: true ,
1236+ } ,
1237+ 0x0B ,
1238+ ) ,
11351239 (
11361240 BinaryFrame :: BridgeCall {
11371241 session_id: "s" . into( ) ,
@@ -1166,6 +1270,10 @@ mod tests {
11661270 } ,
11671271 0x84 ,
11681272 ) ,
1273+ (
1274+ BinaryFrame :: InitReady ,
1275+ 0x8C ,
1276+ ) ,
11691277 ] ;
11701278 for ( frame, expected_type) in & cases {
11711279 let mut buf = Vec :: new ( ) ;
0 commit comments