mirror of
https://github.com/panatgithub/AnkiHeadingSync.git
synced 2026-07-22 06:51:43 +00:00
- 设置页在有缓存时立即显示缓存摘要,并在打开时只做一次轻量 note type freshness 检查 - 手动读取仍负责完整模板与字段刷新,不会在页面打开时读取所有字段 - Add tests and docs for cache summary, stale-cache warning, and failed background checks
5.7 KiB
5.7 KiB
设置页 Anki 模板缓存状态差距审计
本文基于当前仓库真实实现,审计“设置页模板缓存状态显示 + 后台轻量 freshness 检测”的落地差距。
1. 当前设置页已是 cache-first 下拉,但不是 cache-first 状态
- 入口在 src/presentation/settings/PluginSettingTab.ts。
renderCardTypesCard()打开时会先执行hydrateVisibleCardTypeCaches()。- note type 下拉来自:
availableNoteModels,若为空则退回settings.ankiNoteTypeCache
- 字段下拉来自:
settings.ankiModelFieldCache水合出的loadedModelDetails- 再经
getCurrentMappingForConfig()生成 draft mapping
这说明缓存实际上已经参与首屏渲染,当前问题不是“缓存没被用”,而是“状态文案没有反映缓存可用性”。
2. 当前首屏状态文本仍固定为 idle
- 当前类内状态是:
cardTypeStatus: UserFacingMessage = NOTE_TYPE_STATUS_IDLE
NOTE_TYPE_STATUS_IDLE指向settings.mapping.status.idle。renderCardTypesCard()直接渲染renderUserFacingMessage(this.cardTypeStatus)。cardTypeStatus只会在以下情况变化:saveCardTypeConfig()校验失败loadAnkiCardTypeConfig()开始 / 成功 / 失败
结果:即使已有 ankiNoteTypeCache 和 ankiModelFieldCache,首次打开设置页仍显示“请先从 Anki 刷新”语义,而不是缓存摘要。
3. 当前设置页打开时不会做任何后台 freshness 检测
display()->renderCard("card-types")->renderCardTypesCard()的当前路径里没有自动调用:listNoteModels()getModelFieldNamesByModelNames()getNoteModelDetails()
- 唯一主动访问 Anki 的入口仍是点击“手动读取 Anki 里的模板配置”。
这与目标方案的差距是:当前没有“只跑一次 modelNames 的轻量后台检测”。
4. 当前完整刷新流程已经符合“手动触发全量字段读取”约束
loadAnkiCardTypeConfig()当前真实流程是:listNoteModels()一次getModelFieldNamesByModelNames()一次updateSettings({ ankiNoteTypeCache, ankiModelFieldCache })hydrateVisibleCardTypeCaches()syncQaGroupMappingFromCache()renderCard("card-types")
- 当前不会在设置页打开时读取所有字段。
这意味着本轮应保留该完整刷新流程,只新增轻量 listNoteModels() 检测,不改 full refresh 语义。
5. 当前 card 1 已具备局部刷新壳层,可直接复用
display()只在首次进入时containerEl.empty()和初始化 card shells。- 后续都是
renderCard(cardId)的局部刷新。 loadAnkiCardTypeConfig()、saveCardTypeConfig()、saveFieldMapping()等都只刷新card-types卡片。
这与目标方案一致:后台检测完成后只需 renderCard("card-types"),不需要整页重建。
6. 当前没有“一次性检测状态”或“override 状态”的分层模型
- 当前只有一个
cardTypeStatus字段,同时承载:- idle
- manual refresh loading
- manual refresh success
- manual refresh failure
- validation failure
- 没有单独的:
- cache freshness check 状态
- status override
- detected live note type list
- one-shot lifecycle promise
结果:如果直接把后台检测结果写回 cardTypeStatus,会和手动刷新成功/失败状态互相覆盖。
7. 当前没有防重入机制来保证“一次生命周期只检测一次”
- 现在
renderCard("card-types")会在很多交互后被反复调用:- display 初始渲染
- toggle/heading/note type 变更
- QA Group warning acceptance
- manual refresh 前后
- 但类内没有任何
Promise或status标记来阻止重复启动 live 检测。
因此如果要加后台检测,必须把“是否已检测过/是否检测中”挂在 settings tab 实例上,而不是放在 render 逻辑里临时判断。
8. 当前测试已证明缓存渲染存在,但未覆盖状态与后台检测
- src/presentation/settings/PluginSettingTab.test.ts 当前已经覆盖:
ankiNoteTypeCache渲染 note type 下拉ankiModelFieldCache渲染字段下拉- 手动完整刷新只触发
listNoteModels()+getModelFieldNamesByModelNames() getNoteModelDetails()在设置页刷新路径中不应被调用
- 但未覆盖:
- 有缓存时首屏状态摘要
- 首屏后台
listNoteModels()轻量检测 - 检测 changed / failed 分支
- 无缓存时不启动后台检测
- 手动 refresh 成功后清除 changed 提示
9. 当前 i18n 里缺少缓存状态分层文案
- 当前 card types 相关文案已有:
loadedSummaryfailedLoadfailedSaveloadAnki.loading
- 但没有:
cacheEmptycacheSummarycacheChangedcacheCheckFailed
结果:即使实现了 cache-aware status,也没有现成 i18n key 可用。
10. 结论
当前仓库与目标方案的差距主要集中在状态模型,不在缓存渲染主链:
- 缓存已经用于下拉和字段渲染,但状态文本仍是固定 idle。
- 设置页打开时没有任何轻量
modelNamesfreshness check。 - 当前缺少 cache status 与 manual refresh status 的分层模型。
- 当前缺少防止重复后台检测的实例级状态。
- 当前测试和 i18n 都还不知道这套缓存状态语义。
因此最安全的仓库兼容路径是:
- 保留现有缓存渲染和 manual full refresh 流程。
- 新增实例级的一次性
listNoteModels()后台检测状态。 - 用统一的
getCardTypeStatusMessage()计算首屏状态与 override 状态。 - 让后台检测只影响 card 1 的状态提示,不触碰
data.json和字段缓存。