feat: 0.10.0 快照内容级对照、忽略规则高级 glob 与扫描进度反馈 - 快照v2可选携带差异条目双侧内容(folder:read-batch批量读取IPC受控并发、单文件2MB与总量32MB双限超限整体降级为纯状态快照保存永不失败、对照模式双击进入快照基线vs当前文件的内容对比完整复用单文件能力、v1旧快照兼容加载、contents解析防御绝不部分加载、保存期间读取遮罩)、忽略规则匹配器重写支持多段路径/前导/锚定/整段**跨段/段内*通配/!否定规则(最后匹配优先与gitignore一致、父目录剪枝后子项无法反否定、无效规则UI实时提示不再静默丢弃、纯逻辑迁src/shared两进程共用源码)、扫描进度推送(首个push型IPC、scanId复用扫描会话序号旧扫描迟到进度天然丢弃、遮罩显示已比对N/M)、新增33单测与4条E2E(596单测+28E2E全过覆盖率98.16/93.28/93.69/98.16),文档四件套同步
This commit is contained in:
+24
-19
@@ -41,20 +41,21 @@
|
||||
## 4. 目录结构
|
||||
|
||||
```
|
||||
vitest.config.ts # Vitest 配置(jsdom + 测试范围 + 覆盖率 80% 硬门禁)
|
||||
vitest.config.ts # Vitest 配置(jsdom + 测试范围含 shared + 覆盖率 80% 硬门禁)
|
||||
playwright.config.ts # Playwright E2E 配置(对 out/ 产物启动真实 Electron,发布前必跑)
|
||||
e2e/
|
||||
├── helpers.ts # E2E 辅助(启动应用/对话框 stub/临时 fixture/粘贴入口/合成拖放)
|
||||
└── app.spec.ts # E2E 用例(启动/粘贴/编码链路/选项/导航/导出写盘/文件夹对比/增量重扫/拖拽导入/偏好重启)
|
||||
└── app.spec.ts # E2E 用例(启动/粘贴/编码链路/选项/导航/导出写盘/文件夹对比/增量重扫/忽略规则含高级 glob/扫描进度/快照含内容级对照/拖拽导入/偏好重启)
|
||||
src/shared/
|
||||
├── ignoreRules.ts # 忽略规则匹配器纯逻辑(gitignore 简化子集含高级 glob;主进程扫描剪枝与渲染端无效提示共用,段模式预编译 + DP 段序列匹配 + 否定仲裁)
|
||||
└── ignoreRules.test.ts # 忽略规则单元测试(名字/目录/通配回归 + 多段/锚定/跨段/段内通配/否定仲裁/无效清单/上限/IPC 校验)
|
||||
src/main/
|
||||
├── index.ts # 主进程入口(依赖 electron 运行时,覆盖率排除,真实链路由 E2E 覆盖)
|
||||
├── index.ts # 主进程入口(依赖 electron 运行时,覆盖率排除,真实链路由 E2E 覆盖;含 folder:read-batch 批量读取与 folder:scan 进度推送)
|
||||
├── decode.ts # 解码与编码探测纯逻辑(Uint8Array 入参,同步与 worker 路径共用)
|
||||
├── decode.test.ts # 解码单元测试(BOM 三种/严格 UTF-8/GBK 回退/二进制启发式)
|
||||
├── decodeWorker.ts # 解码 worker_threads 入口(覆盖率排除,逻辑由 decode 测试覆盖)
|
||||
├── folderScan.ts # 文件夹对比纯逻辑(递归枚举/对齐/字节判定/采样近似/受控并发比对/语义判等/单点失败降级/忽略规则剪枝)
|
||||
├── folderScan.test.ts # 文件夹扫描单元测试(真实临时目录:状态判定/递归/symlink/截断/近似/语义判等/目录降级/unreadable/忽略规则)
|
||||
├── ignoreRules.ts # 忽略规则纯逻辑(gitignore 简化子集编译为 matcher,无 electron 依赖)
|
||||
├── ignoreRules.test.ts # 忽略规则单元测试(目录剪枝/通配/名字匹配/大小写/非法输入/条数上限/IPC 校验)
|
||||
├── folderScan.ts # 文件夹对比纯逻辑(递归枚举/对齐/字节判定/采样近似/受控并发比对/语义判等/单点失败降级/忽略规则剪枝含高级 glob/比对进度回调)
|
||||
├── folderScan.test.ts # 文件夹扫描单元测试(真实临时目录:状态判定/递归/symlink/截断/近似/语义判等/目录降级/unreadable/忽略规则含 glob 与否定/进度回调)
|
||||
├── scanCacheStore.ts # 扫描缓存跨会话持久化纯数据(目录对键归一化/LRU/防御性解析)
|
||||
├── scanCacheStore.test.ts # 缓存存储单元测试(解析回退/条目过滤/键归一化/LRU 淘汰/序列化往返)
|
||||
├── scanIpc.ts # folder:scan IPC 入参校验与缓存源选择纯逻辑(无 electron 依赖)
|
||||
@@ -72,8 +73,8 @@ src/renderer/src/
|
||||
│ ├── report.test.ts # 单文件报告生成测试
|
||||
│ ├── folderReport.ts # 文件夹报告生成器(HTML/TXT/MD 三格式,快照对照口径附注;对照模式条目表替换为变迁对照表)
|
||||
│ ├── folderReport.test.ts # 文件夹报告测试(统计/结论/三格式/截断警示/unreadable/快照变迁对照表)
|
||||
│ ├── snapshotDiff.ts # 快照基线纯逻辑(结构/解析校验/目录对归一化匹配/六类变迁对照/共享变迁标签映射)
|
||||
│ ├── snapshotDiff.test.ts # 快照单元测试(解析防御/变迁判定/双侧空集/unreadable 语义/目录对归一化匹配)
|
||||
│ ├── snapshotDiff.ts # 快照基线纯逻辑(v1/v2 结构/解析校验含 contents/目录对归一化匹配/六类变迁对照/共享变迁标签映射/内容保存上限常量)
|
||||
│ ├── snapshotDiff.test.ts # 快照单元测试(解析防御/v1 v2 兼容/contents 形态校验/变迁判定/双侧空集/unreadable 语义/目录对归一化匹配)
|
||||
│ └── textUtils.test.ts # 文本扩展名与行数统计测试
|
||||
├── hooks/
|
||||
│ ├── useDiff.test.ts # worker 化计算 hook(快路径/去抖/过期丢弃/回退/卸载清理/字符级大字符量重路径/选项变化保留旧结果防滚动塌陷)
|
||||
@@ -86,11 +87,11 @@ src/renderer/src/
|
||||
│ ├── ErrorBoundary.test.tsx # 渲染错误兜底测试(抛错子组件 fallback/正常子组件透传)
|
||||
│ ├── folderTree.ts # 文件夹条目树纯逻辑(建树/状态聚合/扁平化/过滤含扩展名/子树收集)
|
||||
│ ├── folderTree.test.ts # 条目树单元测试(聚合排序/折叠/过滤/搜索/扩展名过滤/relExt)
|
||||
│ ├── FolderView.test.tsx # 文件夹视图(树形渲染/折叠/统计徽章点击过滤/搜索/扩展名下拉/忽略规则下拉/快照对照模式含变迁过滤归零复位/目录双击/重新扫描与重新选择/双击/导出菜单/虚拟滚动/resize 重算)
|
||||
│ ├── FolderView.test.tsx # 文件夹视图(树形渲染/折叠/统计徽章点击过滤/搜索/扩展名下拉/忽略规则下拉含无效规则提示与进度遮罩/快照对照模式含变迁过滤归零复位与内容对照 title/目录双击/重新扫描与重新选择/双击/导出菜单/虚拟滚动/resize 重算)
|
||||
│ ├── TextInputModal.test.tsx # 粘贴文本弹窗
|
||||
│ └── Toolbar.test.tsx # 工具栏(选项/导航/导出菜单向上弹出/计算中禁用/字符级开关与空白选项联动灰显勾选+已包含徽标+点击解释+已降级与部分降级标记/搜索框计数与 Enter·Shift+Enter·Esc 键盘交互/ref 转发)
|
||||
└── __tests__/
|
||||
├── App.test.tsx # 应用集成级测试(加载/拖拽/粘贴/导出/容错/toast 队列/清空确认/状态栏行数/大输入回退/单文件视图搜索/Ctrl+F/文件夹模式进出与双击/语义判等链路/差异文件导航/扫描竞态丢弃过期结果/增量重扫携带缓存/目录聚合导航/字符级部分降级/忽略规则链路与持久化/快照保存加载对照与拦截)
|
||||
├── App.test.tsx # 应用集成级测试(加载/拖拽/粘贴/导出/容错/toast 队列/清空确认/状态栏行数/大输入回退/单文件视图搜索/Ctrl+F/文件夹模式进出与双击/语义判等链路/差异文件导航/扫描竞态丢弃过期结果/增量重扫携带缓存/目录聚合导航/字符级部分降级/忽略规则链路与持久化/快照保存加载对照与拦截/快照内容级对照(v2 保存含内容·超限降级·双击基线vs当前·v1 兼容)/扫描进度显示与过期丢弃)
|
||||
└── main.test.ts # 入口挂载冒烟测试
|
||||
```
|
||||
|
||||
@@ -147,7 +148,7 @@ src/renderer/src/
|
||||
- 单文件视图搜索(0.9.3):输入关键字即时命中计数与首个命中行 active 定位 · Enter/Shift+Enter 命中行间推进回退(行号随动)· 首尾循环 · 大小写不敏感 · 无命中 0/0 且 Enter 不崩溃不推进 · Esc 清空复位 · Ctrl+F 聚焦搜索框 · 命中行被“仅看差异”折叠时计数仍统计全量行、跳转 toast 提示且不推进
|
||||
- 大输入(超快路径阈值)在无 Worker 环境去抖到期后回退同步计算,完成后无计算中遮罩
|
||||
- 文件夹模式:依次选择两侧目录进入(路径卡片/统计徽章/状态栏切换/默认仅看差异过滤 same) · 任一次选择取消不进入 · 两次选择同一目录防呆提示且不进入 · 扫描失败 toast 且不进入 · 双击差异条目加载两侧进入单文件对比并可返回文件夹(返回清空两侧面板) · 双击单侧条目加载存在侧并清空另一侧 · 双击条目任一侧读取失败(error 返回 / IPC 异常)清空失败侧显示未选择(不残留旧对比内容与旧文件名) · 「返回文件对比」清空文件夹状态回单文件空态(先有文件对比再进文件夹的场景同样清空,不残留旧对比) · 扫描竞态:慢的旧扫描后完成被会话序号丢弃(不覆盖新扫描的目录与条目、不残留扫描遮罩);扫描进行中退出文件夹对比后迟到的结果不把界面拉回文件夹模式
|
||||
- 快照基线(0.9.0,0.9.1 收尾,0.9.2 对称防呆):保存快照落盘内容为合法快照 JSON(含当前结果与目录对) · 截断结果保存快照被拦截提示且不落盘(0.9.1,防对照误报) · 当前扫描结果截断时加载快照同样被拦截(0.9.2,不弹文件选择——截断缺失文件会被误报已移除) · 对照模式中重扫触发截断自动退出对照并提示(0.9.2) · 快照语义判等口径与当前开关不一致时加载提示含口径差异、一致时无提示(0.9.2) · 加载快照对照模式渲染变迁统计与条目标注 · 目录对不一致 / 快照文件无效 / 读取失败拦截提示 · 对照模式导出报告携带快照口径说明与变迁对照明细(0.9.1) · 退出对照恢复常规视图 · 对照随重扫自动刷新
|
||||
- 快照基线(0.9.0,0.9.1 收尾,0.9.2 对称防呆,0.10.0 内容级对照):保存快照落盘内容为合法快照 JSON(含当前结果与目录对) · 截断结果保存快照被拦截提示且不落盘(0.9.1,防对照误报) · 当前扫描结果截断时加载快照同样被拦截(0.9.2,不弹文件选择——截断缺失文件会被误报已移除) · 对照模式中重扫触发截断自动退出对照并提示(0.9.2) · 快照语义判等口径与当前开关不一致时加载提示含口径差异、一致时无提示(0.9.2) · 加载快照对照模式渲染变迁统计与条目标注 · 目录对不一致 / 快照文件无效 / 读取失败拦截提示 · 对照模式导出报告携带快照口径说明与变迁对照明细(0.9.1) · 退出对照恢复常规视图 · 对照随重扫自动刷新 · 快照内容级对照(0.10.0):保存时差异条目双侧内容入 contents(批量读取按路径返回、same 条目不存、单文件超限侧不读该侧 null)/ 内容总量超限整体降级为纯状态快照并提示(vi.mock 压低上限构造)/ 对照模式双击含基线内容条目进入"快照基线 vs 当前"内容对比(左面板快照基线标注、右面板当前文件、有差异徽章)/ v1 快照双击走常规当前文件对比(兼容回归锚)
|
||||
|
||||
### 5.6 diff 计算 worker 化(`useDiff.ts` / `createDiffWorker.ts`)
|
||||
- 快路径:两侧总行数不超过 2000 时同步计算,不创建 worker,结果与 computeDiff 一致
|
||||
@@ -177,15 +178,17 @@ src/renderer/src/
|
||||
- 边界与选项:两个空目录 / maxFiles 截断(truncated + total + 条目数受限;截断后不再深入子目录,total 为已遍历下限) / 超 maxContentBytes 同大小文件头部采样一致判 same 带 approximate / 采样头部不同直接 different
|
||||
- 受控并发:跨多个并发批次(> 2×SCAN_CONCURRENCY)的混合状态全部判定正确、条目排序与并发执行顺序无关
|
||||
- 增量重扫(0.8.0,previous 缓存):指纹一致(size+mtime 未变)零 IO 沿用判定(decode 计数零增长)/ 语义开关翻转按 semSame 纯内存组合(different ↔ semantic-same 零 IO,开→关→开三轮)/ 上次未参与语义(semSame null)而本次开启读内容补判 / 指纹变化(内容修改)重新判定且文件增删正确 / 单侧缺失形状变化不误沿用 / 本次截断忽略 previous 且 cache 产出为空 / unreadable 不进缓存(故障恢复后重扫正确判定)
|
||||
- 忽略规则(0.9.0):目录规则整树剪枝(深层子树不枚举、不计数、不进结果与缓存)/ 扩展名通配与名字匹配跳过文件(大小写不敏感)/ 被忽略文件不占用 maxFiles(原本截断的场景忽略后完整扫描)/ 规则变化后重扫缓存未命中的重新纳入条目走全量判定 / 空规则数组与全非法规则不产生任何剪枝
|
||||
- 忽略规则(0.9.0,0.10.0 高级 glob):目录规则整树剪枝(深层子树不枚举、不计数、不进结果与缓存)/ 扩展名通配与名字匹配跳过文件(大小写不敏感)/ 被忽略文件不占用 maxFiles(原本截断的场景忽略后完整扫描)/ 规则变化后重扫缓存未命中的重新纳入条目走全量判定 / 空规则数组与全非法规则不产生任何剪枝 / 多段路径从根锚定剪枝(其他分支同名目录不受影响)/ ** 跨段剪枝与否定救回(父目录未被剪枝时子路径可被反否定)/ 父目录被剪枝后否定规则救不回子项(gitignore 同款语义)
|
||||
- 比对进度回调(0.10.0):需读内容的条目按批推进进度(total 恒为需读内容条目数、done 单调递增至 total)/ 全部条目零 IO(单侧缺失)时不触发回调
|
||||
|
||||
### 5.10 文件夹视图(`FolderView.tsx`)与条目树(`folderTree.ts`)
|
||||
- 条目树纯逻辑:按路径分段聚合目录/文件(同层字典序);目录聚合子树状态(different > unreadable > only > 语义同 > 相同)与文件计数;折叠目录子树隐藏;过滤(onlyDiff / statusFilter / query 子串不区分大小写 / exts 扩展名集合);空目录剪枝由“过滤后建树”天然保证;relExt 取文件名段扩展名(小写、无扩展名空串、不误取目录名中的点)
|
||||
- 渲染:目录路径卡片 / 重新扫描、重新选择、导出报告与返回按钮 / 统计徽章(相同/语义同/不同/仅左/仅右/无法读取/总数;语义关闭隐藏语义同、无失败隐藏无法读取)
|
||||
- 树形交互:目录行点击折叠展开(默认全展开);搜索命中强制展开命中路径、清空恢复用户折叠;无命中提示
|
||||
- 扩展名过滤(0.8.0):下拉展示全量条目 ext→count(字典序、无扩展名单列);点选过滤与其他条件取交集、计数切 N / 总数;多选并集、再点取消、清除按钮复位;与状态过滤双激活空态提示;点击外部关闭且过滤状态保留
|
||||
- 忽略规则(0.9.0):已有规则时入口标注数量并高亮;下拉打开以当前规则初始化草稿,逐行解析去空白去空行(截断至 50 条)后应用回调并关闭;清空规则回调空数组;点击外部关闭不触发回调
|
||||
- 快照对照模式(0.9.0):变迁统计徽章(已修复/新增差异/新文件/已移除/仍有差异/保持一致)与基线时间替换常规统计行;对照条目平铺全路径渲染、行尾变迁徽章、gone 回退快照数据;零计数变迁不占位;默认隐藏 stable、点击徽章单选过滤再点取消;双击当前条目进单文件对比、已移除条目双击无效;退出对照恢复常规视图;全 stable 空态提示;重扫刷新后过滤的变迁类型计数归零自动复位(0.9.3,残留过滤不再误显空态)
|
||||
- 忽略规则(0.9.0,0.10.0 高级 glob 与无效提示):已有规则时入口标注数量并高亮;下拉打开以当前规则初始化草稿,逐行解析去空白去空行(截断至 50 条)后应用回调并关闭;清空规则回调空数组;点击外部关闭不触发回调;无效规则实时提示"将被忽略的无效规则"(修正/清空后提示消失,不再静默丢弃)
|
||||
- 快照对照模式(0.9.0):变迁统计徽章(已修复/新增差异/新文件/已移除/仍有差异/保持一致)与基线时间替换常规统计行;对照条目平铺全路径渲染、行尾变迁徽章、gone 回退快照数据;零计数变迁不占位;默认隐藏 stable、点击徽章单选过滤再点取消;双击当前条目进单文件对比、已移除条目双击无效;退出对照恢复常规视图;全 stable 空态提示;重扫刷新后过滤的变迁类型计数归零自动复位(0.9.3,残留过滤不再误显空态);对照条目含基线内容时 title 提示"双击查看快照基线内容对照"(0.10.0)
|
||||
- 扫描进度遮罩(0.10.0):progress props 非空时遮罩显示"已比对 N / M",null 时仅基础文案
|
||||
- 过滤:仅看差异隐藏 same 与 semantic-same;徽章点击状态精确过滤(激活态高亮、与仅看差异互斥联动)
|
||||
- 扫描中交互防抖(0.9.2):扫描进行中语义判等开关与忽略规则入口禁用(触发重扫的入口,点击不触发回调/不打开下拉);仅看差异开关与搜索仍可用(纯视图过滤不触发重扫);「重新选择」扫描中保持可用(0.9.3 固化:发起新会话作废在途扫描,与「返回文件对比」同类)
|
||||
- 目录行双击(0.8.0):触发 onOpenDir 携带目录相对路径;双击前折叠态自动展开(toggle 残留消除);重新扫描按钮触发 onRescan 且扫描中禁用
|
||||
@@ -206,9 +209,10 @@ src/renderer/src/
|
||||
- 文件夹新功能(0.7.0):语义判等徽章与过滤(CRLF/LF 差异计语义同)→ 树形折叠展开 → 搜索 → 文件夹报告 TXT 真实落盘(判定口径 + 结论 + 全量条目)
|
||||
- 增量重扫(0.8.0):真实目录修改文件后点「重新扫描」状态正确更新(相同→不同→改回相同,真实 mtime 变化走指纹判定)
|
||||
- 拖拽导入(0.8.0):dropFiles 合成 DataTransfer 拖放——空面板拖入渲染(arrayBuffer → decodeBuffer IPC 全链路)、双侧拖入对比、非文本扩展名拒绝、多文件提示取首个
|
||||
- 忽略规则(0.9.0):真实目录含 node_modules 子树——无规则时差异参与对比,输入规则应用重扫后整树剪枝(不同归零、空态一致提示、被忽略条目消失)
|
||||
- 忽略规则(0.9.0,0.10.0 高级 glob):真实目录含 node_modules 子树——无规则时差异参与对比,输入规则应用重扫后整树剪枝(不同归零、空态一致提示、被忽略条目消失);高级 glob——build 下深层 temp 目录经 build/**/temp 跨段剪枝、*.log 忽略 + !keep.log 否定救回(差异计数精确收敛)、无效规则提示出现
|
||||
- 扫描进度反馈(0.10.0):2000 条目目录扫描期间遮罩"已比对 N / 2000"轮询抓取(瞬态断言),完成后全量判定与遮罩消失
|
||||
- 增量缓存跨会话持久化(0.9.0):第一实例扫描后 userData/scan-cache.json 落盘(等待异步写盘,断言含条目与合法结构)→ 同 userData 第二实例重扫同目录结果正确(主进程注入盘上缓存)
|
||||
- 快照基线(0.9.0,0.9.1 增强):保存快照真实落盘(JSON 含版本与条目)→ 修复差异 + 新增文件重扫 → 加载快照对照(已修复/新文件变迁统计与条目标注)→ 对照模式导出报告真实写盘断言变迁明细(已修复/新文件/保持一致,0.9.1)→ 退出对照恢复
|
||||
- 快照基线(0.9.0,0.9.1 增强,0.10.0 内容级对照):保存快照真实落盘(JSON 含版本与条目)→ 修复差异 + 新增文件重扫 → 加载快照对照(已修复/新文件变迁统计与条目标注)→ 对照模式导出报告真实写盘断言变迁明细(已修复/新文件/保持一致,0.9.1)→ 退出对照恢复;内容级对照——保存 v2 快照(JSON 断言含差异条目双侧内容)→ 修改左侧文件重扫 → 加载快照双击变更条目进入"快照基线 vs 当前"内容对比(左面板"快照 · 文件名"标注、基线旧词与当前新词词级高亮、有差异徽章)
|
||||
- 大文件性能基准(0.9.0):5 万行双文件 20 处差异——打开右侧到「有差异」出现耗时 < 15s;300KB GBK 15000 行——打开到状态栏行数渲染 < 10s(万级实测秒级,上限按慢机 4 倍余量防 flaky,断言失败即性能回归)
|
||||
- 偏好持久化:跨实例重启恢复比较选项与视图开关(同一 userData)
|
||||
- 隔离:每用例启动清空 localStorage + 重载,避免偏好跨用例污染(偏好用例验证实例显式跳过清理)
|
||||
@@ -259,8 +263,9 @@ npm run build
|
||||
|
||||
## 9. 演进方向(后续迭代)
|
||||
|
||||
- 文件夹对比:快照 vs 当前的逐行文本对照(快照保存内容或按需读盘,对照视图内差异明细) · 忽略规则高级 glob(`**` 跨段、否定规则 `!`)
|
||||
- 主进程 IPC 并发场景集成测试(入参校验与缓存注入逻辑已于 0.9.1 单测化:scanIpc)
|
||||
- 快照体验:regressed 场景基线内容保存策略(当前仅保存差异条目,基线一致的条目内容不存——需全量保存的体积代价权衡) · 快照内差异内容的报告导出
|
||||
- 忽略规则:gitignore 更完整子集评估(`?` 单字符、字符类、前导 `!` 组合语义等,按真实需求驱动)
|
||||
- 主进程 IPC 并发场景集成测试(入参校验与缓存注入逻辑已于 0.9.1 单测化:scanIpc;缓存落盘串行化于 0.9.3 修复)
|
||||
- mac 构建实际验证(entitlements 配置就绪但从未打包跑通)
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user