0.16.0 • Published 2 years ago

@one-for-all/artery v0.16.0

Weekly downloads
-
License
Apache-2.0
Repository
-
Last release
2 years ago

Artery

低代码工具链中有两个非常重要的环节,一是为开发者提供一套功能完备的用于构建动态页面的页面引擎;二是将前者构建的页面渲染给最终用户使用的渲染引擎。初看上去,页面引擎似乎包含了渲染引擎的能力,但其实不然。

渲染引擎的重点在于正确且高效的执行开发者的意图,为用户提供符合预期的 UI,渲染引擎只要以一个 URL 为输入就能渲染出一个页面,这个页面又可以链接到其他地址,进而形成完整的业务逻辑链条;而页面引擎的重点在于组织页面结构和编排页面内元素的交互逻辑,为了能够让开发者操作页面元素,不能简单的按照生产环境的标准渲染页面,并且页面引擎还需要提供调试、预览和历史记录等功能。

虽然页面引擎和渲染引擎的侧重点不同,但两者又是紧密联系在一起的。通过页面引擎构建的页面,最终需要交给渲染引擎来渲染,页面引擎最后导出的结果需要被渲染引擎认可,所以为了两者能更好的配合,需要使用统一的语言来沟通,Artery 为此而生。

Artery 是什么?

Artery 是一种用来描述单页面应用 SPA 的接口描述语言,Artery 是一套与实现无关的标准。

我们可以使用 Artery 来描述完整的前端业务,包括 UI、状态和两者之间的关系。理论上,任何的 SPA 都可以使用 Artery 来表达,并由渲染引擎来渲染。全象低代码平台前端核心组件的使用 Demo 的全部功能都是由 Artery 来描述的。

Artery 是渲染引擎页面引擎对接的共同语言,以 Artery 作为标准,我们可以分别独立开发渲染引擎和页面引擎,使得两者之间没有耦合。

Artery 本身并没有约定页面引擎和渲染引擎的实现,任何人都可以按照自己的想法实现对 Artery 的编辑、组合和渲染功能。

Artery 结构简介

Artery 的结构十分简单,但是仍然有许多需要注意的细节,在这里简单给出 Artery 的整体结构介绍,更新细节设计请参考对应的 reference。

Artery 由三部分组成:

  • Node :描述页面结构和组成元素的的 Tree;
  • APIStateSpec :描述页面中使用的 API;
  • SharedStatesSpec :描述页面中的共享状态,或者说本地同步状态;

Node

Node 的数据结构是 Tree,由节点、节点属性和子节点组成。正如 DOM 的结构一样,Node 的结构也反映了最后渲染的页面结构。不同类型的节点 Node 由 type 字段区分,不同类型的节点的属性 Property 也有所差异。

BaseNode

BaseNode 上定义了节点的通用属性,所有节点都是扩展的 BaseNode

名称RequiredType描述
idstring节点在整个 Artery 中的唯一标识
typestring enum表示节点的类型,例如 html-element react-component
propsRecord<string, Property>表示在渲染节点时传递的参数,这些参数不是具体的值,而是描述如何取值的说明
shouldRenderShouldRenderCondition是否渲染此节点的规则
lifecycleHooksLifecycleHooks节点生命周期规则

HTMLNode

HTMLNode 节点会使用原生的 HTML 来渲染,需要指定使用哪个 HTML tag 渲染。

名称requireType描述
typestring值为 html-element
namestringHTML tag,如 div span button
childrenArteryNode[]子节点

ReactComponentNode

ReactComponentNode 节点需要使用 React Component 来渲染,需要声明组件所在的 package 等信息,用来定位到组件的具体实现。

名称RequiredType描述
typestring值为 react-component
packageNamestring组件所属的 package 名称
packageVersionstring组件所属的 package 版本
exportNamestring组件的导出名称,默认为 default
supportStateExposureboolean表示组件是否支持对外暴露内部状态
childrenArteryNode[]子节点

ComposedNode

此节点是由多个其他类型的节点共同组成,这些节点可以共享同一个状态,一般用在循环渲染中。

名称RequiredType描述
typestring值为 composed-node
outLayerHTMLNode or ReactComponentNode表示被组合节点的外层元素,可以为空
nodesArteryNode[]即被组合的节点列表,且每个节点都必须实现 toProps 方法,用来接受前面提到的共享状态

LoopContainerNode

此节点是一个循环渲染的容器,用于循环渲染某个节点。

名称RequiredType描述
typestring值为 loop-container
iterableStatePlainState表示循环的数据来源,其实际值需要为一个数组
loopKeystring当被循环的数组元素为对象,loopKey 为对象的唯一标识,如果被循环的数组元素为基础类型,loopKey 可以为空
nodeArteryNode即被循环渲染的节点
toPropsToPropsFuncSpec循环数据转换函数

注:toProps 当被循环的节点为 html-elementcomposed-node 时,可以在 toProps 中将数组元素转化为节点需要的格式,当 node 为 composed-node 时,toProps 需要省略,因为已经在被组合的节点中实现了

RefNode

此节点为外部引用节点,在节点上记录了外部 Artery 的 ID,可以通过此节点实现 Artery 的组合。

名称RequiredType描述
typestring值为 ref-node
ArteryIDstring被引用的 Artery ID
fallbackNode当对应的 Artery 还有没加载之前,在页面中渲染的内容,可选
orphanbooleanref-node 默认继承父节点的状态,如果想让父节点和 ref-node 子节点状态隔离,可以将 orphan 设置为 true

RouteNode

表示此节点为路由节点。

名称RequiredType描述
typestring值为 route-node
pathstring
nodeNode此路由渲染的节点
exactlyboolean是否严格匹配当前路径

APIStateSpec

APIStateSpec 里定义了当前页面中用到的哪个 API 和对应的状态名称。APIStateSpec 的数据类型定义如下:

interface APIState {
  loading: boolean;
  result?: unknown;
  error?: Error;
}

// map of stateID and apiState
type APIStatesSpec = Record<string, { apiID: string; [key: string]: unknown }>;

注意到在 APIStatesSpec 中只记录了一个 apiID, 并没有关于 API request/response 等信息的描述,这是有意为之的,为了让实现方根据自己的实际情况来解析 API 的具体格式,方便扩展。

SharedStatesSpec

SharedStates 的主要作用是在页面元素之间传递或者共享数据,其结构定义相对简单, TypeScript 格式类型定义如下:

interface SharedState {
  initial: unknown;
}

type SharedStatesSpec = Record<string, SharedState>;

节点 Property

组件一般需要传递多个指定的参数才能正常渲染,在 Artery 中通过 props 定义传递哪些参数和这些参数的值来自哪里。在写 property 时,需要写明 property 的具体类型,类型有下列:

  • constant_property
  • api_result_property
  • api_loading_property
  • shared_state_property
  • node_state_property
  • functional_property
  • render_property

同样的,不同的 property 类型有不同的特定参数。

ConstantProperty

名称Required描述
typeconstant_property
value此属性的值

APIResultProperty

名称Required描述
typeapi_result_property
stateIDstring
convertorStateConvertExpression or StateConvertorFuncSpec
fallbackFallback

APILoadingProperty

名称Required描述
typeapi_loading_property
stateID状态唯一标识 ID

SharedStateProperty

名称Required描述
typeshared_state_property
stateIDstring
fallbackFallback
convertorStateConvertExpression or StateConvertorFuncSpec

NodeStateProperty

名称Required描述
typenode_state_property
nodePathstring
fallbackFallback
convertorStateConvertExpression or StateConvertorFuncSpec

FunctionalProperty

名称Required描述
typefunctional_property
funcBaseFunctionSpec

RenderProperty

名称Required描述
typerender_property
nodeArteryNode
adapterBaseFunctionSpec & { type: 'render_property_function_spec'; }

ComputedProperty

名称Required描述
typecomputed_property
depsArray
convertorStateConvertExpression or StateConvertorFuncSpec
fallbackunknown

InheritedProperty

名称Required描述
typeinherited_property
parentIDstring
convertorStateConvertExpression or StateConvertorFuncSpec
fallbackunknown