UNPKG

rynex

Version:

A minimalist TypeScript framework for building reactive web applications with no virtual DOM

133 lines 3.92 kB
/** * Rynex Lifecycle Hooks * Component lifecycle management */ import { effect } from '../state.js'; /** * Component mount lifecycle hook * Executes callback when element is mounted to DOM */ export function onMount(element, callback) { const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node === element || node.contains?.(element)) { const cleanup = callback(); if (cleanup && typeof cleanup === 'function') { element.dataset.cleanup = 'registered'; element.__cleanup = cleanup; } observer.disconnect(); } }); } } }); observer.observe(document.body, { childList: true, subtree: true }); // Check if already mounted if (document.body.contains(element)) { const cleanup = callback(); if (cleanup && typeof cleanup === 'function') { element.dataset.cleanup = 'registered'; element.__cleanup = cleanup; } observer.disconnect(); } } /** * Component unmount lifecycle hook * Executes callback when element is removed from DOM */ export function onUnmount(element, callback) { const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.type === 'childList') { mutation.removedNodes.forEach((node) => { if (node === element || node.contains?.(element)) { callback(); observer.disconnect(); } }); } } }); observer.observe(document.body, { childList: true, subtree: true }); } /** * Component update lifecycle hook * Executes callback when element attributes or children change */ export function onUpdate(element, callback) { const observer = new MutationObserver((mutations) => { callback(mutations); }); observer.observe(element, { attributes: true, childList: true, subtree: true, characterData: true }); return () => observer.disconnect(); } /** * Watch a reactive value and execute callback when it changes * Returns cleanup function */ export function watch(getter, callback, options) { let oldValue = getter(); if (options?.immediate) { callback(oldValue, oldValue); } const cleanup = effect(() => { const newValue = getter(); if (newValue !== oldValue) { callback(newValue, oldValue); oldValue = newValue; } }); return cleanup; } /** * Watch effect - runs effect immediately and re-runs when dependencies change * Similar to effect but with explicit cleanup handling */ export function watchEffect(effectFn) { let cleanup; const wrappedEffect = () => { if (cleanup) { cleanup(); } cleanup = effectFn(); }; const stopEffect = effect(wrappedEffect); return () => { if (cleanup) { cleanup(); } stopEffect(); }; } /** * On error handler for component errors * Catches and handles errors within a component tree */ export function onError(element, handler) { const errorHandler = (event) => { if (element.contains(event.target)) { event.preventDefault(); handler(event.error || new Error(event.message)); } }; window.addEventListener('error', errorHandler); onUnmount(element, () => { window.removeEventListener('error', errorHandler); }); } //# sourceMappingURL=lifecycle.js.map