ebox/docs/maintainer/ebox-incremental-update-contract.zh.md

74 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ebox 增量更新合同
本文定义底层发布合同。它独立于 ETAF 应用状态,直接使用 Ebox 的调用者和上层包都必须遵守。
## 所有权
1. 调用者拥有新的 source tree。
2. `ebox-tree.el` 拥有 identity、key、遍历和 snapshot。
3. `ebox-style.el`、`ebox-measure.el` 与布局模块拥有归一化、测量和几何。
4. `ebox-incremental.el` 拥有 dirty 分类、live fact 适配、纯声明式 commit 准备和 Ebox 报告语义;`ebox-patch-plan.el` 只用不可变 parent fact 归并 tentative operation。
5. `ebox-surface.el` 投影 retained candidate并让 Ebox runtime-state 发布加入 TP transaction。
6. TP 拥有首次 mount、声明式 commit、handle 更新、viewport/theme 更新和 scroll 更新的通用 retained-surface reconciliation、mount/index 状态、全部 live buffer diff 执行、revision 变更和 rollback。
7. `ebox-buffer-backend.el` 只构造和整形带文本属性的渲染字符串,不拥有 live marker 或 buffer mutation executor。
任何层都不能从可见 buffer 文本推断应用状态;公共调用者不能原地修改已经发布的树。每条公共 live 发布路径,包括 `ebox-render-to-buffer`、其展示包装 `ebox-display-buffer` 以及 commit/update 入口,都使用 retained TP surface公共门面不再提供擦除 buffer 后执行任意 BODY 的 writer。
## Commit 生命周期
```text
新的根树
-> 校验与归一化
-> 复制到 surface-owned candidate state
-> reconciliation TP object、key 与 Ebox identity
-> 测量/布局候选
-> 分类 dirty owner
-> 生成 TP surface plan 与 Ebox report base
-> TP 准备并原子发布 buffer 变更
-> Ebox transaction participant 发布匹配的 runtime index/report
-> 成功后退役 Ebox timer并预热已提交的 scroll state
```
候选要么完整发布要么丢弃。render、TP 写入、Ebox participant 或发布回调失败时,必须保留之前的 buffer 文本、属性、TP revision、Ebox runtime identity、滚动状态和最近一次成功报告。如果目标 buffer 在发布期间被 killteardown 是最终状态rollback 绝不能把它复活。
## Patch 顺序
规划器优先使用 `paint-patch`,再使用 `span-patch`、`owner-rerender`,最后在几何或 identity 使小操作不安全时使用 `root-rerender`。incremental adapter 从 live generation fact 推导 tentative ownerpure patch port 随后只接收这些 artifact 与不可变 parent table。这些名称描述的是 Ebox 的语义 owner 范围;只有 TP 负责计算并执行物理文本/属性 diff。Patch 不得静默扩大语义范围。报告保留 Ebox strategy 与 planned scope同时单独记录 TP 的实际 surface operation 和 revision。
span、owner-scoped、formatting-context 或 mixed 局部输出被拒绝时producer 先重建普通 candidate state再渲染完整 root。被拒绝的尝试留下的临时坐标、fragment 和 paint layer 不能授权发布。报告保留 planned strategy 与 scope普通 fallback 的 `:projection-kind``nil`。因此planned mixed strategy 不能证明计算始终局限在局部。
## 严格 retained viewport reflow
`viewport-reflow` 是一个明确的 retained projection kind只用于范围很窄、由 proof 驱动的 viewport resize 路径。只有以下条件全部满足时规划器才能选择它plan 是一个 root-owned geometry `owner-rerender`;旧 root 与 candidate root 是同一个 retained root没有 dirty entry 修改 childrennode-key set、region-id set 和 parent table 都不变;旧 surface 和当前 style environment 都不需要 cascade 或 inline-inheritance 重新计算;没有 scroll stateroot 没有 visible-overflow scope旧 surface 存在非空 retained node-object table。仅改变 width、仅改变 height 以及同时改变两个轴使用同一套 proof。
选择该路径后candidate 保留已发布的 Ebox topology并复用 retained TP node-object subtree。Producer 仍会重新执行 viewport-sensitive layout 并生成新的 surface planTP 继续负责 scoped buffer diff、revision、stable identity 和原子 rollback。即使最终文本 patch 很小topology、cascade、inheritance、scroll、overflow 或 display-signature 变化也不能报告为 `viewport-reflow`
任意 proof 条件失败时,更新必须使用普通安全 projection 路径。该 fallback 可以执行更宽的 node projection 和 TP reconciliation但必须保持相同的输出、identity、publication 和 rollback 合同。`tests/ebox-surface-tests.el` 覆盖 retained width/height/both-axis 路径、每个不安全 fallback 触发条件,以及 candidate preparation 之后的 publication failure。
## 保留式 scroll window
对于 chrome-free、缓存 rendered lines 已覆盖当前可见窗口的 root scroll owner
lazy prefix 可以仍未完整 materializescroll patch 会
直接从 staged visible window 拼接输出,不再进入完整 candidate layout。它复用已
发布的 cascade、viewport axes、object maps 和 descendant `region-box-table`,只推进
scroll offset 并安装 root `ebox-scroll-window` 属性。证明保持保守cache miss、
chrome、active style dependency、topology 变化或窗口不完整时,回退到普通 retained
路径。Scroll publication 仍经过 TP 与 Ebox participant即使 TP client-state 发布
之后失败也会一起恢复文本、offset、index、object、mount 和 report。
## Identity 与坐标
Key 只在同级兄弟集合内有效。声明式 source tree 不拥有 live TP object、marker 或 buffer 坐标。live 逻辑 `:id` 通过 `ebox-region-resolve` 解析为绑定某个 TP surface object 的不透明 handle同一 source 挂载到两个 buffer 时会得到不同 handle。Region 与 host-ref 位置绑定于 generationbuffer 变更后调用者必须通过公共 accessor 重新获得位置。Buffer marker、display span 和 text property 是发布事实,不是 source tree identity。
## 验证
每条更新路径都要验证:
- 发布后的可见文本和属性完全正确;
- 兄弟节点重排时 keyed identity 稳定;
- rollback 后没有候选数据残留;
- 可以局部更新时 patch 范围受控;
- native reflow 不可用时 fallback 正确。
更新行为的聚焦测试使用 `tests/ebox-commit-tests.el`、`tests/ebox-core-render-tests.el` 和 `tests/ebox-grid-tests.el``tests/ebox-package-tests.el` 守护 live-buffer 发布边界;然后运行 `make check`