Naming Conventions
Libraries should be developed in accordance with naming conventions to ensure consistency.
How to write Mixin Functions
When writing the body of a mixin function, the standard structure is to return a new class that dynamically extends the base class.
Advanced Mixin Techniques
On the previous page, we learned about a simple mixin tailored specifically for Component. However, within the GeaJS ecosystem, you may also want to extend plain objects such as Store and Object. On this page, letβs learn a general-purpose approach to address those needs.
Generalization in Mixin Definitions
At Geastack Community, we are developing @geastack-community/utils, a package that defines common definitions for creating mixins. This package provides useful functions and definitions for creating mixins and performing various other tasks. On this page, letβs migrate some of the definitions we covered on the previous two pages to those predefined in this library.
Symbol-Keyed Internal State
The mixin examples so far have added a single public property (xxxProperty) β something the mixin is explicitly designed to expose. But most real mixins also need to track internal state: a list of resources they created and are responsible for disposing of. withForm, for example, needs to remember every GeaForm it created via createForm(), so dispose() can tear each one down.
Testing Symbol-Keyed Internal State
The previous page exported the tracking symbol under an / @internal */ tag specifically so it stays inspectable β mainly for the mixin's own test suite. This page covers how to actually use it from a test.
Configurable Method Names for Ecosystem Interoperability
Symbol-Keyed Internal State solved collisions for a mixin's internal tracking state. Public methods have the opposite problem: they're supposed to be visible and callable, so a Symbol isn't an option β and that's exactly where a different kind of collision risk shows up.
Composition Order and the Dispose Chain
withMixins states the rule for composition order: mixins are applied right to left, so withMixins(withXxx, withYyy, withZzz, Base) is equivalent to withXxx(withYyy(withZzz(Base))) β withZzz is applied first (its generated class sits closest to Base), and withXxx is applied last (its generated class sits closest to the final, most-derived instance).
Versioning Internal Changes
Symbol-Keyed Internal State recommended exporting the internal tracking symbol under an / @internal */ tag rather than hiding it completely, specifically so a test suite (see Testing Symbol-Keyed Internal State) can inspect it directly. That design choice has a consequence worth calling out on its own: an exported symbol, no matter how clearly it's marked @internal, is still importable by anyone, not just your own test suite.