mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-24 01:28:35 +02:00
Refine shared plugin event routing API
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use yaak::plugin_events::{
|
use yaak::plugin_events::{
|
||||||
GroupedPluginEvent, HostRequest, SharedEvent, SharedPluginEventContext,
|
GroupedPluginEvent, HostRequest, SharedPluginEventContext, handle_shared_plugin_event,
|
||||||
handle_shared_plugin_event,
|
|
||||||
};
|
};
|
||||||
use yaak_models::query_manager::QueryManager;
|
use yaak_models::query_manager::QueryManager;
|
||||||
use yaak_plugins::events::{
|
use yaak_plugins::events::{
|
||||||
@@ -75,36 +74,37 @@ fn build_plugin_reply(
|
|||||||
workspace_id: event.context.workspace_id.as_deref(),
|
workspace_id: event.context.workspace_id.as_deref(),
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
GroupedPluginEvent::Shared(SharedEvent::Reply(payload)) => Some(payload),
|
GroupedPluginEvent::Handled(payload) => payload,
|
||||||
GroupedPluginEvent::Shared(SharedEvent::ErrorResponse(resp)) => {
|
GroupedPluginEvent::ToHandle(host_request) => match host_request {
|
||||||
eprintln!("[plugin:{}] error: {}", plugin_name, resp.error);
|
HostRequest::ErrorResponse(resp) => {
|
||||||
None
|
eprintln!("[plugin:{}] error: {}", plugin_name, resp.error);
|
||||||
}
|
None
|
||||||
GroupedPluginEvent::Shared(SharedEvent::ReloadResponse(_)) => None,
|
}
|
||||||
GroupedPluginEvent::Host(HostRequest::ShowToast(req)) => {
|
HostRequest::ReloadResponse(_) => None,
|
||||||
eprintln!("[plugin:{}] {}", plugin_name, req.message);
|
HostRequest::ShowToast(req) => {
|
||||||
Some(InternalEventPayload::ShowToastResponse(EmptyPayload {}))
|
eprintln!("[plugin:{}] {}", plugin_name, req.message);
|
||||||
}
|
Some(InternalEventPayload::ShowToastResponse(EmptyPayload {}))
|
||||||
GroupedPluginEvent::Host(HostRequest::ListOpenWorkspaces(_)) => {
|
}
|
||||||
let workspaces = match query_manager.connect().list_workspaces() {
|
HostRequest::ListOpenWorkspaces(_) => {
|
||||||
Ok(workspaces) => workspaces
|
let workspaces = match query_manager.connect().list_workspaces() {
|
||||||
.into_iter()
|
Ok(workspaces) => workspaces
|
||||||
.map(|w| WorkspaceInfo { id: w.id.clone(), name: w.name, label: w.id })
|
.into_iter()
|
||||||
.collect(),
|
.map(|w| WorkspaceInfo { id: w.id.clone(), name: w.name, label: w.id })
|
||||||
Err(err) => {
|
.collect(),
|
||||||
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
Err(err) => {
|
||||||
error: format!("Failed to list workspaces in CLI: {err}"),
|
return Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
}));
|
error: format!("Failed to list workspaces in CLI: {err}"),
|
||||||
}
|
}));
|
||||||
};
|
}
|
||||||
Some(InternalEventPayload::ListOpenWorkspacesResponse(ListOpenWorkspacesResponse {
|
};
|
||||||
workspaces,
|
Some(InternalEventPayload::ListOpenWorkspacesResponse(ListOpenWorkspacesResponse {
|
||||||
}))
|
workspaces,
|
||||||
}
|
}))
|
||||||
GroupedPluginEvent::Host(req) => Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
}
|
||||||
error: format!("Unsupported plugin request in CLI: {}", req.type_name()),
|
req => Some(InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
})),
|
error: format!("Unsupported plugin request in CLI: {}", req.type_name()),
|
||||||
GroupedPluginEvent::Ignore => None,
|
})),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ use tauri::{AppHandle, Emitter, Listener, Manager, Runtime};
|
|||||||
use tauri_plugin_clipboard_manager::ClipboardExt;
|
use tauri_plugin_clipboard_manager::ClipboardExt;
|
||||||
use tauri_plugin_opener::OpenerExt;
|
use tauri_plugin_opener::OpenerExt;
|
||||||
use yaak::plugin_events::{
|
use yaak::plugin_events::{
|
||||||
GroupedPluginEvent, HostRequest, SharedEvent, SharedPluginEventContext,
|
GroupedPluginEvent, HostRequest, SharedPluginEventContext, handle_shared_plugin_event,
|
||||||
handle_shared_plugin_event,
|
|
||||||
};
|
};
|
||||||
use yaak_crypto::manager::EncryptionManager;
|
use yaak_crypto::manager::EncryptionManager;
|
||||||
use yaak_models::models::{AnyModel, HttpResponse, Plugin};
|
use yaak_models::models::{AnyModel, HttpResponse, Plugin};
|
||||||
@@ -61,11 +60,32 @@ pub(crate) async fn handle_plugin_event<R: Runtime>(
|
|||||||
workspace_id: fallback_workspace_id.as_deref(),
|
workspace_id: fallback_workspace_id.as_deref(),
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
GroupedPluginEvent::Shared(SharedEvent::Reply(payload)) => Ok(Some(payload)),
|
GroupedPluginEvent::Handled(payload) => Ok(payload),
|
||||||
GroupedPluginEvent::Shared(SharedEvent::ErrorResponse(resp)) => {
|
GroupedPluginEvent::ToHandle(host_request) => {
|
||||||
|
handle_host_plugin_request(
|
||||||
|
app_handle,
|
||||||
|
event,
|
||||||
|
plugin_handle,
|
||||||
|
&plugin_context,
|
||||||
|
host_request,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_host_plugin_request<R: Runtime>(
|
||||||
|
app_handle: &AppHandle<R>,
|
||||||
|
event: &InternalEvent,
|
||||||
|
plugin_handle: &PluginHandle,
|
||||||
|
plugin_context: &yaak_plugins::events::PluginContext,
|
||||||
|
host_request: HostRequest<'_>,
|
||||||
|
) -> Result<Option<InternalEventPayload>> {
|
||||||
|
match host_request {
|
||||||
|
HostRequest::ErrorResponse(resp) => {
|
||||||
error!("Plugin error: {}: {:?}", resp.error, resp);
|
error!("Plugin error: {}: {:?}", resp.error, resp);
|
||||||
let toast_event = plugin_handle.build_event_to_send(
|
let toast_event = plugin_handle.build_event_to_send(
|
||||||
&plugin_context,
|
plugin_context,
|
||||||
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
||||||
message: format!(
|
message: format!(
|
||||||
"Plugin error from {}: {}",
|
"Plugin error from {}: {}",
|
||||||
@@ -80,7 +100,7 @@ pub(crate) async fn handle_plugin_event<R: Runtime>(
|
|||||||
);
|
);
|
||||||
Box::pin(handle_plugin_event(app_handle, &toast_event, plugin_handle)).await
|
Box::pin(handle_plugin_event(app_handle, &toast_event, plugin_handle)).await
|
||||||
}
|
}
|
||||||
GroupedPluginEvent::Shared(SharedEvent::ReloadResponse(req)) => {
|
HostRequest::ReloadResponse(req) => {
|
||||||
let plugins = app_handle.db().list_plugins()?;
|
let plugins = app_handle.db().list_plugins()?;
|
||||||
for plugin in plugins {
|
for plugin in plugins {
|
||||||
if plugin.directory != plugin_handle.dir {
|
if plugin.directory != plugin_handle.dir {
|
||||||
@@ -94,7 +114,7 @@ pub(crate) async fn handle_plugin_event<R: Runtime>(
|
|||||||
if !req.silent {
|
if !req.silent {
|
||||||
let info = plugin_handle.info();
|
let info = plugin_handle.info();
|
||||||
let toast_event = plugin_handle.build_event_to_send(
|
let toast_event = plugin_handle.build_event_to_send(
|
||||||
&plugin_context,
|
plugin_context,
|
||||||
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
||||||
message: format!("Reloaded plugin {}@{}", info.name, info.version),
|
message: format!("Reloaded plugin {}@{}", info.name, info.version),
|
||||||
icon: Some(Icon::Info),
|
icon: Some(Icon::Info),
|
||||||
@@ -108,28 +128,6 @@ pub(crate) async fn handle_plugin_event<R: Runtime>(
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupedPluginEvent::Host(host_request) => {
|
|
||||||
handle_host_plugin_request(
|
|
||||||
app_handle,
|
|
||||||
event,
|
|
||||||
plugin_handle,
|
|
||||||
&plugin_context,
|
|
||||||
host_request,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
GroupedPluginEvent::Ignore => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_host_plugin_request<R: Runtime>(
|
|
||||||
app_handle: &AppHandle<R>,
|
|
||||||
event: &InternalEvent,
|
|
||||||
plugin_handle: &PluginHandle,
|
|
||||||
plugin_context: &yaak_plugins::events::PluginContext,
|
|
||||||
host_request: HostRequest<'_>,
|
|
||||||
) -> Result<Option<InternalEventPayload>> {
|
|
||||||
match host_request {
|
|
||||||
HostRequest::CopyText(req) => {
|
HostRequest::CopyText(req) => {
|
||||||
app_handle.clipboard().write_text(req.text.as_str())?;
|
app_handle.clipboard().write_text(req.text.as_str())?;
|
||||||
Ok(Some(InternalEventPayload::CopyTextResponse(EmptyPayload {})))
|
Ok(Some(InternalEventPayload::CopyTextResponse(EmptyPayload {})))
|
||||||
|
|||||||
@@ -18,16 +18,8 @@ pub struct SharedPluginEventContext<'a> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum GroupedPluginEvent<'a> {
|
pub enum GroupedPluginEvent<'a> {
|
||||||
Shared(SharedEvent<'a>),
|
Handled(Option<InternalEventPayload>),
|
||||||
Host(HostRequest<'a>),
|
ToHandle(HostRequest<'a>),
|
||||||
Ignore,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum SharedEvent<'a> {
|
|
||||||
Reply(InternalEventPayload),
|
|
||||||
ErrorResponse(&'a ErrorResponse),
|
|
||||||
ReloadResponse(&'a ReloadResponse),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -43,8 +35,6 @@ pub enum SharedRequest<'a> {
|
|||||||
SetKeyValue(&'a SetKeyValueRequest),
|
SetKeyValue(&'a SetKeyValueRequest),
|
||||||
DeleteKeyValue(&'a DeleteKeyValueRequest),
|
DeleteKeyValue(&'a DeleteKeyValueRequest),
|
||||||
GetHttpRequestById(&'a GetHttpRequestByIdRequest),
|
GetHttpRequestById(&'a GetHttpRequestByIdRequest),
|
||||||
ErrorResponse(&'a ErrorResponse),
|
|
||||||
ReloadResponse(&'a ReloadResponse),
|
|
||||||
ListFolders(&'a ListFoldersRequest),
|
ListFolders(&'a ListFoldersRequest),
|
||||||
ListHttpRequests(&'a ListHttpRequestsRequest),
|
ListHttpRequests(&'a ListHttpRequestsRequest),
|
||||||
}
|
}
|
||||||
@@ -69,6 +59,8 @@ pub enum HostRequest<'a> {
|
|||||||
ListCookieNames(&'a ListCookieNamesRequest),
|
ListCookieNames(&'a ListCookieNamesRequest),
|
||||||
GetCookieValue(&'a GetCookieValueRequest),
|
GetCookieValue(&'a GetCookieValueRequest),
|
||||||
WindowInfo(&'a WindowInfoRequest),
|
WindowInfo(&'a WindowInfoRequest),
|
||||||
|
ErrorResponse(&'a ErrorResponse),
|
||||||
|
ReloadResponse(&'a ReloadResponse),
|
||||||
OtherRequest(&'a InternalEventPayload),
|
OtherRequest(&'a InternalEventPayload),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +85,8 @@ impl HostRequest<'_> {
|
|||||||
HostRequest::ListCookieNames(_) => "list_cookie_names_request".to_string(),
|
HostRequest::ListCookieNames(_) => "list_cookie_names_request".to_string(),
|
||||||
HostRequest::GetCookieValue(_) => "get_cookie_value_request".to_string(),
|
HostRequest::GetCookieValue(_) => "get_cookie_value_request".to_string(),
|
||||||
HostRequest::WindowInfo(_) => "window_info_request".to_string(),
|
HostRequest::WindowInfo(_) => "window_info_request".to_string(),
|
||||||
|
HostRequest::ErrorResponse(_) => "error_response".to_string(),
|
||||||
|
HostRequest::ReloadResponse(_) => "reload_response".to_string(),
|
||||||
HostRequest::OtherRequest(payload) => payload.type_name(),
|
HostRequest::OtherRequest(payload) => payload.type_name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,10 +108,10 @@ impl<'a> From<&'a InternalEventPayload> for GroupedPluginRequest<'a> {
|
|||||||
GroupedPluginRequest::Shared(SharedRequest::GetHttpRequestById(req))
|
GroupedPluginRequest::Shared(SharedRequest::GetHttpRequestById(req))
|
||||||
}
|
}
|
||||||
InternalEventPayload::ErrorResponse(resp) => {
|
InternalEventPayload::ErrorResponse(resp) => {
|
||||||
GroupedPluginRequest::Shared(SharedRequest::ErrorResponse(resp))
|
GroupedPluginRequest::Host(HostRequest::ErrorResponse(resp))
|
||||||
}
|
}
|
||||||
InternalEventPayload::ReloadResponse(req) => {
|
InternalEventPayload::ReloadResponse(req) => {
|
||||||
GroupedPluginRequest::Shared(SharedRequest::ReloadResponse(req))
|
GroupedPluginRequest::Host(HostRequest::ReloadResponse(req))
|
||||||
}
|
}
|
||||||
InternalEventPayload::ListOpenWorkspacesRequest(req) => {
|
InternalEventPayload::ListOpenWorkspacesRequest(req) => {
|
||||||
GroupedPluginRequest::Host(HostRequest::ListOpenWorkspaces(req))
|
GroupedPluginRequest::Host(HostRequest::ListOpenWorkspaces(req))
|
||||||
@@ -193,17 +187,11 @@ pub fn handle_shared_plugin_event<'a>(
|
|||||||
context: SharedPluginEventContext<'_>,
|
context: SharedPluginEventContext<'_>,
|
||||||
) -> GroupedPluginEvent<'a> {
|
) -> GroupedPluginEvent<'a> {
|
||||||
match GroupedPluginRequest::from(payload) {
|
match GroupedPluginRequest::from(payload) {
|
||||||
GroupedPluginRequest::Shared(SharedRequest::ErrorResponse(resp)) => {
|
GroupedPluginRequest::Shared(req) => {
|
||||||
GroupedPluginEvent::Shared(SharedEvent::ErrorResponse(resp))
|
GroupedPluginEvent::Handled(Some(build_shared_reply(query_manager, req, context)))
|
||||||
}
|
}
|
||||||
GroupedPluginRequest::Shared(SharedRequest::ReloadResponse(req)) => {
|
GroupedPluginRequest::Host(req) => GroupedPluginEvent::ToHandle(req),
|
||||||
GroupedPluginEvent::Shared(SharedEvent::ReloadResponse(req))
|
GroupedPluginRequest::Ignore => GroupedPluginEvent::Handled(None),
|
||||||
}
|
|
||||||
GroupedPluginRequest::Shared(req) => GroupedPluginEvent::Shared(SharedEvent::Reply(
|
|
||||||
build_shared_reply(query_manager, req, context),
|
|
||||||
)),
|
|
||||||
GroupedPluginRequest::Host(req) => GroupedPluginEvent::Host(req),
|
|
||||||
GroupedPluginRequest::Ignore => GroupedPluginEvent::Ignore,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,9 +228,6 @@ fn build_shared_reply(
|
|||||||
http_request,
|
http_request,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
SharedRequest::ErrorResponse(_) | SharedRequest::ReloadResponse(_) => {
|
|
||||||
unreachable!("non-reply shared events are handled before build_shared_reply")
|
|
||||||
}
|
|
||||||
SharedRequest::ListFolders(_) => {
|
SharedRequest::ListFolders(_) => {
|
||||||
let Some(workspace_id) = context.workspace_id else {
|
let Some(workspace_id) = context.workspace_id else {
|
||||||
return InternalEventPayload::ErrorResponse(ErrorResponse {
|
return InternalEventPayload::ErrorResponse(ErrorResponse {
|
||||||
@@ -364,7 +349,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
result,
|
result,
|
||||||
GroupedPluginEvent::Shared(SharedEvent::Reply(InternalEventPayload::ErrorResponse(_)))
|
GroupedPluginEvent::Handled(Some(InternalEventPayload::ErrorResponse(_)))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,9 +366,9 @@ mod tests {
|
|||||||
SharedPluginEventContext { plugin_name: "@yaak/test", workspace_id: Some("wk_test") },
|
SharedPluginEventContext { plugin_name: "@yaak/test", workspace_id: Some("wk_test") },
|
||||||
);
|
);
|
||||||
match by_workspace {
|
match by_workspace {
|
||||||
GroupedPluginEvent::Shared(SharedEvent::Reply(
|
GroupedPluginEvent::Handled(Some(InternalEventPayload::ListHttpRequestsResponse(
|
||||||
InternalEventPayload::ListHttpRequestsResponse(resp),
|
resp,
|
||||||
)) => {
|
))) => {
|
||||||
assert_eq!(resp.http_requests.len(), 1);
|
assert_eq!(resp.http_requests.len(), 1);
|
||||||
}
|
}
|
||||||
other => panic!("unexpected workspace response: {other:?}"),
|
other => panic!("unexpected workspace response: {other:?}"),
|
||||||
@@ -400,9 +385,9 @@ mod tests {
|
|||||||
SharedPluginEventContext { plugin_name: "@yaak/test", workspace_id: None },
|
SharedPluginEventContext { plugin_name: "@yaak/test", workspace_id: None },
|
||||||
);
|
);
|
||||||
match by_folder {
|
match by_folder {
|
||||||
GroupedPluginEvent::Shared(SharedEvent::Reply(
|
GroupedPluginEvent::Handled(Some(InternalEventPayload::ListHttpRequestsResponse(
|
||||||
InternalEventPayload::ListHttpRequestsResponse(resp),
|
resp,
|
||||||
)) => {
|
))) => {
|
||||||
assert_eq!(resp.http_requests.len(), 1);
|
assert_eq!(resp.http_requests.len(), 1);
|
||||||
}
|
}
|
||||||
other => panic!("unexpected folder response: {other:?}"),
|
other => panic!("unexpected folder response: {other:?}"),
|
||||||
@@ -422,7 +407,9 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
GroupedPluginEvent::Host(HostRequest::WindowInfo(req)) => assert_eq!(req.label, "main"),
|
GroupedPluginEvent::ToHandle(HostRequest::WindowInfo(req)) => {
|
||||||
|
assert_eq!(req.label, "main")
|
||||||
|
}
|
||||||
other => panic!("unexpected host classification: {other:?}"),
|
other => panic!("unexpected host classification: {other:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user