ui: add transactional JsVar client validation#166
Merged
Conversation
Replace binding-local size accounting with an optional validation callback that observes the complete tentative state and changed jq path. Add JSONSizeCheck, atomic rollback, shared-state coverage, documentation, and retained benchmarks.
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
MaxClientJsVarBytesaccounting with optionalJsVar.ClientCheckvalidation over the complete tentative state.jq.SetCheckedto roll rejected or panicking mutations back atomically.JSONSizeCheck[T]as an opt-in complete-value serialized-size policy.Migration
This intentionally removes
ui.MaxClientJsVarBytesand the default cumulative state-size policy. Applications must configure an equivalentClientCheckon every request-scoped binding that exposes the same mutable backing object graph, or enforce bounds inPathSetter.ClientCheckapplies only to actual generic browser mutations. Rendering, server writes, invalid or unchanged writes, andPathSettervalues bypass it. The supplied jq path is verbatim and may be noncanonical, so it is an inspection hint rather than an authorization key; usePathSetterto allow-list paths.JSONSizeCheckmarshals the complete tentative value for every accepted mutation attempt. It bounds JSON output rather than Go backing memory, and customMarshalJSONorMarshalTextmethods, omitted fields, aliases, or collection capacity may require a domain-specific check.Benchmarks
Ten identical-workload samples on darwin/arm64, using alternating equal-length values:
The unchecked large-state result is statistically unchanged. The small-state result improved but had higher variance. Checked cases are absolute opt-in costs with no baseline analogue.
Verification
go generate ./...go vet ./...gofmt -l .staticcheck ./...golangci-lint run ./...gosec ./...JAWS_REQUIRE_NODE=1 go test -race -count=1 -coverprofile=coverage.out ./...go build ./...-race -count=100lib/uiand all library packages report 100% statement coverage; total module coverage is 99.9% because the example executable main remains uncovered.Closes #159