UNPKG

alien-dom

Version:

Next-generation JSX client renderer with observable data primitives, immediate DOM references, and more.

77 lines (74 loc) 2.58 kB
import { definePrivateSymbol, setComponentRenderHook, hasPrivate, getPrivate, kAlienRenderFunc, setPrivate, isArray, isFunction, ref, depsHaveChanged, attachRef } from './chunk-JH7ONIU5.mjs'; // hmr.ts var kAlienComponentKey = definePrivateSymbol("componentKey"); var componentRegistry = {}; var usedBeforeRegister = /* @__PURE__ */ new WeakSet(); function hmrRegister(key, tag, hash, deps) { if (usedBeforeRegister.has(tag)) { const name = tag.displayName || tag.name || "<anonymous>"; return console.error( `[HMR] Component "${name}" cannot be immediately used within the same module it was defined in. Either use "queueMicrotask" or import the component from another module.` ); } let [renderRef, oldHash, oldDeps] = componentRegistry[key] || []; const needsUpdateCheck = renderRef != null; renderRef ||= ref(tag); const componentData = [renderRef, hash, deps]; queueMicrotask(() => { componentData[2] = deps = deps.map( (dep) => dep && (getPrivate(dep, kAlienComponentKey) ?? dep) ); if (needsUpdateCheck) { const needsHotUpdate = oldHash != null && oldHash !== hash || oldDeps != null && depsHaveChanged(deps, oldDeps); if (needsHotUpdate) { renderRef.value = tag; } } }); setPrivate(tag, kAlienComponentKey, key); componentRegistry[key] = componentData; attachRef(tag, kAlienRenderFunc, renderRef); } setComponentRenderHook((component) => { if (!hasPrivate(component.tag, kAlienComponentKey)) { usedBeforeRegister.add(component.tag); return component.tag; } const render = getPrivate(component.tag, kAlienRenderFunc); const prevRender = getPrivate(component, kAlienRenderFunc); let isHotUpdate; if (render !== prevRender) { setPrivate(component, kAlienRenderFunc, render); if (prevRender) { isHotUpdate = true; component.memos?.forEach((memo, key, memos) => { if (memo && memo.constructor.name === "NestedTag") return; memos.delete(key); }); component.hooks.forEach((hook, index, hooks) => { if (hook?.dispose) { if (isArray(hook.deps) && !hook.deps.length) { return; } if (isFunction(hook.dispose)) { hook.dispose({ isHotReload: true }); } hooks[index] = void 0; } }); } } return (props) => { try { return render(props); } catch (e) { if (isHotUpdate) { component.truncate(0); component.scheduleUpdate(); } throw e; } }; }); export { hmrRegister };