{
  "version": 3,
  "sources": ["../src/index.ts"],
  "sourcesContent": ["import type { EntryContext } from '@remix-run/server-runtime';\nimport type { ComponentType } from 'react';\nimport { createElement, useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { RemixServer } from '@remix-run/react';\nimport { renderToString } from 'react-dom/server';\n\ntype HeadComponent = ComponentType<{\n  __remix_island_render_server?: boolean;\n}> & {\n  __remix_island_id?: string;\n};\n\nlet globalMounted = false;\nexport interface CreateHeadOpts {\n  id?: string;\n  cleanup?: boolean;\n}\nexport function createHead(\n  Comp: ComponentType,\n  { id = 'remix-island', cleanup = true }: CreateHeadOpts = {},\n): HeadComponent {\n  const Head: HeadComponent = (props) => {\n    const [mounted, setMounted] = useState(globalMounted);\n    useEffect(() => {\n      if (cleanup) {\n        removeOldHead(Head);\n      }\n      globalMounted = true;\n      setMounted(true);\n    }, []);\n\n    if (!mounted && props.__remix_island_render_server) {\n      return createElement(Comp);\n    }\n\n    if (mounted) {\n      return createPortal(createElement(Comp), document.head);\n    }\n\n    return null;\n  };\n\n  Head.displayName = 'RemixIslandHead';\n  Head.__remix_island_id = id;\n\n  return Head;\n}\n\nexport interface RenderHeadToStringOpts {\n  request: Request;\n  remixContext: EntryContext;\n  Head: HeadComponent;\n}\n\nexport function renderHeadToString({\n  request,\n  remixContext,\n  Head,\n}: RenderHeadToStringOpts) {\n  const head = renderToString(\n    createElement(RemixServer, {\n      context: switchRootComponent(remixContext, Head),\n      url: request.url,\n    }),\n  );\n  const id = Head.__remix_island_id;\n  return `<!--${id}-start-->${head}<!--${id}-end-->`;\n}\n\nexport function switchRootComponent(\n  remixContext: EntryContext,\n  Head: HeadComponent,\n): EntryContext {\n  let serverHandoffString = remixContext.serverHandoffString;\n  if (serverHandoffString) {\n    const serverHandoff = JSON.parse(serverHandoffString);\n    // remove errors from JSON string\n    delete serverHandoff?.state?.errors;\n    serverHandoffString = JSON.stringify(serverHandoff);\n  }\n\n  const { Layout, ...rootModuleWithoutLayout } =\n    remixContext.routeModules.root!;\n\n  return {\n    ...remixContext,\n    serverHandoffString,\n    staticHandlerContext: {\n      ...remixContext.staticHandlerContext,\n      errors: null, // remove errors from context\n    },\n    routeModules: {\n      ...remixContext.routeModules,\n      root: {\n        ...rootModuleWithoutLayout,\n        default: () =>\n          createElement(Head, { __remix_island_render_server: true }),\n      },\n    },\n  };\n}\n\nexport function removeOldHead(\n  Head: HeadComponent,\n  parent: HTMLElement = document.head,\n) {\n  let foundOldHeader = false;\n  const nodesToRemove: ChildNode[] = [];\n  const id = Head.__remix_island_id;\n  for (const node of parent.childNodes) {\n    if (!foundOldHeader && node.nodeName !== '#comment') {\n      continue;\n    }\n    if (\n      foundOldHeader &&\n      node.nodeName === '#comment' &&\n      node.nodeValue === `${id}-end`\n    ) {\n      nodesToRemove.push(node);\n      break;\n    }\n    if (\n      foundOldHeader ||\n      (node.nodeName === '#comment' && node.nodeValue === `${id}-start`)\n    ) {\n      foundOldHeader = true;\n      nodesToRemove.push(node);\n    }\n  }\n  for (const node of nodesToRemove) {\n    node.remove();\n  }\n}\n"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAmD;AACnD,uBAA6B;AAC7B,IAAAA,gBAA4B;AAC5B,oBAA+B;AAQ/B,IAAI,gBAAgB;AAKb,SAAS,WACd,MACA,EAAE,KAAK,gBAAgB,UAAU,KAAK,IAAoB,CAAC,GAC5C;AACf,QAAM,OAAsB,CAAC,UAAU;AACrC,UAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,aAAa;AACpD,gCAAU,MAAM;AACd,UAAI,SAAS;AACX,sBAAc,IAAI;AAAA,MACpB;AACA,sBAAgB;AAChB,iBAAW,IAAI;AAAA,IACjB,GAAG,CAAC,CAAC;AAEL,QAAI,CAAC,WAAW,MAAM,8BAA8B;AAClD,iBAAO,4BAAc,IAAI;AAAA,IAC3B;AAEA,QAAI,SAAS;AACX,iBAAO,mCAAa,4BAAc,IAAI,GAAG,SAAS,IAAI;AAAA,IACxD;AAEA,WAAO;AAAA,EACT;AAEA,OAAK,cAAc;AACnB,OAAK,oBAAoB;AAEzB,SAAO;AACT;AAQO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,WAAO;AAAA,QACX,4BAAc,2BAAa;AAAA,MACzB,SAAS,oBAAoB,cAAc,IAAI;AAAA,MAC/C,KAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AACA,QAAM,KAAK,KAAK;AAChB,SAAO,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE;AAC3C;AAEO,SAAS,oBACd,cACA,MACc;AAzEhB;AA0EE,MAAI,sBAAsB,aAAa;AACvC,MAAI,qBAAqB;AACvB,UAAM,gBAAgB,KAAK,MAAM,mBAAmB;AAEpD,UAAO,+CAAe,UAAtB,wBAA6B;AAC7B,0BAAsB,KAAK,UAAU,aAAa;AAAA,EACpD;AAEA,QACE,kBAAa,aAAa,MADpB,SAlFV,IAmFI,IADiB,oCACjB,IADiB,CAAX;AAGR,SAAO,iCACF,eADE;AAAA,IAEL;AAAA,IACA,sBAAsB,iCACjB,aAAa,uBADI;AAAA,MAEpB,QAAQ;AAAA;AAAA,IACV;AAAA,IACA,cAAc,iCACT,aAAa,eADJ;AAAA,MAEZ,MAAM,iCACD,0BADC;AAAA,QAEJ,SAAS,UACP,4BAAc,MAAM,EAAE,8BAA8B,KAAK,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,cACd,MACA,SAAsB,SAAS,MAC/B;AACA,MAAI,iBAAiB;AACrB,QAAM,gBAA6B,CAAC;AACpC,QAAM,KAAK,KAAK;AAChB,aAAW,QAAQ,OAAO,YAAY;AACpC,QAAI,CAAC,kBAAkB,KAAK,aAAa,YAAY;AACnD;AAAA,IACF;AACA,QACE,kBACA,KAAK,aAAa,cAClB,KAAK,cAAc,GAAG,EAAE,QACxB;AACA,oBAAc,KAAK,IAAI;AACvB;AAAA,IACF;AACA,QACE,kBACC,KAAK,aAAa,cAAc,KAAK,cAAc,GAAG,EAAE,UACzD;AACA,uBAAiB;AACjB,oBAAc,KAAK,IAAI;AAAA,IACzB;AAAA,EACF;AACA,aAAW,QAAQ,eAAe;AAChC,SAAK,OAAO;AAAA,EACd;AACF;",
  "names": ["import_react"]
}
