Archived
feat: port el-ui vessels — rename crates→vessels, add El source + manifests
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
//! el-platform — Universal rendering backends for el-ui.
|
||||
//!
|
||||
//! The same component code produces native output for every target platform.
|
||||
//! No bridge. No virtual DOM. Direct platform calls.
|
||||
//!
|
||||
//! The target is chosen in `el.toml`:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [platform]
|
||||
//! target = "web" # web | server | ios | android | macos | linux | windows
|
||||
//! ssr = true
|
||||
//! ```
|
||||
//!
|
||||
//! All platforms implement the `PlatformBackend` trait. A future agent fills in
|
||||
//! the native API calls for iOS/Android/macOS/Linux/Windows — the architecture
|
||||
//! is correct and complete now.
|
||||
|
||||
pub mod backends;
|
||||
pub mod config;
|
||||
pub mod node;
|
||||
|
||||
pub use backends::{
|
||||
android::AndroidBackend,
|
||||
ios::IosBackend,
|
||||
linux::LinuxBackend,
|
||||
macos::MacosBackend,
|
||||
server::ServerBackend,
|
||||
web::WebBackend,
|
||||
windows::WindowsBackend,
|
||||
};
|
||||
pub use config::{PlatformConfig, PlatformTarget};
|
||||
pub use node::{Attribute, EventHandler, PlatformNode, PlatformNodeKind};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlatformError {
|
||||
#[error("render error: {0}")]
|
||||
Render(String),
|
||||
#[error("mount error: {0}")]
|
||||
Mount(String),
|
||||
#[error("unsupported operation on target {target}: {op}")]
|
||||
Unsupported { target: String, op: String },
|
||||
#[error("event binding error: {0}")]
|
||||
EventBinding(String),
|
||||
}
|
||||
|
||||
pub type PlatformResult<T> = Result<T, PlatformError>;
|
||||
|
||||
/// The core trait every platform backend must implement.
|
||||
///
|
||||
/// All rendering paths go through this interface. Component code is identical
|
||||
/// across targets — only the backend chosen by `el.toml` differs.
|
||||
pub trait PlatformBackend: Send + Sync {
|
||||
/// The platform name (e.g. "web", "server", "ios").
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
/// Create a new element node on this platform.
|
||||
fn create_element(&self, tag: &str) -> PlatformResult<PlatformNode>;
|
||||
|
||||
/// Create a text node on this platform.
|
||||
fn create_text(&self, content: &str) -> PlatformResult<PlatformNode>;
|
||||
|
||||
/// Set an attribute on a node.
|
||||
fn set_attribute(&self, node: &mut PlatformNode, name: &str, value: &str)
|
||||
-> PlatformResult<()>;
|
||||
|
||||
/// Remove an attribute from a node.
|
||||
fn remove_attribute(&self, node: &mut PlatformNode, name: &str) -> PlatformResult<()>;
|
||||
|
||||
/// Append a child node to a parent.
|
||||
fn append_child(&self, parent: &mut PlatformNode, child: PlatformNode)
|
||||
-> PlatformResult<()>;
|
||||
|
||||
/// Remove a child node from a parent.
|
||||
fn remove_child(&self, parent: &mut PlatformNode, child_index: usize) -> PlatformResult<()>;
|
||||
|
||||
/// Replace a child node at the given index.
|
||||
fn replace_child(
|
||||
&self,
|
||||
parent: &mut PlatformNode,
|
||||
index: usize,
|
||||
new_child: PlatformNode,
|
||||
) -> PlatformResult<()>;
|
||||
|
||||
/// Bind an event handler to a node.
|
||||
fn bind_event(
|
||||
&self,
|
||||
node: &mut PlatformNode,
|
||||
event: &str,
|
||||
handler: EventHandler,
|
||||
) -> PlatformResult<()>;
|
||||
|
||||
/// Render a node tree to its platform representation.
|
||||
/// For `server`, this returns an HTML string.
|
||||
/// For `web`, this patches the live DOM.
|
||||
/// For native targets, this calls the appropriate native APIs.
|
||||
fn render_to_string(&self, node: &PlatformNode) -> PlatformResult<String>;
|
||||
|
||||
/// Mount a node tree into the platform's root container.
|
||||
/// `container_id` is a platform-specific identifier (CSS selector for web,
|
||||
/// view controller ID for iOS, activity ID for Android, etc.).
|
||||
fn mount(&self, root: PlatformNode, container_id: &str) -> PlatformResult<()>;
|
||||
|
||||
/// Patch an existing mounted tree with a new tree.
|
||||
/// The backend performs the minimal update needed.
|
||||
fn patch(&self, old: &PlatformNode, new: &PlatformNode) -> PlatformResult<()>;
|
||||
|
||||
/// Whether this backend supports SSR (rendering to HTML string on the server).
|
||||
fn supports_ssr(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Select the backend for a given platform target.
|
||||
pub fn backend_for(target: &PlatformTarget) -> Box<dyn PlatformBackend> {
|
||||
match target {
|
||||
PlatformTarget::Web => Box::new(WebBackend::new()),
|
||||
PlatformTarget::Server => Box::new(ServerBackend::new()),
|
||||
PlatformTarget::Ios => Box::new(IosBackend::new()),
|
||||
PlatformTarget::Android => Box::new(AndroidBackend::new()),
|
||||
PlatformTarget::Macos => Box::new(MacosBackend::new()),
|
||||
PlatformTarget::Linux => Box::new(LinuxBackend::new()),
|
||||
PlatformTarget::Windows => Box::new(WindowsBackend::new()),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user