{"version":3,"file":"ssr-server.cjs","names":[],"sources":["../../../src/ssr/ssr-server.ts"],"sourcesContent":["import { crossSerializeStream, getCrossReferenceHeader } from 'seroval'\nimport { invariant } from '../invariant'\nimport { decodePath } from '../utils'\nimport { createLRUCache } from '../lru-cache'\nimport { rootRouteId } from '../root'\nimport minifiedTsrBootStrapScript from './tsrScript?script-string'\nimport { GLOBAL_TSR, TSR_SCRIPT_BARRIER_ID } from './constants'\nimport { dehydrateSsrMatchId } from './ssr-match-id'\nimport { defaultSerovalPlugins } from './serializer/seroval-plugins'\nimport { makeSsrSerovalPlugin } from './serializer/transformer'\nimport type { LRUCache } from '../lru-cache'\nimport type { DehydratedMatch, DehydratedRouter } from './types'\nimport type { AnySerializationAdapter } from './serializer/transformer'\nimport type { AnyRouter } from '../router'\nimport type { AnyRouteMatch } from '../Matches'\nimport type { Manifest, RouterManagedTag } from '../manifest'\n\ndeclare module '../router' {\n  interface ServerSsr {\n    setRenderFinished: () => void\n    cleanup: () => void\n  }\n  interface RouterEvents {\n    onInjectedHtml: {\n      type: 'onInjectedHtml'\n    }\n    onSerializationFinished: {\n      type: 'onSerializationFinished'\n    }\n  }\n}\n\nconst SCOPE_ID = 'tsr'\n\nconst TSR_PREFIX = GLOBAL_TSR + '.router='\nconst P_PREFIX = GLOBAL_TSR + '.p(()=>'\nconst P_SUFFIX = ')'\n\nexport function dehydrateMatch(match: AnyRouteMatch): DehydratedMatch {\n  const dehydratedMatch: DehydratedMatch = {\n    i: dehydrateSsrMatchId(match.id),\n    u: match.updatedAt,\n    s: match.status,\n  }\n\n  const properties = [\n    ['__beforeLoadContext', 'b'],\n    ['loaderData', 'l'],\n    ['error', 'e'],\n    ['ssr', 'ssr'],\n  ] as const\n\n  for (const [key, shorthand] of properties) {\n    if (match[key] !== undefined) {\n      dehydratedMatch[shorthand] = match[key]\n    }\n  }\n  if (match.globalNotFound) {\n    dehydratedMatch.g = true\n  }\n  return dehydratedMatch\n}\n\nconst INITIAL_SCRIPTS = [\n  getCrossReferenceHeader(SCOPE_ID),\n  minifiedTsrBootStrapScript,\n]\n\nclass ScriptBuffer {\n  private router: AnyRouter | undefined\n  private _queue: Array<string>\n  private _scriptBarrierLifted = false\n  private _cleanedUp = false\n  private _pendingMicrotask = false\n\n  constructor(router: AnyRouter) {\n    this.router = router\n    // Copy INITIAL_SCRIPTS to avoid mutating the shared array\n    this._queue = INITIAL_SCRIPTS.slice()\n  }\n\n  enqueue(script: string) {\n    if (this._cleanedUp) return\n    this._queue.push(script)\n    // If barrier is lifted, schedule injection (if not already scheduled)\n    if (this._scriptBarrierLifted && !this._pendingMicrotask) {\n      this._pendingMicrotask = true\n      queueMicrotask(() => {\n        this._pendingMicrotask = false\n        this.injectBufferedScripts()\n      })\n    }\n  }\n\n  liftBarrier() {\n    if (this._scriptBarrierLifted || this._cleanedUp) return\n    this._scriptBarrierLifted = true\n    if (this._queue.length > 0 && !this._pendingMicrotask) {\n      this._pendingMicrotask = true\n      queueMicrotask(() => {\n        this._pendingMicrotask = false\n        this.injectBufferedScripts()\n      })\n    }\n  }\n\n  /**\n   * Flushes any pending scripts synchronously.\n   * Call this before emitting onSerializationFinished to ensure all scripts are injected.\n   *\n   * IMPORTANT: Only injects if the barrier has been lifted. Before the barrier is lifted,\n   * scripts should remain in the queue so takeBufferedScripts() can retrieve them\n   */\n  flush() {\n    if (!this._scriptBarrierLifted) return\n    if (this._cleanedUp) return\n    this._pendingMicrotask = false\n    const scriptsToInject = this.takeAll()\n    if (scriptsToInject && this.router?.serverSsr) {\n      this.router.serverSsr.injectScript(scriptsToInject)\n    }\n  }\n\n  takeAll() {\n    const bufferedScripts = this._queue\n    this._queue = []\n    if (bufferedScripts.length === 0) {\n      return undefined\n    }\n    // Optimization: if only one script, avoid join\n    if (bufferedScripts.length === 1) {\n      return bufferedScripts[0] + ';document.currentScript.remove()'\n    }\n    // Append cleanup script and join - avoid push() to not mutate then iterate\n    return bufferedScripts.join(';') + ';document.currentScript.remove()'\n  }\n\n  injectBufferedScripts() {\n    if (this._cleanedUp) return\n    // Early return if queue is empty (avoids unnecessary takeAll() call)\n    if (this._queue.length === 0) return\n    const scriptsToInject = this.takeAll()\n    if (scriptsToInject && this.router?.serverSsr) {\n      this.router.serverSsr.injectScript(scriptsToInject)\n    }\n  }\n\n  cleanup() {\n    this._cleanedUp = true\n    this._queue = []\n    this.router = undefined\n  }\n}\n\nconst isProd = process.env.NODE_ENV === 'production'\n\ntype FilteredRoutes = Manifest['routes']\n\ntype ManifestLRU = LRUCache<string, FilteredRoutes>\n\nconst MANIFEST_CACHE_SIZE = 100\nconst manifestCaches = new WeakMap<Manifest, ManifestLRU>()\n\nfunction getManifestCache(manifest: Manifest): ManifestLRU {\n  const cache = manifestCaches.get(manifest)\n  if (cache) return cache\n  const newCache = createLRUCache<string, FilteredRoutes>(MANIFEST_CACHE_SIZE)\n  manifestCaches.set(manifest, newCache)\n  return newCache\n}\n\nexport function attachRouterServerSsrUtils({\n  router,\n  manifest,\n  getRequestAssets,\n  includeUnmatchedRouteAssets = true,\n}: {\n  router: AnyRouter\n  manifest: Manifest | undefined\n  getRequestAssets?: () => Array<RouterManagedTag> | undefined\n  includeUnmatchedRouteAssets?: boolean\n}) {\n  router.ssr = {\n    get manifest() {\n      const requestAssets = getRequestAssets?.()\n      if (!requestAssets?.length) return manifest\n      // Merge request-scoped assets into root route without mutating cached manifest\n      return {\n        ...manifest,\n        routes: {\n          ...manifest?.routes,\n          [rootRouteId]: {\n            ...manifest?.routes?.[rootRouteId],\n            assets: [\n              ...requestAssets,\n              ...(manifest?.routes?.[rootRouteId]?.assets ?? []),\n            ],\n          },\n        },\n      }\n    },\n  }\n  let _dehydrated = false\n  let _serializationFinished = false\n  const renderFinishedListeners: Array<() => void> = []\n  const serializationFinishedListeners: Array<() => void> = []\n  const scriptBuffer = new ScriptBuffer(router)\n  let injectedHtmlBuffer = ''\n\n  router.serverSsr = {\n    injectHtml: (html: string) => {\n      if (!html) return\n      // Buffer the HTML so it can be retrieved via takeBufferedHtml()\n      injectedHtmlBuffer += html\n      // Emit event to notify subscribers that new HTML is available\n      router.emit({\n        type: 'onInjectedHtml',\n      })\n    },\n    injectScript: (script: string) => {\n      if (!script) return\n      const html = `<script${router.options.ssr?.nonce ? ` nonce='${router.options.ssr.nonce}'` : ''}>${script}</script>`\n      router.serverSsr!.injectHtml(html)\n    },\n    dehydrate: async (opts?: { requestAssets?: Array<RouterManagedTag> }) => {\n      if (_dehydrated) {\n        if (process.env.NODE_ENV !== 'production') {\n          throw new Error('Invariant failed: router is already dehydrated!')\n        }\n\n        invariant()\n      }\n      let matchesToDehydrate = router.stores.matches.get()\n      if (router.isShell()) {\n        // In SPA mode we only want to dehydrate the root match\n        matchesToDehydrate = matchesToDehydrate.slice(0, 1)\n      }\n      const matches = matchesToDehydrate.map(dehydrateMatch)\n\n      let manifestToDehydrate: Manifest | undefined = undefined\n      // For currently matched routes, send full manifest (preloads + assets).\n      // For unmatched routes, include assets only when includeUnmatchedRouteAssets\n      // is true; otherwise omit them entirely. Preloads for unmatched routes are\n      // still excluded because they are handled via dynamic imports.\n      if (manifest) {\n        // Prod-only caching; in dev manifests may be replaced/updated (HMR)\n        const currentRouteIdsList = matchesToDehydrate.map((m) => m.routeId)\n        const manifestCacheKey = `${currentRouteIdsList.join('\\0')}\\0includeUnmatchedRouteAssets=${includeUnmatchedRouteAssets}`\n\n        let filteredRoutes: FilteredRoutes | undefined\n\n        if (isProd) {\n          filteredRoutes = getManifestCache(manifest).get(manifestCacheKey)\n        }\n\n        if (!filteredRoutes) {\n          const currentRouteIds = new Set(currentRouteIdsList)\n          const nextFilteredRoutes: FilteredRoutes = {}\n\n          for (const routeId in manifest.routes) {\n            const routeManifest = manifest.routes[routeId]!\n            if (currentRouteIds.has(routeId)) {\n              nextFilteredRoutes[routeId] = routeManifest\n            } else if (\n              includeUnmatchedRouteAssets &&\n              routeManifest.assets &&\n              routeManifest.assets.length > 0\n            ) {\n              nextFilteredRoutes[routeId] = {\n                assets: routeManifest.assets,\n              }\n            }\n          }\n\n          if (isProd) {\n            getManifestCache(manifest).set(manifestCacheKey, nextFilteredRoutes)\n          }\n\n          filteredRoutes = nextFilteredRoutes\n        }\n\n        manifestToDehydrate = {\n          routes: filteredRoutes,\n        }\n\n        // Merge request-scoped assets into root route (without mutating cached manifest)\n        if (opts?.requestAssets?.length) {\n          const existingRoot = manifestToDehydrate.routes[rootRouteId]\n          manifestToDehydrate.routes[rootRouteId] = {\n            ...existingRoot,\n            assets: [...opts.requestAssets, ...(existingRoot?.assets ?? [])],\n          }\n        }\n      }\n      const dehydratedRouter: DehydratedRouter = {\n        manifest: manifestToDehydrate,\n        matches,\n      }\n      const lastMatchId = matchesToDehydrate[matchesToDehydrate.length - 1]?.id\n      if (lastMatchId) {\n        dehydratedRouter.lastMatchId = dehydrateSsrMatchId(lastMatchId)\n      }\n      const dehydratedData = await router.options.dehydrate?.()\n      if (dehydratedData) {\n        dehydratedRouter.dehydratedData = dehydratedData\n      }\n      _dehydrated = true\n\n      const trackPlugins = { didRun: false }\n      const serializationAdapters = router.options.serializationAdapters as\n        | Array<AnySerializationAdapter>\n        | undefined\n      const plugins = serializationAdapters\n        ? serializationAdapters\n            .map((t) => makeSsrSerovalPlugin(t, trackPlugins))\n            .concat(defaultSerovalPlugins)\n        : defaultSerovalPlugins\n\n      const signalSerializationComplete = () => {\n        _serializationFinished = true\n        try {\n          serializationFinishedListeners.forEach((l) => l())\n          router.emit({ type: 'onSerializationFinished' })\n        } catch (err) {\n          console.error('Serialization listener error:', err)\n        } finally {\n          serializationFinishedListeners.length = 0\n          renderFinishedListeners.length = 0\n        }\n      }\n\n      crossSerializeStream(dehydratedRouter, {\n        refs: new Map(),\n        plugins,\n        onSerialize: (data, initial) => {\n          let serialized = initial ? TSR_PREFIX + data : data\n          if (trackPlugins.didRun) {\n            serialized = P_PREFIX + serialized + P_SUFFIX\n          }\n          scriptBuffer.enqueue(serialized)\n        },\n        onError: (err: unknown) => {\n          console.error('Serialization error:', err)\n          if (err && (err as any).stack) {\n            console.error((err as any).stack)\n          }\n          signalSerializationComplete()\n        },\n        scopeId: SCOPE_ID,\n        onDone: () => {\n          scriptBuffer.enqueue(GLOBAL_TSR + '.e()')\n          // Flush all pending scripts synchronously before signaling completion\n          // This ensures all scripts are injected before onSerializationFinished is emitted\n          scriptBuffer.flush()\n          signalSerializationComplete()\n        },\n      })\n    },\n    isDehydrated() {\n      return _dehydrated\n    },\n    isSerializationFinished() {\n      return _serializationFinished\n    },\n    onRenderFinished: (listener) => renderFinishedListeners.push(listener),\n    onSerializationFinished: (listener) =>\n      serializationFinishedListeners.push(listener),\n    setRenderFinished: () => {\n      // Wrap in try-catch to ensure scriptBuffer.liftBarrier() is always called\n      try {\n        renderFinishedListeners.forEach((l) => l())\n      } catch (err) {\n        console.error('Error in render finished listener:', err)\n      } finally {\n        // Clear listeners after calling them to prevent memory leaks\n        renderFinishedListeners.length = 0\n      }\n      scriptBuffer.liftBarrier()\n    },\n    takeBufferedScripts() {\n      const scripts = scriptBuffer.takeAll()\n      const serverBufferedScript: RouterManagedTag = {\n        tag: 'script',\n        attrs: {\n          nonce: router.options.ssr?.nonce,\n          className: '$tsr',\n          id: TSR_SCRIPT_BARRIER_ID,\n        },\n        children: scripts,\n      }\n      return serverBufferedScript\n    },\n    liftScriptBarrier() {\n      scriptBuffer.liftBarrier()\n    },\n    takeBufferedHtml() {\n      if (!injectedHtmlBuffer) {\n        return undefined\n      }\n      const buffered = injectedHtmlBuffer\n      injectedHtmlBuffer = ''\n      return buffered\n    },\n    cleanup() {\n      // Guard against multiple cleanup calls\n      if (!router.serverSsr) return\n      renderFinishedListeners.length = 0\n      serializationFinishedListeners.length = 0\n      injectedHtmlBuffer = ''\n      scriptBuffer.cleanup()\n      router.serverSsr = undefined\n    },\n  }\n}\n\n/**\n * Get the origin for the request.\n *\n * SECURITY: We intentionally do NOT trust the Origin header for determining\n * the router's origin. The Origin header can be spoofed by attackers, which\n * could lead to SSRF-like vulnerabilities where redirects are constructed\n * using a malicious origin (CVE-2024-34351).\n *\n * Instead, we derive the origin from request.url, which is typically set by\n * the server infrastructure (not client-controlled headers).\n *\n * For applications behind proxies that need to trust forwarded headers,\n * use the router's `origin` option to explicitly configure a trusted origin.\n */\nexport function getOrigin(request: Request) {\n  try {\n    return new URL(request.url).origin\n  } catch {}\n  return 'http://localhost'\n}\n\n// server and browser can decode/encode characters differently in paths and search params.\n// Server generally strictly follows the WHATWG URL Standard, while browsers may differ for legacy reasons.\n// for example, in paths \"|\" is not encoded on the server but is encoded on chromium (and not on firefox) while \"대\" is encoded on both sides.\n// Another anomaly is that in Node new URLSearchParams and new URL also decode/encode characters differently.\n// new URLSearchParams() encodes \"|\" while new URL() does not, and in this instance\n// chromium treats search params differently than paths, i.e. \"|\" is not encoded in search params.\nexport function getNormalizedURL(url: string | URL, base?: string | URL) {\n  // ensure backslashes are encoded correctly in the URL\n  if (typeof url === 'string') url = url.replace('\\\\', '%5C')\n\n  const rawUrl = new URL(url, base)\n  const { path: decodedPathname, handledProtocolRelativeURL } = decodePath(\n    rawUrl.pathname,\n  )\n  const searchParams = new URLSearchParams(rawUrl.search)\n  const normalizedHref =\n    decodedPathname +\n    (searchParams.size > 0 ? '?' : '') +\n    searchParams.toString() +\n    rawUrl.hash\n\n  return {\n    url: new URL(normalizedHref, rawUrl.origin),\n    handledProtocolRelativeURL,\n  }\n}\n"],"mappings":"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"}