Repository navigation
Dars Framework v1.7.7
Release Notes v1.7.7
Component Lifecycle Hooks, Dynamic VRefs & Safer Runtime Updates
Installation
pip install --upgrade dars-frameworkWhat's New
Component Lifecycle Hooks (onMount, onUpdate, onUnmount)
This release introduces component-level lifecycle hooks, available both for regular components and @FunctionComponent:
- New props on components (and FunctionComponents):
onMountonUpdateonUnmount
- Hooks accept
dScript& functions or inline JS strings. - The VDOM now includes a
lifecycleblock per node with:- Hook type (
inline/dscript). - JS code ready to be executed in the runtime.
- Hook type (
Dynamic createComp/deleteComp with Lifecycle and Events
The dynamic backend helpers are now fully compatible with lifecycle, events and VRefs:
-
createComp(target, root, position="append"):- Uses
VDomBuilderto serialize the full component into VDOM. - Injects the
_eventsmap produced by the exporter for that subtree. - In the runtime,
runtime.createComponent(rootId, vdom, pos):- Builds actual DOM from the VDOM.
- Rehydrates events for the whole subtree (
_attachEventsForVNode). - Registers lifecycle in
__lifecycleand firesonMountfor all nodes with hooks. - Calls
DarsHydrate(el)so the rest of bindings (V(), VRefs, useDynamic, etc.) attach to the dynamic subtree as well.
- Uses
-
deleteComp(id):- Calls
runtime.deleteComponent(id). - The runtime runs
onUnmountfor that id before removing the node and its VDOM entry.
- Calls
Result: components created and destroyed with createComp/deleteComp have the same lifecycle behavior and event rehydration as components rendered in the initial VDOM.
onUpdate wired into dynamic changes and VRefs
The onUpdate hook now fires in two key scenarios:
-
Dynamic state changes (runtime
change()):- When
Dars.change({ id, dynamic: true, ... })is called (e.g. viaupdateComp()), the runtime:- Applies changes to
text,html,style,attrs,classes, etc. - Notifies watchers (
watch()/ internals). - Calls
_runLifecycle(id, 'onUpdate')whether the element exists or the change is purely logical.
- Applies changes to
- When
-
VRef changes via
updateVRef():-
New runtime helper:
Dars.updateVRef(selector). -
The JS generated by
updateVRef(...)now, after updating the DOM andwindow.__DARS_VREF_VALUES__, does:if (window.Dars && window.Dars.updateVRef) { window.Dars.updateVRef(selector); }
-
Dars.updateVRef(selector):- Finds all elements matching the selector.
- For each, walks up the DOM tree until it finds the first ancestor with lifecycle registered.
- Runs
onUpdatefor that id (once per id), allowing parent components to react to shared VRef changes.
-
Improved dynamic VRefs (setVRef + updateVRef)
Several adjustments ensure setVRef() works equally well in the initial render and in components created dynamically via createComp:
setVRef(value, selector)now creates aVRefValuewhose metadata is preserved in the VDOM:Text(text=setVRef(0, ".dyn_count"))serializes as:text: "0"(initial value).class: "dyn_count"auto-added when the selector is of type.class.
- The runtime registers
window.__DARS_VREF_VALUES__['.dyn_count'] = 0during hydration.
- This works the same when that
Textis part of a component created withcreateComp: the VDOM includes both the initial value and the class, andupdateVRef(".dyn_count", ...)can find and update all instances correctly.
New equal() helper for expressions with V()
To make it easier to compose numeric and literal expressions with V(), this release adds the equal() helper in dars.hooks.value_helpers:
from dars.hooks.value_helpers import V, equal
# Sumar 1 a un VRef
Button(
"Increment",
on_click=updateVRef(".dyn_count", V(".dyn_count").int() + 1),
)
# Resetear a 0 usando equal()
Button(
"Reset",
on_click=updateVRef(".dyn_count", equal(0)),
)
# Combinar con otra expresión basada en V()
expr = V(".a").int() + equal(V(".b").int())
updateVRef(".result", expr)equal(value)normalizes any value (literal,V(),MathExpression, etc.) into aMathExpression, so it integrates into the operation tree with the same async semantics andNaNvalidation as the rest of the expression system.
Note: to reset a VRef it's better to use
equal(0)directly as the target value instead of adding it to the current value.
Fixes in updateComp() and JS generation
JS generation for updateComp() (dynamic backend) has been hardened so it works correctly with complex expressions containing // comments and async IIFEs such as those generated by updateVRef(...):
- The internal code in
updateComp()now:- No longer collapses whitespace/newlines in the JS payload, avoiding cases where
//comments consume the rest of the line. - Safely strips the trailing
;fromdScript.codebefore inlining it into thechange({ ... })payload.
- No longer collapses whitespace/newlines in the JS payload, avoiding cases where
- This allows
updateComp()to be combined with complex scripts (including those generated byV()/updateVRef) without causingSyntaxErrorinapp.js.
Documentation updates
The hooks and components documentation has been updated to reflect these changes:
LandingPage/documentation/markdown/hooks.md:- Extended Pythonic Value Helpers section with the new
equal()helper and examples together withV()andupdateVRef.
- Extended Pythonic Value Helpers section with the new
LandingPage/documentation/markdown/components.md:- The Runtime Component Manipulation (createComp / deleteComp) and new Component Lifecycle Hooks sections explain that dynamically created subtrees:
- Rehydrate events.
- Register and execute lifecycle hooks (
onMount/onUpdate/onUnmount). - Are compatible with VRefs and the current VDOM system.
- The Runtime Component Manipulation (createComp / deleteComp) and new Component Lifecycle Hooks sections explain that dynamically created subtrees: