21100aafdf
Represent denied, timeout, unavailable, and error host outcomes with one HostFailure result shape, update the browser adapter, and keep Workout host recovery flowing through app code before UI effects. req: host/002 req: host/005 req: local/003
70 lines
2.4 KiB
Markdown
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
|
|
→ hemx EffectBatch
|
|
```
|
|
|
|
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
|