etaf/docs/proposals/module-boundaries.zh.md

27 KiB
Raw Blame History

ETAF 模块职责与目标架构(设计提案,未实现)

状态:设计提案。本文不描述当前已交付 API。当前行为仍以 architecture.zh.mduser-guide.zh.md 和通过的测试为准。

本文只定义目标模型、模块 owner、依赖方向和完成条件。实现顺序属于单独的 实施计划;历史名称和兼容策略不参与目标架构设计。

用户心智成本是本提案的硬约束:同一能力只有一个规范名称和一种推荐写法;内部 算法、后端节点、wrapper 和兼容别名不能作为并列公共概念。普通应用只需学习 Text、Box、ComponentFragment、布局细节和底层包通过渐进披露进入。

1. 最终模型

ETAF/Ebox 的表示链按职责分层:

AuthorView
  ↓ parse / desugar / string normalization
NormalizedView = Text | Box | Fragment | ComponentCall
  ↓ ETAF Runtime resolves ComponentCall
Resolved candidate + computed properties
  ├─ structure/geometry impact
  │    ↓ Fragment projection preserves RangeAnchors
  │  CanonicalEboxInput = Forest<TextNode | BoxNode> + RangeAnchors
  │    ↓ Ebox measure / layout
  │  LayoutPlan → GeometryPatch
  │
  └─ paint impact
       ↓ source-specific contribution adapter
       (ETAF: etaf-theme-tp; standalone Ebox: ebox-surface-tp)
     TP ContributionPlan → PaintPatch

GeometryPatch and PaintPatch join the existing TP transaction
  ↓ Emacs adapter commit / rollback
Published generation

这些层不是相互竞争或重复 materialize 的树。每次 lowering 只消费上层已经保留的 identity、computed properties 和 child 顺序;同一事实不重复解析或推导。 LayoutPlan 与 ContributionPlan 是同一候选事务的独立派生产物paint-only path 不 构造 CanonicalEboxInput 或运行 layout。两条路径在现有 transaction participant 汇合。plan 不拥有作者 identity也不是 DSL 节点。

Canonical node 的非法状态必须不可表达:

TextNode = {
  value: String,
  measurementProps,
  sourceHandle,
  eboxNodeId
}

BoxNode = {
  outer: inline | block,
  layout: Normal | RowConfig | ColumnConfig | FlexConfig | GridConfig,
  geometryProps,
  parentParticipationProps,
  children: [TextNode | BoxNode],
  sourceHandle,
  eboxNodeId
}

TextNode 没有 children/outer/layoutBoxNode 没有 content/value。participation 字段 存储在 BoxNode但只有直接父 formatting context 可以验证和解释它。

sourceHandle 是来源层拥有的 opaque handleETAF 路径指向 Runtime Text/Box/Range source独立 Ebox DSL 路径指向 Ebox author source。eboxNodeId 只 标识 Ebox retained geometry node。Renderer/surface 保留二者映射Ebox reconciliation 不得接管 Component、Fragment、Range 或 lifecycle identity。

用户需要理解的主要概念只有 TextBoxComponentFragment 是高级 结构语法;Host 是 Renderer 内部术语;Ebox Node 是后端对象,都不构成第二套 组件模型。

NormalizedView 的完整形状是:

View = Text
     | Box
     | Fragment
     | ComponentCall

作者语法和规范化 View 不是同一层。ETAF 与 Ebox 的视觉作者语法共享:

AuthorNode = String
           | TextForm
           | BoxForm
           | RowSugar
           | ColumnSugar
           | FlexSugar
           | GridSugar

String 规范化为 Text五个 Box form 规范化为带对应 typed Layout 的 Box。form 名称不进入 Runtime identity、diff、style、layout 或 paint 协议。ETAF 另外增加 Fragment、 ComponentCall、exprslotEbox DSL 不拥有这些语义。

两层作者语法共享结构词汇和规范化结果不要求共享求值环境ETAF property 是 Elisp expression.ebox DSL 是数据 form。quote 和 expression 的差异只属于 parser不产生两套 canonical schema。

Flex/Grid item 是 material child Box 在父 formatting context 中获得的角色,不是 另一种 View 或父子边类型。participation 属性存储在 child Box合法性、计算和 dirty propagation 由直接父 Flex/Grid Box 拥有。

exprslot 是计算/投影机制,不是视觉节点。目标公共 View 不接受原始 Ebox 节点;缺失的渲染能力必须先形成有类型、有 identity/impact 契约的 View/Ebox 能力, 不能通过 opaque escape 绕过框架语义。

2. Text、Box 与 Fragment

2.1 Text

Text 是文本叶子,负责:

  • 恰好一个求值后为字符串的 payload
  • 字体、前景/背景、下划线等文本 paint
  • 文字测量、换行和文本对齐的输入;
  • 可选 identity、语义和事件属性。

Text 固定为 inline不公开 :outer。它没有 View children不能嵌套 Text 也不能建立任何布局上下文。多个 styled runs 是相邻的多个 Text而不是一棵 Text 子树。需要 block participation、padding、border、尺寸或子布局时使用外层 Box。

两个作者入口的 Text grammar 精确区分求值能力:

ETAF TextForm = (text TEXT-PROP VALUE)
VALUE         = String | (expr :value Expr<String>)

Ebox TextForm = (text TEXT-PROP String)

所有属性键值对必须位于唯一 payload 之前。零个、多个、嵌套 Text 或非字符串 payload 都报错。裸字符串只是无属性 Text 的语法糖,在所有位置只有这一种解释。

2.2 Box 的两个正交轴

Box 同时拥有一个外部参与方式和一个内部布局方式:

:outer  = inline | block
layout = Normal | RowConfig | ColumnConfig | FlexConfig | GridConfig
  • :outer:这个 Box 如何参与父级的 normal 布局;
  • layout variant这个 Box 如何排列自己的子节点。

默认值是:

Box  :outer block  :layout Normal
Text :fixed inline

作者层不公开 :layout 属性,而由 form 名唯一选择 layout

(box ...)                 ; Normal
(row ...)                 ; RowConfig
(column ...)              ; ColumnConfig
(flex ...)                ; FlexConfig
(grid ...)                ; GridConfig

因此 inline-flex 写为 (flex :outer 'inline ...),不是新节点类型。:outer 是所有 Box author form 的公共属性layout config 由对应 form 的闭集属性构造。需要动态 切换 layout 时,由 expr 选择不同 View form而不是把 :layout 当普通动态样式。 Canonical Box 使用 typed Layout variant不公开 :inner 或 Ebox (:display (block flow)) 后端表示。

2.3 normal 的明确范围

normal 是一个真实但刻意收敛的布局上下文:

  • 连续的 inline Text 或 inline Box 进入同一行流并按可用宽度换行;
  • block Box 从新行开始并形成独立块;
  • block 前后的 inline 行会在块边界结束;
  • 子节点顺序保持稳定。

目标不实现完整浏览器 CSS没有 float、table、absolute/fixed positioning、 run-in、list-item 或任意匿名盒规则。Ebox 可以把 normal 映射为内部 flow 算法,但 flow 不是 ETAF 公共词汇。

当父级 Layout 是 Row/Column/Flex/Grid 时,父算法直接拥有子项 位置;子项的 :outer 不改变排列顺序。:outer 只决定节点进入 normal 父级时 是 inline 还是 block。

2.4 其他布局模式

模式 职责
row 简单水平顺序布局,不执行 Flex 空间分配
column 简单垂直顺序布局,不执行 Flex 空间分配
flex Flex sizing、direction、wrap、alignment 和 gap
grid 二维轨道、放置、跨度和 gap

这些都是 Box 的 Layout variant不是 Component也不注册 rowcolumnflexgrid 的第二套 Runtime 节点名称。作者 form 的规范化映射唯一:

box    → Box(layout = Normal)
row    → Box(layout = RowConfig)
column → Box(layout = ColumnConfig)
flex   → Box(layout = FlexConfig)
grid   → Box(layout = GridConfig)

ETAF 与 Ebox 共享这五个 Box author form。所谓“layout form”只表示输入拼写和 对应 config schema不表示保留 Host、node type 或运行时分派。

上表是唯一规范性 lowering 表。Ebox 拥有 canonical Layout variant 和 config schemaETAF parser 只处理自己的 Elisp 求值并选择同名 variant不复制取值规则。 两个入口必须通过跨接口 conformance 测试证明同一结构产生相同 canonical shape、 computed defaults 和错误。

2.5 Ebox DSL 的基础节点与语法糖

ETAF View 和 Ebox DSL 是两层不同接口但共享同一个视觉作者语法Text 是文本 叶子Box 是结构/几何容器。Ebox DSL 的完整视觉语法是:

"plain text"
(text TEXT-PROPS "styled text")
(box BOX-PROPS CHILD...)
(row BOX-PROPS CHILD...)
(column BOX-PROPS CHILD...)
(flex BOX-PROPS CHILD...)
(grid BOX-PROPS CHILD...)

字符串始终规范化为 Texttext 只接受文本内容和 Text 属性;box 只接受 children 和 Box 属性。Ebox DSL 不接受 :content,因此不存在“字符串有时是 Box content、有时又是 child”的双重解释。空 (box :width ... :height ...) 是 合法的空几何容器。

ebox-build 是作者 DSL 的 parse/desugar 入口。程序化公共端口使用两个 typed constructorebox-text-create 构造 TextNodeebox-box-create 接收一个 typed Layout variant 并构造 BoxNode。constructor 不接受作者 form 或扁平的跨 layout 属性袋ETAF Renderer 直接调用它们,不重新拼 DSL。

目标公共端口不保留无 kind 的 (ebox-create :content ...)。若运行时为了性能把 Text payload 融合进相邻 Box 存储,该优化只能发生在 canonical Text identity、 range 和 impact 已建立之后,并且必须可逆地保留这些事实;私有存储编码不能成为 作者或程序化公共 API。Range descriptor 同样是增量后端协议,不是 DSL 节点。

五个 Box author form 必须在 DSL 边界立即、无状态地构造对应 typed Layout variant 不能建立不同的 node type、identity、缓存、验证或渲染分支。任何作者 form 都拒绝 :layoutlayout-specific 属性只由对应 form 接受。

当前 DSL 的其他 tag 必须明确分类,不能与基础节点并列:

当前 tag 分类 目标表达
ebox box 的兼容别名 删除,统一写 box
spacer 空 Box 便捷糖 删除,使用无 children 的 box
row Box layout form 保留并构造 RowConfig
column Box layout form 保留并构造 ColumnConfig
flex Box layout form 保留并构造 FlexConfig
grid Box layout form 保留并构造 GridConfig
item Flex wrapper/糖 删除participation 属性直接写在 child Box
grid-item Grid wrapper/糖 删除placement 属性直接写在 child Box

Flex/Grid 直接 child 自动取得 item 角色item 不是节点类型。需要非默认参与方式时, 唯一推荐路径是显式 child Box

(flex
  (box :flex-grow 1 "Flexible")
  "Fixed")

(grid
  (box :grid-column '(1 :span 2) "Header")
  (box "Body"))

participation/placement 属性存储在 child Box但只由直接父 Flex/Grid 验证和消费; 出现在错误父级时必须报错。属性变化使父布局 owner 进入 geometry path但不改变 child Component/Text 的 identity、lifecycle 或 paint ownership。直接 Text 使用 默认 item 参数;需要非默认参数时显式包 Box。

目标 Ebox DSL 删除 eboxspaceritemgrid-item,保留 Text、Box 与 四个布局糖。布局算法仍由 Ebox 分别实现,但 canonical 视觉节点只保留 TextNode/BoxNode作者语法、canonical tree、layout plan 和运行时存储是不同层次。

2.6 Fragment

Fragment 是无视觉 wrapper 的结构 Range

  • 可以承载零个、一个或多个兄弟 View
  • 不产生 Box、尺寸、背景或布局上下文
  • Runtime 可以为其保留稳定 Range identity 并局部替换;
  • 只接受子节点和可选稳定 :key,不接受视觉/事件属性。

Fragment resolution 不把 Range identity 丢掉。它把 material children 按顺序 splice 进 CanonicalEboxInput forest同时产生 {range-id, before, after} RangeAnchor空 Fragment 仍有可插入锚点,根 Fragment 可以对应零个或多个 forest roots。Range identity 由 ETAF Runtime 拥有Ebox 只消费 descriptor 来形成局部 geometry patch RangeAnchor 不是视觉 node也不参与测量。

Component call 本身没有 :outer 或 Layout。它的根 Text/Box 决定如何参与父级 布局;返回 Fragment 的透明 Component 可以产生多个兄弟节点,因此不存在单一的 “Component 外部盒子”。

2.7 字符串、content 与空 Box

Box 子节点中的字符串规范化为 Text

(box "this is text")

等价于:

(box (text "this is text"))

ETAF 与 Ebox 作者 DSL 都不提供 (box :content "..."):content 只属于 现有未类型化运行时存储,目标公共程序化端口也不保留它。把 :content 暴露给 作者 DSL 或 canonical constructor 都会重新制造 content 与 Text children 两套模型。

ETAF 也不提供 spacer 类型。没有子节点的 Box 就是空 Box。

3. 属性契约

属性是闭集,并按 owner 验证;未知属性和不适用组合必须报错。

Owner 属性类别 代表属性
ETAF Runtime metadata identity/语义/事件/Behavior :key:ref:role:aria-*:on-*:use
ECSS author style source selector/inline declarations :class:id、style declarations
Ebox TextNode canonical 文本测量 font metrics、wrap policy、intrinsic constraints
Ebox BoxNode 外部/内部布局 :outer、typed Layout variant
Ebox BoxNode 几何 width/height/min/max、margin、padding、border widths、box sizing、overflow
Flex container 布局 :flex-direction:flex-wrap:justify-content:align-items:align-content:gap
Flex child Box 父级参与 :order:flex-grow:flex-shrink:flex-basis:align-self
Grid container 布局 track templates、auto flow、gap、item/content alignment
Grid child Box 父级参与 :grid-row:grid-column、row/column span、self alignment
TP contribution paint color/background、underline/overline、border paint、visibility paint

规则:

  • impact 是集合,不是互斥枚举;
  • :key 属于 identity不是视觉属性
  • :class 只进入 ECSS selector:id 是一个 author input可同时投影到 ECSS selector 和语义 metadata但不能由两个模块分别定义含义
  • color/background 等不改变 metrics 的贡献属于 paint-only
  • font family/size/weight 等 metric 属性属于 geometry + paint
  • padding、border width 等属于 geometry + paint
  • :outer、Layout variant 属于 structure + geometry
  • Flex/Grid participation 存储在 child Box但变化时只使对应父布局 owner geometry dirty
  • ECSS cascade 输出必须保留上述 impact set
  • ETAF/Ebox candidate normalization pipeline 只解析一次 property fact再按 owner/impact 交给 Runtime metadata、ECSS、Ebox geometry 和对应 TP adapter各 owner 不重新解析 原 plist
  • border/font 等 multi-impact fact 可以同时投影 geometry 与 paint 字段,但 computed value 只 materialize 一次,不在 Ebox node 中复制 paint-only 状态;
  • TP 只消费已经解析的 paint contribution不判断布局合法性
  • 结构属性变化必须事务性重建对应布局上下文,不能走 paint-only 快速路径。

验证分成两个确定阶段:

  1. normalization 做 form-local schema 校验。box 只接受 Normal/Common Box 属性; flex 才接受 Flex container configgrid 才接受 Grid container config其他 layout-specific 属性立即报错。
  2. Component/Fragment resolution 与 ECSS cascade 完成后Ebox 在 candidate final tree 上做 parent-context 校验。Flex participationgrow/shrink/basis/order/self alignment只允许在直接父 Flex 的 child BoxGrid placement/self alignment 只允许在直接父 Grid 的 child Boxroot 或错误父级报错。

同一个 Box 可以内部建立一种 Layout、外部参与另一种父 Layout例如 Grid 下的 (flex :grid-column ... );这是两个正交字段,不是属性混用。动态事务同时改变父 Layout 和 child participation 时只验证最终 candidate任何失败保留上一代。与 浏览器对不适用 CSS 属性常采取 no-effect 不同,本框架不静默忽略无效组合。

4. 模块 owner

4.1 ETAF Core

etaf-view

  • 定义并规范化 Text、Box、Fragment 和 ComponentCall
  • 将字符串规范化为 Text
  • rowcolumnflexgrid 作者糖规范化为 Box
  • 验证属性闭集、slot、:key 和表达式边界;
  • 不测量、不布局、不写 buffer。

etaf-component

  • 定义 Component props、:view:setup:styles
  • 不调度 Runtime不调用 Ebox。

etaf-runtime

  • 拥有 Component/Fragment/Range identity、响应式依赖、Context、Theme、Action、 Behavior、Data、Resource 和 lifecycle
  • 拥有 candidate generation、事务、提交授权、回滚和释放
  • 决定变化影响哪个 Component、Range、结构属性或 paint contribution
  • 不计算像素和布局。

etaf-renderer

  • 是唯一 ETAF → Ebox 的 lowering adapter
  • 把 ResolvedView 的 structure/geometry projection 转换为 CanonicalEboxInput forest、 RangeAnchors 和 typed measurement/geometry props
  • 不执行 Component lifecycle不访问 Ebox 私有状态。

etaf-theme-tp

  • 是 ETAF/ECSS computed paint contribution → TP 的唯一 adapter
  • 产生 ContributionPlan不测量、不布局、不拥有 TP priority/commit authority
  • paint-only candidate 不调用 etaf-renderer 的 geometry lowering。

Theme 的语义 token 和继承属于 ETAF Context。TP 不拥有“暗色主题”等业务意义。

4.2 Ebox

Ebox 拥有:

  • Ebox DSL 的 String/Text/Box 规范化和布局糖展开;
  • child Box participation 的上下文验证、父布局消费和 dirty propagation
  • typed TextNode/BoxNode constructor 及 canonical 属性 schema
  • Text 测量、换行和行布局;
  • normalrowcolumnflexgrid 几何算法;
  • width/height、box model、overflow、scroll、viewport
  • 稳定 Ebox node identity、geometry snapshot 和结构 patch plan。

Ebox 不理解 Component、slot、Context、Action、Behavior、Data 或 Resource也不 决定 paint contribution 的优先级。

独立 Ebox DSL 的 author paint 由 ebox-surface 的 TP adapter 投影为 inline ContributionPlan它与 ETAF 的 etaf-theme-tp 是两条来源 adapter共同消费 TP 公开 contribution contract。两者都不把 paint-only 属性塞回 CanonicalEboxInput 也不拥有 TP priority、journal 或 commit authority。

ebox-build 独占作者 form 的 parse/desugarebox-text-createebox-box-create 接收已经求值的 canonical 参数,只验证 typed node invariant。 三者最终消费同一个 canonical property schema 并进入同一条布局实现。ETAF Renderer 直接调用 typed programmatic port不能重新拼 DSL 再触发一次解析。 现有无 kind 的 ebox-create :content 不属于目标公共端口。

逻辑边界:

ebox-core   纯测量、布局、快照和结构 patch
ebox-emacs  字体/窗口能力、buffer 位置和结构提交

这不要求立即拆成两个发行包,但纯布局和 Emacs 副作用必须能独立测试。

CanonicalEboxInput forest 经测量产生 LayoutPlanplan 只包含本次候选所需的测量结果、 坐标、尺寸、布局 owner 和 geometry delta。它不新增作者可见 node type不拥有 Component/Text/Box identity提交或回滚结束后可被保留为下一次增量输入或释放。

4.3 ECSS

ECSS 拥有 selector、cascade、继承和 computed properties。输出必须携带属性的 structure/geometry/paint impactECSS 不执行布局,也不写 buffer。

4.4 TP 与提交边界

TP 拥有:

  • Theme、Component style、state、inline 等 paint contribution 的优先级;
  • paint operation 合并;
  • Emacs text property journal、apply 和 rollback。

一次更新的权限顺序固定为:

ETAF Runtime 创建 candidate 并拥有提交授权
    ↓
Ebox candidate stage 结构/几何 patch
    ↓
Ebox surface 把 rollback-capable participant 加入现有 TP transaction
    ↓
TP precommit paintEbox commit 发布 Emacs surface
    ↓
全部成功后 ETAF Runtime 提升 generation
任一步失败则沿现有 Ebox/TP/Runtime journal 回滚

Ebox 不拥有 TP paint 优先级TP 不拥有节点布局;两者都不能自行提升 Runtime generation。目标不新增第二个跨包 coordinator现有 transaction participant 就是 Ebox surface 与 TP/Emacs 提交对齐的唯一机制。

4.5 上层包

拥有 不拥有
etaf-ui Button、Checkbox、Label、Panel、DataGrid 等普通 Component 第二套 Widget Runtime、布局引擎
etaf-sqlite SQLite Data Source、查询、mutation、事务和 dispose Data Controller、View、UI
etaf-performance 应用无关 operation/stage、环境、统计和报告 示例语义、布局规则、调度权限
ebox-playground Ebox 公共布局 API 示例与验证 ETAF
etaf-playground ETAF/UI/SQLite 组合示例、加载命令和状态展示 Core 语法、Runtime、性能协议

etaf-performance 是独立可选包。ETAF、Ebox、TP 和 SQLite 不依赖它;它只通过 公开边界观察和关联阶段。

Playground 的 .etaf manifest 属于 Playground。未来通用 compiler 若存在,必须 降低到同一套 View/Component 契约,不得创建第二套 Runtime。

5. 依赖方向

etaf-ui ─────────────▶ ETAF Core ─────────────▶ Ebox public port
etaf-sqlite ─────────▶ ETAF Data contract
etaf-playground ─────▶ ETAF + optional UI/SQLite
ebox-playground ─────▶ Ebox only
etaf-performance ────▶ public observation boundaries only

ETAF Renderer ───────▶ ECSS computed properties
Ebox style pipeline ─▶ ECSS computed-properties port
ETAF Runtime  ───────▶ Ebox/TP transaction participants
etaf-theme-tp ───────▶ TP contribution contract
Ebox surface ────────▶ TP inline contribution + transaction participant

禁止反向依赖Ebox 不依赖 ETAFTP 不解析 ViewECSS 不写 bufferUI 不调用 Ebox 私有函数SQLite 不知道 UIPlayground 不向 Core 注入协议。

6. Rust 与 Elisp

模块边界先于实现语言。只有接口和等价性测试冻结后,确定性计算才迁移到 Rust

Rust 候选:
  规范化 View 的验证与结构 diff只处理 opaque stable IDs
  ECSS cascade
  Text 测量输入处理与 Ebox 布局
  geometry/paint patch 的纯数据计算

Elisp / Emacs
  执行用户 Component、ref、Context、Action、Data、Resource、lifecycle
  数据库和外部 I/O
  Emacs 事件、字体/窗口能力和最终提交

Component identity、依赖所有权、TP 优先级和 generation authority 不因 Rust 化而 转移。Rust 最多计算无副作用的候选 paint operationsTP 继续拥有 contribution slot、优先级、journal 和 commit/rollback。Elisp 不重复 Rust 已经完成的 diff、 cascade、布局或文字扫描。

7. 正确性与性能不变量

  • 同一事务中的 View、computed properties、geometry snapshot 和 paint contribution 各 materialize 一次;
  • Text 的 paint-only contribution 改变不执行无关 Component也不运行布局
  • :outer、Layout variant 或几何改变只运行受影响的布局 owner
  • Fragment/slot/list 变化只替换对应 Range
  • Ebox/TP/Emacs 任一 participant 失败时保留上一代已提交状态;
  • resize 使用当前窗口事实立即重排,不以隐藏 debounce 改变交互语义;
  • 性能记录器不改变被测路径。

最终门禁必须覆盖:

  • Text/Box/Fragment 结构等价;
  • 字符串只规范化为 Text两个作者 DSL 都拒绝 box :content
  • Text 固定 inline 且恰好一个字符串 payload嵌套/空/多 payload 均报错;
  • ETAF/Ebox 五个 Box form 的 canonical shape、defaults 和错误跨接口一致;
  • 五个 Box author form 产生唯一对应 Layout任何作者 :layout 均报错;
  • Flex/Grid participation 只允许在匹配父级的 child Box错误上下文精确报错
  • participation 变化只运行父布局,不重建 child identity/lifecycle
  • typed Text/Box constructors 拒绝互斥字段和布局糖,并与 ebox-build 共享结果;
  • CanonicalEboxInput 不含 paint-only 字段ETAF 与独立 Ebox paint adapter 各自只投影一次;
  • sourceHandle 与 eboxNodeId 生命周期独立reconciliation 不改变来源 identity
  • outer × layout 合法组合和失败组合;
  • normal inline/block、row、column、flex、grid 的 GUI 行为;
  • Component root 与透明 Fragment 的布局参与;
  • 空/单根/多根 Fragment 都保留 RangeAnchor 并可局部替换;
  • paint-only candidate 不构造 LayoutPlangeometry 与 paint patch 在现有事务汇合;
  • style/Theme/TP 优先级和事务回滚;
  • Research Shelf 与 Flex reference 的连续 resize
  • 固定真实场景 p95 和 max 均不超过 50ms。

8. 当前实现差距与非目标

当前代码仍注册 textfragmentcontainerrowcolumnstackflexgridspacer,并提供 raw-ebox;目标 box:outer、 typed Layout 尚未实现,目标公共 View 也不保留 raw-ebox

当前 Ebox DSL 仍把 box :content 和裸字符串直接编码为无类型 ebox-create :content,并把 itemgrid-item 构造成运行时 wrapper。目标新增 明确的 TextNode/BoxNode canonical IR 与 typed constructors保留 Text、Box 和 五个 Box author form删除 :content 作者/公共 constructor 语法以及 eboxspaceritemgrid-item

这是干净重设计,不要求旧 Host 名称或旧 .etaf 文件继续运行,也不增加长期 兼容层。实现完成前,正式架构和用户指南不得把目标语法描述成当前 API。

非目标:

  • 不实现完整浏览器 CSS
  • 作者 DSL 不提供 spacer、公共 flow(box :content ...)
  • 不把 Flex/Grid item 做成作者节点、视觉 wrapper 或独立 identity
  • 不允许应用把原始 Ebox Node 注入 View
  • 不把布局模式做成 Component 或第二套 Runtime 节点;
  • 不在 Core 中保留旧 Host alias 或可选短写法;
  • 不让 Playground、UI 或数据库包拥有 Core 协议;
  • 不在没有真实编译成本和运行时收益前增加 App 预编译产物。