Frontmatter
| tagName | 10.0.0 |
| name | Neo.mjs v10: The Reactive Revolution |
| publishedAt | 7/24/2025, 6:03:17 AM |
| isPrerelease | |
| isDraft |
Neo.mjs v10: The Reactive Revolution
This release brings significant enhancements and refactorings, improving performance, reactivity, and the overall developer experience.
Core Framework Improvements
- Reactive Core Refactoring (
core.Observable):- Architectural refactoring of
core.Observableto a fully reactive mixin (#7090). - Modernized
core.Observable: Refactoredcore.Observableto align with the reactive config system. This involved converting thelistenersproperty to a reactivelisteners_config, eliminating manual initialization, and establishing true encapsulation using a module-scopedSymbol(eventMapSymbol) for internal event registry management. A bug inremoveListenerrelated to incorrect state access was also fixed. (#7090) - Listeners are now managed as a reactive config within
core.Observable(#7089).
- Architectural refactoring of
- Effect Management System:
- Foundational Refactoring of Effect Management: The core reactivity system has been refactored and unified under a single
Neo.core.EffectManager(#7085). This introduces a clear distinction between:- Execution Batching (
pause()/resume()): Replaced the oldisPausedflag with a numericpauseCounterfor robust, nested batching of UI updates. Effects are queued and executed only when the counter is zero. - Dependency Tracking Suppression (
pauseTracking()/resumeTracking()): A new mechanism (isTrackingPausedflag) to temporarily stop active effects from collecting new dependencies, solving self-dependency issues.
- Execution Batching (
- The
EffectBatchManagersingleton has been completely removed, and its functionality absorbed by the enhancedEffectManager. This results in a more predictable, robust, and resilient reactive system.
- Foundational Refactoring of Effect Management: The core reactivity system has been refactored and unified under a single
- State Management:
- State Provider Refactoring & Deep Merging:
- Refactored
state.Provider'sinternalSetData()method to support intuitive deep-merging of nested objects, allowing dynamic creation of new, fully reactive data structures at runtime. This resolves inconsistent behavior and aligns with expected merge operations. (#7099) - Enhanced Reactivity & Atomic Updates:
state.Providernow features "Reactivity Bubbling," where changes to leaf properties recursively update parent objects, correctly triggering effects on intermediate data objects. PublicsetData()andsetDataAtSameLevel()methods are now wrapped withNeo.batch()(leveraging the newEffectManager's batching capabilities) to ensure all reactive updates are collected, de-duplicated, and executed atomically, preventing race conditions and improving performance. A new test suite (ProviderNestedDataConfigs.mjs) validates this functionality. - Moved all state provider related logic (configs like
bind,modelData,stateProvider_,data_,parentComponent_, and methods likegetStateProvider(),getState(),setState(),beforeGetData(),getConfigInstanceByNtype(), along with lifecycle logic and two-way binding logic) fromsrc/component/Base.mjstosrc/component/Abstract.mjs. This makes state providers available to both classic class-based components and modern functional components. (#7100)
- Refactored
- State Provider Refactoring & Deep Merging:
- Component Base Classes:
- Common Abstract Base Class: Introduced
Neo.component.Abstractas a new common base class for bothNeo.component.Base(classic) andNeo.functional.component.Base(functional) components. This refactoring centralizes shared logic (e.g.,set(),destroy(),mountedPromise, core configs,DomEvents,Observable,VdomLifecyclemixins), improving code reusability, enhancing consistency, and simplifying maintenance by removing duplicated code. (#7089) - Removed redundant
createBindings()calls fromonConstructed(#7101).
- Common Abstract Base Class: Introduced
Functional Components
- VDOM Reconciliation: Enhanced Functional Component VDOM Reconciliation (
#7086). - Lifecycle Hook: Introduced a new
beforeUpdate()lifecycle method toNeo.functional.component.Base(#7084). This hook executes after all state changes from a reactiveEffecthave been processed and just beforeupdateVdom(). It provides a predictable entry point for pre-render logic and allows conditionally canceling a VDOM update by returningfalse. - Functional Button Component: Introduced a new
Neo.functional.button.Basecomponent (#7087). This component serves as a key UI element built using the functional component paradigm, demonstrating integration with the reactive VDOM system and leveraging automatic VDOM node ID generation for efficient diffing. A dedicated test suite and demo application were created. functional.button.Base:beforeSetBadgePosition(),beforeSetIconPosition()now use constructor access for future class extensions.
VDOM & Rendering
util.vdom.TreeBuilder: Improvements tobuildTree(): RefactoredgetVdomTreeandgetVnodeTreeinto a single, DRY method (#7098).util.VDom:syncVdomIds()enhanced for future-proofing and improved filtering.manager.VDomUpdate: Significantly enhanced JSDoc comments and method order/cleanup.
Other Enhancements & Fixes
- Dependencies: Updated FontAwesome to v7.
- Examples Website: Fixed flakiness on Safari (
#7102). - Tests: All 770 unit tests now pass successfully, including a significant number of new tests added since beta.6.
form.field.Text:onInputValueChange()intent made clearer.Portal.view.ViewportController: Cube-layout timing adjustments.core.EffectManager: OptimizedNeo.batchusage.- Removed obsolete
onNeoConfigChange()calls from tests. - Updated
test/siesta/tests/vdom/layout/Cube.mjsto match currentVdomHelper.create()signature.
Documentation Updates
- The
learn/guides/datahandling/StateProviders.mdguide has been updated to accurately describe the new deep-merge behavior of state providers. - Code examples in the
learn/blog/v10-deep-dive-state-provider.mdblog post have been updated to demonstrate the intuitive API usage.
All changes combined into 1 commit: https://github.com/neomjs/neo/commit/c84a2cd65cb9206ffe2221d7a2f675b9466ac646