安装资源 转移至 chrome.storage.local 的 tempStorage. 代码部份放在 OPFS/temp_install_codes#1318
安装资源 转移至 chrome.storage.local 的 tempStorage. 代码部份放在 OPFS/temp_install_codes#1318cyfung1031 wants to merge 3 commits intorelease/v1.4from
chrome.storage.local 的 tempStorage. 代码部份放在 OPFS/temp_install_codes#1318Conversation
|
👀 要大规模的用起 OPFS 来了吗,先不急着处理这个问题,留下一个版本去,v1.4准备做重构UI这件大事 |
先合并吧 |
可以 |
| return cacheInstance.get<[boolean, ScriptInfo]>(cacheKey); | ||
| async getInstallInfo(uuid: string) { | ||
| const entry = await new TempStorageDAO().get(uuid); | ||
| cleanupStaleTempStorageEntries(); |
There was a problem hiding this comment.
每次调用都会启动cleanupStaleTempStorageEntries,而且内部逻辑复杂;我觉得做一个定时任务,每隔多久,扫描一次全部的,清理一下就可以了
| } | ||
| info = createScriptInfo(uuidv4(), code, `file:///*from-local*/${file.name}`, "user", metadata); | ||
| const uuid = uuidv4(); | ||
| info = await createScriptInfoLocal(uuid, code, `file:///*from-local*/${file.name}`, "user", metadata); |
There was a problem hiding this comment.
Pull request overview
本 PR 旨在将“安装页临时安装信息/脚本代码”的存储从原先的 session cache 迁移:元信息转存到 chrome.storage.local 的 tempStorage,脚本代码主体转存到 OPFS 的 temp_install_codes,以降低 session storage 压力并便于跨页面/重启场景取回安装数据。
Changes:
- 新增
TempStorageDAO(chrome.storage.local)用于保存安装临时条目(不含代码正文)。 - 新增 OPFS 目录
temp_install_codes存取/清理临时代码,并在安装页通过 uuid 回读代码。 - Service Worker 与安装页流程改为读写
tempStorage+ OPFS,并新增 stale 清理逻辑入口。
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pkg/utils/scriptInstall.ts | 增加 OPFS 临时代码写入/读取/删除与构造 temp entry 的工具方法 |
| src/pages/install/App.tsx | 安装页改为从 TempStorage + OPFS 组装安装信息,并新增 keep-alive 机制 |
| src/app/service/service_worker/temp.ts | 新增 SW 侧 stale 临时条目清理逻辑 |
| src/app/service/service_worker/subscribe.ts | 订阅更新触发安装页前改为写入 TempStorage + OPFS |
| src/app/service/service_worker/script.ts | getInstallInfo 与打开安装页流程改为读取/写入 TempStorage + OPFS,并触发清理 |
| src/app/repo/tempStorage.ts | 新增 TempStorageDAO(Repo 前缀 tempStorage:)与 staleEntries 逻辑 |
| src/app/cache_key.ts | 移除不再使用的 CACHE_KEY_SCRIPT_INFO 常量 |
| const list = stales.map((e) => e.key); | ||
| const list1 = stales.filter((entry) => entry.type === TempStorageItemType.tempCode).map((e) => e.key); | ||
| await removeCachedCodes(list1); | ||
| cacheInstance.dels(list); |
There was a problem hiding this comment.
这里清理 stale TempStorage 条目时使用了 cacheInstance.dels(list),但 cacheInstance 是 chrome.storage.session(见 src/app/cache.ts),而 TempStorageDAO 数据实际保存在 chrome.storage.local(Repo 基类)。这会导致 tempStorage 条目永远不会被删除,长时间运行会持续堆积。建议改为调用 new TempStorageDAO().deletes(list)(或等价的 delete API)来删除 tempStorage: 前缀下的记录。
| cacheInstance.dels(list); | |
| await new TempStorageDAO().deletes(list); |
src/pages/install/App.tsx
Outdated
| throw new Error("fetch script info failed"); | ||
| } | ||
| const code = await getTempCode(uuid); | ||
| if (code) info.code = code; |
There was a problem hiding this comment.
这里从 OPFS 读取安装代码后仅在 code 为 truthy 时才写回 info.code。但 getTempCode() 在任何异常都会返回空字符串,导致后续 prepareScriptByCode/prepareSubscribeByCode 直接拿到空代码并出现难以定位的错误/空白安装页。建议在 uuid 场景下把“读不到代码”视为错误(例如空字符串就抛错/提示用户),或让 getTempCode 返回 undefined/抛出以便区分“文件不存在/读取失败”和“代码为空”。
| if (code) info.code = code; | |
| // 这里从 OPFS 读不到代码(getTempCode 返回空字符串)应视为错误,避免后续拿到空代码导致空白安装页 | |
| if (code === "") { | |
| throw new Error("failed to load script code from temp storage"); | |
| } | |
| if (code) { | |
| info.code = code; | |
| } |
src/pkg/utils/scriptInstall.ts
Outdated
| export const getTempCode = async (tempUUID: string): Promise<string> => { | ||
| try { | ||
| const folder = await navigator.storage.getDirectory().then((root) => root.getDirectoryHandle("temp_install_codes")); | ||
| const handle = await folder.getFileHandle(`${tempUUID}.user.js`); | ||
| return await handle.getFile().then((f) => f.text()); | ||
| } catch { | ||
| return ""; |
There was a problem hiding this comment.
getTempCode 捕获所有异常并返回空字符串,会把“读取失败/文件不存在”和“代码确实为空”混在一起,调用方很难做可靠的错误处理(目前 install 页也因此可能继续用空代码往下走)。建议改为返回 undefined(文件不存在/读取失败)或直接抛出异常,并在调用处统一提示;如果一定要吞错,至少区分 NotFound 与其它异常并打日志以便排障。
| export const getTempCode = async (tempUUID: string): Promise<string> => { | |
| try { | |
| const folder = await navigator.storage.getDirectory().then((root) => root.getDirectoryHandle("temp_install_codes")); | |
| const handle = await folder.getFileHandle(`${tempUUID}.user.js`); | |
| return await handle.getFile().then((f) => f.text()); | |
| } catch { | |
| return ""; | |
| export const getTempCode = async (tempUUID: string): Promise<string | undefined> => { | |
| try { | |
| const folder = await navigator.storage | |
| .getDirectory() | |
| .then((root) => root.getDirectoryHandle("temp_install_codes")); | |
| const handle = await folder.getFileHandle(`${tempUUID}.user.js`); | |
| return await handle.getFile().then((f) => f.text()); | |
| } catch (err: any) { | |
| // 文件不存在时返回 undefined,其它异常打日志并抛出,方便上层统一处理 | |
| if (err && (err.name === "NotFoundError" || err.code === "NotFoundError")) { | |
| return undefined; | |
| } | |
| console.error("[scriptInstall] Failed to read temp install code", err); | |
| throw err; |
- 修复清理时 cacheInstance.dels 删错存储位置(session→local) - cleanup 改为 chrome.alarms 定时任务,移除 getInstallInfo 副作用 - 安装页 keepAlive 直接更新 TempStorageDAO.savedAt,移除 keepTemp 中转 - getTempCode 区分 NotFoundError 与其他异常,调用方对空代码抛错 - staleEntries 使用 this 替代多余的 new 实例
Code Review 修复已提交修复
|
|
@CodFrm 你把 cleanupStaleTempStorageEntries 改成只检查 savedAt ... 我要再看看 本来的设计是检查session |
|
好吧应该没什么问题。 |
Checklist / 检查清单
Description / 描述
Screenshots / 截图