- 新增设计器静态依赖分析方案,阐述基于 AST 的代码片段解析与依赖图谱构建 - 新增实体生命周期引擎实现规范,定义引擎驱动的事件分发与交互触发策略 - 新增悬浮组件架构设计规范,明确底层数据统一与上层视图分离的核心原则 - 新增应用运行模式架构规范,严格区分设计态、预览态与运行态的边界 - 新增设计器选中与分组交互规范,定义选中态、激活态及下钻交互的行为矩阵
7.0 KiB
DatAlive 应用运行模式 (AppMode) 架构设计规范
在低代码/无代码平台的设计中,渲染引擎需要根据不同的上下文环境展现出不同的行为特征。为了保证底层架构的清晰与解耦,DatAlive 明确确立了 AppMode(应用运行模式) 的三态规范,并对“预览模式”与“运行模式”的功能边界进行了严格的界定。
1. 架构定位:AppMode 是运行时上下文,绝非 Schema
在架构设计的初期,极易将运行模式与应用的数据结构混为一谈。必须极其严厉地明确以下铁律:
AppMode绝对不属于需要存入数据库持久化的design-modeSchema 蓝图! Schema 描述的是“应用长什么样,有什么逻辑”,而AppMode决定的是“渲染引擎现在该用什么姿势来解析这份 Schema”。
在渲染引擎的前端代码实现中,AppMode 应当作为顶级组件的 Props(或全局环境变量)由外部宿主容器(Host Shell)显式注入:
// 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)
这是预览模式的核心灵魂,负责将低代码引擎内部的“黑盒状态”白盒化。
- 全局状态漫游器 (State Explorer):
- 实时展示当前应用中所有的全局变量(
Variables)、查询快照(Queries)和组件暴露的运行时属性。 - 允许开发者手动 Override(覆盖)某个变量的值,实时观察页面的响应式变化。
- 实时展示当前应用中所有的全局变量(
- 数据流监控 (Network / Query Monitor):
- 拦截并展示所有的
Query和Mutation执行情况(完美契合 TanStack Query DevTools)。
- 拦截并展示所有的
- 动作轨迹时间轴 (Action Tracer / Timeline)(最难也是最核心):
- 解决低代码中最难排查的“连锁反应”Bug。
- 以瀑布流日志打印执行顺序:
[事件触发] -> [变量修改] -> [Query执行] -> [成功回调代码执行],让数据流转路径一目了然。
- 代码沙箱异常日志 (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(最小可行性产品)阶段,我们采取 “架构上严格区分,实现上极简降级” 的策略:
- 引擎入口的强约束:在渲染引擎的顶层组件定义中,严格要求传入
mode: AppMode,并根据此字段进行核心模块(如 Router 和 拖拽层)的条件分支渲染。 - 借力生态实现控制台:暂不自研复杂的 Action Tracer,而是直接在预览模式接入
<ReactQueryDevtools />(监控请求状态机)和开启 Redux/Zustand DevTools Middleware(监控变量变化),以极低成本获得企业级调试能力。 - 前端纯净路由闭环:即使没有后端,运行模式(Runtime)也必须在一个独立的 HTML 页面下读取
localStorage进行渲染,以此强制验证渲染引擎是否真正脱离了设计器的胖包上下文。