0.43.0: the webview emitter writes hyperscript, and idiomorph is closed out
`0081563e`. Two of the three things taken from the htmx family on 2026-08-08 were a
record of a decision nobody had implemented. They close differently.
idiomorph was retired rather than implemented. htmx 4 ships `innerMorph` and `outerMorph`
as swap styles, so the extension has nothing to supply; that landed with 0.42.0 and this
is what marks the adoption closed instead of pending.
_hyperscript is in use. The renderer emits programs, from one file, and there is one site
today: the chrome of a region that shows its children one at a time. A strip, a
disclosure and a prev/position/next row have always been emitted with `data-shows` marks
that did nothing at all, so a described carousel needed per-app JavaScript before a
reader could reach frame two of bytes already downloaded. A tab now takes `.chosen` from
its siblings, moves `aria-selected` across the strip and takes `.current` to the frame it
names; a disclosure toggles the one frame under it and reads `aria-expanded` back off it;
previous and next read the index off the current frame, wrap in the arithmetic, and write
the counter beside them.
Permitted by the provenance ruling of 2026-08-18: emitted is fine, hand-written is not.
The rule defends against a script nobody remembers is running, and emitted code
regenerates from its source every time a screen is drawn. The adoption's one rule is kept
and tested: nothing emits a `js` block, which is the only path in the interpreter that
reaches `new Function`.
Frames carry `data-frame="<region id>"` and `data-shown="<n>"` rather than being found by
descent, so a tab group over a gallery steps its own frames and not the gallery's.
The handle gate: a program addresses its region by id, inside a CSS attribute selector,
inside an HTML attribute, inside a language with `${}` interpolation, so a program is
written only when the id is a plain handle and anything else keeps the mark and no
program. Escaping was tried and rejected -- a CSS hex escape for `$` is read by browsers
and not by every selector engine, which is a program that works where it was tried.
`Node::Rich` carries `data-disable-scripting`, the fencing the ruling owed wherever text
a user typed becomes markup. Belt and braces, since the markdown pass is the strict
preset; what it buys is the guarantee no longer depending on which preset is called.
`Shell::hyperscript_src` is the runtime, `without_hyperscript()` drops it, and the
scaffolder vendors 0.9.93 beside htmx. The emitted document was driven under the real
bundle in jsdom -- stepping, wrapping, the counter, a tab's three marks, the disclosure,
and a nested carousel keeping its position while the outer strip moves.
`Destination::Local` is still the mark and not the behaviour. What happens locally is
named by the member carrying the action, and no member names one yet; `71852b16` is the
first that will, and its program belongs in the same file.
MNW server, goingson and audiofiles forward-fixed to 0.43 in the same pass.
21 files changed,
+576 insertions,
-84 deletions
| 3404 |
3404 |
|
|
| 3405 |
3405 |
|
[[package]]
|
| 3406 |
3406 |
|
name = "quasi"
|
| 3407 |
|
- |
version = "0.42.0"
|
|
3407 |
+ |
version = "0.43.0"
|
| 3408 |
3408 |
|
|
| 3409 |
3409 |
|
[[package]]
|
| 3410 |
3410 |
|
name = "quasi-axum"
|
| 3411 |
|
- |
version = "0.42.0"
|
|
3411 |
+ |
version = "0.43.0"
|
| 3412 |
3412 |
|
dependencies = [
|
| 3413 |
3413 |
|
"axum",
|
| 3414 |
3414 |
|
"http",
|
| 3422 |
3422 |
|
|
| 3423 |
3423 |
|
[[package]]
|
| 3424 |
3424 |
|
name = "quasi-basics"
|
| 3425 |
|
- |
version = "0.42.0"
|
|
3425 |
+ |
version = "0.43.0"
|
| 3426 |
3426 |
|
dependencies = [
|
| 3427 |
3427 |
|
"makeover-layout",
|
| 3428 |
3428 |
|
"quasi-http",
|
| 3432 |
3432 |
|
|
| 3433 |
3433 |
|
[[package]]
|
| 3434 |
3434 |
|
name = "quasi-bench"
|
| 3435 |
|
- |
version = "0.42.0"
|
|
3435 |
+ |
version = "0.43.0"
|
| 3436 |
3436 |
|
dependencies = [
|
| 3437 |
3437 |
|
"dhat",
|
| 3438 |
3438 |
|
"makeover",
|
| 3447 |
3447 |
|
|
| 3448 |
3448 |
|
[[package]]
|
| 3449 |
3449 |
|
name = "quasi-http"
|
| 3450 |
|
- |
version = "0.42.0"
|
|
3450 |
+ |
version = "0.43.0"
|
| 3451 |
3451 |
|
dependencies = [
|
| 3452 |
3452 |
|
"form_urlencoded",
|
| 3453 |
3453 |
|
"http",
|
| 3456 |
3456 |
|
|
| 3457 |
3457 |
|
[[package]]
|
| 3458 |
3458 |
|
name = "quasi-immediate"
|
| 3459 |
|
- |
version = "0.42.0"
|
|
3459 |
+ |
version = "0.43.0"
|
| 3460 |
3460 |
|
dependencies = [
|
| 3461 |
3461 |
|
"docengine",
|
| 3462 |
3462 |
|
"egui",
|
| 3466 |
3466 |
|
|
| 3467 |
3467 |
|
[[package]]
|
| 3468 |
3468 |
|
name = "quasi-notifs"
|
| 3469 |
|
- |
version = "0.42.0"
|
|
3469 |
+ |
version = "0.43.0"
|
| 3470 |
3470 |
|
dependencies = [
|
| 3471 |
3471 |
|
"quasi-router",
|
| 3472 |
3472 |
|
"synckit-config",
|
| 3474 |
3474 |
|
|
| 3475 |
3475 |
|
[[package]]
|
| 3476 |
3476 |
|
name = "quasi-router"
|
| 3477 |
|
- |
version = "0.42.0"
|
|
3477 |
+ |
version = "0.43.0"
|
| 3478 |
3478 |
|
dependencies = [
|
| 3479 |
3479 |
|
"makeover-layout",
|
| 3480 |
3480 |
|
]
|
| 3491 |
3491 |
|
|
| 3492 |
3492 |
|
[[package]]
|
| 3493 |
3493 |
|
name = "quasi-tauri"
|
| 3494 |
|
- |
version = "0.42.0"
|
|
3494 |
+ |
version = "0.43.0"
|
| 3495 |
3495 |
|
dependencies = [
|
| 3496 |
3496 |
|
"http",
|
| 3497 |
3497 |
|
"quasi-http",
|
| 3504 |
3504 |
|
|
| 3505 |
3505 |
|
[[package]]
|
| 3506 |
3506 |
|
name = "quasi-tui"
|
| 3507 |
|
- |
version = "0.42.0"
|
|
3507 |
+ |
version = "0.43.0"
|
| 3508 |
3508 |
|
dependencies = [
|
| 3509 |
3509 |
|
"docengine",
|
| 3510 |
3510 |
|
"makeover",
|
| 3516 |
3516 |
|
|
| 3517 |
3517 |
|
[[package]]
|
| 3518 |
3518 |
|
name = "quasi-webview"
|
| 3519 |
|
- |
version = "0.42.0"
|
|
3519 |
+ |
version = "0.43.0"
|
| 3520 |
3520 |
|
dependencies = [
|
| 3521 |
3521 |
|
"docengine",
|
| 3522 |
3522 |
|
"makeover-layout",
|
| 6187 |
6187 |
|
"winnow 1.0.4",
|
| 6188 |
6188 |
|
]
|
| 6189 |
6189 |
|
|
|
6190 |
+ |
[[patch.unused]]
|
|
6191 |
+ |
name = "quasi-type"
|
|
6192 |
+ |
version = "0.1.0"
|
|
6193 |
+ |
|
|
6194 |
+ |
[[patch.unused]]
|
|
6195 |
+ |
name = "makeover-build"
|
|
6196 |
+ |
version = "0.47.0"
|
|
6197 |
+ |
|
|
6198 |
+ |
[[patch.unused]]
|
|
6199 |
+ |
name = "synckit-client"
|
|
6200 |
+ |
version = "0.8.0"
|
|
6201 |
+ |
|
| 6190 |
6202 |
|
[[patch.unused]]
|
| 6191 |
6203 |
|
name = "kberg"
|
| 6192 |
6204 |
|
version = "0.1.0"
|
| 6202 |
6214 |
|
[[patch.unused]]
|
| 6203 |
6215 |
|
name = "tagtree"
|
| 6204 |
6216 |
|
version = "0.4.0"
|
| 6205 |
|
- |
|
| 6206 |
|
- |
[[patch.unused]]
|
| 6207 |
|
- |
name = "quasi-type"
|
| 6208 |
|
- |
version = "0.1.0"
|
| 6209 |
|
- |
|
| 6210 |
|
- |
[[patch.unused]]
|
| 6211 |
|
- |
name = "makeover-build"
|
| 6212 |
|
- |
version = "0.47.0"
|
| 6213 |
|
- |
|
| 6214 |
|
- |
[[patch.unused]]
|
| 6215 |
|
- |
name = "synckit-client"
|
| 6216 |
|
- |
version = "0.8.0"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
description = "The axum host adapter for quasi-router: an HTTP request in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.42.0" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.42.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.43.0" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.43.0" }
|
| 18 |
18 |
|
axum = "0.8.8"
|
| 19 |
19 |
|
http = "1.3.1"
|
| 20 |
20 |
|
tokio = { version = "1.50.0", features = ["rt"] }
|
| 21 |
21 |
|
|
| 22 |
22 |
|
[dev-dependencies]
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.42.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.43.0" }
|
| 24 |
24 |
|
tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
|
| 25 |
25 |
|
tower = { version = "0.5.3", features = ["util"] }
|
| 26 |
26 |
|
http-body-util = "0.1.3"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-basics"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
description = "The first-party widget set: named assemblies of primitives, shared across our apps"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.42.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.43.0" }
|
| 17 |
17 |
|
makeover-layout = "0.31.0"
|
| 18 |
18 |
|
|
| 19 |
19 |
|
[dev-dependencies]
|
| 20 |
20 |
|
# A widget's guarantees are claims about what a renderer draws, so they are
|
| 21 |
21 |
|
# tested against a real one rather than by walking the tree the assembly just
|
| 22 |
22 |
|
# built. The webview is the renderer that recognises names today.
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.42.0" }
|
| 24 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.42.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.43.0" }
|
|
24 |
+ |
quasi-http = { path = "../quasi-http", version = "0.43.0" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
description = "What a described screen costs to render, in time and in allocations"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 22 |
22 |
|
count = ["dep:dhat"]
|
| 23 |
23 |
|
|
| 24 |
24 |
|
[dependencies]
|
| 25 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.42.0" }
|
| 26 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.42.0" }
|
| 27 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.42.0" }
|
|
25 |
+ |
quasi-router = { path = "../quasi-router", version = "0.43.0" }
|
|
26 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.43.0" }
|
|
27 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.43.0" }
|
| 28 |
28 |
|
# `Serves` is the trait carrying `screen` and `fragment`, which is what the
|
| 29 |
29 |
|
# webview is measured through. Taken directly rather than through quasi-webview
|
| 30 |
30 |
|
# because a bench calling a trait method should name the trait it calls.
|
| 31 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.42.0" }
|
|
31 |
+ |
quasi-http = { path = "../quasi-http", version = "0.43.0" }
|
| 32 |
32 |
|
makeover-layout = "0.31.0"
|
| 33 |
33 |
|
makeover-tui = { version = "0.30.0", features = ["theme"] }
|
| 34 |
34 |
|
# Only to load a bundled theme file. `makeover_tui::Theme` is `#[non_exhaustive]`,
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-http"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
description = "The http-shaped seam quasi's webview host adapters share: decoding in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.42.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.43.0" }
|
| 17 |
17 |
|
http = "1.3.1"
|
| 18 |
18 |
|
form_urlencoded = "1.2.2"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-immediate"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
edition = "2024"
|
| 5 |
5 |
|
description = "The immediate-mode renderer for quasi-router: a described screen in, an egui frame out. Immediate mode is the constraint that matters, not the library."
|
| 6 |
6 |
|
license = "MIT"
|
| 12 |
12 |
|
categories = ["gui"]
|
| 13 |
13 |
|
|
| 14 |
14 |
|
[dependencies]
|
| 15 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.42.0" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.43.0" }
|
| 16 |
16 |
|
# The node drawing, which is the makeover layer's and not this crate's. Every
|
| 17 |
17 |
|
# widget here that is not a container comes from it: a screen walk that painted
|
| 18 |
18 |
|
# its own meter would be the divergence the suite exists to end, one copy per
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-notifs"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
description = "Declared notification kinds and the registry that holds them: what a notification says and what it is for, apart from how it reaches a person"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 24 |
24 |
|
describe = ["dep:quasi-router"]
|
| 25 |
25 |
|
|
| 26 |
26 |
|
[dependencies]
|
| 27 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.42.0", optional = true }
|
|
27 |
+ |
quasi-router = { path = "../quasi-router", version = "0.43.0", optional = true }
|
| 28 |
28 |
|
synckit-config = { git = "https://makenot.work/git/max/synckit.git", version = "0.2", optional = true }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-router"
|
| 3 |
|
- |
version = "0.42.0"
|
|
3 |
+ |
version = "0.43.0"
|
| 4 |
4 |
|
description = "Host-agnostic router: a request in, a renderer-agnostic description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|