From 4b8e0ce9569c22ad6b243a6fbe47cb0743d31994 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Sat, 16 May 2026 23:57:03 +0800 Subject: [PATCH] refactor(rust): add op-app composition-root crate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 7.3 strangler reorg — add op-app, the thin crate that names the editor application's composition root. Investigation found no shared host bootstrap left to extract: the editor-UI composition (widgets, theme, layout scene) already lives in op-editor-ui, and each host (op-host-native / op-host-web) owns only platform-specific backend wiring. So per YAGNI op-app stays thin — it re-exports op-editor-ui plus the per-platform host entry point behind its target cfg, and documents the composition. If real cross-host wiring later emerges, it lands here. Builds green on both native and wasm32-unknown-unknown. --- Cargo.lock | 9 ++++++++ crates/op-app/Cargo.toml | 35 ++++++++++++++++++++++++++++++ crates/op-app/src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 crates/op-app/Cargo.toml create mode 100644 crates/op-app/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index fe30ceec1..1d6c8bacf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2278,6 +2278,15 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" name = "op-ai" version = "0.1.0" +[[package]] +name = "op-app" +version = "0.1.0" +dependencies = [ + "op-editor-ui", + "op-host-native", + "op-host-web", +] + [[package]] name = "op-codegen" version = "0.1.0" diff --git a/crates/op-app/Cargo.toml b/crates/op-app/Cargo.toml new file mode 100644 index 000000000..c5c34411e --- /dev/null +++ b/crates/op-app/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "op-app" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +description = "OpenPencil composition root — re-exports the platform host entry points (op-host-native / op-host-web) and documents the editor app composition" + +[lib] +name = "op_app" +path = "src/lib.rs" + +# Phase 7.3 reorg: op-app is the thin composition root. The editor-UI +# composition itself (which widgets, the layout) already lives in the +# op-editor-ui crate, so there is no shared host bootstrap to host +# here today — op-app only re-exports the per-platform host entry +# points behind their target cfg. It deliberately stays thin (YAGNI): +# if real cross-host wiring later emerges, it lands here. + +# The platform-agnostic editor-UI composition. Wasm-clean and already +# a transitive dep of both hosts, so this direct edge costs nothing. +[dependencies] +op-editor-ui = { path = "../op-editor-ui" } + +# Native host (winit + skia-safe + accesskit) — desktop + mobile, NOT +# wasm. Mirrors op-host-native's own target gate so op-app stays +# wasm32-clean and mobile-checkable. +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +op-host-native = { path = "../op-host-native", version = "0.1.0" } + +# Web host (wasm32-unknown-unknown bundle entry). Only resolved on +# the wasm32 target where op-host-web's cdylib / wasm-bindgen setup +# applies. +[target.'cfg(target_arch = "wasm32")'.dependencies] +op-host-web = { path = "../op-host-web", version = "0.1.0" } diff --git a/crates/op-app/src/lib.rs b/crates/op-app/src/lib.rs new file mode 100644 index 000000000..9d4431d55 --- /dev/null +++ b/crates/op-app/src/lib.rs @@ -0,0 +1,47 @@ +//! OpenPencil composition root. +//! +//! Phase 7.3 strangler reorg — `op-app` is the thin crate that names +//! the editor application's composition. It exists so the workspace +//! has one obvious "this is the app" entry point rather than two +//! free-standing host crates. +//! +//! ## What composes the app +//! +//! The editor-UI composition — which widgets exist, how they lay out, +//! the theme, the layout-resolved render scene — already lives in the +//! [`op_editor_ui`] crate. The canonical editor state lives in +//! `op-editor-core`; the `.op` loader in `op-pen-loader`. The two +//! platform hosts wire that shared composition to a concrete backend: +//! +//! - **`op-host-native`** — winit + skia-safe + accesskit GL host +//! (desktop + mobile). The desktop binary is `op-host-desktop`. +//! - **`op-host-web`** — the wasm32-unknown-unknown browser bundle +//! (`WebShell` + `mount()`). +//! +//! Because that composition is already factored into `op-editor-ui`, +//! there is no shared host *bootstrap* code left to extract — each +//! host owns only platform-specific backend wiring. So `op-app` is +//! deliberately thin (YAGNI): it re-exports the per-platform host +//! entry point behind its target `cfg` and serves as the documented +//! composition root. If genuine cross-host wiring later emerges, it +//! lands here. + +/// The platform-agnostic editor-UI composition (widgets, theme, +/// layout scene, render-backend facade, gesture types). +pub use op_editor_ui as editor_ui; + +/// The native host — winit + skia-safe + accesskit (desktop + mobile). +/// +/// Re-exported on every non-wasm target. The shipped desktop +/// executable lives in the `op-host-desktop` crate, which drives +/// [`host_native::WidgetHostNative`] from a winit event loop. +#[cfg(not(target_arch = "wasm32"))] +pub use op_host_native as host_native; + +/// The web host — the wasm32-unknown-unknown browser bundle entry. +/// +/// Re-exported only on the wasm32 target, where `op-host-web`'s +/// `cdylib` / wasm-bindgen setup applies. `host_web::mount` is the +/// JS-facing entry point. +#[cfg(target_arch = "wasm32")] +pub use op_host_web as host_web;