import type { AppInternals } from "./app.js"; import type { VextServerHandle } from "../types/adapter.js"; import type { VextApp } from "../types/app.js"; /** * bootstrap — 框架完整启动编排(Phase 1) * * 启动流程(步骤 0 ~ ⑨): * * 0. config-loader:加载 default → env → local 三层配置 + deepFreeze * ① createApp(config):创建 app + internals(logger / throw / validator / adapter) * ①+ i18n 语言包自动加载:src/locales/ 存在时通过 schemaAdapter.configure 注册 * ② plugin-loader:扫描 src/plugins/,拓扑排序 + setup()(app.use() 可用窗口) * ③ middleware-loader:按 config.middlewares 白名单加载路由级中间件定义 * ④ service-loader:扫描 src/services/,实例化注入 app.services * ⑤ router-loader:扫描 src/routes/,注册路由到 adapter * ⑤+ lockUse():锁定 app.use(),后续调用抛错 * ⑥ 注册内置中间件(requestId → cors → body-parser → rate-limit → response-wrapper) * + 注册插件全局中间件(app.use() 收集的) * + 注册错误处理 + 404 兜底 * ⑦ HTTP 开始监听(adapter.listen) * ⑧ 注册信号处理(SIGTERM / SIGINT → shutdown) * ⑨ 执行 onReady 钩子 + 打印启动日志 * * 错误边界: * 启动过程中任何步骤抛出异常,都会尝试清理已分配的资源: * - 如果 server 已绑定端口 → serverHandle.close() * - 如果 internals 已创建 → internals.shutdown()(执行 onClose hooks) * - 重新抛出错误,由外层 .catch() 处理 * * 注意:内置中间件(requestId / cors / body-parser / rate-limit / response-wrapper) * 在步骤⑥通过 adapter.registerMiddleware() 注册,而非 app.use()。 * 这些中间件在所有路由之前执行(adapter 层保证顺序)。 * 插件通过 app.use() 注册的全局中间件也在步骤⑥注册到 adapter。 * * @param rootDir 用户项目根目录(包含 src/ 的目录) * @returns 启动后的资源句柄(用于测试或 cluster Worker) * * @see 06-built-ins.md §4(createApp 内部概览 + bootstrap 完整调用顺序) * @see 09-cli.md §5(bootstrap.ts 框架内部启动文件) * @see IMPLEMENTATION-PLAN.md 任务 1.15 */ export declare function bootstrap(rootDir?: string): Promise; /** * bootstrap 返回结果 * * 包含启动后的资源引用,主要用于: * - 测试中关闭服务器(serverHandle.close()) * - 访问 app 实例进行断言 * - Cluster Worker 需要 app/internals 引用 * - 手动触发 shutdown(如集成测试收尾) */ export interface BootstrapResult { app: VextApp; serverHandle: VextServerHandle; internals: AppInternals; } /** * startClusterMaster — 启动 Cluster Master 进程 * * 创建 ClusterMaster 实例并调用 start()。 * Master 不执行 bootstrap,只负责 fork 和管理 Worker 进程。 * * 配置读取: * 从 config-loader 加载配置,提取 cluster 部分传给 ClusterMaster。 * 同时将 rootDir 和构建标志通过 cluster.setupPrimary() 传递给 Worker。 * * @param rootDir 用户项目根目录 */ export declare function applyClusterWorkerEnv(args: { rootDir: string; workerCount: number; providerPatch?: unknown; port: number; host?: string; isBuilt: boolean; clusterConfig?: Record; }): void;