0.31.0: a tab strip fetches its panel, it does not reveal it
`dfbc88ce`, ruled by Max 2026-08-18 as option (a). Found writing
mnw-server's library strip, which is the first description anyone has
written with a labelled `Showing::One` region whose children carry
addresses.
What it did before: the strip was a client-side reveal, buttons carrying
`data-shows`, and every child with a `fed_by` emitted `hx-trigger="load"`
regardless of its frame being hidden. So a five-tab strip fetched five
panels on page load and pressing a tab issued nothing. MNW's library page
does one read and four more on demand, so the description as ruled would
have cost it four database reads per view. node.rs said so itself --
"route-bound movement available and unbuilt. Nothing asks for it today" --
and this is what asks.
The strip carries the address now. Where a child of a labelled selective
region carries `fed_by`, that action goes on the tab button and the child
emits no load trigger of its own; both marks sit on the button, so htmx
makes the request and the binder moves the frame. Presence picks between
the two idioms and nothing reads the region's kind, so a carousel of
frames already downloaded is untouched.
Uniform across every child, the shown one included. `9b958e7b` is why:
a screen renders once at final geometry with no placeholder before first
content, and a shown panel arriving on `load` is a placeholder on the one
panel being looked at. So the shown panel comes with the screen and
carries no address, which is what the Askama page it replaces already
does with its include.
A tab is a `button` even though its address is a read, which inverts
`control_tag`'s rule in the one place it should be inverted: a panel
route answers with a fragment, so an `href` to one is a link that
middle-click and copy-link would follow to a shell-less scrap.
`Fires::ClickInStrip` is that, and it is the second member to suppress
the href after `Fires::Load`.
The retained-screen hosts get it through the router rather than through
their own walk. `Screen::feeds` no longer returns a tab's panels, so a
terminal or an egui host stops asking for all five on the way up, and
`Slot::asked_for` is the address a strip presses. quasi-tui presses it:
Left/Right on a strip answers `Step::Call` for a panel that has not
arrived, and `Step::Idle` for one that has. quasi-immediate draws no
strip yet, so it takes the `feeds` half and nothing else.
The walk still descends past a panel, because a panel that arrived can
hold a region that genuinely is waiting, and that one is nobody's tab.
Not done, and it is written down on `asked_for` rather than smoothed
over: a webview re-reads a panel on every press because the markup keeps
the address after `Screen::replace` has dropped it from the tree, while a
retained host reads it once. Both agree on the thing that mattered.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
18 files changed,
+506 insertions,
-70 deletions
| 3404 |
3404 |
|
|
| 3405 |
3405 |
|
[[package]]
|
| 3406 |
3406 |
|
name = "quasi"
|
| 3407 |
|
- |
version = "0.30.0"
|
|
3407 |
+ |
version = "0.31.0"
|
| 3408 |
3408 |
|
|
| 3409 |
3409 |
|
[[package]]
|
| 3410 |
3410 |
|
name = "quasi-axum"
|
| 3411 |
|
- |
version = "0.30.0"
|
|
3411 |
+ |
version = "0.31.0"
|
| 3412 |
3412 |
|
dependencies = [
|
| 3413 |
3413 |
|
"axum",
|
| 3414 |
3414 |
|
"http",
|
| 3422 |
3422 |
|
|
| 3423 |
3423 |
|
[[package]]
|
| 3424 |
3424 |
|
name = "quasi-basics"
|
| 3425 |
|
- |
version = "0.30.0"
|
|
3425 |
+ |
version = "0.31.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.30.0"
|
|
3435 |
+ |
version = "0.31.0"
|
| 3436 |
3436 |
|
dependencies = [
|
| 3437 |
3437 |
|
"dhat",
|
| 3438 |
3438 |
|
"makeover",
|
| 3447 |
3447 |
|
|
| 3448 |
3448 |
|
[[package]]
|
| 3449 |
3449 |
|
name = "quasi-http"
|
| 3450 |
|
- |
version = "0.30.0"
|
|
3450 |
+ |
version = "0.31.0"
|
| 3451 |
3451 |
|
dependencies = [
|
| 3452 |
3452 |
|
"form_urlencoded",
|
| 3453 |
3453 |
|
"http",
|
| 3456 |
3456 |
|
|
| 3457 |
3457 |
|
[[package]]
|
| 3458 |
3458 |
|
name = "quasi-immediate"
|
| 3459 |
|
- |
version = "0.30.0"
|
|
3459 |
+ |
version = "0.31.0"
|
| 3460 |
3460 |
|
dependencies = [
|
| 3461 |
3461 |
|
"docengine",
|
| 3462 |
3462 |
|
"egui",
|
| 3466 |
3466 |
|
|
| 3467 |
3467 |
|
[[package]]
|
| 3468 |
3468 |
|
name = "quasi-notifs"
|
| 3469 |
|
- |
version = "0.30.0"
|
|
3469 |
+ |
version = "0.31.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.30.0"
|
|
3477 |
+ |
version = "0.31.0"
|
| 3478 |
3478 |
|
dependencies = [
|
| 3479 |
3479 |
|
"makeover-layout",
|
| 3480 |
3480 |
|
]
|
| 3491 |
3491 |
|
|
| 3492 |
3492 |
|
[[package]]
|
| 3493 |
3493 |
|
name = "quasi-tauri"
|
| 3494 |
|
- |
version = "0.30.0"
|
|
3494 |
+ |
version = "0.31.0"
|
| 3495 |
3495 |
|
dependencies = [
|
| 3496 |
3496 |
|
"http",
|
| 3497 |
3497 |
|
"quasi-http",
|
| 3504 |
3504 |
|
|
| 3505 |
3505 |
|
[[package]]
|
| 3506 |
3506 |
|
name = "quasi-tui"
|
| 3507 |
|
- |
version = "0.30.0"
|
|
3507 |
+ |
version = "0.31.0"
|
| 3508 |
3508 |
|
dependencies = [
|
| 3509 |
3509 |
|
"docengine",
|
| 3510 |
3510 |
|
"makeover",
|
| 3516 |
3516 |
|
|
| 3517 |
3517 |
|
[[package]]
|
| 3518 |
3518 |
|
name = "quasi-webview"
|
| 3519 |
|
- |
version = "0.30.0"
|
|
3519 |
+ |
version = "0.31.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 = "makeover-build"
|
|
6192 |
+ |
version = "0.46.0"
|
|
6193 |
+ |
|
|
6194 |
+ |
[[patch.unused]]
|
|
6195 |
+ |
name = "quasi-type"
|
|
6196 |
+ |
version = "0.1.0"
|
|
6197 |
+ |
|
| 6190 |
6198 |
|
[[patch.unused]]
|
| 6191 |
6199 |
|
name = "synckit-client"
|
| 6192 |
6200 |
|
version = "0.8.0"
|
| 6206 |
6214 |
|
[[patch.unused]]
|
| 6207 |
6215 |
|
name = "tagtree"
|
| 6208 |
6216 |
|
version = "0.4.0"
|
| 6209 |
|
- |
|
| 6210 |
|
- |
[[patch.unused]]
|
| 6211 |
|
- |
name = "quasi-type"
|
| 6212 |
|
- |
version = "0.1.0"
|
| 6213 |
|
- |
|
| 6214 |
|
- |
[[patch.unused]]
|
| 6215 |
|
- |
name = "makeover-build"
|
| 6216 |
|
- |
version = "0.46.0"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.30.0"
|
|
3 |
+ |
version = "0.31.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.30.0" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.30.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.31.0" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.31.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.30.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.31.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.30.0"
|
|
3 |
+ |
version = "0.31.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.30.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.31.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.30.0" }
|
| 24 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.30.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.31.0" }
|
|
24 |
+ |
quasi-http = { path = "../quasi-http", version = "0.31.0" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.30.0"
|
|
3 |
+ |
version = "0.31.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.30.0" }
|
| 26 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.30.0" }
|
| 27 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.30.0" }
|
|
25 |
+ |
quasi-router = { path = "../quasi-router", version = "0.31.0" }
|
|
26 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.31.0" }
|
|
27 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.31.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.30.0" }
|
|
31 |
+ |
quasi-http = { path = "../quasi-http", version = "0.31.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.30.0"
|
|
3 |
+ |
version = "0.31.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.30.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.31.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.30.0"
|
|
3 |
+ |
version = "0.31.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.30.0" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.31.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.30.0"
|
|
3 |
+ |
version = "0.31.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.30.0", optional = true }
|
|
27 |
+ |
quasi-router = { path = "../quasi-router", version = "0.31.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.30.0"
|
|
3 |
+ |
version = "0.31.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
|