# utils/ 通用工具函数和 React 自定义 Hooks 目录,与具体页面解耦。 ## 工具函数 | 文件 | 用途 | | ------------------------ | --------------------------------------------------------------------------------------------------- | | `chromeStorage.ts` | Chrome Storage API 封装:类型安全的 `StorageUtils` 类,提供 `get/set/remove` 方法 | | `syncSnapshot.ts` | 通用 `localStorage` 快照读取(`snapshot/{key}`),用于 Router 与 `useStorageState` 首屏防闪烁 | | `themeSnapshot.ts` | 主题专用快照读写与 `document.documentElement` class 切换 | | `restrictedUrls.ts` | 受限 URL 检测(`chrome://`、`about:` 等),供 Storage Cleaner 等模块复用 | | `chromeTabs.ts` | Chrome Tabs API 封装:获取活动标签页、获取域名、在新标签页打开扩展页面 | | `clipboard.ts` | 剪贴板操作:`copyTextToClipboard`(文本)、`copyImageToClipboard`(图片) | | `messages.ts` | 扩展消息通信:基于 `@webext-core/messaging`,定义 `MessageAction` 枚举和 `ProtocolMap` 类型安全映射 | | `contextMenu.ts` | 右键菜单配置与操作:定义菜单项、创建菜单、解析点击事件、ID→PageType 映射 | | `base64Converter.ts` | Base64 编解码:文本↔Base64、文件↔Base64、图片预览,定义文件大小限制和图像 MIME 类型 | | `jwt.ts` | JWT 解析:Base64URL 解码、解析 Header/Payload/Signature、JSON 格式化输出 | | `jsonFormatter.ts` | JSON 格式化/压缩:支持缩进、按键排序、minify | | `jsonToYaml.ts` | JSON→YAML 转换 | | `jsonToToml.ts` | JSON→TOML 转换 | | `qrCodeParser.ts` | 二维码解析:基于 `qr-scanner` 库从文件中解析二维码 | | `storageCleaner.ts` | 存储清理:获取当前标签页、计算 Cookie/Storage 大小、清理操作 | | `textStatistics.ts` | 文本统计:使用 `Intl.Segmenter` 计算字符数/单词数/行数/字节大小 | | `format.ts` | 通用格式化:`formatBytes` 将字节转为可读字符串(B/KB/MB/GB/TB) | | `dayjs.ts` | Day.js 初始化:扩展 UTC、Timezone、RelativeTime 插件,加载中文本地化 | | `ruleStorage.ts` | 测试数据生成器规则存储:基于 `localStorage` 的 CRUD、搜索、导入/导出和数量限制(见下方说明) | | `dataExporter.ts` | 测试数据导出:JSON/CSV 转换、文件下载和复制到剪贴板 | | `rightClickInjection.ts` | 右键恢复注入脚本:在页面上下文恢复 contextmenu/copy/paste 等事件默认行为 | ## 自定义 Hooks | 文件 | 用途 | | ----------------------- | -------------------------------------------------------------------------------------------------------------- | | `useStorageState.ts` | Chrome Storage 状态 Hook:类似 `useState`,值自动同步到 `chrome.storage`,使用 `localStorage` 快照消除首屏闪烁 | | `useContextMenuData.ts` | 右键菜单数据 Hook:从 storage 读取待处理数据,匹配 featureKey 后消费并触发回调 | | `useDebounce.ts` | 防抖 Hook:对值进行延迟更新,避免频繁触发 | ### ruleStorage 写入失败处理 `ruleStorage.ts` 使用函数式导出(非 class),存储键为 `testDataGenerator_rules`,最多 `MAX_RULES = 20` 条。 写入经内部 `setAll()` 完成;`localStorage.setItem` 抛错(如配额超限)时返回 `false`,并 `console.error`,**不会部分提交**: | 方法 | 写入失败返回值 | 常见失败原因 | | ---- | -------------- | ------------ | | `save()` | `null` | 达上限、规则不存在(更新时)、`setItem` 异常 | | `update()` | `null` | 规则不存在、`setItem` 异常 | | `deleteRule()` | `false` | 规则不存在、`setItem` 异常 | | `duplicate()` | 仍可能返回对象但数据未持久化 | 见源码:`duplicate` 未检查 `setAll` 返回值(已知缺口) | 调用方应检查返回值后再展示成功 Toast。页面层参考 `FieldList.tsx`:`save`/`update` 返回非空才提示「规则已保存/已更新」。 规则仅持久化 `name`、`description`、`fields` 及时间戳/使用统计;生成数量与导出格式由页面状态管理,不写入规则。 ### useStorageState 初始化防覆盖 `useStorageState` 在挂载时从 storage 异步加载。写入 storage 需满足以下任一条件: - **`loadSucceededRef`**:storage 读取成功 - **`userModifiedRef`**:用户通过 setter 主动修改过值 若 storage 读取失败且用户未修改,不会将默认值写回 storage,避免静默覆盖已有数据。 ## 使用约定 - 工具函数使用**命名导出**(`export function xxx()`) - 工具层不直接展示 Toast;可恢复错误返回可判断结果,需要抛出的解析/转换错误由页面 Hook 或 UI 层捕获 - Hook 使用 `use` 前缀命名,定义返回值接口类型 - 存储操作使用 `chromeStorage.ts` 的 `storageUtil` 封装,不要直接调用 `chrome.storage` - 消息通信使用 `messages.ts` 的 `sendMessage`/`onMessage`,不要使用原生 `chrome.runtime.sendMessage` - 需要首屏快照的新持久化状态,优先复用 `syncSnapshot.ts` 或参考 `themeSnapshot.ts` 模式