Skip to main content

max / makenotwork

Take quasi 0.88.0: the listing filters ask rather than write quasicoherent aeb44860. Three controls said Field::writes for something that writes nothing: the content listing's status and type pickers, and the media picker's folder chooser. All three narrow what a panel shows and put nothing anywhere, which is what consults means. Consult::at_once for each, because a select is at its next value or its last one and there is nothing to wait out. The media picker's own doc had argued the opposite -- "`changes` rather than a consult: a select settles on a value rather than being typed into, so there is nothing to wait for" -- which was the whole confusion: the wait was never what the two members differed on, the event was, and 0.88.0 moved that to the renderer where it belongs.
Author: Max Johnson <me@maxj.phd> · 2026-08-30 21:13 UTC
Signed with PGP, not checked
Commit: adf8bf71551c6aac90f43f4e5fa2bdd5a65d725a
Parent: 6f9f8be
4 files changed, +45 insertions, -41 deletions
M server/Cargo.lock +24 -24
@@ -2875,7 +2875,7 @@
2875 2875 checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
2876 2876 dependencies = [
2877 2877 "libc",
2878 - "windows-sys 0.59.0",
2878 + "windows-sys 0.52.0",
2879 2879 ]
2880 2880
2881 2881 [[package]]
@@ -4811,7 +4811,7 @@
4811 4811 source = "registry+https://github.com/rust-lang/crates.io-index"
4812 4812 checksum = "82cb6a9f675da968c63b6208c641b9dca58fc0133ae53375736b1767b0cab8bd"
4813 4813 dependencies = [
4814 - "windows-sys 0.59.0",
4814 + "windows-sys 0.61.2",
4815 4815 ]
4816 4816
4817 4817 [[package]]
@@ -5722,7 +5722,7 @@
5722 5722 source = "registry+https://github.com/rust-lang/crates.io-index"
5723 5723 checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
5724 5724 dependencies = [
5725 - "windows-sys 0.59.0",
5725 + "windows-sys 0.61.2",
5726 5726 ]
5727 5727
5728 5728 [[package]]
@@ -6636,7 +6636,7 @@
6636 6636
6637 6637 [[package]]
6638 6638 name = "quasi-axum"
6639 - version = "0.87.0"
6639 + version = "0.88.0"
6640 6640 dependencies = [
6641 6641 "axum",
6642 6642 "http 1.4.2",
@@ -6647,7 +6647,7 @@
6647 6647
6648 6648 [[package]]
6649 6649 name = "quasi-basics"
6650 - version = "0.87.0"
6650 + version = "0.88.0"
6651 6651 dependencies = [
6652 6652 "makeover-layout",
6653 6653 "quasi-router",
@@ -6655,7 +6655,7 @@
6655 6655
6656 6656 [[package]]
6657 6657 name = "quasi-http"
6658 - version = "0.87.0"
6658 + version = "0.88.0"
6659 6659 dependencies = [
6660 6660 "form_urlencoded",
6661 6661 "http 1.4.2",
@@ -6664,7 +6664,7 @@
6664 6664
6665 6665 [[package]]
6666 6666 name = "quasi-router"
6667 - version = "0.87.0"
6667 + version = "0.88.0"
6668 6668 dependencies = [
6669 6669 "makeover-layout",
6670 6670 ]
@@ -6687,7 +6687,7 @@
6687 6687
6688 6688 [[package]]
6689 6689 name = "quasi-webview"
6690 - version = "0.87.0"
6690 + version = "0.88.0"
6691 6691 dependencies = [
6692 6692 "docengine",
6693 6693 "makeover-layout",
@@ -6763,7 +6763,7 @@
6763 6763 "once_cell",
6764 6764 "socket2",
6765 6765 "tracing",
6766 - "windows-sys 0.59.0",
6766 + "windows-sys 0.52.0",
6767 6767 ]
6768 6768
6769 6769 [[package]]
@@ -7326,7 +7326,7 @@
7326 7326 "errno",
7327 7327 "libc",
7328 7328 "linux-raw-sys 0.4.15",
7329 - "windows-sys 0.59.0",
7329 + "windows-sys 0.52.0",
7330 7330 ]
7331 7331
7332 7332 [[package]]
@@ -7339,7 +7339,7 @@
7339 7339 "errno",
7340 7340 "libc",
7341 7341 "linux-raw-sys 0.12.1",
7342 - "windows-sys 0.59.0",
7342 + "windows-sys 0.52.0",
7343 7343 ]
7344 7344
7345 7345 [[package]]
@@ -7419,7 +7419,7 @@
7419 7419 "security-framework 3.7.0",
7420 7420 "security-framework-sys",
7421 7421 "webpki-root-certs",
7422 - "windows-sys 0.59.0",
7422 + "windows-sys 0.52.0",
7423 7423 ]
7424 7424
7425 7425 [[package]]
@@ -8545,7 +8545,7 @@
8545 8545 "getrandom 0.4.3",
8546 8546 "once_cell",
8547 8547 "rustix 1.1.4",
8548 - "windows-sys 0.59.0",
8548 + "windows-sys 0.52.0",
8549 8549 ]
8550 8550
8551 8551 [[package]]
@@ -10759,6 +10759,14 @@
10759 10759 "pkg-config",
10760 10760 ]
10761 10761
10762 + [[patch.unused]]
10763 + name = "synckit-client"
10764 + version = "0.10.0"
10765 +
10766 + [[patch.unused]]
10767 + name = "synckit-config"
10768 + version = "0.2.0"
10769 +
10762 10770 [[patch.unused]]
10763 10771 name = "kberg"
10764 10772 version = "0.1.0"
@@ -10773,11 +10781,11 @@
10773 10781
10774 10782 [[patch.unused]]
10775 10783 name = "quasi-immediate"
10776 - version = "0.87.0"
10784 + version = "0.88.0"
10777 10785
10778 10786 [[patch.unused]]
10779 10787 name = "quasi-notifs"
10780 - version = "0.87.0"
10788 + version = "0.88.0"
10781 10789
10782 10790 [[patch.unused]]
10783 10791 name = "quasi-store"
@@ -10785,12 +10793,4 @@
10785 10793
10786 10794 [[patch.unused]]
10787 10795 name = "quasi-tauri"
10788 - version = "0.87.0"
10789 -
10790 - [[patch.unused]]
10791 - name = "synckit-client"
10792 - version = "0.10.0"
10793 -
10794 - [[patch.unused]]
10795 - name = "synckit-config"
10796 - version = "0.2.0"
10796 + version = "0.88.0"
@@ -163,7 +163,7 @@
163 163 # through quasi beside its Askama equivalent, so the cost of describing a screen
164 164 # here is measured rather than argued. Not load-bearing for any shipped route.
165 165 # See wiki look-wave-2, tier G.
166 - quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.87" }
166 + quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.88" }
167 167 # The description vocabulary quasi's screen types are built from. Pinned here
168 168 # rather than reached through quasi-router's re-export because a described
169 169 # screen names FieldKind and Tone directly; it has to track what quasi-router
@@ -179,13 +179,13 @@
179 179 # For the request head the per-viewer state factory reads. axum re-exports it,
180 180 # but the factory's signature is quasi-axum's and names `http::request::Parts`.
181 181 http = "1.3.1"
182 - quasi-axum = { git = "https://makenot.work/git/max/quasi.git", version = "0.87" }
183 - quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.87" }
182 + quasi-axum = { git = "https://makenot.work/git/max/quasi.git", version = "0.88" }
183 + quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.88" }
184 184 # The first-party widget set. The carousel was proved here against three pages
185 185 # and then moved there; what is left in `quasi/widgets/carousel.rs` is the
186 186 # Askama glue. Not `makeover-basics`: a widget is an assembly of `Node`s, so it
187 187 # sits above quasi-router rather than inside the description suite.
188 - quasi-basics = { git = "https://makenot.work/git/max/quasi.git", version = "0.87" }
188 + quasi-basics = { git = "https://makenot.work/git/max/quasi.git", version = "0.88" }
189 189
190 190 # Git source browser
191 191 gix = { version = "0.86", default-features = false, features = ["blame", "mailmap", "revision", "sha1", "max-performance-safe"] }
@@ -277,7 +277,7 @@
277 277 # Written from the crate rather than copied into the repo for the reason the
278 278 # constants exist: a stale copy in a static directory is a silently dead bulk
279 279 # bar, and the version has to be the one the emitter agrees with.
280 - quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.87" }
280 + quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.88" }
281 281
282 282 [dev-dependencies]
283 283 tower = { version = "0.5.3", features = ["util"] }
@@ -386,10 +386,12 @@
386 386
387 387 /// The folder chooser.
388 388 ///
389 - /// `changes` rather than a consult: a select settles on a value rather than
390 - /// being typed into, so there is nothing to wait for. It carries the typed
391 - /// filter forward on the action, because a field's write sends its own value
392 - /// and nothing else.
389 + /// A consult and not a write: it narrows what the grid shows and puts nothing
390 + /// anywhere. `Consult::at_once` because a select is at its next value or its
391 + /// last one and there is nothing to wait out -- which is the half `aeb44860`
392 + /// left with the description after moving the event to the renderer. It
393 + /// carries the typed filter forward on the action, because a field's question
394 + /// sends its own value and nothing else.
393 395 fn folder_filter(folders: &[String], into: &str, name: &str, folder: &str) -> Field {
394 396 let mut options = vec![Choice::new("", "All folders")];
395 397 options.extend(
@@ -398,12 +400,12 @@
398 400 .map(|folder| Choice::new(folder, if folder.is_empty() { "(root)" } else { folder })),
399 401 );
400 402
401 - let mut field = Field::select(FOLDER, "Folder", options).writes(
403 + let mut field = Field::select(FOLDER, "Folder", options).consulting(Consult::at_once(
402 404 Action::get(GRID_PATH)
403 405 .carrying(INTO, into)
404 406 .carrying(NAME, name)
405 407 .replacing(grid_id(into)),
406 - );
408 + ));
407 409 field.value = Some(folder.to_owned());
408 410 field
409 411 }
@@ -562,10 +562,12 @@
562 562 /// The three narrowing controls.
563 563 ///
564 564 /// `N12`'s decision in one function: each is a control with a route, and the
565 - /// answer is the panel under the new view. The search box asks as it is typed
566 - /// ([`Consult`]) and the two pickers write when they settle
567 - /// ([`Field::writes`]) -- which is the difference between a value that is
568 - /// still being written and one that is chosen in a single gesture.
565 + /// answer is the panel under the new view. All three ask rather than write --
566 + /// narrowing a listing puts nothing anywhere -- and the difference between a
567 + /// value still being written and one chosen in a single gesture is the wait:
568 + /// the search box takes the typing wait and the two pickers
569 + /// [`Consult::at_once`]. `aeb44860`, which is where the pickers stopped
570 + /// claiming to be writes.
569 571 fn filters(slug: &str, items: &[ContentItem], view: &View) -> Slot {
570 572 let narrowed = view.narrowed();
571 573
@@ -604,12 +606,12 @@
604 606 .with(Node::field(
605 607 Field::select("status", "Status", statuses)
606 608 .value(view.status.clone().unwrap_or_default())
607 - .writes(narrowed.without_status().panel(slug)),
609 + .consulting(Consult::at_once(narrowed.without_status().panel(slug))),
608 610 ))
609 611 .with(Node::field(
610 612 Field::select("type", "Type", types)
611 613 .value(view.kind.clone().unwrap_or_default())
612 - .writes(narrowed.without_kind().panel(slug)),
614 + .consulting(Consult::at_once(narrowed.without_kind().panel(slug))),
613 615 ))
614 616 }
615 617