moirai-pal
Platform Abstraction Layer for the Moirai
runtime's async I/O. One Reactor trait over the platform's native readiness
mechanism, so the async stack needs no external runtime:
| Target | Mechanism |
|---|---|
| Linux | epoll |
| macOS / BSD | kqueue |
| Windows | WSAPoll socket readiness polling and a thread-owned Win32 window |
| WebAssembly | Web APIs via JavaScript interop |
Modules: reactor, net, fs, timer, plus the per-platform unix,
windows, and wasm implementations. On Windows, windows::window::NativeWindow
provides a bounded message queue and ARGB software presentation surface for a
consumer-owned event loop. NativeWindow::wait_events adds a finite message
queue wait for event-driven hosts; waits beyond its 30-second bound are
rejected. Each native window enters per-monitor-v2 DPI awareness for its
thread-owned lifetime and restores the prior thread context on drop, so
WM_DPICHANGED reports real monitor transitions when the host supplies them.
Native IME start, preedit, commit and cancellation phases are returned as
bounded UTF-8 snapshots.
windows::webview::WebViewHost embeds the installed Windows WebView2 runtime
inside a NativeWindow for packaged HTML5, CSS and WebAssembly applications.
The module is opt-in: enable the webview2 feature on moirai-pal; default
Windows consumers compile the native window and file providers without the
WebView2 COM binding.
It admits only a validated file:/// package prefix, bounds UTF-16 JSON
messages, denies external and new-window navigation, and keeps creation,
navigation and teardown waits finite. The WebView2 runtime is a Windows system
prerequisite; this provider does not require a registry token, signing key or
other application credential.
All WebView2 permission requests are denied synchronously before a profile or
OS prompt can grant access, and the host emits a bounded
WebViewEvent::PermissionDenied snapshot for the consumer's audit surface.
WebViewHost::capture_preview_png obtains a bounded PNG from WebView2's own
preview stream, so an occluded or hardware-composed surface can be inspected
without a GDI screenshot. The controller fills its window's client area and is
visible from creation, so a hidden window still renders and captures; a
controller hidden through set_visible(false) refuses capture, because
WebView2 withholds a hidden controller's capture until it is shown.
fs::open_file_within_root opens a native regular file through directory
handles, using openat on Unix and relative NtCreateFile calls on Windows.
It rejects traversal and link components before returning the handle that the
caller reads. WebAssembly reports an explicit unsupported error; browser file
bytes use the DOM file provider instead.
The WASM module owns the browser boundary used by Atlas applications. WebDocument
and WebElement provide bounded DOM updates, input/select values, checked
checkbox/radio state, disabled button/input/select state, modal dialog lifecycle
and focus control. Pointer events expose their browser identifier, and elements
can capture, query, and release that identifier through the same owned seam.
Pointer events also expose a value snapshot with normalized device type,
viewport and target-relative CSS-pixel coordinates, button state, modifier
keys and primary-pointer state. Wheel events expose bounded deltas with their
browser unit, viewport and target-relative coordinates and the same
modifier-key snapshot. Target-relative coordinates let a consumer route one
event stream to a specific canvas without re-reading layout through a second
browser binding.
Drag events expose CSS-pixel coordinates and an owned DropMetadata snapshot
with at most 512 validated files; names, media types and byte sizes are bounded
before they reach an application. The provider bounds file metadata separately
from the consumer's 256 MiB byte batch limit. The seam does not read file bytes
or treat a name as a filesystem path.
Text controls expose bounded values, UTF-16 selection ranges with direction,
and bounded InputEvent/CompositionEvent metadata through owned snapshots.
WebDocument::clipboard resolves the secure-context browser text clipboard;
WebClipboard::read_text and write_text are asynchronous and enforce the
same 1 MiB UTF-8 bound as text controls. Browser permission and transient
user-activation failures remain explicit errors, and no native clipboard
handle crosses the provider boundary.
WebDocument::canvas_by_id resolves an HTML5 canvas and WebCanvas::present
uploads a borrowed, validated RGBA8 frame under the shared platform size and
byte bounds; the provider retains no frame bytes after the call.
WebGpuCanvas::from_current_document is the explicit GPU counterpart: it
asynchronously acquires the browser's WebGPU adapter and device, configures a
webgpu canvas, and presents the same borrowed frame through
copyExternalImageToTexture. WebGPU absence, device loss, and upload errors
are returned to the consumer; the PAL never changes a requested GPU surface to
the 2-D path implicitly. WebGpuCanvas::recreate explicitly replaces a lost
device and clears the configured extent. Each device has a cancellable
GPUDevice.lost observer, and presentation returns a typed I/O error after the
browser event loop reports loss. Failed recovery leaves the prior state
unchanged. Browser WebGPU remains an optional secure-context capability, and
consumers own their presentation-policy choice.
Unsupported targets and browser metadata failures return explicit errors or
None; grapheme segmentation and editing policy stay with the application or
host layer. Native IME event production stays in the Windows provider.
WebEventListener removes its callback registration when dropped. WebAnimationFrame
binds one requestAnimationFrame callback to a cancellation-safe future and
cancels it when the future is dropped. spawn_local uses the browser event loop
for futures; applications do not create a second executor or retain detached
JavaScript closures.
spawn_local_with_handle adds
a single-owner LocalTaskHandle; cancelling or dropping it wakes the task and
drops its child future, releasing a pending PAL receive or timer.
[]
= "0.6"
use ;
This is a runtime-internal layer; most users reach it through
moirai-async rather than directly.
Full documentation: https://docs.rs/moirai-pal
License
Licensed under either of Apache-2.0 or MIT at your option.