mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-17 23:13:51 +01:00
Plugin module loading
This commit is contained in:
@@ -1 +0,0 @@
|
||||
sayHello('Plugin');
|
||||
3
src-tauri/plugins/hello-world/hello.js
Normal file
3
src-tauri/plugins/hello-world/hello.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export function hello() {
|
||||
sayHello('Plugin');
|
||||
}
|
||||
5
src-tauri/plugins/hello-world/index.js
Normal file
5
src-tauri/plugins/hello-world/index.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { hello } from './hello.js';
|
||||
|
||||
export function entrypoint() {
|
||||
hello();
|
||||
}
|
||||
@@ -32,7 +32,7 @@ use window_ext::TrafficLightWindowExt;
|
||||
mod models;
|
||||
mod render;
|
||||
mod window_ext;
|
||||
mod plugins;
|
||||
mod plugin;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct CustomResponse {
|
||||
@@ -689,7 +689,7 @@ fn main() {
|
||||
let w = create_window(app_handle, None);
|
||||
w.restore_state(StateFlags::all())
|
||||
.expect("Failed to restore window state");
|
||||
plugins::test_plugins(&app_handle);
|
||||
plugin::test_plugins(&app_handle);
|
||||
}
|
||||
|
||||
// ExitRequested { api, .. } => {
|
||||
|
||||
97
src-tauri/src/plugin.rs
Normal file
97
src-tauri/src/plugin.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
use boa_engine::{
|
||||
js_string,
|
||||
module::{ModuleLoader, SimpleModuleLoader},
|
||||
property::Attribute,
|
||||
Context, JsArgs, JsNativeError, JsValue, Module, NativeFunction, Source,
|
||||
};
|
||||
use boa_runtime::Console;
|
||||
use tauri::AppHandle;
|
||||
|
||||
pub fn test_plugins(app_handle: &AppHandle) {
|
||||
let plugin_dir = app_handle
|
||||
.path_resolver()
|
||||
.resolve_resource("plugins/hello-world")
|
||||
.expect("failed to resolve plugin directory resource");
|
||||
let plugin_entry_file = app_handle
|
||||
.path_resolver()
|
||||
.resolve_resource("plugins/hello-world/index.js")
|
||||
.expect("failed to resolve plugin entry point resource");
|
||||
|
||||
// Module loader for the specific plugin
|
||||
let loader = &SimpleModuleLoader::new(plugin_dir).expect("failed to create module loader");
|
||||
let dyn_loader: &dyn ModuleLoader = loader;
|
||||
|
||||
let context = &mut Context::builder()
|
||||
.module_loader(dyn_loader)
|
||||
.build()
|
||||
.expect("failed to create context");
|
||||
|
||||
add_runtime(context);
|
||||
add_globals(context);
|
||||
|
||||
let source = Source::from_filepath(&plugin_entry_file).expect("Error opening file");
|
||||
|
||||
// Can also pass a `Some(realm)` if you need to execute the module in another realm.
|
||||
let module = Module::parse(source, None, context).expect("failed to parse module");
|
||||
|
||||
// Insert parsed entrypoint into the module loader
|
||||
// TODO: Is this needed if loaded from file already?
|
||||
loader.insert(plugin_entry_file, module.clone());
|
||||
|
||||
let _promise_result = module
|
||||
.load_link_evaluate(context)
|
||||
.expect("failed to evaluate module");
|
||||
|
||||
// Very important to push forward the job queue after queueing promises.
|
||||
context.run_jobs();
|
||||
|
||||
// // Checking if the final promise didn't return an error.
|
||||
// match promise_result.state() {
|
||||
// PromiseState::Pending => return Err("module didn't execute!".into()),
|
||||
// PromiseState::Fulfilled(v) => {
|
||||
// assert_eq!(v, JsValue::undefined())
|
||||
// }
|
||||
// PromiseState::Rejected(err) => {
|
||||
// return Err(JsError::from_opaque(err).try_native(context)?.into())
|
||||
// }
|
||||
// }
|
||||
|
||||
let namespace = module.namespace(context);
|
||||
|
||||
let entrypoint_fn = namespace
|
||||
.get(js_string!("entrypoint"), context)
|
||||
.expect("failed to get entrypoint")
|
||||
.as_callable()
|
||||
.cloned()
|
||||
.ok_or_else(|| JsNativeError::typ().with_message("export wasn't a function!"))
|
||||
.expect("Failed to get entrypoint");
|
||||
|
||||
// Actually call the entrypoint function
|
||||
let _result = entrypoint_fn
|
||||
.call(&JsValue::undefined(), &[], context)
|
||||
.expect("Failed to call entrypoint");
|
||||
}
|
||||
|
||||
fn add_runtime(context: &mut Context<'_>) {
|
||||
let console = Console::init(context);
|
||||
context
|
||||
.register_global_property(js_string!(Console::NAME), console, Attribute::all())
|
||||
.expect("the console builtin shouldn't exist");
|
||||
}
|
||||
|
||||
fn add_globals(context: &mut Context<'_>) {
|
||||
context
|
||||
.register_global_builtin_callable(
|
||||
"sayHello",
|
||||
1,
|
||||
NativeFunction::from_fn_ptr(|_, args, context| {
|
||||
let value: String = args
|
||||
.get_or_undefined(0)
|
||||
.try_js_into(context)
|
||||
.expect("failed to convert arg");
|
||||
println!("Hello {}!", value);
|
||||
Ok(value.into())
|
||||
}),
|
||||
)
|
||||
.expect("failed to register global");
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
use boa_engine::{
|
||||
js_string, property::Attribute, Context, JsArgs, NativeFunction, Source,
|
||||
};
|
||||
use boa_runtime::Console;
|
||||
use tauri::AppHandle;
|
||||
|
||||
pub fn test_plugins(app_handle: &AppHandle) {
|
||||
let file = app_handle
|
||||
.path_resolver()
|
||||
.resolve_resource("plugins/hello-world.js")
|
||||
.expect("failed to resolve resource");
|
||||
let src = Source::from_filepath(&file).expect("Error opening file");
|
||||
|
||||
// Instantiate the execution context
|
||||
let mut context = Context::default();
|
||||
add_runtime(&mut context);
|
||||
|
||||
// Add globals
|
||||
context
|
||||
.register_global_builtin_callable(
|
||||
"sayHello",
|
||||
1,
|
||||
NativeFunction::from_fn_ptr(|_, args, context| {
|
||||
let value: String = args
|
||||
.get_or_undefined(0)
|
||||
.try_js_into(context)
|
||||
.expect("failed to convert arg");
|
||||
|
||||
println!("Hello {}!", value);
|
||||
|
||||
Ok(value.into())
|
||||
}),
|
||||
)
|
||||
.expect("failed to register global");
|
||||
|
||||
context.eval(src).expect("failed to execute script");
|
||||
}
|
||||
|
||||
fn add_runtime(context: &mut Context<'_>) {
|
||||
let console = Console::init(context);
|
||||
context
|
||||
.register_global_property(js_string!(Console::NAME), console, Attribute::all())
|
||||
.expect("the console builtin shouldn't exist");
|
||||
}
|
||||
@@ -165,7 +165,7 @@ export const Sidebar = memo(function Sidebar({ className }: Props) {
|
||||
tabIndex={hidden ? -1 : 0}
|
||||
className={classNames(
|
||||
className,
|
||||
'h-full pb-3 overflow-y-scroll overflow-x-visible pt-2',
|
||||
'h-full pb-3 overflow-y-scroll overflow-x-visible hide-scrollbars pt-2',
|
||||
)}
|
||||
>
|
||||
<SidebarItems
|
||||
|
||||
Reference in New Issue
Block a user