README.mdpreviewREADME.mdsource105 lines · 5.9 KB · raw
1# Chapter 22: jev-ui — what the Jev sites' pages share
2
3lmjtfy.fun and whiskers.lmjtfy.fun look alike on purpose: near-black on white,
4one pink band, ordered-dither dot fields and old operating system windows with
5a black title bar, after typesafe.ai. This crate is the one copy of that look,
6so the second site did not get a second copy of it.
7
8It is the opposite of its neighbours in one way: nothing here talks to Jev.
9It is the page around whatever a site says.
10
11## What a site gets
12
13| From | What |
14| --- | --- |
15| `asset` | The files a page loads, embedded: `ui.css`, `ui.js` (the copy buttons and the dither fields), the three fonts and a fourth, a small pixel-emoji font. `asset::find(path)` for a fallback route, `Asset::href()` for a link named by the hash of its bytes. |
16| `shell` | `document(head, body_attrs, body)`: the one head (title, preview tags, preloaded fonts, the shared sheet and script, and a `<script>` for Datastar when asked) and the body's open and close. `Assets::Linked` for a site whose policy forbids inline script, `Assets::Inline` for one that does not. |
17| `components` | `nav`, `headline`, `window` (and `window_with_id`), `sheet`, `band`, `copy_line`, `footer`, `skip_link`, the 12 by 12 `pixel_icon`, and SerenityOS's pixel emoji: `PixelEmoji` (play, pause, the two hourglasses), `pixel_emoji` and an `hourglass` that turns over (still under reduced motion). |
18| `preview` | `Preview`: Open Graph and Twitter tags that cannot be built wrong (an origin that is not https, a video of odd size, a card too small to be shown large), for a still card or a looping video, and `missing(html, kind)` to check a rendered page. |
19| `wire` | A call to Jev as a window: `json` prints a body from the raw text (whitespace added, nothing else), `exchange` is the folding request-and-response window (`exchange_with` when the title bar is markup or the body starts with something of the site's), `bars` is lmjtfy's probability rule with an optional decision tick, `printed_json` reads a panel back for a test. |
20| `flow` | `spine`: a flow drawn as one SVG from rows of steps, each with the ways it can end. Built from the data it is given, so a site that builds the rows from the code that runs the flow cannot draw a step the code lacks. |
21| `card` | The preview card's look as SVG: `Chrome` (the dither, the pink band, the window with its title bar, in lmjtfy's measures), and pixel `text`. A site composes what goes inside the window. |
22
23A page, in whiskers' shape:
24
25```rust
26use jev_ui::components::{Link, Nav, band, nav, sheet, window};
27use jev_ui::shell::{Assets, Attr, Head, document};
28
29let head = Head { title: "Whiskers", meta: preview_tags, style: SITE_CSS, assets: Assets::Linked,
30                  datastar: true, icon: Some("/favicon.svg"), extra: maud::html! {} };
31let page = document(&head, &[Attr::new("data-signals", "{}")], body);
32```
33
34and in the Worker, every asset the crate owns in one route:
35
36```rust
37// as the router's fallback; `path` and `query` are the request's
38if let Some(asset) = jev_ui::asset::find(path) {
39    // content-type: asset.content_type, cache-control: asset.cache_control(query), body: asset.body
40}
41```
42
43and the script Datastar needs, from the Aldebaran crate that owns it:
44
45```rust
46// a route for `jev_ui::shell::DATASTAR_PATH`
47// content-type: text/javascript; charset=utf-8, body: aldebaran_datastar::SCRIPT
48```
49
50## What is a parameter and what is not
51
52Everything a site differs in is a field: the title, the tags, the site's own
53stylesheet (it comes after the shared one), the nav's links, what sits between
54the name and the links, the footer's words, a picture's query. The look is not
55a parameter: there is one palette, light only, as typesafe.ai's is. A site
56that wants another look is not a Jev site.
57
58Fonts are served by the site itself, from this crate (Inter Tight, JetBrains
59Mono and VT323, see [assets/](assets/)). A Jev site makes no request to another
60site for them.
61
62## Try it
63
64```
65cargo test -p jev-ui
66cargo build -p jev-ui --target wasm32-unknown-unknown
67```
68
69## lmjtfy on it
70
71lmjtfy (`~/lmjtfy`) wears this crate: its head and body come from `shell::document`
72with `Assets::Inline` (its pages set no content security policy), its nav, headline,
73windows, sheet, band, footer and copy line from `components`, its icons from
74`components::icons`, its JSON panels, a choice's rule and its Jev, LLM and tool call
75windows from `wire`, and its fonts from `/fonts/*`, one route per `asset::ALL` entry
76(`/{repo}/{*path}` would otherwise take them). `page.css` holds only lmjtfy's own
77rules, after the shared sheet, and `page.js` only its own behaviour. Datastar's script
78is `aldebaran_datastar::SCRIPT`, served by each site at `shell::DATASTAR_PATH`.
79
80## Outstanding
81
82- [ ] lmjtfy's own Open Graph tags (`view.rs`'s `preview` and `view/code.rs`'s) are still
83      its own: the home page's carries a canonical link and `noindex` that
84      `preview::Preview` has no field for, and they should move onto it.
85- [ ] A score's bars (a tag in the label) and the budget's (a figure of its own, not a
86      percentage) are still lmjtfy's; `wire::Bar` has neither a tag nor a figure.
87- [ ] `packages/card` draws lmjtfy's own card straight into a PNG with the
88      same palette, dither and pixel text as `card.rs`; now that lmjtfy depends on
89      this crate, one of the two should draw from the other.
90- [ ] lmjtfy's `.rete` diagram is Rete-specific and stays its own, but its CSS box language is what `flow` borrows.
91- [ ] Mermaid (lmjtfy's code pages) is still fetched from jsdelivr there; it is
92      not part of this crate.
93
94## For the people who maintain it
95
96### In this folder
97
98| Path | What |
99| --- | --- |
100| [src/](src/) | The code: Chapter 22½. |
101| [assets/](assets/) | The stylesheet, the script and the fonts: Chapter 22¾. |
102| [Cargo.toml](Cargo.toml) | Dependencies: `maud` and `font8x8` only. |
103| [CLAUDE.md](CLAUDE.md) | Invariants for agents. |
104
105← Previous: [Chapter 21½: inside jev-mock/src](../jev-mock/src/) · Up: [jevcrates](../) · Next: [Chapter 22½: inside jev-ui/src](src/) →