feat: v0.1.0 — Studio Plugin SDK
First release of the SDK that Studio plugins depend on. What v0.1 ships: - WIT contract under wit/ (studio-plugin.wit + deps/platform/world.wit, both verbatim from fai/platform/wit/). - wit-bindgen 0.36 generate! call with pub_export_macro enabled so the emitted __export_studio_plugin_impl! macro is reachable from downstream plugin crates. - export_plugin!(MyType) convenience macro that wraps the bindgen-generated impl macro. - README documenting usage + v0.1 limits (single-world -> all-three-hooks-required, no proc-macro yet, edition 2021 pinned by wit-bindgen output). What v0.1 doesn't yet do: - Plugins still declare all three Guest impls (theme, translate, output-view). v0.2 splits the WIT into one world per hook. - No #[plugin(...)] proc-macro. v0.2 wraps generate! + Guest impl generation into a single attribute. - Host-side: the hub doesn't yet load studio-plugin-world components or expose InvokePlugin RPC — that's the next push. Validated against the in-tree studio-theme-solarized plugin: 22 KiB stripped .wasm artefact, valid Component Model, passes wasm-tools component wit inspection. Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
commit
3753c6bc37
7 changed files with 562 additions and 0 deletions
104
src/lib.rs
Normal file
104
src/lib.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
//! `fai-studio-plugin-sdk` — ergonomic wrapper around the
|
||||
//! Studio-plugin WIT contract.
|
||||
//!
|
||||
//! Studio plugins are WASM components targeting the
|
||||
//! `studio-plugin` world declared in `wit/studio-plugin.wit`
|
||||
//! (a verbatim copy of `fai/platform`'s authoritative file).
|
||||
//! They export between one and three hooks — `translate`,
|
||||
//! `output-view`, `theme` — and import the same `host`
|
||||
//! interface every flow module uses for structured logging.
|
||||
//!
|
||||
//! # SKELETON
|
||||
//!
|
||||
//! v0.1 of this crate gives plugins:
|
||||
//!
|
||||
//! * `wit_bindgen!`-generated bindings re-exported under
|
||||
//! [`bindings`] so plugins reference one stable name.
|
||||
//! * Ergonomic re-exports for the most-used types
|
||||
//! ([`ColorScheme`], [`PluginError`], [`RenderedOutput`]).
|
||||
//! * An `export_plugin!` macro that hides the `export!`
|
||||
//! incantation. v0.1 takes a single struct that
|
||||
//! implements one or more `Guest` traits; v0.2 will
|
||||
//! turn this into a proper proc-macro
|
||||
//! (`#[plugin(theme, translate)]`).
|
||||
//!
|
||||
//! What v0.1 deliberately does NOT yet do:
|
||||
//!
|
||||
//! * Generate any glue for the *host* side (the hub still
|
||||
//! needs a dedicated component loader for
|
||||
//! `studio-plugin`-world components — that lands as part
|
||||
//! of the `InvokePlugin` RPC implementation).
|
||||
//! * Provide testing helpers. Plugins author their own
|
||||
//! unit tests against the trait impls directly.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
/// Raw bindings generated from the WIT contract. Plugins
|
||||
/// access types through the convenient re-exports below in
|
||||
/// most cases; this module is here for when they need the
|
||||
/// underlying definitions (e.g. to implement multiple Guest
|
||||
/// traits in one struct).
|
||||
pub mod bindings {
|
||||
wit_bindgen::generate!({
|
||||
world: "studio-plugin",
|
||||
path: "wit",
|
||||
// Generate bindings for the entire WIT package
|
||||
// (incl. fai:platform/host that studio-plugin imports
|
||||
// for log emission), so plugins don't need a separate
|
||||
// `with: …` mapping.
|
||||
generate_all,
|
||||
// Export the `export!` macro publicly so downstream
|
||||
// plugin crates can invoke it via the SDK's
|
||||
// `export_plugin!` wrapper without each plugin
|
||||
// re-running `wit_bindgen::generate!()` against a
|
||||
// copy of the WIT files.
|
||||
pub_export_macro: true,
|
||||
});
|
||||
}
|
||||
|
||||
// v0.1: plugin authors reference paths inside `bindings::`
|
||||
// directly. The typical ones are:
|
||||
//
|
||||
// bindings::exports::fai::studio_plugin::theme::Guest
|
||||
// bindings::exports::fai::studio_plugin::translate::Guest
|
||||
// bindings::exports::fai::studio_plugin::output_view::Guest
|
||||
// bindings::fai::studio_plugin::plugin_types::ColorScheme
|
||||
// bindings::fai::studio_plugin::plugin_types::PluginError
|
||||
// bindings::fai::studio_plugin::plugin_types::RenderedOutput
|
||||
//
|
||||
// Stable re-exports under terser names land in v0.2 — they
|
||||
// have to wait for the proc-macro that materialises the
|
||||
// `Guest` impls anyway.
|
||||
|
||||
/// Convenience constructor: declare a plugin component by
|
||||
/// pointing this macro at the struct that implements the hook
|
||||
/// `Guest` traits.
|
||||
///
|
||||
/// ```ignore
|
||||
/// use fai_studio_plugin_sdk::{export_plugin, bindings};
|
||||
///
|
||||
/// struct MyTheme;
|
||||
/// impl bindings::exports::fai::studio_plugin::theme::Guest for MyTheme {
|
||||
/// fn theme_for(b: String)
|
||||
/// -> Result<bindings::fai::studio_plugin::plugin_types::ColorScheme,
|
||||
/// bindings::fai::studio_plugin::plugin_types::PluginError>
|
||||
/// {
|
||||
/// // ...
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// export_plugin!(MyTheme);
|
||||
/// ```
|
||||
///
|
||||
/// One struct can implement multiple `Guest` traits — the SDK
|
||||
/// does not require a separate struct per hook.
|
||||
///
|
||||
/// Under the hood this resolves to the `__export_studio_plugin_impl!`
|
||||
/// macro that `wit_bindgen::generate!(pub_export_macro: true)`
|
||||
/// emitted at the crate root.
|
||||
#[macro_export]
|
||||
macro_rules! export_plugin {
|
||||
($struct:ident) => {
|
||||
$crate::__export_studio_plugin_impl!($struct with_types_in $crate::bindings);
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue