Summary:
This ticket covers a critical enhancement to Neo.core.Config to add support for an execution scope in its subscribe method. This was driven by the need for functional components to safely observe Neo.core.Effect state changes without creating circular dependencies. The implementation evolved to handle complex edge cases, resulting in a more robust and powerful subscription system.
Rationale:
The initial problem was an infinite loop in functional components. The component's vdomEffect would trigger an update, which would read this.vnode, creating a dependency on the result of the update itself.
The chosen solution was to make Effect.isRunning a reactive Neo.core.Config and have the component subscribe to it. This required the subscription callback to be executed in the component's scope. The Config.subscribe method, however, lacked support for a scope parameter.
Implementation Journey:
- Initial Goal: Add a
scope parameter to subscribe.
- First Approach: A simple implementation was considered, storing the
fn and scope in a Map.
- Identifying an Edge Case: It was determined that subscribing the same function with different scopes would lead to silent overwrites (e.g.,
map.set(fn, scopeA) followed by map.set(fn, scopeB)).
- Final Architecture: To solve this robustly, a more sophisticated nested data structure was implemented:
Map<string, Map<function, Set<scope>>>.
- The top-level
Map keys are the subscriber owner's ID.
- The second-level
Map keys are the callback functions.
- The
Set stores all unique scopes registered for that specific function.
This ensures that every fn-scope combination is treated as a unique subscription, preventing conflicts and data loss.
- Intent-Driven Comments: Due to the non-obvious complexity of the final data structure, detailed comments were added to
Config.mjs to explain the why behind the design, ensuring future maintainability.
Definition of Done:
Neo.core.Config.subscribe now accepts a scope property.
- The internal implementation correctly handles multiple subscriptions of the same function with different scopes.
- The
notify method correctly executes callbacks with their specified scope.
- The cleanup function returned by
subscribe correctly removes the specific fn/scope subscription and cleans up parent data structures if they become empty.
- The code is documented with intent-driven comments explaining the data structure.
Summary: This ticket covers a critical enhancement to
Neo.core.Configto add support for an executionscopein itssubscribemethod. This was driven by the need for functional components to safely observeNeo.core.Effectstate changes without creating circular dependencies. The implementation evolved to handle complex edge cases, resulting in a more robust and powerful subscription system.Rationale: The initial problem was an infinite loop in functional components. The component's
vdomEffectwould trigger an update, which would readthis.vnode, creating a dependency on the result of the update itself.The chosen solution was to make
Effect.isRunninga reactiveNeo.core.Configand have the component subscribe to it. This required the subscription callback to be executed in the component's scope. TheConfig.subscribemethod, however, lacked support for ascopeparameter.Implementation Journey:
scopeparameter tosubscribe.fnandscopein aMap.map.set(fn, scopeA)followed bymap.set(fn, scopeB)).Map<string, Map<function, Set<scope>>>.Mapkeys are the subscriber owner's ID.Mapkeys are the callback functions.Setstores all unique scopes registered for that specific function. This ensures that everyfn-scopecombination is treated as a unique subscription, preventing conflicts and data loss.Config.mjsto explain the why behind the design, ensuring future maintainability.Definition of Done:
Neo.core.Config.subscribenow accepts ascopeproperty.notifymethod correctly executes callbacks with their specified scope.subscribecorrectly removes the specificfn/scopesubscription and cleans up parent data structures if they become empty.