// file: kb-app-demo-desktop/src/demo_execution_metadata.rs // version: 16 //! Shared desktop contracts for metadata execution demos. use tauri::Emitter; // rust-rules: trait-import /// UI-safe progress event shared by Metadata execution workflows. #[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, ts_rs::TS)] #[serde(rename_all = "camelCase")] #[ts( export, export_to = "../frontend/ts/bindings/kb_app_demo_desktop/demo_execution_metadata/DemoExecutionMetadataProgressPayload.ts" )] pub(crate) struct DemoExecutionMetadataProgressPayload { /// RFC3339 event timestamp. pub timestamp: std::string::String, /// Stable lowercase log level. pub level: std::string::String, /// Stable execution stage. pub stage: std::string::String, /// Operator-visible message. pub message: std::string::String, /// Optional transaction signature. pub signature: std::option::Option, } /// Metadata-window observer shared by Metaplex and Solana Program Metadata workflows. pub(crate) struct DemoExecutionMetadataObserver<'a> { /// Tauri application handle used for targeted progress events. pub(crate) app_handle: tauri::AppHandle, /// Shared cooperative cancellation flag. pub(crate) cancel_requested: &'a std::sync::atomic::AtomicBool, } impl crate::DemoExecutionMetadataObserver<'_> { fn emit( &self, timestamp: std::string::String, level: &str, stage: &str, message: std::string::String, signature: std::option::Option, ) { let payload = crate::DemoExecutionMetadataProgressPayload { timestamp, level: level.to_string(), stage: stage.to_string(), message, signature, }; let emit_result = self.app_handle.emit_to( "demo_execution_metadata", "demo-execution-metadata-progress", payload, ); if let std::result::Result::Err(error) = emit_result { tracing::warn!( target: crate::TRACING_TARGET, action = "emit_metadata_execution_progress", error = %error, "cannot emit Metadata execution progress" ); } } fn cancelled(&self) -> bool { return self.cancel_requested.load(std::sync::atomic::Ordering::Relaxed); } } impl ks_pipeline::BackfillObserver for crate::DemoExecutionMetadataObserver<'_> { fn on_progress(&self, event: &ks_pipeline::BackfillProgressEvent) { self.emit( event.timestamp.clone(), event.level.code(), "canonical_insert", event.message.clone(), std::option::Option::None, ); } fn is_cancelled(&self) -> bool { return self.cancelled(); } } impl ks_pipeline::CoreExtractionObserver for crate::DemoExecutionMetadataObserver<'_> { fn on_progress(&self, event: &ks_pipeline::CoreExtractionProgressEvent) { self.emit( event.timestamp.clone(), event.level.code(), "core_extraction", event.message.clone(), std::option::Option::None, ); } fn is_cancelled(&self) -> bool { return self.cancelled(); } } impl ks_pipeline::DecodeReplayObserver for crate::DemoExecutionMetadataObserver<'_> { fn on_progress(&self, event: &ks_pipeline::DecodeReplayProgressEvent) { self.emit( event.timestamp.clone(), event.level.code(), "decode_replay", event.message.clone(), std::option::Option::None, ); } fn is_cancelled(&self) -> bool { return self.cancelled(); } } impl ks_pipeline_demo_scenarios::SolanaExecutionObserver for crate::DemoExecutionMetadataObserver<'_> { fn on_execution_progress( &self, event: &ks_pipeline_demo_scenarios::SolanaExecutionProgressEvent, ) { self.emit( event.timestamp.clone(), event.level.code(), event.stage.as_str(), event.message.clone(), event.signature.clone(), ); } fn is_execution_cancelled(&self) -> bool { return self.cancelled(); } } /// Returns Devnet profile options shared by the Metadata execution panel. pub(crate) fn demo_execution_metadata_options( state: tauri::State<'_, crate::AppState>, ) -> crate::DemoExecutionSolanaCoreOptionsPayload { return crate::demo_execution_solana_core_options(state); } #[cfg(test)] mod tests { #[test] fn metadata_frontend_listens_to_the_metadata_specific_progress_event() { let source = std::include_str!("../frontend/ts/demo_execution_metadata.ts"); assert!(source.contains("demo-execution-metadata-progress")); assert!(!source.contains( "listen(\"demo-execution-solana-core-progress\"" )); } }