/** * Phase 18.α — Dev Error Overlay client IIFE. * * This file EXPORTS a string (`OVERLAY_CLIENT_SCRIPT`) that is inlined * into the SSR `
` by the injector. It is NOT compiled as a * module; the whole body runs in parse order on every dev page load. * * Size target: < 10 KB gzipped (current ≈ 2 KB gz). No dependencies. * Only touches `window`, `document`, `navigator.clipboard`, and a tiny * WeakSet. * * Listeners installed: * - `window.onerror` → uncaught script errors * - `unhandledrejection` → Promise rejections * - custom event `__MANDU_ERROR__` → the server embeds a 500 payload * in the HTML, fires this event on DOMContentLoaded, and the * overlay picks it up. User code can also `dispatchEvent` it to * surface synthetic errors. * * Everything scoped in an IIFE — NO globals leak except the single * `__MANDU_OVERLAY_MOUNTED__` sentinel that prevents double-mount on * HMR. */ import { OVERLAY_STYLES } from "./overlay-styles"; import { OVERLAY_CUSTOM_EVENT, OVERLAY_MOUNTED_FLAG, OVERLAY_PAYLOAD_ELEMENT_ID, } from "./types"; /** * Build the client-side IIFE body as a string. Parameterised by the * style block and the two sentinel names so tests can verify the exact * shape without re-declaring the constants. */ function buildOverlayClientScript(): string { // The IIFE below references the constants through string interpolation, // NOT through imports — because it runs in the browser and has no // module loader. return `(function(){ var MOUNTED=${JSON.stringify(OVERLAY_MOUNTED_FLAG)}; var EVT=${JSON.stringify(OVERLAY_CUSTOM_EVENT)}; var PAYLOAD_ID=${JSON.stringify(OVERLAY_PAYLOAD_ELEMENT_ID)}; if(typeof window==="undefined"||typeof document==="undefined")return; if(window[MOUNTED]===true)return; window[MOUNTED]=true; var STYLE=${JSON.stringify(OVERLAY_STYLES)}; var seen=new WeakSet(); function parseFrames(stack){ if(typeof stack!=="string"||stack.length===0)return []; var lines=stack.split("\\n"); var out=[]; for(var i=0;i