npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@one-for-all/artery

v0.16.0

Published

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

Downloads

5

Readme

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

| 名称 | Required | Type | 描述 | | :--------------- | -------- | -------------------------- | ---------------------------------------------------------------------------- | | id | 是 | string | 节点在整个 Artery 中的唯一标识 | | type | 是 | string enum | 表示节点的类型,例如 html-element react-component 等 | | props | 否 | Record<string, Property> | 表示在渲染节点时传递的参数,这些参数不是具体的值,而是描述如何取值的说明 | | shouldRender | 否 | ShouldRenderCondition | 是否渲染此节点的规则 | | lifecycleHooks | 否 | LifecycleHooks | 节点生命周期规则 |

HTMLNode

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

| 名称 | require | Type | 描述 | | :--------- | ------- | -------------- | ------------------------------------- | | type | 是 | string | 值为 html-element | | name | 是 | string | HTML tag,如 div span button 等 | | children | 否 | ArteryNode[] | 子节点 |

ReactComponentNode

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

| 名称 | Required | Type | 描述 | | :--------------------- | -------- | -------------- | -------------------------------- | | type | 是 | string | 值为 react-component | | packageName | 是 | string | 组件所属的 package 名称 | | packageVersion | 是 | string | 组件所属的 package 版本 | | exportName | 否 | string | 组件的导出名称,默认为 default | | supportStateExposure | 否 | boolean | 表示组件是否支持对外暴露内部状态 | | children | 否 | ArteryNode[] | 子节点 |

ComposedNode

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

| 名称 | Required | Type | 描述 | | :--------- | -------- | ---------------------------------- | ----------------------------------------------------------------------------------- | | type | 是 | string | 值为 composed-node | | outLayer | 否 | HTMLNode or ReactComponentNode | 表示被组合节点的外层元素,可以为空 | | nodes | 是 | ArteryNode[] | 即被组合的节点列表,且每个节点都必须实现 toProps 方法,用来接受前面提到的共享状态 |

LoopContainerNode

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

| 名称 | Required | Type | 描述 | | :-------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------- | | type | 是 | string | 值为 loop-container | | iterableState | 是 | PlainState | 表示循环的数据来源,其实际值需要为一个数组 | | loopKey | 是 | string | 当被循环的数组元素为对象,loopKey 为对象的唯一标识,如果被循环的数组元素为基础类型,loopKey 可以为空 | | node | 是 | ArteryNode | 即被循环渲染的节点 | | toProps | 是 | ToPropsFuncSpec | 循环数据转换函数 |

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

RefNode

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

| 名称 | Required | Type | 描述 | | :--------- | -------- | ------------ | -------------------------------------------------------------------------------------------------- | | type | 是 | string | 值为 ref-node | | ArteryID | 是 | string | 被引用的 Artery ID | | fallback | 否 | Node | 当对应的 Artery 还有没加载之前,在页面中渲染的内容,可选 | | orphan | 否 | boolean | ref-node 默认继承父节点的状态,如果想让父节点和 ref-node 子节点状态隔离,可以将 orphan 设置为 true |

RouteNode

表示此节点为路由节点。

| 名称 | Required | Type | 描述 | | :-------- | -------- | ------------ | -------------------- | | type | 是 | string | 值为 route-node | | path | 是 | string | | | node | 是 | Node | 此路由渲染的节点 | | exactly | 是 | boolean | 是否严格匹配当前路径 |

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 | 描述 | | :------ | -------- | ------------------- | | type | 是 | constant_property | | value | 是 | 此属性的值 |

APIResultProperty

| 名称 | Required | 描述 | | :---------- | -------- | ---------------------------------------------------- | | type | 是 | api_result_property | | stateID | 是 | string | | convertor | 否 | StateConvertExpression or StateConvertorFuncSpec | | fallback | 是 | Fallback |

APILoadingProperty

| 名称 | Required | 描述 | | :-------- | -------- | ---------------------- | | type | 是 | api_loading_property | | stateID | 是 | 状态唯一标识 ID |

SharedStateProperty

| 名称 | Required | 描述 | | :---------- | -------- | ------------------------------------------------ | | type | 是 | shared_state_property | | stateID | 是 | string | | fallback | 是 | Fallback | | convertor | 否 | StateConvertExpression or StateConvertorFuncSpec |

NodeStateProperty

| 名称 | Required | 描述 | | :---------- | -------- | ------------------------------------------------ | | type | 是 | node_state_property | | nodePath | 是 | string | | fallback | 是 | Fallback | | convertor | 否 | StateConvertExpression or StateConvertorFuncSpec |

FunctionalProperty

| 名称 | Required | 描述 | | :----- | -------- | --------------------- | | type | 是 | functional_property | | func | 是 | BaseFunctionSpec |

RenderProperty

| 名称 | Required | 描述 | | :-------- | -------- | --------------------------------------------------------------- | | type | 是 | render_property | | node | 是 | ArteryNode | | adapter | 是 | BaseFunctionSpec & { type: 'render_property_function_spec'; } |

ComputedProperty

| 名称 | Required | 描述 | | :---------- | -------- | ------------------------------------------------ | | type | 是 | computed_property | | deps | 是 | Array | | convertor | 是 | StateConvertExpression or StateConvertorFuncSpec | | fallback | 是 | unknown |

InheritedProperty

| 名称 | Required | 描述 | | :---------- | -------- | ------------------------------------------------ | | type | 是 | inherited_property | | parentID | 是 | string | | convertor | 否 | StateConvertExpression or StateConvertorFuncSpec | | fallback | 是 | unknown |