mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-24 01:28:35 +02:00
Fix plugin dev rebuild signaling and reload toast timing
This commit is contained in:
@@ -4,8 +4,8 @@ use crate::utils::http;
|
|||||||
use keyring::Entry;
|
use keyring::Entry;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rolldown::{
|
use rolldown::{
|
||||||
Bundler, BundlerOptions, ExperimentalOptions, InputItem, LogLevel, OutputFormat, Platform,
|
BundleEvent, Bundler, BundlerOptions, ExperimentalOptions, InputItem, LogLevel, OutputFormat,
|
||||||
WatchOption, Watcher,
|
Platform, WatchOption, Watcher, WatcherEvent,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
@@ -114,12 +114,53 @@ async fn dev(args: PluginPathArg) -> CommandResult {
|
|||||||
ensure_plugin_build_inputs(&plugin_dir)?;
|
ensure_plugin_build_inputs(&plugin_dir)?;
|
||||||
|
|
||||||
ui::info(&format!("Watching plugin {}...", plugin_dir.display()));
|
ui::info(&format!("Watching plugin {}...", plugin_dir.display()));
|
||||||
ui::info("Press Ctrl-C to stop");
|
|
||||||
|
|
||||||
let bundler = Bundler::new(bundler_options(&plugin_dir, true))
|
let bundler = Bundler::new(bundler_options(&plugin_dir, true))
|
||||||
.map_err(|err| format!("Failed to initialize Rolldown watcher: {err}"))?;
|
.map_err(|err| format!("Failed to initialize Rolldown watcher: {err}"))?;
|
||||||
let watcher = Watcher::new(vec![Arc::new(Mutex::new(bundler))], None)
|
let watcher = Watcher::new(vec![Arc::new(Mutex::new(bundler))], None)
|
||||||
.map_err(|err| format!("Failed to start Rolldown watcher: {err}"))?;
|
.map_err(|err| format!("Failed to start Rolldown watcher: {err}"))?;
|
||||||
|
let emitter = watcher.emitter();
|
||||||
|
let watch_root = plugin_dir.clone();
|
||||||
|
let _event_logger = tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
let event = {
|
||||||
|
let rx = emitter.rx.lock().await;
|
||||||
|
rx.recv()
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(event) = event else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
match event {
|
||||||
|
WatcherEvent::Change(change) => {
|
||||||
|
let changed_path = Path::new(change.path.as_str());
|
||||||
|
let display_path = changed_path
|
||||||
|
.strip_prefix(&watch_root)
|
||||||
|
.map(|p| p.display().to_string())
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
changed_path
|
||||||
|
.file_name()
|
||||||
|
.map(|name| name.to_string_lossy().into_owned())
|
||||||
|
.unwrap_or_else(|| "unknown".to_string())
|
||||||
|
});
|
||||||
|
ui::info(&format!("Rebuilding plugin {display_path}"));
|
||||||
|
}
|
||||||
|
WatcherEvent::Event(BundleEvent::BundleEnd(_)) => {}
|
||||||
|
WatcherEvent::Event(BundleEvent::Error(event)) => {
|
||||||
|
if event.error.diagnostics.is_empty() {
|
||||||
|
ui::error("Plugin build failed");
|
||||||
|
} else {
|
||||||
|
for diagnostic in event.error.diagnostics {
|
||||||
|
ui::error(&diagnostic.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WatcherEvent::Close => break,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
watcher.start().await;
|
watcher.start().await;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ async fn handle_host_plugin_request<R: Runtime>(
|
|||||||
&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),
|
||||||
timeout: Some(3000),
|
timeout: Some(5000),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ export class PluginInstance {
|
|||||||
this.#mod = {};
|
this.#mod = {};
|
||||||
|
|
||||||
const fileChangeCallback = async () => {
|
const fileChangeCallback = async () => {
|
||||||
await this.#mod?.dispose?.();
|
|
||||||
this.#importModule();
|
|
||||||
const ctx = this.#newCtx(workerData.context);
|
const ctx = this.#newCtx(workerData.context);
|
||||||
try {
|
try {
|
||||||
|
await this.#mod?.dispose?.();
|
||||||
|
this.#importModule();
|
||||||
await this.#mod?.init?.(ctx);
|
await this.#mod?.init?.(ctx);
|
||||||
this.#sendPayload(
|
this.#sendPayload(
|
||||||
workerData.context,
|
workerData.context,
|
||||||
@@ -90,7 +90,7 @@ export class PluginInstance {
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
ctx.toast.show({
|
await ctx.toast.show({
|
||||||
message: `Failed to initialize plugin ${this.#workerData.bootRequest.dir.split('/').pop()}: ${err}`,
|
message: `Failed to initialize plugin ${this.#workerData.bootRequest.dir.split('/').pop()}: ${err}`,
|
||||||
color: 'notice',
|
color: 'notice',
|
||||||
icon: 'alert_triangle',
|
icon: 'alert_triangle',
|
||||||
@@ -1003,6 +1003,7 @@ function watchFile(filepath: string, cb: () => void) {
|
|||||||
const stat = statSync(filepath, { throwIfNoEntry: false });
|
const stat = statSync(filepath, { throwIfNoEntry: false });
|
||||||
if (stat == null || stat.mtimeMs !== watchedFiles[filepath]?.mtimeMs) {
|
if (stat == null || stat.mtimeMs !== watchedFiles[filepath]?.mtimeMs) {
|
||||||
watchedFiles[filepath] = stat ?? null;
|
watchedFiles[filepath] = stat ?? null;
|
||||||
|
console.log('[plugin-runtime] watchFile triggered', filepath);
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user