feat(storage): 拦截并持久化 localStorage 到磁盘,解决随机端口导致的数据丢失 - #301
Merged
Conversation
- 新增 DesktopStorageManager,将 Web Storage 数据落盘至当前 Profile 目录下的 desktop-storage.json - 支持 200ms 防抖异步落盘及窗口关闭 / before-quit 时的 flushSync() 原子写入保证 - Preload 注入主上下文透明代理 Storage.prototype 与 window.localStorage(支持方法调用与属性读写) - 页面加载前同步拉取磁盘数据,解决 DSH 启动随机端口引起的同源隔离(Origin 变更)导致纯前端插件数据丢失的问题 - 增加 DesktopStorageManager 单元测试与测试覆盖
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景与问题
在 macOS / Windows 桌面端(
dsh-desktop),每次启动由reservePort()动态分配随机可用端口(例如本次启动是http://127.0.0.1:54321,下次重启变成http://127.0.0.1:58962)。按照 W3C 浏览器的同源策略(Same-Origin Policy),Origin 由
协议 + 主机 + 端口三者决定,端口改变等于进入全新的独立域。因此,依赖浏览器原生window.localStorage的纯前端插件(例如各类设置滑块、UI 主题、自定义面板等)在应用重启后读到的均为空存储,导致用户配置与状态丢失。如果强制要求所有纯客户端插件重构成「Host + Client 双端架构」,开发门槛高且会使现有社区纯前端小插件失去持久化能力。
改动方案与实现细节
本 PR 采用 Preload 拦截代理 + 主进程磁盘持久化 方案,对插件生态 100% 透明无侵入:
主进程存储管理 (
DesktopStorageManager):profiles/<profile>/desktop-storage.json,生命周期与 Profile 深度绑定,天然支持备份与迁移。.tmp->rename原子写入,杜绝断电或崩溃导致 JSON 损坏。before-quit,提供flushSync()同步原子落盘保证,确保退出前 0 数据丢失。Preload 透明代理 (
setupDesktopStoragePersistence):document-start阶段)通过同步 IPC (dsh:storage-load-sync) 拉取磁盘数据到内存中。Storage.prototype(getItem、setItem、removeItem、clear、key、length)。window.localStorage,同时兼容localStorage['key'] = 'val'属性直接赋值与读取。测试覆盖:
test/desktop-storage.test.ts,覆盖空文件初始化、CRUD 一致性、防抖批量写入、同步 Flush 退出、JSON 损坏容错自愈及跨 Profile 隔离。