Files
hemx/docs/recipes/host-capabilities.md
slhx agent a28eb78ded docs(local): describe projections before generated effects
Keep local/offline and host capability recipes on app-owned command/event/projection flow without teaching raw EffectBatch as the authoring boundary.

req: local/001

req: local/002

req: host/002
2026-06-12 08:00:49 +02:00

70 lines
2.4 KiB
Markdown

# Recipe: typed host capabilities
`hemx-host` is the boundary between a hemx app and a browser, PWA,
WebView, or native shell. It is not a mobile framework and it is not a new UI
runtime. A host adapter can perform explicit host side effects or return facts;
app code still owns domain decisions and returns normal hemx effects. req: host/001 req: host/002
## Contract
Declare the capability shape the app may use:
```rust
use hemx_host::{Capability, CapabilityManifest, CapabilityShape, CapabilityUse};
let manifest = CapabilityManifest::new([
CapabilityUse::new(Capability::Haptics, CapabilityShape::Fire),
CapabilityUse::new(Capability::Share, CapabilityShape::Request),
]);
```
Check the manifest against the concrete host profile before executing calls:
```rust
use hemx_host::{HostProfile, HostCheckError};
let host = HostProfile::new(
"web",
[CapabilityUse::new(Capability::Share, CapabilityShape::Request)],
);
let result: Result<(), HostCheckError> = manifest.check(&host);
```
Permission-sensitive capabilities such as microphone, camera, notifications,
secure storage, file picker, and geolocation need a user-facing reason in the
manifest before standard host checks pass. req: host/003 req: host/004
## Browser/PWA adapter
`hemx-host::BROWSER_HOST_JS` is an optional tiny browser adapter. It exposes
`window.hemxBrowserHost.perform(call)`, accepts the serde JSON shape of
`HostCall`, calls browser APIs such as `navigator.share` or `navigator.vibrate`,
and returns the serde JSON shape of `HostEvent`. It does not query, patch, or
own the DOM; the app consumes the host event and returns ordinary hemx effects.
req: host/001 req: host/002 req: host/005
## Event flow
Host events are facts, not app mutations. Denied, timeout, unavailable, and
error cases all use `HostEvent::Failed(HostFailure { kind, ... })`, so app code
handles one typed result shape before producing UI effects:
```text
HostEvent
→ app/domain command
→ domain validation and optional persistence
→ projection/rendering
→ generated UI effects
```
Adapters must not mutate DOM, append domain events, or write application state
on behalf of the app. req: host/002 req: host/005
## Mobile
iOS and Android shells are thin host adapters around a WebView. They implement
manifest-backed calls such as haptics, share, microphone streams, secure
storage, notifications, and explicit custom capabilities; hemx still owns UI
effects and the app still owns state. req: host/001 req: host/002