52 lines
1.8 KiB
Markdown
52 lines
1.8 KiB
Markdown
# width-measurement(子模块规范)
|
||
|
||
## 子模块名称
|
||
|
||
width-measurement(宽度测量与降级)
|
||
|
||
## 目标描述
|
||
|
||
提供统一的宽度测量接口与缓存策略,并定义“宽度不可用”时的确定性降级行为(approx mode),确保 APP 与 WIDGET 在测量能力差异下仍能:
|
||
|
||
- 保持搜索/评分流程可运行
|
||
- 输出可解释(meta 打点)
|
||
- 性能稳定(缓存与上限)
|
||
|
||
## 输入/输出定义
|
||
|
||
### 输入
|
||
|
||
- `context: 'APP' | 'WIDGET'`
|
||
- `fontSpec?: { fontSize: number; fontWeight?: string; fontFamily?: string }`
|
||
- `measureWidth?: (text: string, fontSpec) => number`(可选注入)
|
||
- `text: string`
|
||
- `slice?: { start: number; end: number }`(可选:段落切片测量)
|
||
|
||
### 输出
|
||
|
||
- `width: number | null`
|
||
- 当不可用/失败时返回 `null`(触发 approx mode)
|
||
- `meta?: { isApprox: boolean; reason?: 'WIDTH_UNKNOWN' | 'MEASURE_FAILED' }`
|
||
|
||
并提供缓存约定(逻辑输出):
|
||
|
||
- 字符串测量缓存 key:`(text, fontSpecKey, contextProfile)`
|
||
- 切片测量缓存 key:`(start, end, fontSpecKey, contextProfile)`
|
||
|
||
## 验收标准(可验证)
|
||
|
||
- **测量一致**:在 APP 注入 `measureWidth` 时,同一输入重复测量命中缓存(不会重复计算)
|
||
- **失败降级**:`measureWidth` 缺失/抛错/返回 NaN 时:
|
||
- 输出 `width=null`
|
||
- meta 标记 `isApprox=true` 且 reason 可追踪
|
||
- **approx mode 口径一致**:
|
||
- EN:宽度近似值使用 `wordCount`
|
||
- TC:宽度近似值使用 `charCount`(或 grapheme 数)
|
||
- **确定性**:相同输入在相同 contextProfile 下,测量与降级行为一致
|
||
|
||
## 依赖与关联
|
||
|
||
- **被依赖**:`search-engine-app`、`search-engine-widget`、`overflow-fallback`
|
||
- **依赖**:`core-contract`(fontSpecKey 规范化、切片文本重组)
|
||
|