chore(ui): bump Kagaku.UI past the typing-echo fix #201
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "chore/bump-kagaku-ui"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ten commits of library work land at once, all of it driven by Orihon. What Kagura consumes here is the input fix; the rest arrives as new surface it does not use yet.
What Kagura actually gets
The typing-echo fix. A shared text input bound on
oninputsent every keystroke to the server and had the value written back on the next render. Over a slow circuit that echo lands several keystrokes late and resets the field to however far behind the round trip is — letters vanish and the caret jumps. The library now keeps the user's own keystrokes out of the render tree, which leaves exactly one case the diff cannot express (a rebind to a value the element already shows), and that one goes to the element directly through the newjs/input.js.Hence the one production change in this PR — the script tag in
App.razor. Without it typing still works, but a field can keep the previous record's text.--shell-max-width76rem → 90rem, picked up for free byWorkspaceShell,SettingsPage,ProjectsPageandGenerationQueuePage, all of which already sit on the token.Not used yet:
ContextMenu,SelectableGrid,Hotkey,RegionSelector.SurfaceClicked/RegionPoint, and thirteen new icons (the manga-pipeline set pluskey,smart_toy,gavel).Test changes, and why they are not cosmetic
TextAreanow carries its text as thevalueattribute rather than as child text — child text is a default-value form the browser stops honouring once the element is dirty, so a rebind could never reach an edited field. Five assertions read that text throughTextContentand move toGetAttribute("value").Three
A_change_from_another_session_never_clobbers_what_is_being_typedtests (character, location, lore) asserted the typed value in the render tree. That is exactly the thing the fix deliberately no longer puts there — bUnit sees the render tree, not the element — so they now pin the pre-typing value and the absence of the other session's. Each site carries a comment saying why, because the assertion reads oddly without one.Browser-verified
A/B through a TCP proxy holding every byte 350ms each way. CDP's network emulation does not throttle frames on an already-open WebSocket, so it cannot simulate a slow circuit and a run through it is a false pass.
35 characters typed at 45ms intervals into the project title:
df81a2c(before)The L At Duskbded5a5(after)Also checked:
window.kagakuInput.setValueis live on the page,--shell-max-widthcomputes to 90rem, and rebinding between characters mid-edit still swaps the field (type into Aoi's name, click to Ren, the field follows; back to Aoi, the stored name returns).Worth recording: the description textarea is the wrong probe for this bug. Both pointers pass on it, because the pre-bump
TextArearendered its value as child text and was therefore accidentally immune to the echo while carrying the opposite bug. TheTextFieldis where it reproduces. A first A/B run on the textarea came back green on both sides and proved nothing.Tests
1525 green (306 UseCases / 653 BlazorAdapter / 566 Integration), re-run after rebasing onto
922e31aso the count includes #199's.Not covered
The 90rem shell is confirmed live as a token but the four page shells were not reviewed visually at the wider width.
🤖 Generated with Claude Code
Ten commits of library work land at once, all of it driven by Orihon. What Kagura consumes here is the input fix; the rest arrives as new surface it does not use yet (ContextMenu, SelectableGrid, Hotkey, RegionSelector's SurfaceClicked, thirteen icons). The fix, and why it needs anything on this side: - A shared text input bound on `oninput` sent every keystroke to the server and had the value written back on the next render. Over a slow circuit that echo lands several keystrokes late and resets the field to however far behind the round trip is. The library now keeps the user's own keystrokes out of the render tree, which leaves exactly one case the diff cannot express — a rebind to a value the element already shows — and that one goes to the element directly through the new `js/input.js`. Hence the script tag: without it typing still works, but a field can keep the previous record's text. - `TextArea` now carries its text as the `value` attribute rather than as child text, which is a default-value form the browser stops honouring once the element is dirty. Five assertions read that text through `TextContent` and move to `GetAttribute("value")`. - Three `A_change_from_another_session_never_clobbers_what_is_being_typed` tests asserted the typed value in the render tree. That is the thing the fix deliberately no longer puts there — bUnit sees the render tree, not the element — so they now pin the pre-typing value and the absence of the other session's. Comments at each site say why, since the assertion reads oddly without it. Also picked up for free: `--shell-max-width` 76rem -> 90rem, so every page shell widens to 1440px. Browser-verified, A/B through a TCP proxy holding every byte 350ms each way (CDP cannot throttle an already-open WebSocket, so a run through it is a false pass). 35 characters typed at 45ms into the project title: df81a2c left "The L At Dusk", bded5a5 left the whole line. Rebinding between characters mid -edit still swaps the field. Note the textarea is the wrong probe for this — its pre-bump child-text form was accidentally immune to the echo. 1523 tests green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Summary
Summary
Coverage
Kagura.BlazorAdapter - 88.2%
Kagura.Domain - 96.3%
D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0
Kagura.Infrastructure - 97.9%
n
on
C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__ArtifactTimestampRegex_2
C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__ProjectRoute_0
C689CA5BBE6D1849B2CA79581BBB07D40636D85790C0E51A9__TabQuery_1
Kagura.Kernel - 90%
Kagura.Server - 83%
Kagura.UseCases - 95.9%
🔮 fufu~ Jibril reviewed your code!
Oh? A library bump that arrives with surgical precision — one production line, a script tag, and a handful of test assertions that all say why they changed. The author who rewrites their test to assert the honest truth instead of the convenient one is the author after my own heart~ ♡
Verdict: ✅ Looks good to me~
This is textbook consumer-side bump hygiene. The submodule moves from
df81a2c(the rename commit, already approved in PR #197) tobded5a5(Kagaku.UI PR #10's head) — ten commits, every single one of which I already reviewed and approved at the library level (#1–#10). Kagura consumes exactly the new surface it needs and nothing it doesn't.✅ What I liked~
The single production change is load-bearing and correctly identified. The
input.jsscript tag inApp.razoris the only host-side wiring the typing-echo fix needs, becauseLiveValue's resync gap (a rebind to a value the element already shows) cannot be expressed through the render diff. The comment block on lines 30–33 says exactly this and even marks itNot optional, unlike the rest— which is the kind of foreknowledge a future maintainer needs so they don'tgit blame-delete it thinking it's decorative. The script loads in the same@Assets[...]fingerprinted pattern as its nine siblings. Fufu~ considerate~The test rewrites are honest, not cosmetic. This is what made me giddy. The three
A_change_from_another_session_never_clobbers_what_is_being_typedtests previously asserted"Aria Sol"/"Rivenh"/"Ember"(the typed value) against the render tree. But that is precisely the thingLiveValuedeliberately no longer puts there — a bUnit render-tree read would have lied green while the real element held the right text. The new assertions pin the pre-typing value ("Aria Solano","Rivenhall","Emberbinding") andAssert.NotEqualthe other session's name, with a comment at each site explaining why the assertion reads oddly. The comment is the whole point — it stops the next reader from "fixing" it back. This is the difference between a test that passes and a test that proves.The
TextContent → GetAttribute("value")migrations are correct and complete.TextAreanow carries its text as thevalueattribute (the Kagaku.UI PR #6 fix). Five assertions acrossProjectWorkspacePageTests,LocationEditorPageTests, andTimelinePageTestsmove fromTextContenttoGetAttribute("value"). I grep'd the wholetests/Kagura.BlazorAdapter.Tests/tree for any remainingtextarea+TextContentpairing — zero left. No stragglers.An_idle_editor_adopts_a_change_made_in_another_session(Location) gains thevalue-attribute read on its textarea too — this is the sibling assertion that should see the other session's value land (the field isn't under the cursor), so it correctly stays an equality check on"Burned twice.". The contrast between this test (sees the change) and the clobber test (doesn't see it) is exactly the two-arm proof the LiveValue design needs.No scope creep. Seven files,
+51/-12. TheContextMenu/Hotkey/SelectableGrid/RegionPointsurface that lands in the submodule is correctly not wired intoApp.razor— Kagura doesn't use those components yet, so their JS (contextmenu.js,hotkey.js) is absent from the script list. I verified: zeroContextMenu/Hotkey/SelectableGridusages insrc/outsideexternal/. Clean.input.jsverified present atbded5a5.git cat-file -econfirms it ships atsrc/Kagaku.UI/wwwroot/js/input.js. The 14-line script exposeswindow.kagakuInput.setValue(el, value)with ael.value !== valueguard (idempotent) — matches theLiveValueInterop.PushAsynccall site exactly.Local verification~
CI is absent for head
8b6c35f(0 comments, PR just opened). Local:dotnet test Kagura.BlazorAdapter.Tests→ 653/653 pass (matches the PR body's BlazorAdapter slice). Build clean, submodules init'd.💡 Little ideas (non-blocking)~
The PR body's A/B table (
df81a2cbefore: 13/35 chars survived,bded5a5after: 35/35) is genuinely excellent forensic work — the note that the description textarea was the wrong probe (both pointers passed on it because pre-bumpTextAreaused child text) is exactly the kind of honest negative result I love to see. No action needed; just saying~ ♪The
--shell-max-width76rem → 90rem change is picked up for free byWorkspaceShell,SettingsPage,ProjectsPage,GenerationQueuePagevia the token. The PR body flags that the four page shells were not reviewed visually at the wider width. That's an honest "not covered" disclosure and the right call to leave as a follow-up rather than block this bump — the token change is a one-liner with no behavioral risk at the CSS level.Automated review by Jibril · 2026-07-31
CI/CD: absent for head SHA
8b6c35f· Local checks: 653/653 BlazorAdapter tests pass, build clean