From cf33a7d943e8087e0126a795b91e9197677d35dc Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 17 Feb 2023 13:44:11 -0800 Subject: [PATCH] Split to separate files --- plugins/plugin.ts | 6 +- src-tauri/src/commands.rs | 45 +++++++++++ src-tauri/src/main.rs | 163 ++------------------------------------ src-tauri/src/runtime.rs | 102 ++++++++++++++++++++++++ src-tauri/src/runtime.ts | 14 ++++ 5 files changed, 170 insertions(+), 160 deletions(-) create mode 100644 src-tauri/src/commands.rs create mode 100644 src-tauri/src/runtime.rs create mode 100644 src-tauri/src/runtime.ts diff --git a/plugins/plugin.ts b/plugins/plugin.ts index 5bdf5c94..454fcfaf 100644 --- a/plugins/plugin.ts +++ b/plugins/plugin.ts @@ -1,3 +1,3 @@ -Deno.core.print('---------------------------\n'); -Deno.core.print('- 👋 Hello from plugin.ts -\n'); -Deno.core.print('---------------------------\n'); +console.log('---------------------------'); +console.log('- 👋 Hello from plugin.ts -'); +console.log('---------------------------'); diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs new file mode 100644 index 00000000..447711c4 --- /dev/null +++ b/src-tauri/src/commands.rs @@ -0,0 +1,45 @@ +#[derive(serde::Serialize)] +pub struct CustomResponse { + status: String, + body: String, + elapsed: u128, + elapsed2: u128, + url: String, +} + +#[tauri::command] +pub async fn send_request(url: &str) -> Result { + let start = std::time::Instant::now(); + + let mut abs_url = url.to_string(); + if !abs_url.starts_with("http://") && !abs_url.starts_with("https://") { + abs_url = format!("http://{}", url); + } + + let resp = reqwest::get(abs_url.to_string()).await; + let elapsed = start.elapsed().as_millis(); + + crate::runtime::run_plugin_sync("../plugins/plugin.ts").unwrap(); + + match resp { + Ok(v) => { + let url2 = v.url().to_string(); + let status = v.status().to_string(); + let body = v.text().await.unwrap(); + let elapsed2 = start.elapsed().as_millis(); + Ok(CustomResponse { + status, + body, + elapsed, + elapsed2, + url: url2, + }) + } + Err(e) => Err(e.to_string()), + } +} + +#[tauri::command] +pub fn greet(name: &str) -> String { + format!("Hello, {}! You've been greeted from Rust!", name) +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index db689709..9c131c2d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,163 +1,12 @@ -#![cfg_attr( - all(not(debug_assertions), target_os = "windows"), - windows_subsystem = "windows" -)] - -use std::rc::Rc; - -use deno_ast::MediaType; -use deno_ast::ParseParams; -use deno_ast::SourceTextInfo; -use deno_core::error::AnyError; -use deno_core::futures::FutureExt; -use deno_core::ModuleSource; -use deno_core::ModuleType; -use deno_core::RuntimeOptions; -use deno_core::{Extension, JsRuntime}; -use futures::executor; - -// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command -#[tauri::command] -fn greet(name: &str) -> String { - format!("Hello, {}! You've been greeted from Rust!", name) -} - -#[derive(serde::Serialize)] -struct CustomResponse { - status: String, - body: String, - elapsed: u128, - elapsed2: u128, - url: String, -} - -async fn run_plugin(file_path: &str) -> Result<(), AnyError> { - let extension = Extension::builder("runjs").ops(vec![]).build(); - - // Initialize a runtime instance - let mut runtime = JsRuntime::new(RuntimeOptions { - module_loader: Some(Rc::new(TsModuleLoader)), - extensions: vec![extension], - ..Default::default() - }); - - let main_module = deno_core::resolve_path(file_path)?; - let mod_id = runtime.load_main_module(&main_module, None).await?; - let result = runtime.mod_evaluate(mod_id); - runtime.run_event_loop(false).await?; - result.await? -} - -#[tauri::command] -async fn send_request(url: &str) -> Result { - let start = std::time::Instant::now(); - - let mut abs_url = url.to_string(); - if !abs_url.starts_with("http://") && !abs_url.starts_with("https://") { - abs_url = format!("http://{}", url); - } - - let resp = reqwest::get(abs_url.to_string()).await; - let elapsed = start.elapsed().as_millis(); - - let result = executor::block_on(run_plugin( - "/Users/gschier/Workspace/tauri-app/plugins/plugin.ts", - )); - if let Err(e) = result { - eprintln!("Error running plugin: {}", e); - } - - match resp { - Ok(v) => { - let url2 = v.url().to_string(); - let status = v.status().to_string(); - let body = v.text().await.unwrap(); - let elapsed2 = start.elapsed().as_millis(); - Ok(CustomResponse { - status, - body, - elapsed, - elapsed2, - url: url2, - }) - } - Err(e) => Err(e.to_string()), - } -} - -struct TsModuleLoader; - -impl deno_core::ModuleLoader for TsModuleLoader { - fn resolve( - &self, - specifier: &str, - referrer: &str, - _kind: deno_core::ResolutionKind, - ) -> Result { - deno_core::resolve_import(specifier, referrer).map_err(|e| e.into()) - } - - fn load( - &self, - module_specifier: &deno_core::ModuleSpecifier, - _maybe_referrer: Option, - _is_dyn_import: bool, - ) -> std::pin::Pin> { - let module_specifier = module_specifier.clone(); - async move { - let path = module_specifier.to_file_path().unwrap(); - - // Determine what the MediaType is (this is done based on the file - // extension) and whether transpiling is required. - let media_type = MediaType::from(&path); - let (module_type, should_transpile) = match MediaType::from(&path) { - MediaType::JavaScript | MediaType::Mjs | MediaType::Cjs => { - (ModuleType::JavaScript, false) - } - MediaType::Jsx => (ModuleType::JavaScript, true), - MediaType::TypeScript - | MediaType::Mts - | MediaType::Cts - | MediaType::Dts - | MediaType::Dmts - | MediaType::Dcts - | MediaType::Tsx => (ModuleType::JavaScript, true), - MediaType::Json => (ModuleType::Json, false), - _ => panic!("Unknown extension {:?}", path.extension()), - }; - - // Read the file, transpile if necessary. - let code = std::fs::read_to_string(&path)?; - let code = if should_transpile { - let parsed = deno_ast::parse_module(ParseParams { - specifier: module_specifier.to_string(), - text_info: SourceTextInfo::from_string(code), - media_type, - capture_tokens: false, - scope_analysis: false, - maybe_syntax: None, - })?; - parsed.transpile(&Default::default())?.text - } else { - code - }; - - // Load and return module. - let module = ModuleSource { - code: code.into_bytes().into_boxed_slice(), - module_type, - module_url_specified: module_specifier.to_string(), - module_url_found: module_specifier.to_string(), - }; - Ok(module) - } - .boxed_local() - } -} +mod commands; +mod runtime; fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![send_request, greet]) + .invoke_handler(tauri::generate_handler![ + commands::send_request, + commands::greet + ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src-tauri/src/runtime.rs b/src-tauri/src/runtime.rs new file mode 100644 index 00000000..d1009f59 --- /dev/null +++ b/src-tauri/src/runtime.rs @@ -0,0 +1,102 @@ +use deno_ast::{MediaType, ParseParams, SourceTextInfo}; +use deno_core::error::AnyError; +use deno_core::{Extension, JsRuntime, ModuleSource, ModuleType, RuntimeOptions}; +use std::rc::Rc; + +use deno_core::futures::FutureExt; +use futures::executor; + +pub fn run_plugin_sync(file_path: &str) -> Result<(), AnyError> { + executor::block_on(run_plugin(file_path)) +} + +pub async fn run_plugin(file_path: &str) -> Result<(), AnyError> { + let extension = Extension::builder("pluginjs").ops(vec![]).build(); + + // Initialize a runtime instance + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(Rc::new(TsModuleLoader)), + extensions: vec![extension], + ..Default::default() + }); + + runtime + .execute_script("", include_str!("runtime.ts")) + .unwrap(); + + let main_module = deno_core::resolve_path(file_path)?; + let mod_id = runtime.load_main_module(&main_module, None).await?; + let result = runtime.mod_evaluate(mod_id); + runtime.run_event_loop(false).await?; + result.await? +} + +struct TsModuleLoader; + +impl deno_core::ModuleLoader for TsModuleLoader { + fn resolve( + &self, + specifier: &str, + referrer: &str, + _kind: deno_core::ResolutionKind, + ) -> Result { + deno_core::resolve_import(specifier, referrer).map_err(|e| e.into()) + } + + fn load( + &self, + module_specifier: &deno_core::ModuleSpecifier, + _maybe_referrer: Option, + _is_dyn_import: bool, + ) -> std::pin::Pin> { + let module_specifier = module_specifier.clone(); + async move { + let path = module_specifier.to_file_path().unwrap(); + + // Determine what the MediaType is (this is done based on the file + // extension) and whether transpiling is required. + let media_type = MediaType::from(&path); + let (module_type, should_transpile) = match MediaType::from(&path) { + MediaType::JavaScript | MediaType::Mjs | MediaType::Cjs => { + (ModuleType::JavaScript, false) + } + MediaType::Jsx => (ModuleType::JavaScript, true), + MediaType::TypeScript + | MediaType::Mts + | MediaType::Cts + | MediaType::Dts + | MediaType::Dmts + | MediaType::Dcts + | MediaType::Tsx => (ModuleType::JavaScript, true), + MediaType::Json => (ModuleType::Json, false), + _ => panic!("Unknown extension {:?}", path.extension()), + }; + + // Read the file, transpile if necessary. + let code = std::fs::read_to_string(&path)?; + let code = if should_transpile { + let parsed = deno_ast::parse_module(ParseParams { + specifier: module_specifier.to_string(), + text_info: SourceTextInfo::from_string(code), + media_type, + capture_tokens: false, + scope_analysis: false, + maybe_syntax: None, + })?; + parsed.transpile(&Default::default())?.text + } else { + code + }; + + // Load and return module. + let module = ModuleSource { + code: code.into_bytes().into_boxed_slice(), + module_type, + module_url_specified: module_specifier.to_string(), + module_url_found: module_specifier.to_string(), + }; + Ok(module) + } + .boxed_local() + } +} diff --git a/src-tauri/src/runtime.ts b/src-tauri/src/runtime.ts new file mode 100644 index 00000000..b15da94f --- /dev/null +++ b/src-tauri/src/runtime.ts @@ -0,0 +1,14 @@ +(function (globalThis) { + function argsToMessage(...args) { + return args.map((arg) => JSON.stringify(arg)).join(' '); + } + + globalThis.console = { + log: (...args) => { + Deno.core.print(`[log]: ${argsToMessage(...args)}\n`, false); + }, + error: (...args) => { + Deno.core.print(`[err]: ${argsToMessage(...args)}\n`, true); + }, + }; +})(globalThis);