Is your feature request related to a problem? Please describe.
When Neo.setupClass processes the class hierarchy, static config values from parent classes are currently overwritten by those from child classes if a config property with the same name exists. This prevents the intended hierarchical merging of config values based on the merge strategy defined in their respective configDescriptors.
For example, if Component.Base defines style_ with a merge: 'shallow' descriptor:
style_: {
[isDescriptor]: true,
merge : 'shallow',
value : null
},
And then MyComponent extends Component.Base with static config = {style: {color: "red"}}, and MyEnhancedComponent extends MyComponent with static config = {style: {backgroundColor: "blue"}}. The desired outcome is that MyEnhancedComponent's final style config should be {color: "red", backgroundColor: "blue"} due to the inherited shallow merge strategy. However, the current Object.assign(config, cfg) in Neo.setupClass would simply overwrite the style property, resulting in {backgroundColor: "blue"} and losing the color: "red" from MyComponent.
Describe the solution you'd like
The Neo.setupClass method in src/Neo.mjs should be modified to perform hierarchical merging of static config values based on the merge strategy defined in their configDescriptors. As Neo.setupClass traverses the class prototype chain, when merging the static config (cfg) of the current class into the accumulated config object, it should:
- Identify if the config property has a corresponding
configDescriptor (which would have been collected from the highest class in the hierarchy that defined it).
- If a
merge strategy is defined in the descriptor, apply that strategy using Neo.mergeConfig to combine the existing config value with the cfg value.
- If no
merge strategy is defined, or if the values are not objects (and thus shallow/deep merges are not applicable), it should default to replacement.
This ensures that static config values are merged correctly across the class hierarchy, respecting the defined merge strategies.
Describe alternatives you've considered
The current "overwrite" behavior is the alternative, which leads to the described problem. This proposed solution directly addresses the need for hierarchical value merging in static config.
Additional context
This change is crucial for the predictability and correctness of how static config values are inherited and combined across the class hierarchy. It allows developers to define complex default configurations that are intelligently merged by subclasses, rather than simply being overwritten. This is distinct from instance-level config merging (handled by Base.mjs#mergeConfig), as this change focuses on the final static config object that Neo.setupClass produces.
Is your feature request related to a problem? Please describe. When
Neo.setupClassprocesses the class hierarchy,static configvalues from parent classes are currently overwritten by those from child classes if a config property with the same name exists. This prevents the intended hierarchical merging of config values based on themergestrategy defined in their respectiveconfigDescriptors.For example, if
Component.Basedefinesstyle_with amerge: 'shallow'descriptor:style_: { [isDescriptor]: true, merge : 'shallow', value : null },And then
MyComponentextendsComponent.Basewithstatic config = {style: {color: "red"}}, andMyEnhancedComponentextendsMyComponentwithstatic config = {style: {backgroundColor: "blue"}}. The desired outcome is thatMyEnhancedComponent's finalstyleconfig should be{color: "red", backgroundColor: "blue"}due to the inheritedshallowmerge strategy. However, the currentObject.assign(config, cfg)inNeo.setupClasswould simply overwrite thestyleproperty, resulting in{backgroundColor: "blue"}and losing thecolor: "red"fromMyComponent.Describe the solution you'd like The
Neo.setupClassmethod insrc/Neo.mjsshould be modified to perform hierarchical merging ofstatic configvalues based on themergestrategy defined in theirconfigDescriptors. AsNeo.setupClasstraverses the class prototype chain, when merging thestatic config(cfg) of the current class into the accumulatedconfigobject, it should:configDescriptor(which would have been collected from the highest class in the hierarchy that defined it).mergestrategy is defined in the descriptor, apply that strategy usingNeo.mergeConfigto combine the existingconfigvalue with thecfgvalue.mergestrategy is defined, or if the values are not objects (and thusshallow/deepmerges are not applicable), it should default to replacement.This ensures that
static configvalues are merged correctly across the class hierarchy, respecting the definedmergestrategies.Describe alternatives you've considered The current "overwrite" behavior is the alternative, which leads to the described problem. This proposed solution directly addresses the need for hierarchical value merging in
static config.Additional context This change is crucial for the predictability and correctness of how
static configvalues are inherited and combined across the class hierarchy. It allows developers to define complex default configurations that are intelligently merged by subclasses, rather than simply being overwritten. This is distinct from instance-level config merging (handled byBase.mjs#mergeConfig), as this change focuses on the finalstatic configobject thatNeo.setupClassproduces.