A race condition exists in src/mixin/VdomLifecycle.mjs where child components can trigger VDOM updates concurrently with their parent's initialization phase (initVnode).
The Issue:
initVnode sets me.isVdomUpdating = true but fails to register the update with the global VDomUpdate manager.
- Consequently, the hierarchical safeguard
isParentUpdating fails for child components because VDomUpdate.getInFlightUpdateDepth(parent.id) returns undefined.
- Additionally,
me.isVdomUpdating is set to false prematurely in initVnode, before the component is mounted and the update promise is resolved.
Symptoms:
- Child components triggering updates (e.g., via
vnodeInitialized hooks) collide with the parent's ongoing initialization.
- This can lead to state desynchronization with the VDOM worker, resulting in duplicate DOM insertions (as seen in
Panel components duplicating headers/bodies).
Proposed Fix:
- Register In-Flight Update:
initVnode must call VDomUpdate.registerInFlightUpdate(me.id, -1) to formally lock the tree.
- Centralize Cleanup: Move
me.isVdomUpdating = false into resolveVdomUpdate to ensure the flag remains true until the entire transaction (including callbacks and mounting) is complete.
- Refactor: Update
executeVdomUpdate to rely on resolveVdomUpdate for clearing the flag, ensuring consistency.
A race condition exists in
src/mixin/VdomLifecycle.mjswhere child components can trigger VDOM updates concurrently with their parent's initialization phase (initVnode).The Issue:
initVnodesetsme.isVdomUpdating = truebut fails to register the update with the globalVDomUpdatemanager.isParentUpdatingfails for child components becauseVDomUpdate.getInFlightUpdateDepth(parent.id)returnsundefined.me.isVdomUpdatingis set tofalseprematurely ininitVnode, before the component is mounted and the update promise is resolved.Symptoms:
vnodeInitializedhooks) collide with the parent's ongoing initialization.Panelcomponents duplicating headers/bodies).Proposed Fix:
initVnodemust callVDomUpdate.registerInFlightUpdate(me.id, -1)to formally lock the tree.me.isVdomUpdating = falseintoresolveVdomUpdateto ensure the flag remains true until the entire transaction (including callbacks and mounting) is complete.executeVdomUpdateto rely onresolveVdomUpdatefor clearing the flag, ensuring consistency.