fix(site/v0.8.0): 站点版本同步 + 现场失败修复(file:// 打不开 OPFS 的可操作错误)

用户报告"站点演示失败了",实测复现并定位根因:

- 现象:直接双击 site/demo.html(file://)→ 点「🌲 Aria」→
  " 数据库初始化失败: Failed to open AriaEngine database "demo""(Memory 正常)。
- 根因:file:// 属不透明来源,Chromium 拒绝 navigator.storage.getDirectory()
  并抛 SecurityError;此时 isSecureContext 仍为 true、API 也存在,无法提前探测。
  引擎把它包成 ARIA_OPEN_ERROR 时丢掉了底层错误 → 消息对用户不可操作。
- 修复:OPFSBackend.open() 显式检查并抛 ARIA_OPFS_UNAVAILABLE,消息给出两条出路
  (用 http(s) 打开 / 改用 mode:'memory'),原始 SecurityError 挂 cause;
  site/demo.html 额外用中文说明"为什么失败 + 怎么修"。

顺带修掉一个更普遍的问题:DatabaseError 的第三个参数只进 details,err.cause
恒为 undefined,而文档/注释多处写"底层错误作为 cause 保留"。现在两者都成立
(details 语义不变;cause 声明为公开字段并接入标准错误链)。

站点版本同步:demo.html(title / 状态栏 / SQL 预置脚本 / console 日志)与
benchmark.html(title)此前仍是 v0.7.4(日志甚至是 v0.4.2)→ 统一 v0.8.0;
docs.html 的 AriaEngine 版本演进列表补上 v0.8.0 条目、错误码表补
ARIA_OPFS_UNAVAILABLE;README 补"OPFS 需要 http(s) 页面"的浏览器兼容说明。

回归与门禁:tests/engine/aria-opfs-unavailable.test.ts(5 项,含正常环境正控);
变异 R19 / R20 均被拦住(总计 42/42);93 套件 / 1985 用例;覆盖率
90.59 / 82.61 / 94.14 / 93.50(阈值 90/82/94/93);e2e 14/14;lint + 两份 tsc 干净;
dist 重建(251,731 B / gzip 63,431 B)并已同步全部体积宣称。
This commit is contained in:
thzxx
2026-09-15 17:09:29 +08:00
parent 0b44620721
commit c1c3036abd
25 changed files with 439 additions and 55 deletions
+32 -8
View File
@@ -11,8 +11,8 @@ All notable changes to MetonaSqlark will be documented in this file.
> 必然复发的结构**:多处并存的语义实现被收敛为唯一实现,并第一次让崩溃语义、
> 错误码一致性、入口等价性变成可机器验证的门禁。
>
> 测试规模 1304 → **198092 套件)+ 14 项 e2e**(另 4 个重型套件在独立 CI
> job 串行运行);B-6 与审查轮的全部修复另有 **40 项变异验证**`scripts/mutation-b6.py`
> 测试规模 1304 → **198593 套件)+ 14 项 e2e**(另 4 个重型套件在独立 CI
> job 串行运行);B-6 与审查轮的全部修复另有 **42 项变异验证**`scripts/mutation-b6.py`
> 全部通过,且脚本自带正控 / 编译失败区分 / 超时 / 逐字节恢复校验 / 进程锁)。
### 工作流 B · 结构根治(消除整类缺陷)
@@ -93,7 +93,7 @@ All notable changes to MetonaSqlark will be documented in this file.
- 新增 `tests/v080-b6-single-commit-point.test.ts`(审查轮后扩到 **96 项**
manifest 严格校验表驱动 24 例 + 事务水位 P0 + 前缀空洞语义 + 在途读者与退休文件 +
孤儿回收门槛 + 稀疏/损坏分支 + 旧格式形状校验 + bloom 配置透传)与
`scripts/mutation-b6.py`**40 项**变异验证:把修复回退到修复前行为,对应用例
`scripts/mutation-b6.py`**42 项**变异验证:把修复回退到修复前行为,对应用例
必须失败 —— 全部被拦住)。
- **B-6 存储提交点(KVStore 侧止血)** — 两处 P0:① `open()` 遇损坏日志尾部会**清空整个
日志**(写 3 条 → 第 4 条撕裂 → 重开可见 → 再重开全空);② 自动 checkpoint
@@ -135,7 +135,7 @@ All notable changes to MetonaSqlark will be documented in this file.
statements 90 / branches 82 / functions 94 / lines 93);CI 常规 job 带
`--coverage`lint 去掉 `continue-on-error`;新增 `tests/` 类型检查
(修复 **103 个**被 babel 剥离类型掩盖的测试类型错误);CI 校验 dist 与源码同步。
→ 实测(v0.8.0 收尾复测)Statements 90.59% / Branches 82.59% / Functions 94.14% /
→ 实测(v0.8.0 收尾复测)Statements 90.59% / Branches 82.61% / Functions 94.14% /
Lines 93.50%(命令与 CI 常规 job 完全一致,可复现)。
- **测试介质忠实性修正**(两处同源缺陷,此前让所有多实例/多库验证跑在错误语义上)
- `SharedMemoryBackend` 的读缓存是每实例私有的 → 介质退化为"每实例一份快照",
@@ -232,8 +232,8 @@ All notable changes to MetonaSqlark will be documented in this file.
functions 94% 阈值 → 实测 93.84%),暴露出退化路径 `cloneRowFallback` 从未被测试;
`tests/engine/row-clone.test.ts`8 项:structuredClone 可用/不可用/抛错三条路径、
Date/TypedArray/ArrayBuffer、深拷贝不泄漏、批量拷贝)后门禁恢复通过。
- 最终数字(口径修正后,含新增的 8 项测试):92 套件 / 1980 用例,
语句 90.59% / 分支 82.59% / 函数 94.14% / 行 93.50%。
- 最终数字(口径修正后,含新增的 8 项测试):93 套件 / 1985 用例,
语句 90.59% / 分支 82.61% / 函数 94.14% / 行 93.50%。
**测试质量修正("绿"不等于"有保护"**
@@ -246,6 +246,30 @@ All notable changes to MetonaSqlark will be documented in this file.
- `<=` 收紧为严格 `<`(冻结意图的水位必须**严格低于**意图起点);删掉死代码
`const inner``void manifest`)与误名的"非 JSON"用例。
### 现场失败修复(站点演示页 file:// 打不开 Aria 引擎)
用户报告"站点演示失败了"。复现与根因(真实 Chromium 实测,非推断):
- **现象**:直接双击 `site/demo.html``file://`)→ 点「🌲 Aria」→
`❌ 数据库初始化失败: Failed to open AriaEngine database "demo"`(切回 Memory 正常)。
- **根因**`file://` 属于不透明来源,Chromium 认为本地文件"不适合 Web 应用访问"
`navigator.storage.getDirectory()``SecurityError`。注意此时
`isSecureContext === true` 且 API **存在** —— 只有真正调用才会失败,所以无法提前探测;
而引擎把它包成 `ARIA_OPEN_ERROR` 时**丢掉了底层错误**,消息对用户不可操作。
- **修复**`OPFSBackend.open()` 显式检查 OPFS 可用性,抛 `ARIA_OPFS_UNAVAILABLE`
消息里直接给出两条出路(**用 http(s) 打开**`node tests/e2e/server.cjs` /
`npx serve .`,或改用 `mode: 'memory'`),并把原始 `SecurityError` 挂在 cause 上。
- **顺带修掉一个更普遍的问题**`DatabaseError` 的第三个参数只存进 `details`
**`err.cause` 恒为 undefined** —— 而文档/注释多处写"底层错误作为 cause 保留"。
现在两个字段都成立(`details` 语义不变,向后兼容;`cause` 接入标准错误链)。
- **站点版本同步**`site/demo.html`title/状态栏/SQL 预置脚本/console 日志)、
`site/benchmark.html`title)此前仍标 v0.7.4(甚至 v0.4.2),已统一到 v0.8.0
`site/docs.html` 的 AriaEngine 版本演进列表补上 v0.8.0 条目,错误码表补
`ARIA_OPFS_UNAVAILABLE`
- 回归:`tests/engine/aria-opfs-unavailable.test.ts`5 项:storage 缺失 /
SecurityError 带 cause 与建议 / 正常环境正控 / DatabaseError 两个字段语义),
变异 R19 / R20 均被拦住。
### 文档订正(第二轮 G6:16 条不成立的宣称)
- **MVCC**`site/docs.html`(表格、事务行、能力表)与 `site/demo.html` 仍写
@@ -254,10 +278,10 @@ All notable changes to MetonaSqlark will be documented in this file.
- **`backup()`**`interface.ts` 注释仍写"一致性快照" → 改为"逐表读取(非跨表快照)"。
- **WAL 空洞**`docs.html` 写"空洞检测截断" → 改为"内部空洞如实上报并拒绝静默继续"。
- **体积**README 与 docs.html 写"~105KB / gzip ~27KB" → 实测 min 产物
251,109 字节 / gzip 63,145 字节(`stat -c%s dist/metona-sqlark.min.js`
251,731 字节 / gzip 63,431 字节(`stat -c%s dist/metona-sqlark.min.js`
`gzip -c dist/metona-sqlark.min.js | wc -c`)。
- **测试与覆盖率**README badge/正文、site 徽标与数字卡、CHANGELOG 全部更新为
实测值(1980 / 92 套件 / 90.59% / 82.59% / 94.14% / 93.50%)。
实测值(1985 / 93 套件 / 90.59% / 82.61% / 94.14% / 93.50%)。
- **存储模式**site 仍写"5 种存储引擎" → 改为"4 种模式 + 3 种后端"
"Tree-shakable"改为"UMD/ESM/CJS 多格式输出"(单文件 bundle + 未声明
`sideEffects`,不宜宣称可摇树)。