Code Monkey home page Code Monkey logo

lowcode-datasource's Introduction

核心原理

考虑之后的扩展性和兼容性,核心分为了 2 类包,一个是 datasource-engine ,另一个是 datasource-engine-x-handler ,x 的意思其实是对应数据源的 type,比如说 datasource-engine-mtop-handler,也就是说我们会将真正的请求工具放在 handler 里面去处理,engine 在使用的时候由使用方自身来决定需要注册哪些 handler,这样的目的有 2 个,一个是如果将所有的 handler 都放到一个包,对于端上来说这个包过大,有一些浪费资源和损耗性能的问题,另一个是如果有新的类型的数据源出现,只需要按照既定的格式去新增一个对应的 handler 处理器即可,达到了高扩展性的目的;

DataSourceEngine

  • engine: engine 主要分 2 类,一类是面向 render 引擎的,可以从 engine/interpret 引入,一类是面向出码或者说直接单纯使用数据源引擎的场景,可以从 engine/runtime 引入,代码如下
import { createInterpret, createRuntime } from '@alilc/lowcode-datasource-engine'; 

create 方法定义如下

interface IDataSourceEngineFactory {
    create(dataSource: DataSource, context: Omit<IRuntimeContext, 'dataSourceMap' | 'reloadDataSource'>, extraConfig?: {
        requestHandlersMap: RequestHandlersMap;
        [key: string]: any;
    }): IDataSourceEngine;
}

create 接收三个参数,第一个是 DataSource,对于运行时渲染和出码来说,DataSource 的定义分别如下:

/**
 * 数据源对象--运行时渲染
 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
 */
export interface DataSource {
    list: DataSourceConfig[];
    dataHandler?: JSFunction;
}
/**
 * 数据源对象
 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
 */
export interface DataSourceConfig {
    id: string;
    isInit: boolean | JSExpression;
    type: string;
    requestHandler?: JSFunction;
    dataHandler?: JSFunction;
    options?: {
        uri: string | JSExpression;
        params?: JSONObject | JSExpression;
        method?: string | JSExpression;
        isCors?: boolean | JSExpression;
        timeout?: number | JSExpression;
        headers?: JSONObject | JSExpression;
        [option: string]: CompositeValue;
    };
    [otherKey: string]: CompositeValue;
}

但是对于出码来说,create 和 DataSource 定义如下:

export interface IRuntimeDataSourceEngineFactory {
    create(dataSource: RuntimeDataSource, context: Omit<IRuntimeContext, 'dataSourceMap' | 'reloadDataSource'>, extraConfig?: {
        requestHandlersMap: RequestHandlersMap;
        [key: string]: any;
    }): IDataSourceEngine;
}

export interface RuntimeOptionsConfig {
    uri: string;
    params?: Record<string, unknown>;
    method?: string;
    isCors?: boolean;
    timeout?: number;
    headers?: Record<string, unknown>;
    shouldFetch?: (options: RuntimeDataSourceConfig) => boolean;
    [option: string]: unknown;
}
export declare type RuntimeOptions = () => RuntimeOptionsConfig; // 考虑需要动态获取值的情况,这里在运行时会真正的转为一个 function

export interface RuntimeDataSourceConfig {
    id: string;
    isInit: boolean;
    type: string;
    requestHandler?: () => {};
    dataHandler: (data: unknown, err?: Error) => {};
    options?: RuntimeOptions;
    [otherKey: string]: unknown;
}
/**
 * 数据源对象
 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
 */
export interface RuntimeDataSource {
    list: RuntimeDataSourceConfig[];
    dataHandler?: (dataMap: DataSourceMap) => void;
}

2 者的区别还是比较明显的,一个是带 js 表达式一类的字符串,另一个是真正转为直接可以运行的 js 代码,对于出码来说,转为可执行的 js 代码的过程是出码自身负责的,对于渲染引擎来说,它只能接受到初始的 schema json 所以需要数据源引擎来做转化

  • context:数据源引擎内部有一些使用了 this 的表达式,这些表达式需要求值的时候依赖上下文,因此需要将当前的上下文丢给数据源引擎,另外在 handler 里面去赋值的时候,也会用到诸如 setState 这种上下文里面的 api,当然,这个是可选的,我们后面再说。
/**
 * 运行时上下文--暂时是参考 react,当然可以自己构建,完全没问题
 */
export interface IRuntimeContext<TState extends object = Record<string, unknown>> {
    /** 当前容器的状态 */
    readonly state: TState;
    /** 设置状态(浅合并) */
    setState(state: Partial<TState>): void;
    /** 自定义的方法 */
    [customMethod: string]: any;
    /** 数据源, key 是数据源的 ID */
    dataSourceMap: Record<string, IRuntimeDataSource>;
    /** 重新加载所有的数据源 */
    reloadDataSource(): Promise<void>;
    /** 页面容器 */
    readonly page: IRuntimeContext & {
        readonly props: Record<string, unknown>;
    };
    /** 低代码业务组件容器 */
    readonly component: IRuntimeContext & {
        readonly props: Record<string, unknown>;
    };
}
  • extraConfig:这个字段是为了留着扩展用的,除了一个必填的字段 requestHandlersMap
export declare type RequestHandler<T = unknown> = (ds: RuntimeDataSourceConfig, context: IRuntimeContext) => Promise<RequestResult<T>>;
export declare type RequestHandlersMap = Record<string, RequestHandler>;

RequestHandlersMap 是一个把数据源以及对应的数据源 handler 关联起来的桥梁,它的 key 对应的是数据源 DataSourceConfig 的 type,比如 mtop/http/jsonp ... ,每个类型的数据源在真正使用的时候会调用对应的 type-handler,并将当前的参数和上下文带给对应的 handler。

create 调用结束后,可以获取到一个 DataSourceEngine 实例

export interface IDataSourceEngine {
    /** 数据源, key 是数据源的 ID */
    dataSourceMap: Record<string, IRuntimeDataSource>;
    /** 重新加载所有的数据源 */
    reloadDataSource(): Promise<void>;
}

lowcode-datasource's People

Contributors

alibaba-oss avatar blueju avatar clarence-pan avatar jacklian avatar leoyuan avatar liujuping avatar xingmolu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.