6 Commits
Author SHA1 Message Date
Helen Kwok fd5e2feff6 web-api: drop a timed-out call, and give screenshot() one data field (#620)
A call that timed out left the app's request future running, so an app that releases a request when its future is dropped (the desktop ControlRequest abandons a request nobody waits for) ran the call late, after the page had been told it failed. call() now drives the request future itself and drops it when the timer wins.

The desktop control protocols name the base64 PNG of ui.screenshot differently (pngBase64, png_base64, png, base64), so screenshot() gave the page a different shape in each app. It now also puts the PNG in data and leaves the app's own field where it is.

The timer handle is kept as the environment returned it: Node returns an object, not a number, so a numeric id never cleared the timer and it fired after its closure was dropped.
2026-11-06 16:54:07 +01:00
Helen Kwok a94d849df2 web-api: one window.<app> command API for the web builds 2026-11-05 13:31:10 +08:00
Helen Kwok ce99c8d61c craft-web-host: tests for message types, file names and the host objects the bridge parses, and a CI workflow that runs them 2026-11-05 13:31:10 +08:00
Helen Kwok 5fcc392302 craft-web-host: Fn listeners, so a nested event reaches the queue
wasm-bindgen throws "closure invoked recursively" when an FnMut closure
is called while it runs, before its body can queue the message. The
listeners only read their captures, so they are Fn; the handler's state
stays behind the Inbox's RefCell.
2026-11-05 13:30:14 +08:00
Helen Kwok ae1fa48449 craft-web-host: queue messages that arrive while the handler runs
A page host dispatches its events synchronously, so it can answer (a
saved for the save the handler just posted) while the handler is still
running. The nested borrow_mut then panicked. Both transports now hand
messages to an Inbox that queues each one and drains the queue one call
at a time, in order; nothing is dropped. The new test fails with the old
borrow ("already borrowed").

FileData::size() reads a Blob's length from the Blob; a host's size
field is no longer trusted for an app's size check. lib.rs gets the
crate-level deny of unwrap, expect, panic and the like.
2026-11-05 13:30:14 +08:00
Helen Kwok da0b274a28 craft-web-host: the host messages as one contract and one bridge
The messages between a Craft app's web build and the page that hosts it
(ready, host, open, save, saved, dirty, failed, handoff, handoff-done),
as proposed on #358. The contract part (message kinds, the version, the
?host=parent / data-host="page" switch, file-name clean-up) builds
everywhere and is tested natively; the web module (wasm32) is the bridge
an app's web shell calls: same-origin parent only, files as bytes or a
Blob without copying, saves as a transferred ArrayBuffer, dirty repeats
suppressed. Compatible with the bridges shipped before it: optional
fields stay optional, and a host treats an unknown ready.version as 1.
2026-11-05 13:30:14 +08:00