109 lines
4.0 KiB
TypeScript
109 lines
4.0 KiB
TypeScript
import type { Entity, Condition } from '../shared';
|
|
import type { Interaction } from '../interaction';
|
|
import type { QueryConfig } from './query-config';
|
|
|
|
/**
|
|
* 数据查询配置
|
|
*
|
|
* 【架构定位】:
|
|
*
|
|
* 1. 它是低代码数据流“三层漏斗”模型的中间层(核心业务层)。
|
|
* 2. 遵循 CQRS 架构,专职处理幂等的“读操作(Read)”。
|
|
* 3. 它是连接底层 DataSource(协议层)与顶层 Component(视图层)的桥梁。
|
|
*
|
|
* 【引擎实现指引】:
|
|
*
|
|
* 渲染引擎应将其映射为一个强大的状态机(如 TanStack Query 的 `useQuery` 实例)。
|
|
*
|
|
* 它不应将 `isLoading`, `data`, `error` 等运行时快照存入此 Schema,
|
|
* 而是由引擎在全局内存(QueryClient)中动态维护这些衍生状态,供组件声明式地订阅。
|
|
*/
|
|
export interface Query extends Entity {
|
|
/**
|
|
* 执行条件
|
|
*
|
|
* 决定了该查询是否允许被发送(无论是因为页面加载、轮询还是组件订阅)。
|
|
*
|
|
* 核心场景(串行依赖):
|
|
*
|
|
* 当 Query B 需要用到 Query A 的返回结果作为参数时,
|
|
* 可在此配置 `enabled: { type: 'code', code: 'return !!context.queries.QueryA.data' }`。
|
|
* 引擎会挂起 Query B,直到 Query A 成功返回并填充了数据,Query B 才会被自动放行。
|
|
*
|
|
* 如果不填,默认允许执行。
|
|
*/
|
|
enabled?: Condition;
|
|
/**
|
|
* 页面加载时自动执行
|
|
*
|
|
* 性能优化的杀手锏。
|
|
*
|
|
* 如果为 true,引擎在路由命中(或应用启动)的极早期阶段,
|
|
* 在 UI 组件树还未开始渲染时,就提前向服务器发起请求。
|
|
* 这样当底层图表组件渲染完毕并尝试订阅此 Query 时,数据可能已经“热乎”地躺在缓存里了,
|
|
* 从而彻底消灭组件的初始白屏 Loading 时间。
|
|
*/
|
|
prefetch: boolean;
|
|
/**
|
|
* 定时轮询策略
|
|
*
|
|
* 数字大屏(Dashboard)的灵魂特性。赋予数据流实时刷新的能力。
|
|
*/
|
|
polling: {
|
|
/**
|
|
* 是否开启轮询
|
|
*/
|
|
enabled: boolean;
|
|
/**
|
|
* 轮询间隔时间(单位:毫秒 ms)
|
|
*
|
|
* 引擎实现指引:在页面不可见(浏览器标签页隐藏)时,引擎应智能暂停轮询以节省性能。
|
|
*/
|
|
interval: number;
|
|
};
|
|
/**
|
|
* 过滤器管道
|
|
*
|
|
* 极其关键的数据转换层(Transform Layer)。
|
|
* 包含了一系列被引用的全局 Filter ID。
|
|
*
|
|
* 引擎实现指引:
|
|
*
|
|
* 当底层 API 返回原始 JSON 后,在存入 Query 内存缓存池(或喂给组件)之前,
|
|
* 必须将原始数据像接水管一样,串行流过这些 Filter 函数。
|
|
* data = filter3(filter2(filter1(rawData)))
|
|
*
|
|
* 优势:让组件拿到的永远是极其纯净、格式规整的业务数据(如 `[{ x, y }]` 数组),
|
|
* 实现了“一份原始接口数据,清洗出多种衍生视图”的极致复用。
|
|
*/
|
|
filterIds: string[];
|
|
/**
|
|
* 交互
|
|
*
|
|
* 请求生命周期与副作用控制流
|
|
*
|
|
* 挂载于查询状态突变时的高阶事件侦听器。
|
|
*
|
|
* 引擎实现指引:
|
|
*
|
|
* 1. `onSuccess` (请求成功):常用于触发数据获取后的连锁反应(如更新某个全局 Variable,或弹出“数据同步成功”的 Toast)。
|
|
* 2. `onError` (请求失败):常用于统一拦截错误,触发异常上报或显示全局 Error Modal。
|
|
*
|
|
* 这将原本散落在组件里的异步回调地狱,完美收拢到了数据请求自身的配置中。
|
|
* 若无副作用,必须为一个显式的空数组 `[]`。
|
|
*/
|
|
interactions: Interaction[];
|
|
/**
|
|
* 具体的请求协议配置
|
|
*
|
|
* 采用极其强大的“多态联合类型(Polymorphism Union Type)”。
|
|
*
|
|
* 它决定了这究竟是一个静态的 Mock 数据(Static),
|
|
* 还是一个通过 HTTP 调用的 REST 请求(Rest),
|
|
* 抑或是一个直连数据库执行的 SQL 语句(Database)。
|
|
*
|
|
* 引擎通过读取 `config.type` 决定派发给哪个底层的 DataSource 客户端去执行。
|
|
*/
|
|
config: QueryConfig;
|
|
}
|