1
This commit is contained in:
1
src-tauri/src/commands/mod.rs
Normal file
1
src-tauri/src/commands/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod quickjs;
|
||||
99
src-tauri/src/commands/quickjs.rs
Normal file
99
src-tauri/src/commands/quickjs.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
//! Generic Tauri commands for invoking any JS script registered in the
|
||||
//! embedded QuickJS runtime. Replaces the per-pipeline command so adding a
|
||||
//! new flow only requires:
|
||||
//!
|
||||
//! 1. Drop a new `.js` file into `src-tauri/js/`.
|
||||
//! 2. Add it to `js_runtime::SCRIPT_FILES`.
|
||||
//! 3. Inside the JS file, register one or more entries on
|
||||
//! `globalThis.__scripts[<scriptName>]`.
|
||||
//!
|
||||
//! Frontend usage:
|
||||
//!
|
||||
//! ```ts
|
||||
//! import { invoke } from "@tauri-apps/api/core";
|
||||
//! import { listen } from "@tauri-apps/api/event";
|
||||
//!
|
||||
//! const off = await listen("quickjs:event", (e) => console.log(e.payload));
|
||||
//! const result = await invoke("run_quickjs_script", {
|
||||
//! scriptName: "process_douyin_share",
|
||||
//! params: { shareText: "...", modelConfig: {...}, ... },
|
||||
//! });
|
||||
//! off();
|
||||
//! ```
|
||||
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use tauri::{AppHandle, Emitter, Window};
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::js_runtime::{self, PipelineEvent};
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
pub enum FrontendEvent {
|
||||
Progress {
|
||||
#[serde(rename = "scriptName")]
|
||||
script_name: String,
|
||||
status: String,
|
||||
},
|
||||
Log {
|
||||
#[serde(rename = "scriptName")]
|
||||
script_name: String,
|
||||
level: String,
|
||||
msg: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
fields: Option<Value>,
|
||||
},
|
||||
}
|
||||
|
||||
const EVENT_NAME: &str = "quickjs:event";
|
||||
|
||||
/// Run an arbitrary registered QuickJS script by name.
|
||||
///
|
||||
/// `script_name` must already be registered on `globalThis.__scripts` by
|
||||
/// one of the bundled `js/*.js` files. `params` is forwarded as-is to the
|
||||
/// script entry function.
|
||||
#[tauri::command]
|
||||
pub async fn run_quickjs_script(
|
||||
app: AppHandle,
|
||||
window: Window,
|
||||
script_name: String,
|
||||
params: Value,
|
||||
) -> Result<Value, String> {
|
||||
let (tx, mut rx) = mpsc::unbounded_channel::<PipelineEvent>();
|
||||
|
||||
// Forward script events to the frontend window.
|
||||
let app_for_emit = app.clone();
|
||||
let win_label = window.label().to_string();
|
||||
let script_for_emit = script_name.clone();
|
||||
let pump = tokio::spawn(async move {
|
||||
while let Some(ev) = rx.recv().await {
|
||||
let payload: FrontendEvent = match ev {
|
||||
PipelineEvent::Progress(s) => FrontendEvent::Progress {
|
||||
script_name: script_for_emit.clone(),
|
||||
status: s,
|
||||
},
|
||||
PipelineEvent::Log { level, msg, fields } => FrontendEvent::Log {
|
||||
script_name: script_for_emit.clone(),
|
||||
level,
|
||||
msg,
|
||||
fields,
|
||||
},
|
||||
};
|
||||
let _ = app_for_emit.emit_to(&win_label, EVENT_NAME, payload);
|
||||
}
|
||||
});
|
||||
|
||||
let result = js_runtime::run_script(script_name, params, tx)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
pump.await.ok();
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Diagnostic helper — returns the list of registered script names.
|
||||
#[tauri::command]
|
||||
pub async fn list_quickjs_scripts() -> Result<Vec<String>, String> {
|
||||
js_runtime::list_scripts().await.map_err(|e| e.to_string())
|
||||
}
|
||||
Reference in New Issue
Block a user