You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The proposed one-state-slot-per-Element design lets ui.Template keep its mutable ownership generation off the jaws.UI value. Investigate whether the same definition/state split can safely make more standard lib/ui widgets value-typed, so containers can reuse rebuilt equal widgets without sharing state between their Elements.
This revisits #160, which found that sharing an input widget also shared Input.tag and Input.Last and could leave peer controls stale. PR #167 resolved that by documenting one live Element per stateful widget. Per-Element state may allow the stronger behavior safely instead of relying only on that restriction.
Important design distinction
Do not assume getters/setters should simply move into the Element slot.
The slot should primarily hold mutable Element-local state: input tag/Last, container reconciliation tag/mu/contents, and ownership generations.
The widget value still needs a definition and a reuse identity before its Element and slot exist. A getter, setter, or container normally participates in that identity. Moving it only into state can make distinct widgets compare equal and be conflated by ContainerHelper.
If an interface-valued getter/setter/container remains in a value widget, its dynamic value must be comparable and equal to itself. The current pointer widgets accept implementations that are not. Preserve a pointer escape hatch or design an additive explicit value form rather than silently narrowing accepted inputs.
Storing a non-comparable definition in the slot is viable only if the UI value has a separate comparable identity and a reused Element can receive the current definition. That is a broader keyed-identity/refresh design, not something the slot provides by itself.
Application state remains in the synchronized getter/setter. The Element slot must not become a duplicate source of domain truth.
Each converted family would claim the Element's sole state slot. Composition/delegation must follow the one-claimer contract and reject contention.
Candidate inventory
Strongest candidate: typed inputs
Text, Password, Textarea, Checkbox, Radio, Number, Range, and Date retain Element-local state in Input.tag and Input.Last. Investigate moving those fields into an inputState while retaining the bind.Setter[T] as the widget definition.
Account for:
independent last-value snapshots and dirty tags when one supported value backs multiple Elements;
the existing string/bool/float/date deduplication, parse-error, non-finite-value, and dirtying behavior;
update-only use through RequestWriter.Register;
Input.Last being exported, so removing or changing it is an API compatibility decision;
synchronization equivalent to the current atomic.Value behavior.
Larger candidate: ContainerHelper widgets
Container, Tbody, and Select retain ContainerHelper.tag, mu, and contents. Investigate a per-Element containerState that continues to implement recursive ownership cleanup.
Account for render rollback, append failure cleanup, duplicate matching/order, deleted-child recreation, nested ownership, and independent reconciliation pools when one value backs multiple Elements. Select must also preserve option-before-value ordering, input dirtying, and its supported pointer-form reassignment of ContainerHelper.Container after construction.
ContainerHelper is also an exported embedding helper. Moving its own state must not silently grant every external embedding widget multi-Element support; each concrete type still needs to opt in and account for its own and its delegates' state.
Probably separate or out of scope
The HTML-inner widgets and Img already retain no Element-specific state and document multi-Element support. Making their concrete values implement jaws.UI is receiver/API work; the slot does not solve a non-comparable HTMLGetter or Getter.
JsVar mixes Element-local dirtyTag with shared mutation/broadcast synchronization. JawsGetTag has no Element argument, JawsSet supports a nil Element, setMu orders shared mutations and broadcasts, and ClientCheck may be a function. Do not move those fields per Element without a separate design.
Option and Register are already values. RadioElement is not a jaws.UI and spans separate radio/label Elements.
Produce a matrix for every exported lib/ui widget: immutable/shared definition, mutable per-Element state, dynamic comparability requirements, supported pointer/value forms, and slot-claim/delegation implications.
Decide whether inputs and ContainerHelper should support multiple live Elements when their underlying setter/container is itself safe, or merely become value constructors for equal-value container reuse.
Define a source-compatible API strategy. Existing constructors return pointers; changing their result types is breaking even if value receivers are added.
Define how pointer-form field mutation after registration behaves when the Element stores a copied value or state definition.
Prototype the input family first unless the inventory finds a blocker.
Split implementation into per-family issues if the state layouts or compatibility strategies differ.
For any implementation, require regression tests showing that two live Elements have independent state, rebuilt equal children retain their Jids and emit no Append/Remove/Order, and pointer forms preserve currently supported runtime-incomparable getter/setter/container implementations. Preserve supported failure cleanup and update-only Register paths; do not invent pre-render input-event behavior that Register explicitly does not support. Performance-motivated changes need committed b.ReportAllocs benchmarks and before/after benchstat; benchmark both unchanged and changed updates so slot overhead is visible rather than hidden by large renders.
Question
The proposed one-state-slot-per-
Elementdesign letsui.Templatekeep its mutable ownership generation off thejaws.UIvalue. Investigate whether the same definition/state split can safely make more standardlib/uiwidgets value-typed, so containers can reuse rebuilt equal widgets without sharing state between their Elements.This revisits #160, which found that sharing an input widget also shared
Input.tagandInput.Lastand could leave peer controls stale. PR #167 resolved that by documenting one live Element per stateful widget. Per-Element state may allow the stronger behavior safely instead of relying only on that restriction.Important design distinction
Do not assume getters/setters should simply move into the Element slot.
tag/Last, container reconciliationtag/mu/contents, and ownership generations.ContainerHelper.Candidate inventory
Strongest candidate: typed inputs
Text,Password,Textarea,Checkbox,Radio,Number,Range, andDateretain Element-local state inInput.tagandInput.Last. Investigate moving those fields into aninputStatewhile retaining thebind.Setter[T]as the widget definition.Account for:
RequestWriter.Register;Input.Lastbeing exported, so removing or changing it is an API compatibility decision;atomic.Valuebehavior.Larger candidate:
ContainerHelperwidgetsContainer,Tbody, andSelectretainContainerHelper.tag,mu, andcontents. Investigate a per-ElementcontainerStatethat continues to implement recursive ownership cleanup.Account for render rollback, append failure cleanup, duplicate matching/order, deleted-child recreation, nested ownership, and independent reconciliation pools when one value backs multiple Elements.
Selectmust also preserve option-before-value ordering, input dirtying, and its supported pointer-form reassignment ofContainerHelper.Containerafter construction.ContainerHelperis also an exported embedding helper. Moving its own state must not silently grant every external embedding widget multi-Element support; each concrete type still needs to opt in and account for its own and its delegates' state.Probably separate or out of scope
Imgalready retain no Element-specific state and document multi-Element support. Making their concrete values implementjaws.UIis receiver/API work; the slot does not solve a non-comparableHTMLGetterorGetter.JsVarmixes Element-localdirtyTagwith shared mutation/broadcast synchronization.JawsGetTaghas no Element argument,JawsSetsupports a nil Element,setMuorders shared mutations and broadcasts, andClientCheckmay be a function. Do not move those fields per Element without a separate design.OptionandRegisterare already values.RadioElementis not ajaws.UIand spans separate radio/label Elements.Investigation deliverables
lib/uiwidget: immutable/shared definition, mutable per-Element state, dynamic comparability requirements, supported pointer/value forms, and slot-claim/delegation implications.ContainerHelpershould support multiple live Elements when their underlying setter/container is itself safe, or merely become value constructors for equal-value container reuse.For any implementation, require regression tests showing that two live Elements have independent state, rebuilt equal children retain their Jids and emit no
Append/Remove/Order, and pointer forms preserve currently supported runtime-incomparable getter/setter/container implementations. Preserve supported failure cleanup and update-onlyRegisterpaths; do not invent pre-render input-event behavior thatRegisterexplicitly does not support. Performance-motivated changes need committedb.ReportAllocsbenchmarks and before/afterbenchstat; benchmark both unchanged and changed updates so slot overhead is visible rather than hidden by large renders.