Files
hemx/docs/recipes/host-capabilities.md
T
slhx agent 21100aafdf feat(host): unify typed failure results
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
2026-06-12 07:58:44 +02:00

2.4 KiB

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:

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:

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:

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