mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-30 06:02:00 +02:00
Plugin execution context (#119)
This commit is contained in:
@@ -1,25 +1,40 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use tauri::{Runtime, WebviewWindow};
|
||||
use ts_rs::TS;
|
||||
|
||||
use yaak_models::models::{
|
||||
Environment, Folder, GrpcRequest, HttpRequest,
|
||||
HttpResponse, Workspace,
|
||||
};
|
||||
use yaak_models::models::{Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, Workspace};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct InternalEvent {
|
||||
pub id: String,
|
||||
pub plugin_ref_id: String,
|
||||
pub reply_id: Option<String>,
|
||||
pub payload: InternalEventPayload,
|
||||
pub window_context: WindowContext,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case", tag = "type")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub enum WindowContext {
|
||||
None,
|
||||
Label { label: String },
|
||||
}
|
||||
|
||||
impl WindowContext {
|
||||
pub fn from_window<R: Runtime>(window: &WebviewWindow<R>) -> Self {
|
||||
Self::Label {
|
||||
label: window.label().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case", tag = "type")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub enum InternalEventPayload {
|
||||
BootRequest(BootRequest),
|
||||
BootResponse(BootResponse),
|
||||
@@ -53,8 +68,8 @@ pub enum InternalEventPayload {
|
||||
|
||||
CopyTextRequest(CopyTextRequest),
|
||||
|
||||
RenderHttpRequestRequest(RenderHttpRequestRequest),
|
||||
RenderHttpRequestResponse(RenderHttpRequestResponse),
|
||||
TemplateRenderRequest(TemplateRenderRequest),
|
||||
TemplateRenderResponse(TemplateRenderResponse),
|
||||
|
||||
ShowToastRequest(ShowToastRequest),
|
||||
|
||||
@@ -71,7 +86,7 @@ pub enum InternalEventPayload {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct BootRequest {
|
||||
pub dir: String,
|
||||
pub watch: bool,
|
||||
@@ -79,7 +94,7 @@ pub struct BootRequest {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct BootResponse {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
@@ -88,21 +103,21 @@ pub struct BootResponse {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct ImportRequest {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct ImportResponse {
|
||||
pub resources: ImportResources,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct FilterRequest {
|
||||
pub content: String,
|
||||
pub filter: String,
|
||||
@@ -110,49 +125,49 @@ pub struct FilterRequest {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct FilterResponse {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct ExportHttpRequestRequest {
|
||||
pub http_request: HttpRequest,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct ExportHttpRequestResponse {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct SendHttpRequestRequest {
|
||||
pub http_request: HttpRequest,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct SendHttpRequestResponse {
|
||||
pub http_response: HttpResponse,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct CopyTextRequest {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct RenderHttpRequestRequest {
|
||||
pub http_request: HttpRequest,
|
||||
pub purpose: RenderPurpose,
|
||||
@@ -160,14 +175,29 @@ pub struct RenderHttpRequestRequest {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct RenderHttpRequestResponse {
|
||||
pub http_request: HttpRequest,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateRenderRequest {
|
||||
pub data: serde_json::Value,
|
||||
pub purpose: RenderPurpose,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateRenderResponse {
|
||||
pub data: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct ShowToastRequest {
|
||||
pub message: String,
|
||||
#[ts(optional = nullable)]
|
||||
@@ -178,7 +208,7 @@ pub struct ShowToastRequest {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub enum Color {
|
||||
Custom,
|
||||
Default,
|
||||
@@ -199,7 +229,7 @@ impl Default for Color {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub enum Icon {
|
||||
Copy,
|
||||
Info,
|
||||
@@ -209,7 +239,7 @@ pub enum Icon {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct GetTemplateFunctionsResponse {
|
||||
pub functions: Vec<TemplateFunction>,
|
||||
pub plugin_ref_id: String,
|
||||
@@ -217,7 +247,7 @@ pub struct GetTemplateFunctionsResponse {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunction {
|
||||
pub name: String,
|
||||
pub args: Vec<TemplateFunctionArg>,
|
||||
@@ -225,7 +255,7 @@ pub struct TemplateFunction {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case", tag = "type")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub enum TemplateFunctionArg {
|
||||
Text(TemplateFunctionTextArg),
|
||||
Select(TemplateFunctionSelectArg),
|
||||
@@ -235,7 +265,7 @@ pub enum TemplateFunctionArg {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunctionBaseArg {
|
||||
pub name: String,
|
||||
#[ts(optional = nullable)]
|
||||
@@ -248,7 +278,7 @@ pub struct TemplateFunctionBaseArg {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunctionTextArg {
|
||||
#[serde(flatten)]
|
||||
pub base: TemplateFunctionBaseArg,
|
||||
@@ -258,7 +288,7 @@ pub struct TemplateFunctionTextArg {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunctionHttpRequestArg {
|
||||
#[serde(flatten)]
|
||||
pub base: TemplateFunctionBaseArg,
|
||||
@@ -266,7 +296,7 @@ pub struct TemplateFunctionHttpRequestArg {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunctionSelectArg {
|
||||
#[serde(flatten)]
|
||||
pub base: TemplateFunctionBaseArg,
|
||||
@@ -275,7 +305,7 @@ pub struct TemplateFunctionSelectArg {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunctionCheckboxArg {
|
||||
#[serde(flatten)]
|
||||
pub base: TemplateFunctionBaseArg,
|
||||
@@ -283,7 +313,7 @@ pub struct TemplateFunctionCheckboxArg {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct TemplateFunctionSelectOption {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
@@ -291,7 +321,7 @@ pub struct TemplateFunctionSelectOption {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct CallTemplateFunctionRequest {
|
||||
pub name: String,
|
||||
pub args: CallTemplateFunctionArgs,
|
||||
@@ -299,14 +329,14 @@ pub struct CallTemplateFunctionRequest {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct CallTemplateFunctionResponse {
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct CallTemplateFunctionArgs {
|
||||
pub purpose: RenderPurpose,
|
||||
pub values: HashMap<String, String>,
|
||||
@@ -314,7 +344,7 @@ pub struct CallTemplateFunctionArgs {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub enum RenderPurpose {
|
||||
Send,
|
||||
Preview,
|
||||
@@ -328,12 +358,12 @@ impl Default for RenderPurpose {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default)]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct GetHttpRequestActionsRequest {}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct GetHttpRequestActionsResponse {
|
||||
pub actions: Vec<HttpRequestAction>,
|
||||
pub plugin_ref_id: String,
|
||||
@@ -341,7 +371,7 @@ pub struct GetHttpRequestActionsResponse {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct HttpRequestAction {
|
||||
pub key: String,
|
||||
pub label: String,
|
||||
@@ -350,7 +380,7 @@ pub struct HttpRequestAction {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct CallHttpRequestActionRequest {
|
||||
pub key: String,
|
||||
pub plugin_ref_id: String,
|
||||
@@ -359,28 +389,28 @@ pub struct CallHttpRequestActionRequest {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct CallHttpRequestActionArgs {
|
||||
pub http_request: HttpRequest,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct GetHttpRequestByIdRequest {
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct GetHttpRequestByIdResponse {
|
||||
pub http_request: Option<HttpRequest>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct FindHttpResponsesRequest {
|
||||
pub request_id: String,
|
||||
pub limit: Option<i32>,
|
||||
@@ -388,14 +418,14 @@ pub struct FindHttpResponsesRequest {
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct FindHttpResponsesResponse {
|
||||
pub http_responses: Vec<HttpResponse>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to="events.ts")]
|
||||
#[ts(export, export_to = "events.ts")]
|
||||
pub struct ImportResources {
|
||||
pub workspaces: Vec<Workspace>,
|
||||
pub environments: Vec<Environment>,
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::events::{
|
||||
CallTemplateFunctionRequest, CallTemplateFunctionResponse, FilterRequest, FilterResponse,
|
||||
GetHttpRequestActionsRequest, GetHttpRequestActionsResponse, GetTemplateFunctionsResponse,
|
||||
ImportRequest, ImportResponse, InternalEvent, InternalEventPayload, RenderPurpose,
|
||||
WindowContext,
|
||||
};
|
||||
use crate::nodejs::start_nodejs_plugin_runtime;
|
||||
use crate::plugin_handle::PluginHandle;
|
||||
@@ -17,7 +18,7 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tauri::path::BaseDirectory;
|
||||
use tauri::{AppHandle, Manager, Runtime};
|
||||
use tauri::{AppHandle, Manager, Runtime, WebviewWindow};
|
||||
use tokio::fs::read_dir;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::sync::{mpsc, Mutex};
|
||||
@@ -98,7 +99,7 @@ impl PluginManager {
|
||||
Ok(_) => {
|
||||
info!("Plugin runtime client connected!");
|
||||
plugin_manager
|
||||
.initialize_all_plugins(&app_handle)
|
||||
.initialize_all_plugins(&app_handle, WindowContext::None)
|
||||
.await
|
||||
.expect("Failed to reload plugins");
|
||||
}
|
||||
@@ -171,17 +172,21 @@ impl PluginManager {
|
||||
[bundled_plugin_dirs, installed_plugin_dirs].concat()
|
||||
}
|
||||
|
||||
pub async fn uninstall(&self, dir: &str) -> Result<()> {
|
||||
pub async fn uninstall(&self, window_context: WindowContext, dir: &str) -> Result<()> {
|
||||
let plugin = self
|
||||
.get_plugin_by_dir(dir)
|
||||
.await
|
||||
.ok_or(PluginNotFoundErr(dir.to_string()))?;
|
||||
self.remove_plugin(&plugin).await
|
||||
self.remove_plugin(window_context, &plugin).await
|
||||
}
|
||||
|
||||
async fn remove_plugin(&self, plugin: &PluginHandle) -> Result<()> {
|
||||
async fn remove_plugin(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
plugin: &PluginHandle,
|
||||
) -> Result<()> {
|
||||
// Terminate the plugin
|
||||
plugin.terminate().await?;
|
||||
plugin.terminate(window_context).await?;
|
||||
|
||||
// Remove the plugin from the list
|
||||
let mut plugins = self.plugins.lock().await;
|
||||
@@ -193,7 +198,12 @@ impl PluginManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_plugin_by_dir(&self, dir: &str, watch: bool) -> Result<()> {
|
||||
pub async fn add_plugin_by_dir(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
dir: &str,
|
||||
watch: bool,
|
||||
) -> Result<()> {
|
||||
info!("Adding plugin by dir {dir}");
|
||||
let maybe_tx = self.server.app_to_plugin_events_tx.lock().await;
|
||||
let tx = match &*maybe_tx {
|
||||
@@ -202,9 +212,13 @@ impl PluginManager {
|
||||
};
|
||||
let plugin_handle = PluginHandle::new(dir, tx.clone());
|
||||
|
||||
// Add the new plugin
|
||||
self.plugins.lock().await.push(plugin_handle.clone());
|
||||
|
||||
// Boot the plugin
|
||||
let event = self
|
||||
.send_to_plugin_and_wait(
|
||||
window_context,
|
||||
&plugin_handle,
|
||||
&InternalEventPayload::BootRequest(BootRequest {
|
||||
dir: dir.to_string(),
|
||||
@@ -218,27 +232,29 @@ impl PluginManager {
|
||||
_ => return Err(UnknownEventErr),
|
||||
};
|
||||
|
||||
// Set the boot response
|
||||
plugin_handle.set_boot_response(&resp).await;
|
||||
|
||||
// Add the new plugin after it boots
|
||||
self.plugins.lock().await.push(plugin_handle.clone());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn initialize_all_plugins<R: Runtime>(
|
||||
&self,
|
||||
app_handle: &AppHandle<R>,
|
||||
window_context: WindowContext,
|
||||
) -> Result<()> {
|
||||
let dirs = self.list_plugin_dirs(app_handle).await;
|
||||
for d in dirs.clone() {
|
||||
// First remove the plugin if it exists
|
||||
if let Some(plugin) = self.get_plugin_by_dir(d.dir.as_str()).await {
|
||||
if let Err(e) = self.remove_plugin(&plugin).await {
|
||||
if let Err(e) = self.remove_plugin(window_context.to_owned(), &plugin).await {
|
||||
warn!("Failed to remove plugin {} {e:?}", d.dir);
|
||||
}
|
||||
}
|
||||
if let Err(e) = self.add_plugin_by_dir(d.dir.as_str(), d.watch).await {
|
||||
if let Err(e) = self
|
||||
.add_plugin_by_dir(window_context.to_owned(), d.dir.as_str(), d.watch)
|
||||
.await
|
||||
{
|
||||
warn!("Failed to add plugin {} {e:?}", d.dir);
|
||||
}
|
||||
}
|
||||
@@ -280,12 +296,13 @@ impl PluginManager {
|
||||
source_event: &InternalEvent,
|
||||
payload: &InternalEventPayload,
|
||||
) -> Result<()> {
|
||||
let reply_id = Some(source_event.clone().id);
|
||||
let window_label = source_event.to_owned().window_context;
|
||||
let reply_id = Some(source_event.to_owned().id);
|
||||
let plugin = self
|
||||
.get_plugin_by_ref_id(source_event.plugin_ref_id.as_str())
|
||||
.await
|
||||
.ok_or(PluginNotFoundErr(source_event.plugin_ref_id.to_string()))?;
|
||||
let event = plugin.build_event_to_send(&payload, reply_id);
|
||||
let event = plugin.build_event_to_send_raw(window_label, &payload, reply_id);
|
||||
plugin.send(&event).await
|
||||
}
|
||||
|
||||
@@ -319,22 +336,29 @@ impl PluginManager {
|
||||
|
||||
async fn send_to_plugin_and_wait(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
plugin: &PluginHandle,
|
||||
payload: &InternalEventPayload,
|
||||
) -> Result<InternalEvent> {
|
||||
let events = self
|
||||
.send_to_plugins_and_wait(payload, vec![plugin.to_owned()])
|
||||
.send_to_plugins_and_wait(window_context, payload, vec![plugin.to_owned()])
|
||||
.await?;
|
||||
Ok(events.first().unwrap().to_owned())
|
||||
}
|
||||
|
||||
async fn send_and_wait(&self, payload: &InternalEventPayload) -> Result<Vec<InternalEvent>> {
|
||||
async fn send_and_wait(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
payload: &InternalEventPayload,
|
||||
) -> Result<Vec<InternalEvent>> {
|
||||
let plugins = { self.plugins.lock().await.clone() };
|
||||
self.send_to_plugins_and_wait(payload, plugins).await
|
||||
self.send_to_plugins_and_wait(window_context, payload, plugins)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn send_to_plugins_and_wait(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
payload: &InternalEventPayload,
|
||||
plugins: Vec<PluginHandle>,
|
||||
) -> Result<Vec<InternalEvent>> {
|
||||
@@ -343,7 +367,7 @@ impl PluginManager {
|
||||
// 1. Build the events with IDs and everything
|
||||
let events_to_send = plugins
|
||||
.iter()
|
||||
.map(|p| p.build_event_to_send(payload, None))
|
||||
.map(|p| p.build_event_to_send(window_context.to_owned(), payload, None))
|
||||
.collect::<Vec<InternalEvent>>();
|
||||
|
||||
// 2. Spawn thread to subscribe to incoming events and check reply ids
|
||||
@@ -388,11 +412,17 @@ impl PluginManager {
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
pub async fn get_http_request_actions(&self) -> Result<Vec<GetHttpRequestActionsResponse>> {
|
||||
pub async fn get_http_request_actions<R: Runtime>(
|
||||
&self,
|
||||
window: &WebviewWindow<R>,
|
||||
) -> Result<Vec<GetHttpRequestActionsResponse>> {
|
||||
let reply_events = self
|
||||
.send_and_wait(&InternalEventPayload::GetHttpRequestActionsRequest(
|
||||
GetHttpRequestActionsRequest {},
|
||||
))
|
||||
.send_and_wait(
|
||||
WindowContext::from_window(window),
|
||||
&InternalEventPayload::GetHttpRequestActionsRequest(
|
||||
GetHttpRequestActionsRequest {},
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut all_actions = Vec::new();
|
||||
@@ -405,9 +435,23 @@ impl PluginManager {
|
||||
Ok(all_actions)
|
||||
}
|
||||
|
||||
pub async fn get_template_functions(&self) -> Result<Vec<GetTemplateFunctionsResponse>> {
|
||||
pub async fn get_template_functions<R: Runtime>(
|
||||
&self,
|
||||
window: &WebviewWindow<R>,
|
||||
) -> Result<Vec<GetTemplateFunctionsResponse>> {
|
||||
self.get_template_functions_with_context(WindowContext::from_window(window))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_template_functions_with_context(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
) -> Result<Vec<GetTemplateFunctionsResponse>> {
|
||||
let reply_events = self
|
||||
.send_and_wait(&InternalEventPayload::GetTemplateFunctionsRequest)
|
||||
.send_and_wait(
|
||||
window_context,
|
||||
&InternalEventPayload::GetTemplateFunctionsRequest,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut all_actions = Vec::new();
|
||||
@@ -420,13 +464,18 @@ impl PluginManager {
|
||||
Ok(all_actions)
|
||||
}
|
||||
|
||||
pub async fn call_http_request_action(&self, req: CallHttpRequestActionRequest) -> Result<()> {
|
||||
pub async fn call_http_request_action<R: Runtime>(
|
||||
&self,
|
||||
window: &WebviewWindow<R>,
|
||||
req: CallHttpRequestActionRequest,
|
||||
) -> Result<()> {
|
||||
let ref_id = req.plugin_ref_id.clone();
|
||||
let plugin = self
|
||||
.get_plugin_by_ref_id(ref_id.as_str())
|
||||
.await
|
||||
.ok_or(PluginNotFoundErr(ref_id))?;
|
||||
let event = plugin.build_event_to_send(
|
||||
WindowContext::from_window(window),
|
||||
&InternalEventPayload::CallHttpRequestActionRequest(req),
|
||||
None,
|
||||
);
|
||||
@@ -436,6 +485,7 @@ impl PluginManager {
|
||||
|
||||
pub async fn call_template_function(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
fn_name: &str,
|
||||
args: HashMap<String, String>,
|
||||
purpose: RenderPurpose,
|
||||
@@ -449,7 +499,10 @@ impl PluginManager {
|
||||
};
|
||||
|
||||
let events = self
|
||||
.send_and_wait(&InternalEventPayload::CallTemplateFunctionRequest(req))
|
||||
.send_and_wait(
|
||||
window_context,
|
||||
&InternalEventPayload::CallTemplateFunctionRequest(req),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let value = events.into_iter().find_map(|e| match e.payload {
|
||||
@@ -462,11 +515,18 @@ impl PluginManager {
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub async fn import_data(&self, content: &str) -> Result<(ImportResponse, String)> {
|
||||
pub async fn import_data<R: Runtime>(
|
||||
&self,
|
||||
window: &WebviewWindow<R>,
|
||||
content: &str,
|
||||
) -> Result<(ImportResponse, String)> {
|
||||
let reply_events = self
|
||||
.send_and_wait(&InternalEventPayload::ImportRequest(ImportRequest {
|
||||
content: content.to_string(),
|
||||
}))
|
||||
.send_and_wait(
|
||||
WindowContext::from_window(window),
|
||||
&InternalEventPayload::ImportRequest(ImportRequest {
|
||||
content: content.to_string(),
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// TODO: Don't just return the first valid response
|
||||
@@ -489,8 +549,9 @@ impl PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn filter_data(
|
||||
pub async fn filter_data<R: Runtime>(
|
||||
&self,
|
||||
window: &WebviewWindow<R>,
|
||||
filter: &str,
|
||||
content: &str,
|
||||
content_type: &str,
|
||||
@@ -508,6 +569,7 @@ impl PluginManager {
|
||||
|
||||
let event = self
|
||||
.send_to_plugin_and_wait(
|
||||
WindowContext::from_window(window),
|
||||
&plugin,
|
||||
&InternalEventPayload::FilterRequest(FilterRequest {
|
||||
filter: filter.to_string(),
|
||||
|
||||
@@ -26,4 +26,4 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
_ => {}
|
||||
})
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::error::Result;
|
||||
use crate::events::{BootResponse, InternalEvent, InternalEventPayload};
|
||||
use crate::events::{BootResponse, InternalEvent, InternalEventPayload, WindowContext};
|
||||
use crate::server::plugin_runtime::EventStreamEvent;
|
||||
use crate::util::gen_id;
|
||||
use std::sync::Arc;
|
||||
use log::info;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, Mutex};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -33,6 +33,16 @@ impl PluginHandle {
|
||||
|
||||
pub fn build_event_to_send(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
payload: &InternalEventPayload,
|
||||
reply_id: Option<String>,
|
||||
) -> InternalEvent {
|
||||
self.build_event_to_send_raw(window_context, payload, reply_id)
|
||||
}
|
||||
|
||||
pub(crate) fn build_event_to_send_raw(
|
||||
&self,
|
||||
window_context: WindowContext,
|
||||
payload: &InternalEventPayload,
|
||||
reply_id: Option<String>,
|
||||
) -> InternalEvent {
|
||||
@@ -41,16 +51,21 @@ impl PluginHandle {
|
||||
plugin_ref_id: self.ref_id.clone(),
|
||||
reply_id,
|
||||
payload: payload.clone(),
|
||||
window_context,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn terminate(&self) -> Result<()> {
|
||||
pub async fn terminate(&self, window_context: WindowContext) -> Result<()> {
|
||||
info!("Terminating plugin {}", self.dir);
|
||||
let event = self.build_event_to_send(&InternalEventPayload::TerminateRequest, None);
|
||||
let event = self.build_event_to_send(
|
||||
window_context,
|
||||
&InternalEventPayload::TerminateRequest,
|
||||
None,
|
||||
);
|
||||
self.send(&event).await
|
||||
}
|
||||
|
||||
pub async fn send(&self, event: &InternalEvent) -> Result<()> {
|
||||
pub(crate) async fn send(&self, event: &InternalEvent) -> Result<()> {
|
||||
self.to_plugin_tx
|
||||
.lock()
|
||||
.await
|
||||
@@ -61,15 +76,6 @@ impl PluginHandle {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn send_payload(
|
||||
&self,
|
||||
payload: &InternalEventPayload,
|
||||
reply_id: Option<String>,
|
||||
) -> Result<()> {
|
||||
let event = self.build_event_to_send(payload, reply_id);
|
||||
self.send(&event).await
|
||||
}
|
||||
|
||||
pub async fn set_boot_response(&self, resp: &BootResponse) {
|
||||
let mut boot_resp = self.boot_resp.lock().await;
|
||||
*boot_resp = resp.clone();
|
||||
|
||||
Reference in New Issue
Block a user