{"version":3,"file":"Asset.cjs","names":["<Title attrs={attrs} children={children} />","<HeadElement tag=\"meta\" attrs={attrs} />","tag=\"meta\"","<HeadElement tag=\"link\" attrs={attrs} />","tag=\"link\"","<InlineCssStyle attrs={attrs}>{children}</InlineCssStyle>","<HeadElement tag=\"style\" attrs={attrs} children={children} />","tag=\"style\"","<Script attrs={attrs} children={children} />","<HeadElement\n      tag=\"style\"\n      attrs={{ ...attrs, [INLINE_CSS_HYDRATION_ATTR]: '' }}\n      children={html}\n    />","children={html}","ref={(e) => (el = e)}","<title ref={(e) => (el = e)} {...props.attrs}>\n      {props.children as string}\n    </title>","<script {...attrs} />","innerHTML={children}","<script {...attrs} innerHTML={children} />"],"sources":["../../src/Asset.tsx"],"sourcesContent":["import { isServer } from '@tanstack/router-core/isServer'\nimport { createEffect, onCleanup, onSettled } from 'solid-js'\nimport { useRouter } from './useRouter'\nimport type { RouterManagedTag } from '@tanstack/router-core'\nimport type { JSX } from '@solidjs/web'\n\nconst INLINE_CSS_HYDRATION_ATTR = 'data-tsr-inline-css'\n\nexport function Asset(asset: RouterManagedTag): JSX.Element | null {\n  const { tag, attrs, children } = asset\n\n  switch (tag) {\n    case 'title':\n      return <Title attrs={attrs} children={children} />\n    case 'meta':\n      return <HeadElement tag=\"meta\" attrs={attrs} />\n    case 'link':\n      return <HeadElement tag=\"link\" attrs={attrs} />\n    case 'style':\n      if (\n        asset.inlineCss &&\n        (process.env.TSS_INLINE_CSS_ENABLED === 'true' ||\n          (process.env.TSS_INLINE_CSS_ENABLED === undefined && isServer))\n      ) {\n        return <InlineCssStyle attrs={attrs}>{children}</InlineCssStyle>\n      }\n\n      return <HeadElement tag=\"style\" attrs={attrs} children={children} />\n    case 'script':\n      return <Script attrs={attrs} children={children} />\n    default:\n      return null\n  }\n}\n\n// On the client, relocate a rendered head element into document.head so head\n// tags end up in the right place even when <HeadContent /> is rendered in\n// <body>. The *same* node that Solid rendered/hydrated is moved — never\n// recreated — so the server-rendered node stays claimed (its hydration id is\n// preserved) and stylesheets/scripts are not refetched or re-executed.\n//\n// When <HeadContent /> is placed in <head> (the SSR/hydration case), the node\n// is already in document.head, so this is a no-op and the element is left\n// exactly where Solid hydrated it.\nfunction useRelocateToHead(getEl: () => Node | undefined) {\n  onSettled(() => {\n    const el = getEl()\n    if (el && el.parentNode !== document.head) {\n      document.head.appendChild(el)\n    }\n  })\n\n  onCleanup(() => {\n    const el = getEl()\n    if (el?.parentNode) {\n      el.parentNode.removeChild(el)\n    }\n  })\n}\n\nfunction InlineCssStyle({\n  attrs,\n  children,\n}: {\n  attrs?: Record<string, any>\n  children?: RouterManagedTag['children']\n}) {\n  const isInlineCssPlaceholder = children === undefined\n  const html = isInlineCssPlaceholder\n    ? typeof document === 'undefined'\n      ? ''\n      : (document.querySelector<HTMLStyleElement>(\n          `style[${INLINE_CSS_HYDRATION_ATTR}]`,\n        )?.textContent ?? '')\n    : (children ?? '')\n\n  return (\n    <HeadElement\n      tag=\"style\"\n      attrs={{ ...attrs, [INLINE_CSS_HYDRATION_ATTR]: '' }}\n      children={html}\n    />\n  )\n}\n\ninterface ScriptAttrs {\n  [key: string]: string | boolean | undefined\n  src?: string\n}\n\nfunction HeadElement(props: {\n  tag: 'meta' | 'link' | 'style'\n  attrs?: Record<string, any>\n  children?: unknown\n}): JSX.Element | null {\n  // Each branch must live in its own `case` block so the Solid compiler emits\n  // exactly ONE getNextElement() per invocation. Sequential `if ... return`\n  // statements compile to multiple getNextElement() calls that all execute,\n  // desyncing the hydration key counter (causing \"expected <style>\" mismatches\n  // and unclaimed nodes).\n  //\n  // We capture the element via the JSX return value (a real DOM node in Solid)\n  // rather than a `ref` attribute: a `ref` compiles to a _$ref() call that\n  // interferes with attribute spreading on hydration-claimed nodes (wiping the\n  // SSR attributes).\n  let element: Element\n  switch (props.tag) {\n    case 'style': {\n      const attrs = {\n        ...props.attrs,\n        innerHTML:\n          typeof props.children === 'string' ? props.children : undefined,\n      }\n      element = (<style {...attrs} />) as unknown as Element\n      break\n    }\n    case 'meta':\n      element = (<meta {...props.attrs} />) as unknown as Element\n      break\n    default:\n      element = (<link {...props.attrs} />) as unknown as Element\n  }\n\n  // Move the rendered/hydrated element into <head> when <HeadContent /> is\n  // placed in <body>. No-op when already in <head>. Called unconditionally so\n  // server and client register the same primitives (see Title).\n  useRelocateToHead(() => element)\n\n  return element as unknown as JSX.Element\n}\n\nfunction Title(props: {\n  attrs?: Record<string, any>\n  children?: unknown\n}): JSX.Element | null {\n  let el: HTMLTitleElement | undefined\n\n  // IMPORTANT: call these hooks UNCONDITIONALLY (do not guard with isServer).\n  // Solid's hydration relies on the component body registering the same\n  // reactive primitives in the same order on the server and the client. An\n  // `if (!isServer)` guard would skip them on the server but run them on the\n  // client, desyncing the hydration owner tree and causing the server <title>\n  // to be left unclaimed (and a duplicate appended). These hooks are no-ops\n  // during SSR anyway.\n\n  // Move the rendered/hydrated <title> into <head> when <HeadContent /> is\n  // placed in <body>. No-op when already in <head>.\n  useRelocateToHead(() => el)\n\n  // Keep document.title in sync during client-side navigation.\n  createEffect(\n    () => props.children,\n    (titleText) => {\n      document.title = typeof titleText === 'string' ? titleText : ''\n    },\n  )\n\n  return (\n    <title ref={(e) => (el = e)} {...props.attrs}>\n      {props.children as string}\n    </title>\n  )\n}\n\nfunction Script(props: {\n  attrs?: Record<string, any>\n  children?: unknown\n}): JSX.Element | null {\n  const router = useRouter()\n  const attrs = props.attrs\n  const children = props.children\n\n  const dataScript =\n    typeof attrs?.type === 'string' &&\n    attrs.type !== '' &&\n    attrs.type !== 'text/javascript' &&\n    attrs.type !== 'module'\n\n  // --- Server rendering ---\n  if (isServer ?? router.isServer) {\n    if (attrs?.src) {\n      return <script {...attrs} />\n    }\n\n    if (typeof children === 'string') {\n      return <script {...attrs} innerHTML={children} />\n    }\n\n    return null\n  }\n\n  // --- Client rendering ---\n\n  // Data scripts (e.g. application/ld+json) are rendered in the tree;\n  // they don't need to execute.\n  if (dataScript && typeof children === 'string') {\n    return <script {...attrs} innerHTML={children} />\n  }\n\n  // For executable scripts, use imperative DOM injection so the browser\n  // actually executes them during client-side navigation. The injection is\n  // idempotent (it checks for an already-present matching script), so the\n  // server-rendered script node is reused rather than duplicated.\n  createEffect(\n    () => ({ attrs, children, dataScript }) as const,\n    ({ attrs, children, dataScript }) => {\n      if (dataScript) return\n\n      let script: HTMLScriptElement | undefined\n\n      if (attrs?.src) {\n        const normSrc = (() => {\n          try {\n            const base = document.baseURI || window.location.href\n            return new URL(attrs.src, base).href\n          } catch {\n            return attrs.src\n          }\n        })()\n        const existingScript = Array.from(\n          document.querySelectorAll('script[src]'),\n        ).find((el) => (el as HTMLScriptElement).src === normSrc)\n\n        if (existingScript) {\n          return\n        }\n\n        script = document.createElement('script')\n\n        for (const [key, value] of Object.entries(attrs)) {\n          if (value !== undefined && value !== false) {\n            script.setAttribute(\n              key,\n              typeof value === 'boolean' ? '' : String(value),\n            )\n          }\n        }\n\n        document.head.appendChild(script)\n      } else if (typeof children === 'string') {\n        const typeAttr =\n          typeof attrs?.type === 'string' ? attrs.type : 'text/javascript'\n        const nonceAttr =\n          typeof attrs?.nonce === 'string' ? attrs.nonce : undefined\n        const existingScript = Array.from(\n          document.querySelectorAll('script:not([src])'),\n        ).find((el) => {\n          if (!(el instanceof HTMLScriptElement)) return false\n          const sType = el.getAttribute('type') ?? 'text/javascript'\n          const sNonce = el.getAttribute('nonce') ?? undefined\n          return (\n            el.textContent === children &&\n            sType === typeAttr &&\n            sNonce === nonceAttr\n          )\n        })\n\n        if (existingScript) {\n          return\n        }\n\n        script = document.createElement('script')\n        script.textContent = children\n\n        if (attrs) {\n          for (const [key, value] of Object.entries(attrs)) {\n            if (value !== undefined && value !== false) {\n              script.setAttribute(\n                key,\n                typeof value === 'boolean' ? '' : String(value),\n              )\n            }\n          }\n        }\n\n        document.head.appendChild(script)\n      }\n\n      return () => {\n        if (script?.parentNode) {\n          script.parentNode.removeChild(script)\n        }\n      }\n    },\n  )\n\n  return null\n}\n"],"mappings":"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"}