Friday, September 25, 2026
1 change · master
Code cleanup and technical improvements
The mail module now registers model fields when records are actually initialized instead of relying on a fixed startup map. This makes later-loaded mail updates visible without rebuilding the store, improving reliability while keeping performance broadly stable.
Original PR description
Before this commit, the store knows every field of every model before a single record exists: makeStore instantiates a throwaway record per model to collect its declarations, then walks the models…
Before this commit, the store knows every field of every model before a single record exists: makeStore instantiates a throwaway record per model to collect its declarations, then walks the models twice, once to pair each relation with its inverse, once to map every field, getter and method an _inherits parent provides to the relation it is read through. The problem is that both maps are fixed at boot: a member a model gains later, from a patch in a lazily loaded bundle, is never seen. This commit registers the fields of a model when its first record runs setup(), pairing a relation with its inverse and with its _inherits parent as each side registers, and resolves an _inherits member on access, ModelInternal.resolveParentField(name): a name this model does not own, neither as a field, a technical key nor a member of its class prototype, and that a parent provides. A positive answer is cached, a negative one is not, as the parent may register the field later. The throwaway record and both loops go. Every read of a record goes through the resolution, so the cheapest answers come first: a model with no _inherits returns on one property read, and a name the model owns on one lookup, both before the cache. Over 200k reads, master against this commit: an own field 122ns / 130ns, an inherited one 1115ns / 1136ns, a technical key 95ns / 98ns. Only a name that is none of those, on a model that does inherit, walks the parent again on every read, 98ns / 305ns; opening a channel of 30 messages resolves 44491 names and walks 80 of them.