import type { Server, ServerWebSocket } from "bun";
import type { RoutesManifest, RouteSpec, HydrationConfig, StaticParamSetSchema } from "../spec/schema";
import type { BundleManifest } from "../bundler/types";
import type { ManduFilling, RenderMode } from "../filling/filling";
import { ManduContext, CookieManager } from "../filling/context";
import { Router } from "./router";
import { renderSSR, resolveAsyncElement } from "./ssr";
import {
resolveMetadata,
renderMetadata,
renderTitle,
type Metadata,
type MetadataItem,
type GenerateMetadata,
} from "../seo";
import { type ErrorFallbackProps } from "./boundary";
import React from "react";
import path from "path";
import fs from "fs/promises";
import { PORTS } from "../constants";
import {
type CacheStore,
type CacheStoreStats,
type CacheConfig,
lookupCache,
createCacheEntry,
createCachedResponse,
computeCacheControl,
getCacheStoreStats,
setGlobalCache,
setGlobalCacheDefaults,
getGlobalCacheDefaults,
createCacheStoreFromConfig,
} from "./cache";
import {
createNotFoundResponse,
createHandlerNotFoundResponse,
createPageLoadErrorResponse,
createSSRErrorResponse,
errorToResponse,
err,
ok,
type Result,
} from "../error";
import {
type CorsOptions,
isPreflightRequest,
handlePreflightRequest,
applyCorsToResponse,
isCorsRequest,
} from "./cors";
import { validateImportPath } from "./security";
import {
createRuntimeDevtoolsAdapter,
recordRuntimeRequest,
shouldRecordRuntimeRequest,
type RuntimeDevtoolsAdapter,
type RuntimeKitchenHandler,
} from "./devtools-adapter";
import {
createRuntimeObservabilityLifecycle,
type RuntimeObservabilityLifecycle,
} from "./observability-lifecycle";
import {
handleOpenAPIRequest,
isOpenAPIEndpointEnabled,
resolveOpenAPIEndpointSettings,
type OpenAPIEndpointSettings,
} from "./openapi-endpoint";
import {
type MiddlewareFn,
type MiddlewareConfig,
loadMiddlewareSync,
} from "./middleware";
import {
buildRequestMiddlewareChain,
runRequestMiddleware,
type ComposedHandler,
} from "./request-middleware";
import type { Middleware } from "../middleware/define";
import {
startRuntimeSchedulerLifecycle,
type RuntimeSchedulerOptions,
} from "./scheduler-lifecycle";
import { createFetchHandler } from "./handler";
import { wrapBunWebSocket, type WSHandlers, type WSUpgradeData } from "../filling/ws";
import { maybeHandleImageFeatureRequest } from "./image-feature";
import {
serveStaticFile,
computeStrongEtag,
computeStaticCacheControl,
matchesEtag,
} from "./static-files";
export { __clearStaticEtagCacheForTests } from "./static-files";
import { extractShellHtml, createPPRResponse } from "./ppr";
import { renderPageResponse, type InlineClientHydrationTarget } from "./page-render-response";
import { isRedirectResponse } from "./redirect";
import { isNotFoundResponse } from "./not-found";
import { newId } from "../id";
// Phase 18.κ — typed RPC dispatch (tRPC-like). See
// `packages/core/src/contract/rpc.ts` + `docs/architect/typed-rpc.md`.
import {
matchRpcPath,
dispatchRpc,
registerRpc,
clearRpcRegistry,
type RpcDefinition,
type RpcProcedureRecord,
} from "../contract/rpc";
import type { GuardConfig } from "../guard/types";
import type { ManduHooks, ManduPlugin } from "../plugins/hooks";
import { handleMetadataRoute as dispatchMetadataRoute } from "../routes/metadata-routes";
import {
DEFAULT_PRERENDER_DIR,
DEFAULT_PRERENDER_CACHE_CONTROL,
loadPrerenderIndex,
resolvePrerenderedFile,
type PrerenderIndex,
} from "../bundler/prerender";
import {
buildOverlayErrorHtml,
buildPayloadFromError,
OVERLAY_CUSTOM_EVENT,
shouldInjectOverlay,
} from "../dev-error-overlay";
// Phase 18.μ — i18n dispatch. `resolveLocale()` is pure (no side effects),
// `createTranslator()` binds a per-request `t()` to the registry.
import {
resolveLocale,
createTranslator,
isI18nDefinition,
isMessageRegistry,
} from "../i18n";
import type {
I18nDefinition,
ResolvedLocale,
Translator,
} from "../i18n/types";
import type { MessageRegistry } from "../i18n/message-registry";
import {
appendRateLimitHeaders,
createRateLimitResponse,
MemoryRateLimiter,
normalizeRateLimitOptions,
type NormalizedRateLimitOptions,
type RateLimitOptions,
} from "./rate-limit";
export {
createRateLimiter,
type RateLimitDecision,
type RateLimitOptions,
} from "./rate-limit";
// ========== Server Options ==========
export interface ServerOptions {
port?: number;
hostname?: string;
/** 프로젝트 루트 디렉토리 */
rootDir?: string;
/** 개발 모드 여부 */
isDev?: boolean;
/** HMR 포트 (개발 모드에서 사용) */
hmrPort?: number;
/** 번들 매니페스트 (Island hydration용) */
bundleManifest?: BundleManifest;
/** Public 디렉토리 경로 (기본: 'public') */
publicDir?: string;
/**
* CORS 설정
* - true: 모든 Origin 허용
* - false: CORS 비활성화 (기본값)
* - CorsOptions: 세부 설정
*/
cors?: boolean | CorsOptions;
/**
* Streaming SSR 활성화
* - true: 모든 페이지에 Streaming SSR 적용
* - false: 기존 renderToString 사용 (기본값)
*/
streaming?: boolean;
/**
* API 라우트 Rate Limit 설정
*/
rateLimit?: boolean | RateLimitOptions;
/**
* CSS 파일 경로 (SSR 링크 주입용)
* - string: 해당 경로로 주입 (예: "/.mandu/client/globals.css")
* - false: CSS 링크 주입 비활성화 (Tailwind 미사용 시)
* - undefined: false로 처리 (404 방지, dev/build에서 명시적 전달 필요)
*/
cssPath?: string | false;
/**
* 커스텀 레지스트리 (핸들러/설정 분리)
* - 제공하지 않으면 기본 전역 레지스트리 사용
* - 테스트나 멀티앱 시나리오에서 createServerRegistry()로 생성한 인스턴스 전달
*/
registry?: ServerRegistry;
/**
* Guard config for Kitchen dev dashboard (dev mode only)
*/
guardConfig?: GuardConfig | null;
/**
* SSR 캐시 설정 (ISR/SWR 용).
*
* Phase 18.ζ — `CacheConfig` 객체를 추가로 지원한다.
* - `true` : 기본 메모리 캐시 (LRU 1000 엔트리)
* - `CacheStore` : 커스텀 캐시 구현체 (e.g. redis 어댑터)
* - `CacheConfig` : `{ defaultMaxAge, defaultSwr, maxEntries, store }`
* 전역 기본값을 설정 — loader 가 `_cache` 를 안 내도
* 자동으로 캐싱됨 (Next.js `export const revalidate` 등가).
* - `false`/undefined : 캐시 비활성화
*/
cache?: boolean | CacheStore | CacheConfig;
/**
* Internal management token for local CLI/runtime control endpoints.
* When set, token-protected endpoints such as `/_mandu/cache` become available.
*/
managementToken?: string;
/**
* Phase 18.κ — override initial `.mandu/client/*` health state when
* starting a dev server.
*/
clientBundleHealthy?: boolean;
/** Optional failure reason surfaced by dev overlay when unhealthy. */
clientBundleFailureReason?: string;
/** Optional route ID associated with the latest client-bundle failure. */
clientBundleFailureRouteId?: string;
/**
* Issue #192 — enable CSS View Transitions auto-inject (default `true`).
* When `true`, every SSR response gets
* `` in its `