UNPKG

@redwoodjs/sdk

Version:

A full-stack webapp toolkit designed for TypeScript, Vite, and React Server Components

52 lines (51 loc) 2.4 kB
export const injectHMRPreamble = () => { let headFound = false; const hmrScript = ` <script> import RefreshRuntime from "/@react-refresh" RefreshRuntime.injectIntoGlobalHook(window) window.$RefreshReg$ = () => {} window.$RefreshSig$ = () => (type) => type window.__vite_plugin_react_preamble_installed__ = true </script> `; return new TransformStream({ transform(chunk, controller) { if (!headFound) { const chunkStr = new TextDecoder().decode(chunk); const headMatch = chunkStr.match(/<head[^>]*>/i); if (headMatch) { headFound = true; const index = headMatch.index + headMatch[0].length; const before = chunkStr.slice(0, index); const after = chunkStr.slice(index); const firstScriptMatch = after.match(/<script[^>]*>/i); if (firstScriptMatch) { // Insert before the first script const scriptIndex = firstScriptMatch.index; const beforeScript = after.slice(0, scriptIndex); const afterScript = after.slice(scriptIndex); controller.enqueue(new TextEncoder().encode(before + beforeScript + hmrScript + afterScript)); } else { // If no script tags found, check for </head> const headEndMatch = after.match(/<\/head>/i); if (headEndMatch) { // Insert before </head> const headEndIndex = headEndMatch.index; const beforeHeadEnd = after.slice(0, headEndIndex); const afterHeadEnd = after.slice(headEndIndex); controller.enqueue(new TextEncoder().encode(before + beforeHeadEnd + hmrScript + afterHeadEnd)); } else { // If we haven't found </head> yet, just append after <head> controller.enqueue(new TextEncoder().encode(before + hmrScript + after)); } } return; } } controller.enqueue(chunk); } }); };