/** * model-reloader.ts — 选择性 Model 定义重载(monSQLize 热重载集成) * * Soft Reload 时只重新加载 invalidation set 中包含的 model 定义文件, * 其他 model 定义保持不变。使用 monSQLize v1.1.8 原生 Model.redefine() API。 * * 核心流程: * * 1. 扫描 outDir/models/ 下所有 .js 文件 * 2. 筛选出在 invalidation set 中的文件(需要重载的) * 3. 保存受影响 model 的旧定义(用于回滚) * 4. 逐个 require() 新编译产物,调用 Model.redefine() 更新定义 * 5. 如果任何步骤失败,回滚所有受影响的 model 到旧定义 * * 安全保证: * * | 场景 | 行为 | * |-------------------------------|---------------------------------------------------| * | model 文件不在失效集合中 | 完全不触碰,定义保持不变 | * | require() 新模块失败 | 回滚所有受影响 model 到旧定义,向上抛出错误 | * | Model.redefine() 失败 | 回滚所有受影响 model 到旧定义,向上抛出错误 | * | 嵌套目录(admin/role) | 正确映射为 AdminRole(复用 deriveModelName) | * | 无 models/ 目录 | 静默跳过,返回空结果 | * * @module lib/dev/model-reloader * @see model-loader.ts(初始加载逻辑,deriveModelName 复用) * @see service-reloader.ts(设计模式参考) */ /** * 最小化的 VextApp 接口(仅包含 model-reloader 需要的字段) * * 使用局部接口避免对完整 VextApp 类型的直接依赖, * 便于单元测试中构造 mock 对象。 */ export interface ModelReloaderApp { logger: { info(...args: unknown[]): void; warn(...args: unknown[]): void; debug(...args: unknown[]): void; error(...args: unknown[]): void; }; } /** * Model 重载结果 */ export interface ModelReloadResult { /** 受影响(重载)的 model 数量 */ reloaded: number; /** 未受影响(保持不变)的 model 数量 */ unchanged: number; /** 重载的 model collection name 列表 */ reloadedNames: string[]; } /** * reloadModels — 选择性重载 model 定义 * * 只重新加载变更的 model 定义文件,其他 model 保持不变。 * 使用 monSQLize v1.1.8 的 Model.redefine() API 原子更新定义。 * * 流程: * 1. 扫描 outDir/models/ 下所有 .js 文件 * 2. 筛选出在 invalidation set 中的文件 * 3. 保存受影响 model 的旧定义 * 4. 逐个 require() 新模块 + Model.redefine() 更新 * 5. 失败时回滚所有受影响 model * * @param app VextApp 实例(需要 app.logger) * @param outDir 编译产物目录(.vext/dev/ 的绝对路径) * @param invalidated require.cache 失效集合(绝对路径集合) * @returns 重载结果(重载数 / 未变更数 / 重载的 name 列表) * @throws 重载失败时抛出错误(已回滚受影响 model) */ export declare function reloadModels(app: ModelReloaderApp, outDir: string, invalidated: Set): Promise;