0.50.0: a route can answer with a file, and every host puts it somewhere
67881a88, ruled 2026-08-21 by Max: (a), the route answers with the file and the
host puts it somewhere. Outcome::File { name, kind, bytes } mirrors
Outcome::Suggestions, and the description never names a path -- the exact mirror
of the upload ruling of 2026-08-18, where the destination is opaque in the other
direction.
kind is Accepted, the same type the upload half already uses, rather than a
second way to name a file kind. name is a suggestion: safe_file_name is in the
router because a name reaching a host is user input by the time it gets there,
and the host that forgets is the one that writes ../../.ssh/authorized_keys
beside the process.
Four hosts, four answers to the same description. quasi-http writes
Content-Disposition in both RFC 6266 forms and consults no renderer, because
bytes are not markup -- the one outcome that cost the Serves trait nothing.
quasi-tauri inherits that path. quasi-tui and quasi-immediate hand the file to
their host through a new Runtime::handed, drained like refreshes: these crates
own no I/O, the division that already keeps Step::Call from calling anything.
The webview needed a fifth thing. A control reaches its route through htmx, htmx
makes an XHR, and an XHR is not a navigation -- so the browser saves nothing and
the file is swapped into the page as text. DOWNLOAD_JS cancels the swap and
hands the body over as a blob, reading the same header the no-script path reads.
Its one limit is stated in the file: the body arrives as a string, so a payload
that is not valid UTF-8 is mangled, and every export in the tree is JSON, CSV or
ICS. The alternatives all cost more than the case is worth -- responseType on
every request breaks every ordinary swap, and refetching runs the route twice.
The template was serving neither quasi-selection.js nor quasi-clock.js while
Shell::under named both, which was two 404s and nothing in the log. build.rs
writes all three from the renderer's constants now, beside the stylesheets and
on the same bargain, and its quasi pins move 0.44 -> 0.50.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
31 files changed,
+945 insertions,
-87 deletions
| 2589 |
2589 |
|
[[package]]
|
| 2590 |
2590 |
|
name = "makeover"
|
| 2591 |
2591 |
|
version = "3.0.0"
|
| 2592 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2593 |
|
- |
checksum = "3e6da78c376074e48eb2324394004afc847e674e05ed2ea4bec1331073990b3f"
|
| 2594 |
2592 |
|
dependencies = [
|
| 2595 |
2593 |
|
"include_dir",
|
| 2596 |
2594 |
|
"serde",
|
| 2600 |
2598 |
|
[[package]]
|
| 2601 |
2599 |
|
name = "makeover-geometry"
|
| 2602 |
2600 |
|
version = "0.7.0"
|
| 2603 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2604 |
|
- |
checksum = "91a82b16c4f5b66dd7e87ed92fff7d22185e4d88e5355de6166dd64450cf6a16"
|
| 2605 |
2601 |
|
|
| 2606 |
2602 |
|
[[package]]
|
| 2607 |
2603 |
|
name = "makeover-immediate"
|
| 2608 |
|
- |
version = "0.32.0"
|
| 2609 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2610 |
|
- |
checksum = "437b1e68f0d1ce824f458e623fc901e81f961b97f167c58c9400453f976fc175"
|
|
2604 |
+ |
version = "0.33.0"
|
| 2611 |
2605 |
|
dependencies = [
|
| 2612 |
2606 |
|
"egui",
|
| 2613 |
2607 |
|
"egui_extras",
|
| 2616 |
2610 |
|
|
| 2617 |
2611 |
|
[[package]]
|
| 2618 |
2612 |
|
name = "makeover-layout"
|
| 2619 |
|
- |
version = "0.33.0"
|
| 2620 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2621 |
|
- |
checksum = "7ba9bae28e348ef6df04ddf04222703b5ea680ac2c978f0dce8679e2acbdc5a0"
|
|
2613 |
+ |
version = "0.35.0"
|
| 2622 |
2614 |
|
|
| 2623 |
2615 |
|
[[package]]
|
| 2624 |
2616 |
|
name = "makeover-touch"
|
| 2625 |
|
- |
version = "0.23.0"
|
| 2626 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2627 |
|
- |
checksum = "0f6272302ba50183af43fe35064db861d77b4786ab6f8994ed9bb6c18c57bba0"
|
|
2617 |
+ |
version = "0.24.0"
|
| 2628 |
2618 |
|
dependencies = [
|
| 2629 |
2619 |
|
"makeover-geometry",
|
| 2630 |
2620 |
|
"makeover-layout",
|
| 2632 |
2622 |
|
|
| 2633 |
2623 |
|
[[package]]
|
| 2634 |
2624 |
|
name = "makeover-tui"
|
| 2635 |
|
- |
version = "0.32.0"
|
| 2636 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2637 |
|
- |
checksum = "778fc5d11417d03fa54b43176d63b26d7db397cf05595d1832cbdbdc71a93a48"
|
|
2625 |
+ |
version = "0.33.0"
|
| 2638 |
2626 |
|
dependencies = [
|
| 2639 |
2627 |
|
"makeover",
|
| 2640 |
2628 |
|
"makeover-layout",
|
| 2643 |
2631 |
|
|
| 2644 |
2632 |
|
[[package]]
|
| 2645 |
2633 |
|
name = "makeover-webview"
|
| 2646 |
|
- |
version = "0.55.0"
|
| 2647 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2648 |
|
- |
checksum = "2cd308d279ece9665206044886d0da8762ce9eb81368e0f15a5afb8c0650cb41"
|
|
2634 |
+ |
version = "0.56.0"
|
| 2649 |
2635 |
|
dependencies = [
|
| 2650 |
2636 |
|
"makeover-geometry",
|
| 2651 |
2637 |
|
"makeover-layout",
|
| 3414 |
3400 |
|
|
| 3415 |
3401 |
|
[[package]]
|
| 3416 |
3402 |
|
name = "quasi"
|
| 3417 |
|
- |
version = "0.48.0"
|
|
3403 |
+ |
version = "0.50.0"
|
| 3418 |
3404 |
|
|
| 3419 |
3405 |
|
[[package]]
|
| 3420 |
3406 |
|
name = "quasi-axum"
|
| 3421 |
|
- |
version = "0.48.0"
|
|
3407 |
+ |
version = "0.50.0"
|
| 3422 |
3408 |
|
dependencies = [
|
| 3423 |
3409 |
|
"axum",
|
| 3424 |
3410 |
|
"http",
|
| 3432 |
3418 |
|
|
| 3433 |
3419 |
|
[[package]]
|
| 3434 |
3420 |
|
name = "quasi-basics"
|
| 3435 |
|
- |
version = "0.48.0"
|
|
3421 |
+ |
version = "0.50.0"
|
| 3436 |
3422 |
|
dependencies = [
|
| 3437 |
3423 |
|
"makeover-layout",
|
| 3438 |
3424 |
|
"quasi-http",
|
| 3442 |
3428 |
|
|
| 3443 |
3429 |
|
[[package]]
|
| 3444 |
3430 |
|
name = "quasi-bench"
|
| 3445 |
|
- |
version = "0.48.0"
|
|
3431 |
+ |
version = "0.50.0"
|
| 3446 |
3432 |
|
dependencies = [
|
| 3447 |
3433 |
|
"dhat",
|
| 3448 |
3434 |
|
"makeover",
|
| 3457 |
3443 |
|
|
| 3458 |
3444 |
|
[[package]]
|
| 3459 |
3445 |
|
name = "quasi-http"
|
| 3460 |
|
- |
version = "0.48.0"
|
|
3446 |
+ |
version = "0.50.0"
|
| 3461 |
3447 |
|
dependencies = [
|
| 3462 |
3448 |
|
"form_urlencoded",
|
| 3463 |
3449 |
|
"http",
|
| 3466 |
3452 |
|
|
| 3467 |
3453 |
|
[[package]]
|
| 3468 |
3454 |
|
name = "quasi-immediate"
|
| 3469 |
|
- |
version = "0.48.0"
|
|
3455 |
+ |
version = "0.50.0"
|
| 3470 |
3456 |
|
dependencies = [
|
| 3471 |
3457 |
|
"docengine",
|
| 3472 |
3458 |
|
"egui",
|
| 3476 |
3462 |
|
|
| 3477 |
3463 |
|
[[package]]
|
| 3478 |
3464 |
|
name = "quasi-notifs"
|
| 3479 |
|
- |
version = "0.48.0"
|
|
3465 |
+ |
version = "0.50.0"
|
| 3480 |
3466 |
|
dependencies = [
|
| 3481 |
3467 |
|
"quasi-router",
|
| 3482 |
3468 |
|
"synckit-config",
|
| 3484 |
3470 |
|
|
| 3485 |
3471 |
|
[[package]]
|
| 3486 |
3472 |
|
name = "quasi-router"
|
| 3487 |
|
- |
version = "0.48.0"
|
|
3473 |
+ |
version = "0.50.0"
|
| 3488 |
3474 |
|
dependencies = [
|
| 3489 |
3475 |
|
"makeover-layout",
|
| 3490 |
3476 |
|
]
|
| 3501 |
3487 |
|
|
| 3502 |
3488 |
|
[[package]]
|
| 3503 |
3489 |
|
name = "quasi-tauri"
|
| 3504 |
|
- |
version = "0.48.0"
|
|
3490 |
+ |
version = "0.50.0"
|
| 3505 |
3491 |
|
dependencies = [
|
| 3506 |
3492 |
|
"http",
|
| 3507 |
3493 |
|
"quasi-http",
|
| 3514 |
3500 |
|
|
| 3515 |
3501 |
|
[[package]]
|
| 3516 |
3502 |
|
name = "quasi-tui"
|
| 3517 |
|
- |
version = "0.48.0"
|
|
3503 |
+ |
version = "0.50.0"
|
| 3518 |
3504 |
|
dependencies = [
|
| 3519 |
3505 |
|
"docengine",
|
| 3520 |
3506 |
|
"makeover",
|
| 3526 |
3512 |
|
|
| 3527 |
3513 |
|
[[package]]
|
| 3528 |
3514 |
|
name = "quasi-webview"
|
| 3529 |
|
- |
version = "0.48.0"
|
|
3515 |
+ |
version = "0.50.0"
|
| 3530 |
3516 |
|
dependencies = [
|
| 3531 |
3517 |
|
"docengine",
|
| 3532 |
3518 |
|
"makeover-layout",
|
| 6197 |
6183 |
|
"winnow 1.0.4",
|
| 6198 |
6184 |
|
]
|
| 6199 |
6185 |
|
|
|
6186 |
+ |
[[patch.unused]]
|
|
6187 |
+ |
name = "quasi-type"
|
|
6188 |
+ |
version = "0.1.0"
|
|
6189 |
+ |
|
|
6190 |
+ |
[[patch.unused]]
|
|
6191 |
+ |
name = "makeover-timing"
|
|
6192 |
+ |
version = "0.1.0"
|
|
6193 |
+ |
|
| 6200 |
6194 |
|
[[patch.unused]]
|
| 6201 |
6195 |
|
name = "kberg"
|
| 6202 |
6196 |
|
version = "0.1.0"
|
| 6211 |
6205 |
|
|
| 6212 |
6206 |
|
[[patch.unused]]
|
| 6213 |
6207 |
|
name = "tagtree"
|
| 6214 |
|
- |
version = "0.4.0"
|
| 6215 |
|
- |
|
| 6216 |
|
- |
[[patch.unused]]
|
| 6217 |
|
- |
name = "quasi-type"
|
| 6218 |
|
- |
version = "0.1.0"
|
|
6208 |
+ |
version = "0.4.1"
|
| 6219 |
6209 |
|
|
| 6220 |
6210 |
|
[[patch.unused]]
|
| 6221 |
6211 |
|
name = "synckit-client"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.49.0"
|
|
3 |
+ |
version = "0.50.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.49.0" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.49.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.50.0" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.50.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.49.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.50.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.49.0"
|
|
3 |
+ |
version = "0.50.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.49.0" }
|
| 17 |
|
- |
makeover-layout = "0.34.0"
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.50.0" }
|
|
17 |
+ |
makeover-layout = "0.35.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.49.0" }
|
| 24 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.49.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.50.0" }
|
|
24 |
+ |
quasi-http = { path = "../quasi-http", version = "0.50.0" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.49.0"
|
|
3 |
+ |
version = "0.50.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.49.0" }
|
| 26 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.49.0" }
|
| 27 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.49.0" }
|
|
25 |
+ |
quasi-router = { path = "../quasi-router", version = "0.50.0" }
|
|
26 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.50.0" }
|
|
27 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.50.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.49.0" }
|
| 32 |
|
- |
makeover-layout = "0.34.0"
|
|
31 |
+ |
quasi-http = { path = "../quasi-http", version = "0.50.0" }
|
|
32 |
+ |
makeover-layout = "0.35.0"
|
| 33 |
33 |
|
makeover-tui = { version = "0.33.0", features = ["theme"] }
|
| 34 |
34 |
|
# Only to load a bundled theme file. `makeover_tui::Theme` is `#[non_exhaustive]`,
|
| 35 |
35 |
|
# so `Theme::from_theme` is the one way to get one, the same reason quasi-tui's
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-http"
|
| 3 |
|
- |
version = "0.49.0"
|
|
3 |
+ |
version = "0.50.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.49.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.50.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.49.0"
|
|
3 |
+ |
version = "0.50.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.49.0" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.50.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
|