docs: 新增 DatAlive 设计器核心架构设计文档

- 新增设计器静态依赖分析方案,阐述基于 AST 的代码片段解析与依赖图谱构建
- 新增实体生命周期引擎实现规范,定义引擎驱动的事件分发与交互触发策略
- 新增悬浮组件架构设计规范,明确底层数据统一与上层视图分离的核心原则
- 新增应用运行模式架构规范,严格区分设计态、预览态与运行态的边界
- 新增设计器选中与分组交互规范,定义选中态、激活态及下钻交互的行为矩阵
This commit is contained in:
2026-04-10 23:03:45 +08:00
parent 12b9ab3f4b
commit c3846da8ae
5 changed files with 496 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
# DatAlive 应用运行模式 (AppMode) 架构设计规范
在低代码/无代码平台的设计中,渲染引擎需要根据不同的上下文环境展现出不同的行为特征。为了保证底层架构的清晰与解耦,DatAlive 明确确立了 **AppMode(应用运行模式)** 的三态规范,并对“预览模式”与“运行模式”的功能边界进行了严格的界定。
## 1. 架构定位:AppMode 是运行时上下文,绝非 Schema
在架构设计的初期,极易将运行模式与应用的数据结构混为一谈。必须极其严厉地明确以下铁律:
> **`AppMode` 绝对不属于需要存入数据库持久化的 `design-mode` Schema 蓝图!**
> Schema 描述的是“应用长什么样,有什么逻辑”,而 `AppMode` 决定的是“渲染引擎现在该用什么姿势来解析这份 Schema”。
在渲染引擎的前端代码实现中,`AppMode` 应当作为顶级组件的 Props(或全局环境变量)由外部宿主容器(Host Shell)显式注入:
```tsx
// AppMode 的三态枚举(定义于引擎层,而非 Schema 层)
export type AppMode =
| 'design' // 设计态:引擎进入“沙盒模式”,劫持交互与路由,渲染视觉辅助线。
| 'preview' // 预览态:放行业务事件,提供沉浸式体验,但挂载强大的白盒调试工具。
| 'runtime'; // 运行态:绝对纯净的运行环境,无任何设计器代码注入。
```
### 1.1 为什么拒绝使用 `publish` 作为模式?
在架构设计中,必须将 **“底层渲染状态(Render State / AppMode)”** 与 **“应用版本生命周期(Lifecycle Status)”** 彻底解耦。
* `runtime`(运行时)是一个渲染引擎的“物理运行环境”。
* `publish`(发布)是一个应用的“版本流转动作”(如 `draft`, `testing`, `published`)。
即便是本地测试的一个未发布的草稿版本,当它脱离设计器独立在手机上扫码预览时,其底层的渲染模式依然是 `runtime`
---
## 2. 预览模式 (Preview) vs 运行模式 (Runtime):同源异构的双生子
如果抛开后端服务和数据存储介质不谈,纯粹从前端功能视角来看,**预览模式**和**运行模式**在底层逻辑上是 100% 同源的(共享同一套 Schema 渲染管线),但在外在表现上却截然不同。
**一个形象的比喻:**
* **预览模式(Preview)**:是导演(开发者)在看**监视器**。画面里可能有收音麦克风穿帮、有场记板、有剧本标注。发现演员台词念错了,导演会喊“咔(报错)”,然后立刻重来。
* **运行模式(Runtime)**:是观众在电影院看**最终上映的电影**。画面绝对干净,剧情连贯,即便有个别穿帮镜头(Bug),电影也会继续放下去,绝不会突然黑屏跳出一段剧本代码。
### 2.1 核心功能差异对比
| 维度 | 预览模式 (Preview Mode) | 运行模式 (Runtime Mode) | 设计模式 (Design Mode) |
| :--- | :--- | :--- | :--- |
| **目标用户** | 应用搭建者、实施人员 | 最终业务人员(如客服、仓管) | 平台实施人员 |
| **路由引擎 (Routing)** | 原生 `BrowserRouter` 或 Hash,独立窗口展示。 | 干净的业务地址(如 `/apps/my-dashboard`)。 | **强制隔离**:必须使用 `MemoryRouter`,防止点击 a 标签导致设计器真刷新或逃逸。 |
| **异常处理 (Error)** | **严厉的教练**:大张旗鼓地报错(Error Boundary 标红),将 JS 堆栈暴露在控制台。 | **温柔的服务员**:静默容错,降级 UI 或弹出温和的 Toast,绝不暴露底层堆栈。 | 忽略破坏性错误,保护画布不崩溃。 |
| **破坏性操作 (Mutation)**| 允许执行,但通常通过拦截器指向 Mock 或沙箱环境。 | 毫无保留地真实执行业务逻辑。 | **强力封杀**:引擎必须静默拦截所有的 `Mutation` 动作,防止在画布点击按钮删除了真实数据。 |
| **环境纯净度** | 包裹在调试器上下文中,注入各种 DevTools。 | 轻量级纯净容器。剔除所有设计器相关的 JS 胖包和无用 DOM。 | 挂载 `react-moveable` 等庞大的拖拽与辅助渲染引擎。 |
---
## 3. 预览模式专属辅助工具 (Preview Utilities) 深度展开
为了让“导演”能更好地排查“演员”的问题,预览模式必须配备一系列强大的领域特定(Domain-Specific)辅助工具。传统的浏览器 F12 DevTools 对低代码编译后的虚拟 DOM 是“瞎”的,因此必须集成以下工具:
### 3.1 低代码控制台 (Low-Code Console / Debugger)
这是预览模式的核心灵魂,负责将低代码引擎内部的“黑盒状态”白盒化。
1. **全局状态漫游器 (State Explorer)**
* 实时展示当前应用中所有的全局变量(`Variables`)、查询快照(`Queries`)和组件暴露的运行时属性。
* 允许开发者手动 Override(覆盖)某个变量的值,实时观察页面的响应式变化。
2. **数据流监控 (Network / Query Monitor)**
* 拦截并展示所有的 `Query``Mutation` 执行情况(完美契合 TanStack Query DevTools)。
3. **动作轨迹时间轴 (Action Tracer / Timeline)**(最难也是最核心):
* 解决低代码中最难排查的“连锁反应”Bug。
* 以瀑布流日志打印执行顺序:`[事件触发] -> [变量修改] -> [Query执行] -> [成功回调代码执行]`,让数据流转路径一目了然。
4. **代码沙箱异常日志 (Code Sandbox Logger)**
* 专门捕获用户手写的 `DynamicExpression` (如 `type: 'code'`) 中抛出的 JS 异常,将其劫持并优雅地打印在低代码控制台中。
### 3.2 组件审查器 (Component Inspector)
在预览模式下,开发者有时需要快速定位 UI 问题,但又不想切回设计模式:
* **悬浮高亮 (Hover Outline)**:按住特定快捷键(如 `Alt` / `Option`)在页面上移动鼠标,被掠过的组件会显示高亮边框和其 `Entity.id`
* **快捷跳转 (Quick Jump)**:点击被高亮的组件,利用 `postMessage` 与父级设计器通信,设计器立即在画布中选中该组件,右侧面板自动展开其配置项。
---
## 4. MVP 阶段的务实落地策略
在 DatAlive 的 MVP(最小可行性产品)阶段,我们采取 **“架构上严格区分,实现上极简降级”** 的策略:
1. **引擎入口的强约束**:在渲染引擎的顶层组件定义中,严格要求传入 `mode: AppMode`,并根据此字段进行核心模块(如 Router 和 拖拽层)的条件分支渲染。
2. **借力生态实现控制台**:暂不自研复杂的 Action Tracer,而是直接在预览模式接入 `<ReactQueryDevtools />`(监控请求状态机)和开启 Redux/Zustand DevTools Middleware(监控变量变化),以极低成本获得企业级调试能力。
3. **前端纯净路由闭环**:即使没有后端,运行模式(Runtime)也必须在一个独立的 HTML 页面下读取 `localStorage` 进行渲染,以此强制验证渲染引擎是否真正脱离了设计器的胖包上下文。