Name | Modified | Size | Downloads / Week |
---|---|---|---|
Parent folder | |||
Effect-Based Reactivity System source code.tar.gz | 2025-07-09 | 16.8 MB | |
Effect-Based Reactivity System source code.zip | 2025-07-09 | 18.5 MB | |
README.md | 2025-07-09 | 7.5 kB | |
Totals: 3 Items | 35.3 MB | 3 |
Neo.mjs v10.0.0-beta.5 Release Notes
This beta release dramatically expands on the reactive programming model introduced in beta.4, delivering a powerful, end-to-end Effect-Based Reactivity System. This new system provides a declarative and highly efficient way to manage component state, create reactive data transformations, and build dynamic user interfaces with minimal boilerplate.
This release also includes significant enhancements to the framework's mixin system and state providers, further improving code organization and state management capabilities.
Core Framework & Features
A core philosophy of Neo.mjs is to provide developers with powerful, flexible options. This release reinforces that principle by dramatically enhancing the framework's reactive core. These new features provide a more direct, declarative way to manage state and build UIs—offering a familiar entry point for developers from other ecosystems—while seamlessly integrating with the established power and productivity of Neo.mjs's declarative component tree architecture.
The pace of innovation in this release is a testament to the power and flexibility of the new architecture. The features introduced in this beta represent a quantum leap forward, enabling development patterns that are more declarative, more powerful, and more intuitive than ever before.
1. The New Effect-Based Reactivity System
The core of this release is a new suite of classes (core.Effect
, core.EffectManager
, core.BatchEffectManager
) that enable true "spreadsheet-style" reactivity. An "Effect" is a function that automatically re-runs whenever any of its reactive dependencies change.
- Automatic Dependency Tracking: The framework now automatically tracks which reactive configs are accessed within an Effect. You declare a config as reactive by adding a trailing underscore in the
static config
block (e.g.,myValue_
), and then access it without the underscore (this.myValue
). You no longer need to manually subscribe to changes; the dependency graph is built and maintained for you. - Arbitrary Cross-Instance Bindings: Since bindings are now powered by
core.Effect
, they can depend on any reactive config from anycore.Base
instance—not just components or state providerdata
. This allows for creating powerful, arbitrary data flows between any part of your application (e.g., binding a component's property to a data store'scount
).javascript // A component can now bind its text to its provider's data AND a store's count bind: { text: data => `${data.title}: ${myStore.count} items` }
- Synchronous Batching (
core.BatchEffectManager
): Multiple state changes can be batched together into a single, atomic update. This prevents "glitching" (where the UI updates multiple times for a single user action) and ensures that effects run only once with the final, consistent state. - Foundation for Declarative VDOM: The new Effect system lays the groundwork for a truly declarative component model. As a proof-of-concept, a new
button.Effect
class was created to demonstrate that a component's VDOM can now be generated by a single, reactive function that automatically re-runs when its state dependencies change. This powerful new paradigm, which will be fully realized in the upcoming Functional Components epic, will make component rendering logic more readable, centralized, and easily extensible. - Lifecycle-Aware Subscriptions: A new
core.Base#observeConfig()
method provides a safe, convenient way to subscribe to config changes, automatically handling the cleanup of subscriptions when a component is destroyed to prevent memory leaks.
2. Architectural Evolution: State Management Overhaul
state.Provider
has been completely rewritten to be more powerful, explicit, and performant, leveraging the new Effect-based reactivity core. This is a significant architectural evolution from the previous version.
The Old System: Bindings received a single, implicitly merged data
object, which was a combination of all state providers in the component's hierarchy.
The New System: The new model is more explicit and powerful, providing clearer data flow and eliminating "magic".
- Reactive Data Proxies: The
data
object of a provider is now a deep Proxy. You can now trigger reactive updates simply by direct assignment (myProvider.data.foo = 'new value'
), and any component bound to that data will update automatically. - Explicit Hierarchical Access: Instead of an implicitly merged object, hierarchical data is now accessed explicitly through the
parent
property on the data proxy (e.g.,data.parent.someValue
). This makes data origins clear and easy to trace. - Formulas: State providers now support formulas—functions that derive their value from other state properties (e.g.,
fullName: data =>
${data.firstName} ${data.lastName}``). These formulas are themselves reactive and will automatically re-calculate when their dependencies change. - Enhanced Two-Way Bindings: Two-way data bindings are now more robust and efficient, powered by the new reactive core.
3. Enhanced Class System
- Automatic Static Config Merging for Mixins: The framework's mixin system is now significantly more powerful. Previously limited to methods, mixins can now contribute to the
static config
of a class. The configs are intelligently merged with a clear order of precedence:- The target class's own
static config
always has the highest priority. - For conflicting configs between mixins, the mixin that appears earlier in the
mixins
array wins. - Mixins on a base class take precedence over mixins on an extended class.
- The target class's own
- Granular Cloning Strategies: The reactive config system now features
clone
andcloneOnGet
descriptor flags, providing fine-grained control over how and when config values are cloned. This is critical for performance tuning and handling complex data types.
New Learning Content
- New Guide: "Declarative VDOM with Effects": A new guide has been added to the documentation to explain the principles of the new reactivity system and demonstrate how to build components using an Effect-based approach.
All changes combined in 1 commit: https://github.com/neomjs/neo/commit/2105ea95b8b498c73d9c54f6bffe8de8704dfe0d
This release represents a major leap forward for the Neo.mjs framework, providing a state-of-the-art reactive programming model that is both powerful and easy to use.
Call To Action
We are incredibly excited for you to explore these new capabilities.
- Explore Effects: Try creating your own effects to manage component logic and state.
- Leverage State Providers: Experiment with the new Proxy-based data objects and formulas in
state.Provider
. - Read the New Guide: Check out the Declarative VDOM with Effects guide to get started with the new paradigm.
- Share Your Feedback: Your insights are invaluable. Please share your experiences and report any issues via GitHub Issues or our Slack Channel.