{"version":3,"file":"serve.js","names":[],"sources":["esm/serve.js"],"sourcesContent":["import FSExtra from \"fs-extra\";\nimport { setServerGlobals } from \"./server/setServerGlobals\";\nimport { setServerWebSocket } from \"./server/setServerWebSocket\";\nimport { setupBuildInfo } from \"./server/setupBuildOptions\";\nimport { ensureExists } from \"./utils/ensureExists\";\nimport { resolveServeOutDir } from \"./utils/buildOutputPointer\";\nimport {\n  formatErrorSafely,\n  installPrepareStackTraceGuard\n} from \"./cli/install-error-handlers\";\ninstallPrepareStackTraceGuard();\nprocess.on(\"uncaughtException\", (err) => {\n  try {\n    process.stderr.write(`[one serve] uncaught exception\n${formatErrorSafely(err)}\n`);\n  } catch {\n  }\n});\nprocess.on(\"unhandledRejection\", (reason) => {\n  try {\n    process.stderr.write(\n      `[one serve] unhandled rejection\n${formatErrorSafely(reason)}\n`\n    );\n  } catch {\n  }\n});\nasync function serve(args = {}) {\n  if (args.cluster) {\n    const { cpus, platform } = await import(\"node:os\");\n    const numWorkers = typeof args.cluster === \"number\" ? args.cluster : cpus().length;\n    const isBun = typeof process.versions.bun !== \"undefined\";\n    const canReusePort = ![\"win32\", \"darwin\"].includes(platform()) && (isBun || (() => {\n      const [major, minor] = process.versions.node.split(\".\").map(Number);\n      return major > 22 || major === 22 && minor >= 12 || major >= 23;\n    })());\n    if (canReusePort) {\n      return await serveWithReusePort(args, numWorkers);\n    } else if (!isBun) {\n      return await serveWithCluster(args, numWorkers);\n    } else {\n      console.warn(\n        `[one] cluster mode not supported on ${platform()} with bun, running single process`\n      );\n      return await startWorker(args);\n    }\n  }\n  return await startWorker(args);\n}\nasync function serveWithReusePort(args, numWorkers) {\n  const { fork } = await import(\"node:child_process\");\n  console.info(`[one] cluster: starting ${numWorkers} workers (SO_REUSEPORT)`);\n  const workers = [];\n  let recentCrashes = 0;\n  let lastCrashTime = 0;\n  function spawnWorker() {\n    const child = fork(\n      process.argv[1],\n      process.argv.slice(2).filter((a) => !a.startsWith(\"--cluster\")),\n      {\n        env: { ...process.env, ONE_CLUSTER_WORKER: \"1\" },\n        stdio: \"inherit\"\n      }\n    );\n    workers.push(child);\n    child.on(\"exit\", (code, signal) => {\n      const idx = workers.indexOf(child);\n      if (idx >= 0) workers.splice(idx, 1);\n      if (code === 0 || signal === \"SIGTERM\" || signal === \"SIGINT\") return;\n      const now = Date.now();\n      if (now - lastCrashTime < 5e3) {\n        recentCrashes++;\n      } else {\n        recentCrashes = 1;\n      }\n      lastCrashTime = now;\n      if (recentCrashes > numWorkers * 2) {\n        console.error(`[one] too many worker crashes, stopping`);\n        process.exit(1);\n      }\n      console.error(\n        `[one] worker ${child.pid} died (code ${code}, signal ${signal}), restarting`\n      );\n      setTimeout(spawnWorker, Math.min(recentCrashes * 500, 5e3));\n    });\n  }\n  for (let i = 0; i < numWorkers; i++) {\n    spawnWorker();\n  }\n  const shutdown = () => {\n    for (const w of workers) {\n      w.kill(\"SIGTERM\");\n    }\n    setTimeout(() => process.exit(0), 5e3);\n  };\n  process.on(\"SIGINT\", shutdown);\n  process.on(\"SIGTERM\", shutdown);\n  await new Promise(() => {\n  });\n}\nasync function serveWithCluster(args, numWorkers) {\n  const cluster = await import(\"node:cluster\");\n  if (cluster.default.isPrimary) {\n    console.info(`[one] cluster: starting ${numWorkers} workers (IPC)`);\n    for (let i = 0; i < numWorkers; i++) {\n      cluster.default.fork();\n    }\n    let recentCrashes = 0;\n    let lastCrashTime = 0;\n    cluster.default.on(\"exit\", (worker, code, signal) => {\n      if (code === 0 || signal === \"SIGTERM\" || signal === \"SIGINT\") return;\n      const now = Date.now();\n      if (now - lastCrashTime < 5e3) {\n        recentCrashes++;\n      } else {\n        recentCrashes = 1;\n      }\n      lastCrashTime = now;\n      if (recentCrashes > numWorkers * 2) {\n        console.error(`[one] too many worker crashes, stopping`);\n        process.exit(1);\n      }\n      console.error(\n        `[one] worker ${worker.process.pid} died (code ${code}, signal ${signal}), restarting`\n      );\n      setTimeout(() => cluster.default.fork(), Math.min(recentCrashes * 500, 5e3));\n    });\n    const shutdown = () => {\n      for (const id in cluster.default.workers) {\n        cluster.default.workers[id]?.process.kill(\"SIGTERM\");\n      }\n      setTimeout(() => process.exit(0), 5e3);\n    };\n    process.on(\"SIGINT\", shutdown);\n    process.on(\"SIGTERM\", shutdown);\n    return;\n  }\n  return await startWorker(args);\n}\nasync function startWorker(args) {\n  const outDir = await resolveServeOutDir(args?.outDir);\n  const buildInfo = await FSExtra.readJSON(`${outDir}/buildInfo.json`);\n  const { oneOptions } = buildInfo;\n  setServerGlobals();\n  setServerWebSocket();\n  setupBuildInfo(buildInfo);\n  ensureExists(oneOptions);\n  const { labelProcess } = await import(\"./cli/label-process\");\n  const { removeUndefined } = await import(\"./utils/removeUndefined\");\n  const {\n    loadEnv,\n    serve: vxrnServe,\n    serveStaticAssets,\n    compileCacheRules\n  } = await import(\"vxrn/serve\");\n  const { oneServe } = await import(\"./server/oneServe\");\n  labelProcess(\"serve\");\n  if (args?.loadEnv) {\n    await loadEnv(\"production\");\n  }\n  const cacheRules = oneOptions.server?.cacheControl ? compileCacheRules(oneOptions.server.cacheControl) : void 0;\n  return await vxrnServe({\n    outDir: buildInfo.outDir || outDir,\n    app: args?.app,\n    ...oneOptions.server,\n    ...removeUndefined({\n      port: args?.port ? +args.port : void 0,\n      host: args?.host,\n      compress: args?.compress\n    }),\n    async beforeRegisterRoutes(options, app) {\n      await oneServe(oneOptions, buildInfo, app, {\n        serveStaticAssets: (ctx) => serveStaticAssets({ ...ctx, cacheRules })\n      });\n    },\n    async afterRegisterRoutes(options, app) {\n    }\n  });\n}\nexport {\n  serve\n};\n//# sourceMappingURL=serve.js.map\n"],"mappings":"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"}