Files
datalive-design/docs/应用运行模式架构规范.md
skycurtain c3846da8ae docs: 新增 DatAlive 设计器核心架构设计文档
- 新增设计器静态依赖分析方案,阐述基于 AST 的代码片段解析与依赖图谱构建
- 新增实体生命周期引擎实现规范,定义引擎驱动的事件分发与交互触发策略
- 新增悬浮组件架构设计规范,明确底层数据统一与上层视图分离的核心原则
- 新增应用运行模式架构规范,严格区分设计态、预览态与运行态的边界
- 新增设计器选中与分组交互规范,定义选中态、激活态及下钻交互的行为矩阵
2026-04-10 23:03:45 +08:00

80 lines
7.0 KiB
Markdown
Raw Permalink 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.
# 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` 进行渲染,以此强制验证渲染引擎是否真正脱离了设计器的胖包上下文。