Big Brother is Watching
In Topic 6, we saw that Lego.init() sets up a "watchdog." Now, let's look at exactly how that watchdog functions. This is what makes LegoDOM feel "automatic"—you can inject HTML into the page using vanilla JavaScript, and Lego will instantly recognize it and bring it to life.
Mutation Observer
The MutationObserver is a built-in browser API that provides the ability to watch for changes being made to the DOM tree. In this library, it acts as the "Event Loop" for block lifecycles.
1. The Configuration
LegoDOM observes the document.body with specific settings:
observer.observe(document.body, { childList: true, subtree: true });childList: true: Tells the observer to watch for elements being added or removed.subtree: true: This is vital. Without this, LegoDOM would only see things added directly to the<body>. With it, LegoDOM sees changes happening deep inside nested divs or other blocks.
2. Processing addedNodes
Whenever a new piece of HTML is injected (via innerHTML, appendChild, etc.), the observer receives a list of addedNodes.
Filter: LegoDOM checks
n.nodeType === Node.ELEMENT_NODEto ensure it is an Element (like a<div>or<my-comp>) and not just a fragment of text.The Action: It calls
snap(n). This triggers the entire initialization process: attaching the Shadow DOM, creating reactive state, and rendering the template.Auto-Discovery (v2.0): If
snap(n)doesn't find a template in the registry, the observer now checksLego.config.loader. If configured, it pauses to fetch the block definition from the server.
3. Processing removedNodes
When an element is deleted from the page, the observer catches it in removedNodes.
Cleanup: It calls
unsnap(n).Lifecycle Hook:
unsnapchecks the block's state for anunmountedfunction. This allows you to perform cleanup, like stopping timers or closing WebSocket connections, preventing memory leaks.
Why this is superior to manual initialization
In most frameworks, you have to tell LegoDOM when you’ve changed the page (e.g., calling root.render()). This library turns that upside down by using the browser's native MutationObserver to watch the DOM and react automatically. Unlike some libraries where adding a button via innerHTML requires a manual "re-scan" or "re-bind" call, this setup makes LegoDOM reactive to the DOM itself: the moment a tag like <user-card> appears in the document, it is automatically detected and upgraded into a functional, living block.
1. The Strategy: "Observe Once, Act Everywhere"
LegoDOM sets up a single observer on document.body.
childList: true: This tells the observer to watch for the addition or removal of direct children.subtree: true: This is the "secret sauce." It extends the observation to the entire DOM tree. If you have a deeply nesteddivand you inject a Lego block into it, the observer will see it.
2. The Logic Loop: Added Nodes
When the observer detects changes, it provides a list of MutationRecord objects. LegoDOM loops through these records specifically looking for addedNodes.
Type Filtering: It checks
n.nodeType === Node.ELEMENT_NODE. This ensures LegoDOM ignores text changes or comments and only focuses on Elements (tags).The Upgrade (Snapping): For every new element found, it calls
snap(n). This is why you can dodocument.body.innerHTML += '<my-counter></my-counter>'in the console, and the counter will immediately start working.
3. The Logic Loop: Removed Nodes
This is equally important for "garbage collection." When an element is deleted, it appears in removedNodes.
The
unsnapTrigger: LegoDOM callsunsnap(n).Lifecycle Cleanup: Inside
unsnap, LegoDOM looks for a developer-definedunmountedfunction. This is where you'd killsetIntervaltimers or close database connections. Without this, your app would suffer from "Memory Leaks"—processes that keep running even though the block is gone.