@@ -365,6 +365,60 @@ impl Bash {
365365 } )
366366 }
367367
368+ // ========================================================================
369+ // Snapshot / Resume
370+ // ========================================================================
371+
372+ /// Serialize interpreter state (shell variables, VFS contents, counters) to bytes.
373+ ///
374+ /// Returns a `Buffer` (Uint8Array) that can be persisted and used with
375+ /// `Bash.fromSnapshot()` to restore the session later.
376+ #[ napi]
377+ pub fn snapshot ( & self ) -> napi:: Result < napi:: bindgen_prelude:: Buffer > {
378+ block_on_with ( & self . state , |s| async move {
379+ let bash = s. inner . lock ( ) . await ;
380+ let bytes = bash
381+ . snapshot ( )
382+ . map_err ( |e| napi:: Error :: from_reason ( e. to_string ( ) ) ) ?;
383+ Ok ( napi:: bindgen_prelude:: Buffer :: from ( bytes) )
384+ } )
385+ }
386+
387+ /// Restore interpreter state from a snapshot previously created with `snapshot()`.
388+ #[ napi]
389+ pub fn restore_snapshot ( & self , data : napi:: bindgen_prelude:: Buffer ) -> napi:: Result < ( ) > {
390+ block_on_with ( & self . state , |s| async move {
391+ let mut bash = s. inner . lock ( ) . await ;
392+ bash. restore_snapshot ( & data)
393+ . map_err ( |e| napi:: Error :: from_reason ( e. to_string ( ) ) )
394+ } )
395+ }
396+
397+ /// Create a new Bash instance from a snapshot.
398+ #[ napi( factory) ]
399+ pub fn from_snapshot ( data : napi:: bindgen_prelude:: Buffer ) -> napi:: Result < Self > {
400+ let bash =
401+ RustBash :: from_snapshot ( & data) . map_err ( |e| napi:: Error :: from_reason ( e. to_string ( ) ) ) ?;
402+ let rt = tokio:: runtime:: Builder :: new_current_thread ( )
403+ . enable_all ( )
404+ . build ( )
405+ . map_err ( |e| napi:: Error :: from_reason ( format ! ( "Failed to create runtime: {e}" ) ) ) ?;
406+ Ok ( Self {
407+ state : Arc :: new ( SharedState {
408+ inner : Mutex :: new ( bash) ,
409+ rt : tokio:: sync:: Mutex :: new ( rt) ,
410+ cancelled : Arc :: new ( AtomicBool :: new ( false ) ) ,
411+ username : None ,
412+ hostname : None ,
413+ max_commands : None ,
414+ max_loop_iterations : None ,
415+ python : false ,
416+ external_functions : Vec :: new ( ) ,
417+ external_handler : None ,
418+ } ) ,
419+ } )
420+ }
421+
368422 // ========================================================================
369423 // VFS — direct filesystem access
370424 // ========================================================================
0 commit comments