一键导入
plugins
Use when installing app or server plugins—wiring observability, auth, live queries, or other optional integrations into a pocopine app.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when installing app or server plugins—wiring observability, auth, live queries, or other optional integrations into a pocopine app.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Use when turning a Claude Design (or any mockup/design) into a well-structured pocopine app — choosing app architecture (a store plus layout/leaf components), translating inline styles into Pine Stylekit, wiring icons and resizable regions, and verifying the result.
Use when working with the pocopine Pine icons feature — the `icon!` proc macro for compile-time Rust SVG embedding, or the `<pine-icon>` template primitive with `register_icons!` for tree-shaking-friendly template rendering.
Use when building styles with Pine Stylekit, the Pocopine-native utility-CSS compiler, or working with @theme tokens and CSS generation in Rust/WASM projects
Use when building enter/leave transitions, layout animations, stagger effects, or spring-physics motion in pocopine components
Use when implementing authentication in pocopine apps — JWT verification, credentials, OAuth providers, session management, or guards
Use when defining background jobs, enqueueing work, configuring workers, or troubleshooting job execution in pocopine apps
基于 SOC 职业分类
| name | plugins |
| description | Use when installing app or server plugins—wiring observability, auth, live queries, or other optional integrations into a pocopine app. |
Pocopine provides a first-class plugin system for both frontend (AppPlugin) and backend (ServerPlugin) to inject optional integrations—observability, auth, live queries, devtools—without editing core or copying boilerplate.
App.Router.Core trait:
pub trait AppPlugin {
fn name(&self) -> &'static str { std::any::type_name::<Self>() }
fn install(self, app: App) -> App;
}
Installing plugins:
App::plugin(plugin) — builder method; plugin closures also implement AppPlugin.App::provide_plugin(service) — inside install, register a runtime service.App::hook_plugin::<Service, Event>() — register a Hook<Event> impl on the service.App::hook_component_plugin::<Service, Component, Event>() — fire hook only for a specific component type.Extracting services in components:
Plugin<T> — required; panics if T not installed.Option<Plugin<T>> — optional; returns None if missing.self.plugin::<T>() — extract from a method; required form.self.plugins().get::<T>() — extract from a method; optional form.Lifecycle events:
AppBootStarted, AppBootCompleted, AppBootFailedComponentSetup, ComponentMounted, ComponentReady, ComponentUnmountedRouteNavigationStarted, RouteNavigationCompleted, RouteNavigationFailedServerFunctionClientStarted, ServerFunctionClientCompleted, ServerFunctionClientFailedMacro support:
pocopine::app! {
plugins: [plugin1(), plugin2()],
components: [...],
routes: [...],
}
Core trait:
pub trait ServerPlugin {
fn name(&self) -> &'static str { std::any::type_name::<Self>() }
fn install(self, server: Server) -> Server;
}
Installing plugins:
Server::new(router).plugin(plugin) — builder method; closures also implement ServerPlugin.Server::provide_plugin(service) — register an Arc<T> runtime service.Server::hook_plugin::<Service, Event>() — register a ServerHook<Event> impl.Lifecycle events:
ServerBootStarted, ServerListening, ServerBootFailedHttpRequestStarted, HttpRequestCompleted, HttpRequestFailedServerFunctionStarted, ServerFunctionCompleted, ServerFunctionRejected, ServerFunctionFailedHook trait:
pub trait ServerHook<E>: Send + Sync + 'static {
fn call(&self, event: E);
}
From /home/zempare-mambisi/RustProjects/pocopine/crates/pocopine-sync-query/src/plugin.rs:
pub fn query_client_plugin() -> QueryClientPlugin {
QueryClientPlugin::default()
}
impl AppPlugin for QueryClientPlugin {
fn name(&self) -> &'static str {
"pocopine-sync-query"
}
fn install(self, app: App) -> App {
app.provide_plugin::<Rc<QueryClient>>(
Rc::new(self.into_client())
)
}
}
Usage in a component:
fn on_ready(&self, query: Plugin<Rc<QueryClient>>) {
query.observe(MyQuery);
}
From /home/zempare-mambisi/RustProjects/pocopine/crates/pocopine-auth-client/src/plugin.rs:
impl AppPlugin for AuthPluginBuilder {
fn name(&self) -> &'static str {
"pocopine-auth-client"
}
fn install(self, app: App) -> App {
if let Some(storage) = self.token_storage {
install_storage(storage);
crate::hydrate_from_storage();
}
let session = AuthSession::new();
app.provide_plugin(session)
.route_rejection_handler(UnauthorizedRedirect {
login_route: self.login_route,
param: self.return_to_query_param,
})
}
}
// Usage:
auth_plugin()
.login_route("/login")
.with_bearer_middleware(true)
.with_token_storage(LocalStorage::new("token"))
From /home/zempare-mambisi/RustProjects/pocopine/crates/pocopine-server/tests/server_plugin.rs:
impl ServerHook<ServerBootStarted> for EventLog {
fn call(&self, event: ServerBootStarted) {
self.record(format!("boot:{}", event.addr));
}
}
impl ServerPlugin for EventLog {
fn name(&self) -> &'static str {
"event-logger"
}
fn install(self, server: Server) -> Server {
server
.provide_plugin(self.clone())
.hook_plugin::<EventLog, ServerBootStarted>()
}
}
// In main:
Server::new(router)
.plugin(EventLog::default())
.serve("0.0.0.0:3000")
.await
Hook/Service Ordering: If a hook is registered before its service is provided, boot validation will catch it and render a detailed error. Install services before or after hooks—validator doesn't care about order, only completeness.
Duplicate Services: Calling provide_plugin twice with the same type panics immediately, naming both providers. This is intentional—fail loud, not silently overwrite.
Plugin Lifecycle is Sync: install runs synchronously during builder assembly. Async setup should spawn tasks from install or attach a before_mount / after_mount hook.
No Dynamic Uninstall: Installed services and hooks live for the app's lifetime. There is no removal or hot-swap API; dynamically-loaded plugins are out of scope.
Server Registry is Process-Global: A second Server::serve call in the same process replaces the first's plugin registry. Tests should call pocopine_server::__reset_for_test() between serves.
Macro Apps Can Inspect Manifest: When using pocopine::app! { plugins: [...] }, plugins see static component and route metadata before mount, but cannot register additional components or routes. The static registry contract (RFC-060) is preserved.
Layer Order in Server Plugins: Server::layer() wraps only routes that exist at the call site. Add routes first, then layers, to avoid silently bypassing middleware.
App-Level Performance: Component mount/unmount hot paths use a bitmask cache to skip plugin-only metadata stamps when no hooks are registered. This is automatic; plugins stay cheap when unused.
crates/pocopine-core/src/plugin.rs — the trait, registry, and event dispatch.crates/pocopine-server/src/plugin.rs — the trait, registry, and hook bitmask gating.crates/pocopine-auth-client/src/plugin.rs — builder pattern, lifecycle hooks, optional storage.crates/pocopine-sync-query/src/plugin.rs — minimal Rc<T> service provision.crates/pocopine-server/tests/server_plugin.rs — boot event ordering, validation errors.rfcs/rfc-076-app-plugin-lifecycle.md — design, lifecycle order, observability shape.rfcs/rfc-077-server-plugin-lifecycle.md — host-side plugin shape, HTTP events, validation.docs/app-plugins.md — full lifecycle order, four integration paths, testing contract.docs/server-plugins.md — quickstart, layer ordering, cost model, active_plugin lookups.