@nsnanocat/preference-panes 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -103
- package/dist/preference-panes.mjs +849 -1100
- package/dist/preference-panes.request.js +168 -571
- package/package.json +64 -64
- package/src/SettingsHandler.mjs +127 -123
- package/src/browser/client.mjs +218 -102
- package/src/browser/index.d.ts +143 -20
- package/src/browser/index.mjs +5 -0
- package/src/browser/panel.css +293 -94
- package/src/browser/panel.mjs +510 -272
- package/src/index.d.ts +143 -54
- package/src/index.mjs +5 -0
- package/src/lib/boxjs.mjs +117 -104
- package/src/lib/settings-path.mjs +31 -11
- package/src/proxy/request.mjs +23 -14
package/README.md
CHANGED
|
@@ -1,140 +1,97 @@
|
|
|
1
1
|
# @nsnanocat/preference-panes
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
通用 WebView 设置面板与代理持久化存储桥接。0.3.0 起,BoxJS 完全由前端解析;API 只按安装配置中的根和模块读写数据,不下载配置、不重复校验字段或枚举。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 目录
|
|
6
6
|
|
|
7
7
|
| 目录 | 内容 |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| `dist/` | 构建产物,不提交 Git |
|
|
9
|
+
| src/SettingsHandler.mjs | 模块存储桥接 class |
|
|
10
|
+
| src/browser/ | WebView 控件、内存会话和样式 |
|
|
11
|
+
| src/lib/ | 前端 BoxJS 与通用路径解析 |
|
|
12
|
+
| src/proxy/ | 代理宿主打包入口 |
|
|
13
|
+
| test/ | 类型与行为回归测试 |
|
|
14
|
+
| examples/ | BoxJS、HTML 和 Surge 集成示例 |
|
|
15
|
+
| apifox/ | 接口说明、原生 JSON 与生成器 |
|
|
16
|
+
| .github/ | CI、双平台发布工作流 |
|
|
17
|
+
| dist/ | 构建产物,不提交 Git |
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
Biome 与 NSNanoCat Util/FlatBufferRoot 对齐:tab、LF、320 列,保留统一 lint 规则。类型声明位于 src/index.d.ts 和 src/browser/index.d.ts,JSDoc 使用中英双语。
|
|
21
20
|
|
|
22
|
-
##
|
|
21
|
+
## 代理接口
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
| --- | --- | --- |
|
|
26
|
-
| 进入主菜单 | 并发 HEAD `/configs/<模块>` | 不读取持久化设置 |
|
|
27
|
-
| 打开、再次进入或刷新模块页 | GET 模块 BoxJS,再 GET 声明字段的公共子树,各一次 | 建立新的内存会话,替换旧值 |
|
|
28
|
-
| 修改单值 | POST 对应键路径,正文为 JSON 值本身 | 仅 HTTP 200 后更新该键 |
|
|
29
|
-
| 删除单值 | DELETE 对应键路径 | 仅 HTTP 200 后移除覆盖值,显示 BoxJS 默认值 |
|
|
30
|
-
| 保存、删除后 | 不追加 GET | 成功或失败显示临时通知 |
|
|
31
|
-
|
|
32
|
-
只有 `/api/` 是固定前缀。`@BiliBili.Enhanced.Settings.Home.Top_left` 映射为 `/api/Enhanced/Settings/Home/Top_left`;`BiliBili` 从 BoxJS ID 解析,不经浏览器 header 传递。
|
|
33
|
-
|
|
34
|
-
配置资源与数据接口使用不同前缀:`/configs/Enhanced` 是 BoxJS Mock,`/api/Enhanced/…` 是持久化 API。配置 Mock 地址不部署同名线上文件,关闭模块后 HEAD 非 200 或失败即禁用入口;它的下载源可以是另一个在线资源地址。公共 HTML、JS、CSS 可以在线托管后由代理 Mock 提供,选项由浏览器实时生成。
|
|
35
|
-
|
|
36
|
-
## 浏览器组件
|
|
37
|
-
|
|
38
|
-
```js
|
|
39
|
-
import { mountPreferencePanes } from "@nsnanocat/preference-panes/browser";
|
|
40
|
-
import "@nsnanocat/preference-panes/browser/panel.css";
|
|
41
|
-
|
|
42
|
-
const panel = mountPreferencePanes({
|
|
43
|
-
element: document.querySelector("#preferences"),
|
|
44
|
-
title: "Preferences"
|
|
45
|
-
});
|
|
46
|
-
// 卸载时 panel.destroy()
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
同一份 HTML 从 `/settings/{module}` 路径读取模块标识,按固定约定读取配置:
|
|
50
|
-
|
|
51
|
-
```text
|
|
52
|
-
/settings/Enhanced → GET /configs/Enhanced
|
|
53
|
-
/settings/Global → GET /configs/Global
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
不需要查询参数。路径中的 module 既决定配置 Mock 路径,也选择 BoxJS ID 中对应模块的字段,例如 `@BiliBili.Enhanced.Settings.…` 中的 Enhanced。配置文件的实际下载地址由模块模板中的 Mock 规则指定,不写入 HTML 或页面 URL。HTML 和通用 JS 不包含业务模块目录。
|
|
57
|
-
|
|
58
|
-
| 地址 | 谁响应 | 内容 |
|
|
59
|
-
| --- | --- | --- |
|
|
60
|
-
| `/settings/Enhanced` | 公共 HTML Mock | 通用设置页面 |
|
|
61
|
-
| `/configs/Enhanced` | Enhanced 的配置 Mock | argument config 经原有生成器生成的 BoxJS JSON |
|
|
62
|
-
| `/api/Enhanced/` 或 `/api/Enhanced/Settings/` | 通用读写脚本 | 已声明字段的持久化子树 |
|
|
63
|
-
| `/api/Enhanced/Settings/Home/Top_left` | 同一个通用读写脚本 | 单键 GET/POST/DELETE |
|
|
64
|
-
|
|
65
|
-
模块模板的配置规则只匹配 `/configs/…`,脚本规则只匹配 `/api/…`,两者没有交集,不依赖命中先后顺序。代理脚本自己的 configURL 参数由模块模板提供,指向与 Mock 相同版本的 BoxJS 下载源,用于写入校验;该 configURL 是代理脚本的模块模板参数,不是页面参数。
|
|
66
|
-
|
|
67
|
-
业务主菜单由调用项目维护(Biliverse 由 Enhanced 负责),每次进入通过 `client.probe(module)` 并发 HEAD `/configs/{module}`,再打开 `/settings/模块标识`。HEAD 只检测配置 Mock 可用性,不读取存储。
|
|
68
|
-
|
|
69
|
-
通用设置页每次进入、刷新或浏览器缓存恢复时,用 `client.open(module)` GET `/configs/{module}` 一次,再 GET 持久化子树一次。用配置实时生成表单,值放在内存,不使用 localStorage/sessionStorage。保存/删除仅 HTTP 200 后更新缓存和通知,不追加 GET。现有 UI 可直接使用同一客户端的 snapshot/set/remove/leave;snapshot 返回副本。
|
|
70
|
-
|
|
71
|
-
默认 CSS 是独立的通用样式,可由调用方替换;本包不依赖 Bilibili 样式或框架。字段定义由 BoxJS 决定,通用 JS 只定义每类控件如何绘制,不编入各项目的具体选项。
|
|
72
|
-
|
|
73
|
-
## 代理读写组件
|
|
74
|
-
|
|
75
|
-
```js
|
|
23
|
+
~~~js
|
|
76
24
|
import { SettingsHandler } from "@nsnanocat/preference-panes";
|
|
77
25
|
|
|
78
26
|
const handler = new SettingsHandler({
|
|
79
27
|
origin: "https://example.org",
|
|
80
|
-
|
|
28
|
+
storageKey: "Root",
|
|
29
|
+
module: "Module"
|
|
81
30
|
});
|
|
82
31
|
const response = await handler.handle($request);
|
|
83
|
-
//
|
|
84
|
-
|
|
32
|
+
// 使用现有代理宿主的 done 适配。
|
|
33
|
+
// Adapt the response with the existing proxy host's done function.
|
|
34
|
+
~~~
|
|
85
35
|
|
|
86
|
-
|
|
36
|
+
安装配置固定 Root.Module,浏览器不能通过 header 指定其它根。API 不接受 configURL、loadConfig 或 resolveSettings,也不依赖 BoxJS 是否可用。
|
|
87
37
|
|
|
88
|
-
|
|
38
|
+
| 请求 | 行为 |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| HEAD /api/Module/… | 确认路由可达,不读取存储 |
|
|
41
|
+
| GET /api/Module/Settings/key | 返回原值,缺失返回 404 |
|
|
42
|
+
| POST /api/Module/Settings/key | 以任意 JSON 值替换该位置,成功 200 |
|
|
43
|
+
| DELETE /api/Module/Settings/key | 删除键或子树,不存在也成功 |
|
|
44
|
+
| GET /api/Module/Caches | 返回所有 Caches |
|
|
45
|
+
| DELETE /api/Module/Caches | 清空缓存,保留 Settings |
|
|
46
|
+
| DELETE /api/Module/ | 重置模块全部数据,保留 Root 下其它模块 |
|
|
89
47
|
|
|
90
|
-
|
|
48
|
+
POST 正文就是值本身,允许对象、数组、null、字符串、数字或布尔值。不存在于 BoxJS 中的键也允许读写。使用 util Storage/Lodash 做根对象读改写,保留同级数据;每次 GET 读一次根,POST/DELETE 读一次再写一次,不发网络请求。仍检查模块归属、路径格式、请求来源、JSON 语法和正文大小;不做 BoxJS 业务校验。
|
|
91
49
|
|
|
92
|
-
|
|
50
|
+
## WebView
|
|
93
51
|
|
|
94
|
-
|
|
52
|
+
~~~js
|
|
53
|
+
import { mountPreferencePanes } from "@nsnanocat/preference-panes/browser";
|
|
54
|
+
import "@nsnanocat/preference-panes/browser/panel.css";
|
|
95
55
|
|
|
96
|
-
|
|
56
|
+
const panel = mountPreferencePanes({ element: document.querySelector("#preferences") });
|
|
57
|
+
// 卸载时调用 panel.destroy()。
|
|
58
|
+
// Call panel.destroy() when unmounting.
|
|
59
|
+
~~~
|
|
97
60
|
|
|
98
|
-
|
|
61
|
+
同一份 HTML 从 /settings/{module} 读取模块名,再 GET /configs/{module} 取得 BoxJS 并生成控件。配置源地址写在模块的 Mock 规则中,不写入页面 query 参数或 API。
|
|
99
62
|
|
|
100
|
-
|
|
63
|
+
每次进入主菜单仅并发 HEAD 各配置 Mock。打开、再次进入或刷新模块页,各 GET 一次 BoxJS 与设置子树;404 的设置子树按无覆盖值处理。保存/删除根据 HTTP 200 更新页面缓存并显示通知,不追加 GET。
|
|
101
64
|
|
|
102
|
-
|
|
103
|
-
| --- | --- |
|
|
104
|
-
| `name`、`val`、`type`、`desc`、`items` | 控件标题、默认值、类型、说明和选项 |
|
|
105
|
-
| `placeholder` | 文本和数字输入框的占位提示 |
|
|
106
|
-
| `rows`、`autoGrow` | 多行文本框的基础行数和自动高度;保存值仍为字符串 |
|
|
107
|
-
| app 的 `name`、`author`、`desc`、`descs`、`repo` | 页面名称、作者、多段说明及项目链接 |
|
|
108
|
-
| app 的 `icon`、`icons` | 显式图标优先;否则取彩色版 `icons[1]`,单个图标则用 `icons[0]` |
|
|
109
|
-
| app 的 `id`、`script` | 保留在 `definition.metadata` 中,不参与路径映射或脚本执行 |
|
|
65
|
+
设置页使用分组行布局:单选为下拉框,开关为即时切换,多选显示摘要并进入可前进/后退的二级选项页。文本输入、下拉选择及勾选变化均立即串行 POST,无逐项保存或删除按钮;失败恢复当前项已保存值,较新的输入不会被较早请求覆盖。多选页返回时保留主列表滚动位置,不重新 GET 配置。单键 DELETE 能力保留在 API/客户端方法中,不作为逐项页面按钮展示。
|
|
110
66
|
|
|
111
|
-
|
|
67
|
+
模块页底部提供查看/刷新 Caches、清空 Caches 和重置模块。查看缓存按需 GET;清空和重置经确认后 DELETE,成功只更新本页状态。重置后控件显示当前 BoxJS 默认值,再次进入页面才重新读取。模块选择、设置值校验和默认值处理都在前端完成。
|
|
112
68
|
|
|
113
|
-
|
|
69
|
+
业务主菜单由调用项目维护,Biliverse 的入口和四个模块按钮归 Enhanced。未提供对应配置 Mock 的插件入口保持禁用。
|
|
114
70
|
|
|
115
|
-
|
|
71
|
+
## BoxJS 兼容
|
|
116
72
|
|
|
117
|
-
|
|
73
|
+
前端接受字段数组、单 app 和 apps 订阅。字段 ID 为 @根.模块.子路径.键;模块归属来自字段 ID,不能用 app 名称推断。
|
|
118
74
|
|
|
119
|
-
|
|
75
|
+
- name/val/type/desc/items:控件标题、默认值、类型、说明和选项。
|
|
76
|
+
- boolean/selects/checkboxes/text/textarea/number:支持的控件类型。
|
|
77
|
+
- placeholder/rows/autoGrow:输入提示、多行基础行数和自动高度。
|
|
78
|
+
- app name/author/desc/descs/repo:纯文本标题、作者、说明和项目链接。
|
|
79
|
+
- icon/icons:显式图标优先,原版 icons 为透明/彩色顺序,不是亮暗顺序。
|
|
80
|
+
- script:仅保留元数据,不下载或执行。
|
|
81
|
+
|
|
82
|
+
不执行 BoxJS HTML、脚本、动态字符串 items,不通过 keys 推导额外字段。WebView 使用原生网络与对象访问,不打入 util 的网络、存储或 Lodash polyfill。代理安装的 storageKey/module 应由接入方与 BoxJS 路径保持一致。
|
|
83
|
+
|
|
84
|
+
## 构建与发布
|
|
85
|
+
|
|
86
|
+
~~~sh
|
|
120
87
|
npm ci --registry=https://registry.npmjs.org/ --@nsnanocat:registry=https://registry.npmjs.org/
|
|
121
88
|
npm run build
|
|
122
89
|
npm run check
|
|
123
90
|
npm run apifox:generate
|
|
124
91
|
npm run apifox:check
|
|
125
92
|
npm pack --dry-run
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
构建生成可直接加载的 `dist/preference-panes.mjs` 和代理 IIFE `dist/preference-panes.request.js`,公共样式源码位于 `src/browser/panel.css`。代理包包括 util 的平台适配和 `@nsnanocat/url`,不依赖 Node 内置模块。
|
|
129
|
-
|
|
130
|
-
[Surge 模板](examples/surge.sgmodule)使用原生 Map Local 提供静态资源,http-request 提供持久化 API。模板中的域名均为占位,尚未部署;需要把源码资源和 dist 产物发布到自己的资源地址。其 `argument` 只配置 `origin` 和 `configURL`,不会固化字段。Map Local 下载缓存的更新时机由代理管理;浏览器 no-store 不会强制 Surge 更新资源缓存。配置 Mock 与脚本 configURL 应引用同一版本的 BoxJS。
|
|
131
|
-
|
|
132
|
-
Quantumult X 等不能通过模板传递 `$argument` 的平台,需要在构建入口注入这两个地址参数,再打包同一通用执行端;本仓库没有声称该 Surge 模板可直接安装到其它代理。隔离测试覆盖 Surge/QX 宿主 API,尚未在用户设备上安装验收。
|
|
133
|
-
|
|
134
|
-
## 接口文档与发布
|
|
93
|
+
~~~
|
|
135
94
|
|
|
136
|
-
-
|
|
137
|
-
- [Apifox 原生 JSON](apifox/preference-panes.apifox.json)
|
|
138
|
-
- [Apifox 项目](https://app.apifox.com/project/8803052)、[文档维护与同步](apifox/README.md)
|
|
95
|
+
构建生成 dist/preference-panes.mjs 和 dist/preference-panes.request.js;公开 import 路径由 exports 保持稳定。0.3.0 的安装参数替换 0.2.0 的 configURL,HTTP 读写从声明字段变为模块内的任意数据,是一次契约升级。
|
|
139
96
|
|
|
140
|
-
|
|
97
|
+
[完整接口说明](apifox/guide.md) · [Apifox JSON](apifox/preference-panes.apifox.json) · [同步方式](apifox/README.md) · [发布工作流](.github/RELEASING.md)
|