173 lines
9.2 KiB
Markdown
173 lines
9.2 KiB
Markdown
# 4-18 [done] 树域 final DOM shell 切换硬门禁 v1
|
||||
|
|
|
|||
|
|
> 创建时间:2026-04-28
|
|||
|
|
>
|
|||
|
|
> 目的:纠正此前把 `Rust/WASM reducer runtime` 误当成 `final Rust renderer` 的完成口径,重新定义 page tree / file tree / picker 真正收口所需的不可绕过门禁。
|
|||
|
|
>
|
|||
|
|
> 前置文档:
|
|||
|
|
> - `/mnt/Data1T/mnote/design/04-tree-domain/done/4-11-tree-rust-family-final-renderer-and-host-thinning-checklist-v1.md`
|
|||
|
|
> - `/mnt/Data1T/mnote/design/04-tree-domain/process/4-16-tree-rust-family-remaining-final-runtime-checklist-v1.md`
|
|||
|
|
> - `/mnt/Data1T/mnote/design/04-tree-domain/process/1.md`
|
|||
|
|
|
|||
|
|
## 1. 口径纠偏
|
|||
|
|
|
|||
|
|
### 2026-04-28 收口结果
|
|||
|
|
|
|||
|
|
本轮 `task-010` 至 `task-013` 已按本文硬门禁完成默认主路径切换:
|
|||
|
|
|
|||
|
|
- `TreeShellHost` 在 `rust_family + workspaceId` 下默认选择 `rust_wasm_dom_shell_host`。
|
|||
|
|
- `TreeShellIframeHost` 仅在显式 `NEXT_PUBLIC_TREE_SHELL_LEGACY_IFRAME_HOST=1` 时进入,继续作为 legacy/debug 排障 host。
|
|||
|
|
- 默认 page tree / file tree / picker 主路径标注 `data-tree-browser-bridge="dom_wasm"`,负向测试禁止 `iframe_srcdoc` 被当成默认成功路径。
|
|||
|
|
- 默认 DOM host 不再调用 `LOCAL_TREE_SHELL_TEMPLATE`、`buildInlinePageTreeHtml`、`buildInlineFileTreeHtml`、`buildInlinePickerHtml`。
|
|||
|
|
- 默认 DOM host 的展开、选择、高亮、打开、右键、拖放、picker pick 由 `reduceTreeShellRuntime` WASM artifact 或同源 `/api/tree/runtime/reduce` Rust seam 返回的 `state / hostEvents / commandEvents` 驱动;本地 JS fallback reducer 只保留在 legacy iframe host 内。
|
|||
|
|
- `task112-tree-rust-family-regression-smoke.js` 与 `task113-picker-keyboard-regression-smoke.js` 已支持并验证默认 DOM host;legacy iframe 仅兼容显式 legacy 路径。
|
|||
|
|
|
|||
|
|
`task-010` 之前,过去几轮已经完成的是:
|
|||
|
|
|
|||
|
|
- Rust renderer input / state family / runtime facade。
|
|||
|
|
- `tree-shell-runtime-wasm` reducer artifact。
|
|||
|
|
- 3000 主路径 wasm-first `reduceTreeShellRuntime`。
|
|||
|
|
- page / filetree / picker 的若干 hostEvent / commandEvent / DOM patch 切片。
|
|||
|
|
- `rust_runtime_artifact_host` 主路径标识。
|
|||
|
|
|
|||
|
|
这些都只是 `Rust/WASM reducer runtime-first`,不是 `final Rust DOM renderer`。
|
|||
|
|
|
|||
|
|
`task-010` 之前真正没有完成的是:
|
|||
|
|
|
|||
|
|
- 当时 `TreeShellIframeHost` 仍在 3000 主路径生成 `srcDoc`。
|
|||
|
|
- 当时 `LOCAL_TREE_SHELL_TEMPLATE` 仍承载 DOM 壳、事件绑定、hydration、fallback renderer 与状态 patch。
|
|||
|
|
- 当时 `data-tree-browser-bridge="iframe_srcdoc"` 仍是默认真实流量的浏览器执行层。
|
|||
|
|
- 当时 page / filetree / picker 的 DOM shell 仍由 JS adapter 维护,Rust/WASM 只主导 reducer result。
|
|||
|
|
|
|||
|
|
因此,后续任何文档、harness、提交说明都不能再把 `task112/task113 通过`、`rust_runtime_artifact_host` 或 `wasmModuleUrl/jsGlueUrl 非空` 作为 final renderer 完成声明;必须同时检查默认 host implementation、浏览器 bridge 标记和 legacy flag 边界。
|
|||
|
|
|
|||
|
|
## 2. 不可绕过的完成定义
|
|||
|
|
|
|||
|
|
只有同时满足以下条件,才允许声明“页面树 / 文件树已切换为 Rust final renderer”:
|
|||
|
|
|
|||
|
|
- 3000 默认真实流量的 page tree / file tree / picker 不再通过 `TreeShellIframeHost` 的 `srcDoc` 内联模板承载 DOM shell。
|
|||
|
|
- 默认主路径不再标注 `data-tree-browser-bridge="iframe_srcdoc"`。
|
|||
|
|
- `LOCAL_TREE_SHELL_TEMPLATE`、`buildInlinePageTreeHtml`、`buildInlineFileTreeHtml`、`buildInlinePickerHtml` 不再参与默认 page / filetree / picker 渲染路径。
|
|||
|
|
- `TreeShellIframeHost` 只能作为显式 legacy/debug host 存在,必须由明确 debug flag 或 debug route 进入。
|
|||
|
|
- Rust/WASM 或等价 Rust family renderer 持有初始渲染、动态 DOM patch、事件绑定归一化、展开/选择/高亮/拖放反馈的运行时 DOM shell。
|
|||
|
|
- 3000 host 只保留挂载、认证、transport、文件字节读取、postMessage / command bridge、artifact 资源发布等浏览器能力边界。
|
|||
|
|
- page / filetree / picker 的主路径回归测试必须包含负向断言:默认路径不得出现 `iframe_srcdoc` DOM renderer。
|
|||
|
|
- `task112/task113` 仍通过,并且 smoke 需要验证的是新 Rust DOM shell 主路径,而不是旧 inline iframe host。
|
|||
|
|
|
|||
|
|
## 3. 第一优先级:先加负向门禁
|
|||
|
|
|
|||
|
|
下一轮实现前必须先补负向测试,防止继续小步绕开最终目标。
|
|||
|
|
|
|||
|
|
### 前端门禁
|
|||
|
|
|
|||
|
|
- `tree-shell-iframe-host.test.tsx` 或新测试必须断言默认主路径不再输出:
|
|||
|
|
- `srcDoc={renderedInlineSrcDoc}`
|
|||
|
|
- `data-tree-browser-bridge="iframe_srcdoc"`
|
|||
|
|
- `LOCAL_TREE_SHELL_TEMPLATE`
|
|||
|
|
- `buildInlineInitialTreeHtml`
|
|||
|
|
- `buildInlinePageTreeHtml`
|
|||
|
|
- `buildInlineFileTreeHtml`
|
|||
|
|
- `buildInlinePickerHtml`
|
|||
|
|
- 允许这些字符串只出现在显式 `legacy/debug` 测试或旧 host 文件中,但不能在默认 host implementation 测试里作为成功条件。
|
|||
|
|
|
|||
|
|
### smoke 门禁
|
|||
|
|
|
|||
|
|
- `task112-tree-rust-family-regression-smoke.js` 需要确认 page/filetree 默认 renderer host 不是 inline srcdoc host。
|
|||
|
|
- `task113-picker-keyboard-regression-smoke.js` 需要确认 picker 默认 renderer host 不是 inline srcdoc host。
|
|||
|
|
- direct `/api/tree/shell -> 3104` debug disabled 仍应保留,但它不能替代 final DOM shell 验收。
|
|||
|
|
|
|||
|
|
### 文档门禁
|
|||
|
|
|
|||
|
|
- `harness` 任务完成条件必须包含“不依赖 iframe srcdoc DOM shell”。
|
|||
|
|
- 任一阶段文档若只完成 reducer/state family,标题和完成记录必须写成 `runtime reducer/state-family stage`,不得写成 `final renderer completed`。
|
|||
|
|
|
|||
|
|
## 4. 实现路线
|
|||
|
|
|
|||
|
|
### Phase P:冻结旧 inline host 主路径
|
|||
|
|
|
|||
|
|
状态:已完成。
|
|||
|
|
|
|||
|
|
目标:把旧 `TreeShellIframeHost` 从“默认主路径”降级为“legacy/debug 候选”。
|
|||
|
|
|
|||
|
|
执行项:
|
|||
|
|
|
|||
|
|
- 新增主路径 host 名称,例如 `rust_dom_shell_host` 或 `rust_wasm_dom_shell_host`。
|
|||
|
|
- 保留旧 `TreeShellIframeHost`,但改名或包裹为 `LegacyTreeShellIframeHost`,只允许 debug/legacy flag 进入。
|
|||
|
|
- `TreeShellHost` 默认选择新 host;旧 host 不再作为 `rust_family` 默认实现。
|
|||
|
|
- 所有旧 `srcDoc` 合同测试迁到 legacy/debug 测试组。
|
|||
|
|
|
|||
|
|
验收:
|
|||
|
|
|
|||
|
|
- 默认 `TreeShellHost` 测试不再匹配 `iframe_srcdoc`。
|
|||
|
|
- legacy/debug 测试仍能证明旧 host 可用于回退排障。
|
|||
|
|
|
|||
|
|
### Phase Q:建立 Rust/WASM DOM shell host
|
|||
|
|
|
|||
|
|
状态:已完成默认主路径切换。
|
|||
|
|
|
|||
|
|
目标:给 page / filetree / picker 建立一个不依赖 inline JS template 的 DOM shell 承载。
|
|||
|
|
|
|||
|
|
执行项:
|
|||
|
|
|
|||
|
|
- 复用现有 `rendererInput` 与 `TreeShellRuntimeRequest/Result`。
|
|||
|
|
- WASM artifact 输出或驱动 DOM shell 初始化,不再由 `buildInline*Html` 生成主路径 HTML。
|
|||
|
|
- DOM patch、hostEvent、commandEvent 的应用入口统一放在新 host adapter,adapter 只负责浏览器边界,不维护树状态机。
|
|||
|
|
- page tree 先切,再切 picker,最后切 filetree。
|
|||
|
|
|
|||
|
|
验收:
|
|||
|
|
|
|||
|
|
- page / picker / filetree 默认主路径首屏可见。
|
|||
|
|
- 键盘、展开、选择、右键、打开、拖放反馈继续工作。
|
|||
|
|
- `task112/task113` 使用新 host 通过。
|
|||
|
|
|
|||
|
|
### Phase R:删除默认路径 JS renderer 状态机
|
|||
|
|
|
|||
|
|
状态:已完成默认路径隔离;旧 JS renderer/state machine 仅保留在 legacy iframe host。
|
|||
|
|
|
|||
|
|
目标:移除默认主路径对旧 JS DOM renderer/state machine 的依赖。
|
|||
|
|
|
|||
|
|
执行项:
|
|||
|
|
|
|||
|
|
- 默认路径删除对 `renderTree()`、`renderFileTree()`、`hydrateInitialPageTree()`、`hydrateInitialPickerTree()` 等旧 DOM shell 的调用。
|
|||
|
|
- 旧本地 fallback reducer 只保留在 legacy/debug host,不参与默认真实流量。
|
|||
|
|
- 删除或隔离 `buildInlinePageTreeHtml` / `buildInlineFileTreeHtml` / `buildInlinePickerHtml` 的默认路径调用。
|
|||
|
|
|
|||
|
|
验收:
|
|||
|
|
|
|||
|
|
- 默认 host implementation 中没有 `srcDoc` 主渲染链。
|
|||
|
|
- 默认主路径没有第二套 JS 展开、选择、高亮、拖放接受规则。
|
|||
|
|
- `TreeShellIframeHost` 可被删除,或只以 `LegacyTreeShellIframeHost` 形式留在 debug 目录。
|
|||
|
|
|
|||
|
|
### Phase S:最终文档收口
|
|||
|
|
|
|||
|
|
状态:已更新 4-11、4-16、4-18 的真实代码状态。
|
|||
|
|
|
|||
|
|
目标:只在真实代码满足门禁后移动文档状态。
|
|||
|
|
|
|||
|
|
执行项:
|
|||
|
|
|
|||
|
|
- `4-11`、`4-16`、`4-18` 中所有 final DOM shell gate 勾选。
|
|||
|
|
- 将真正完成后的最终清单移动到 `done/`。
|
|||
|
|
- 若 `4-12` 到 `4-15` 的旧标题继续误导,则移动到 `design/old/done` 或在标题中明确标记 `state-family stage`。
|
|||
|
|
|
|||
|
|
验收:
|
|||
|
|
|
|||
|
|
- 文档状态与默认真实流量一致。
|
|||
|
|
- 没有任何 `done` 文档暗示 `iframe_srcdoc` 主路径等于 final Rust renderer。
|
|||
|
|
|
|||
|
|
## 5. 非目标
|
|||
|
|
|
|||
|
|
- 不拆除 Convex substrate。
|
|||
|
|
- 不恢复 `3104` 为默认浏览器入口。
|
|||
|
|
- 不把文件字节读取、浏览器 DnD `File[]` 对象直接塞入 Rust/WASM。
|
|||
|
|
- 不因为切 DOM shell 而重写 tree command / projection / artifact contract。
|
|||
|
|
- 不把 `task112/task113` 的旧 inline host smoke 当作最终通过标准。
|
|||
|
|
|
|||
|
|
## 6. 当前下一步
|
|||
|
|
|
|||
|
|
本文定义的 final DOM shell 硬门禁已收口。后续继续推进时,不应再回到 `iframe_srcdoc` 默认路径,而应沿以下方向继续减少过渡面:
|
|||
|
|
|
|||
|
|
1. 保留 `NEXT_PUBLIC_TREE_SHELL_LEGACY_IFRAME_HOST=1` 作为短期排障开关,后续在 smoke 与线上观测稳定后删除旧 host。
|
|||
|
|
2. 继续把剩余 tree command、Page Aggregate、snapshot 独立事件等非 DOM shell 收口项按各自设计稿推进。
|
|||
|
|
3. 若新增 page / filetree / picker 交互,默认必须接入 `TreeShellRuntimeRequest/Result`,不得在 DOM host 增加第二套 JS reducer。
|