refactor(minesweeper): model idiomatic JaWS state - #386
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
gameandcellstate, with no DTOs, projections, render snapshots, or retained presentation copiescellButtonembedsui.Button, inherits its unmodified render path, and overrides onlyJawsUpdatecell.InitialAttrs()template parameter, leaving the initial TailHTML emptyFinal widget shape
The template makes every render dependency explicit:
cell.Button()constructs a fresh*cellButtonthat embeds the standardui.Buttonover the authoritative*cell. It does not implementJawsRender; Go method promotion suppliesui.Button.JawsRender, including getter, precise-tag, click, and context-menu registration. The outer definition overrides onlyJawsUpdate, because a dirty cell must updatedata-state,aria-label,disabled, and inner HTML as one local read of authoritative state.InitialAttrs()returns escapedtemplate.HTMLAttrfor the ordinary render parameter.BoardTag()andGameOverTag()are ordinary template parameters as well. The cell does not implementJawsInitialHTMLAttr, and neither the render path nor the updater retains presentation state.Initial attributes and inner HTML are separate synchronized reads, as permitted by the JaWS render contract. Dirty selection applies to dependencies already registered on an Element; each later matching dirty event re-reads the authoritative cell and brings every registered copy current.
Framework guidance
The repository history and all standard widgets support keeping
JawsInitialHTMLAttrinitial-only. Its result is raw opening-tag syntax: it identifies neither attribute ownership nor removals, so treating it as an update getter would create an underspecified live-DOM contract. A future general dynamic-attribute API would need explicit ownership/diff semantics, preferably structured set/remove operations.The updated JaWS skill now says, in stronger terms:
Review resolution
Implemented across the review rounds:
:8080class="cell"template-owned and update onlydata-stategame.mubefore all JaWS Element operationscelltypeSprintfcalljw.Loggerfor the long-running server, with the rationale documented; direct UI tests leave it nil so contract violations fail fastBenchmarks
The committed benchmark measures both the initial page and one-shot tail response. Payload bytes are stable across runs:
main(b337341)ced56ea)mainCompared with
ced56ea, ten 1-second samples on darwin/arm64 (Apple M5 Max) give:The measured goal is the initial network payload. The fresh overload's allocation cost is reported rather than hidden.
BenchmarkSingleCellDirtyFanoutremains stable at about 168 ns/op, 180 B/op, and 12 allocs/op across six 1-second samples.Follow-up
Issue #387 proposes batching TailHTML operations through one client dispatcher call with a compact JSON payload. It records the existing TailHTML/WebSocket decoding drift and the requirement to preserve the current ordering relative to
jawsAttachChildren(document).Verification
go generate ./...go vet ./...gofmt -l .gofumpt -l examples/minesweeper/*.go contracts.gogit diff --checkstaticcheck ./...golangci-lint v2.13.1 rungosec ./...go build ./...JAWS_REQUIRE_NODE=1 go test -race ./...JAWS_REQUIRE_NODE=1 go test ./...go test -race -cover ./examples/minesweeper(99.0%)go docreview forUpdaterandInitialHTMLAttrHandlerquick_validate.py