mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 09:41:57 +00:00
fix: eslint
This commit is contained in:
parent
17289d466a
commit
98f3a17c3c
@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
extends: '../../.eslintrc',
|
||||
rules: {
|
||||
'@typescript-eslint/no-parameter-properties': 1,
|
||||
'@typescript-eslint/no-parameter-properties': 0,
|
||||
'no-param-reassign': 0,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
import {
|
||||
DataSourceConfig,
|
||||
DataSourceEngineOptions,
|
||||
IDataSourceEngine,
|
||||
IDataSourceEngineFactory,
|
||||
IRuntimeContext,
|
||||
} from '../types';
|
||||
import { RuntimeDataSource } from './RuntimeDataSource';
|
||||
|
||||
export class DataSourceEngine implements IDataSourceEngine {
|
||||
private _dataSourceMap: Record<string, RuntimeDataSource> = {};
|
||||
|
||||
constructor(
|
||||
private _dataSourceConfig: DataSourceConfig,
|
||||
private _runtimeContext: IRuntimeContext,
|
||||
private _options?: DataSourceEngineOptions,
|
||||
) {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
_dataSourceConfig.list?.forEach((ds) => {
|
||||
// 确保数据源都有处理器
|
||||
const requestHandler = ds.requestHandler || _options?.requestHandlersMap?.[ds.type];
|
||||
if (!requestHandler) {
|
||||
throw new Error(`No request handler for "${ds.type}" data source`);
|
||||
}
|
||||
|
||||
this._dataSourceMap[ds.id] = new RuntimeDataSource(
|
||||
ds.id,
|
||||
ds.type,
|
||||
getValue(ds.options) || {},
|
||||
requestHandler.bind(_runtimeContext),
|
||||
ds.dataHandler ? ds.dataHandler.bind(_runtimeContext) : undefined,
|
||||
(data) => {
|
||||
_runtimeContext.setState({ [ds.id]: data });
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public get dataSourceMap() {
|
||||
return this._dataSourceMap;
|
||||
}
|
||||
|
||||
public async reloadDataSource() {
|
||||
try {
|
||||
const allDataSourceConfigList = this._dataSourceConfig.list || [];
|
||||
|
||||
// urlParams 类型的优先加载
|
||||
for (const ds of allDataSourceConfigList) {
|
||||
if (ds.type === 'urlParams' && (getValue(ds.isInit) ?? true)) {
|
||||
await this._dataSourceMap[ds.id].load();
|
||||
}
|
||||
}
|
||||
|
||||
// 然后是所有其他的
|
||||
const remainDataSourceConfigList = allDataSourceConfigList.filter((x) => x.type !== 'urlParams');
|
||||
|
||||
// 先发起异步的
|
||||
const asyncLoadings: Array<Promise<unknown>> = [];
|
||||
for (const ds of remainDataSourceConfigList) {
|
||||
if (getValue(ds.isInit) ?? true) {
|
||||
const options = getValue(ds.options);
|
||||
if (options && !options.isSync) {
|
||||
this._dataSourceMap[ds.id].setOptions(options);
|
||||
asyncLoadings.push(this._dataSourceMap[ds.id].load(options?.params).catch(() => {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 再按先后顺序发起同步请求
|
||||
for (const ds of remainDataSourceConfigList) {
|
||||
if (getValue(ds.isInit) ?? true) {
|
||||
const options = getValue(ds.options);
|
||||
if (options && options.isSync) {
|
||||
this._dataSourceMap[ds.id].setOptions(options);
|
||||
await this._dataSourceMap[ds.id].load(options?.params);
|
||||
await sleep(0); // TODO: 如何优雅地解决 setState 的异步问题?
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore error
|
||||
}
|
||||
|
||||
await Promise.all(asyncLoadings);
|
||||
} finally {
|
||||
const allDataHandler = this._dataSourceConfig.dataHandler;
|
||||
if (allDataHandler) {
|
||||
await allDataHandler(this._getDataMapOfAll());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _getDataMapOfAll(): Record<string, unknown> {
|
||||
const dataMap: Record<string, unknown> = {};
|
||||
|
||||
Object.entries(this._dataSourceMap).forEach(([dsId, ds]) => {
|
||||
dataMap[dsId] = ds.data;
|
||||
});
|
||||
|
||||
return dataMap;
|
||||
}
|
||||
}
|
||||
|
||||
export const create: IDataSourceEngineFactory['create'] = (dataSourceConfig, runtimeContext, options) => {
|
||||
return new DataSourceEngine(dataSourceConfig, runtimeContext, options);
|
||||
};
|
||||
|
||||
function getValue<T>(valueOrValueGetter: T | (() => T)): T;
|
||||
function getValue<T extends boolean>(valueOrValueGetter: T | (() => T)): T | undefined {
|
||||
if (typeof valueOrValueGetter === 'function') {
|
||||
try {
|
||||
return valueOrValueGetter();
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
return valueOrValueGetter;
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms = 0) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
import { DataSourceOptions, IRuntimeDataSource, RequestHandler, RuntimeDataSourceStatus } from '../types';
|
||||
import { DataSourceResponse } from '../types/DataSourceResponse';
|
||||
|
||||
export class RuntimeDataSource<
|
||||
TParams extends Record<string, unknown> = Record<string, unknown>,
|
||||
TRequestResult = unknown,
|
||||
TResultData = unknown
|
||||
> implements IRuntimeDataSource<TParams, TResultData> {
|
||||
private _status: RuntimeDataSourceStatus = RuntimeDataSourceStatus.Initial;
|
||||
|
||||
private _data?: TResultData;
|
||||
|
||||
private _error?: Error;
|
||||
|
||||
private _latestOptions: DataSourceOptions<TParams>;
|
||||
|
||||
constructor(
|
||||
private _id: string,
|
||||
private _type: string,
|
||||
private _initialOptions: DataSourceOptions<TParams>,
|
||||
private _requestHandler: RequestHandler<DataSourceOptions<TParams>, DataSourceResponse<TRequestResult>>,
|
||||
private _dataHandler:
|
||||
| ((
|
||||
data: DataSourceResponse<TRequestResult> | undefined,
|
||||
error: unknown | undefined,
|
||||
) => TResultData | Promise<TResultData>)
|
||||
| undefined,
|
||||
private _onLoaded: (data: TResultData) => void,
|
||||
) {
|
||||
this._latestOptions = _initialOptions;
|
||||
}
|
||||
|
||||
public get status() {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public get data() {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
public get error() {
|
||||
return this._error;
|
||||
}
|
||||
|
||||
public async load(params?: TParams): Promise<TResultData> {
|
||||
try {
|
||||
this._latestOptions = {
|
||||
...this._latestOptions,
|
||||
params: {
|
||||
...this._latestOptions.params,
|
||||
...params,
|
||||
} as TParams,
|
||||
};
|
||||
|
||||
this._status = RuntimeDataSourceStatus.Loading;
|
||||
|
||||
const data = await this._request(this._latestOptions);
|
||||
|
||||
this._status = RuntimeDataSourceStatus.Loaded;
|
||||
|
||||
this._onLoaded(data);
|
||||
|
||||
this._data = data;
|
||||
return data;
|
||||
} catch (err) {
|
||||
this._error = err;
|
||||
this._status = RuntimeDataSourceStatus.Error;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
public setOptions(options: DataSourceOptions<TParams>) {
|
||||
this._latestOptions = options;
|
||||
}
|
||||
|
||||
private async _request(options: DataSourceOptions<TParams>) {
|
||||
try {
|
||||
const response = await this._requestHandler(options);
|
||||
|
||||
const data = this._dataHandler
|
||||
? await this._dataHandler(response, undefined)
|
||||
: ((response.data as unknown) as TResultData);
|
||||
|
||||
return data;
|
||||
} catch (err) {
|
||||
if (this._dataHandler) {
|
||||
const data = await this._dataHandler(undefined, err);
|
||||
return data;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ali/lowcode-types": "^1.0.10",
|
||||
"@ali/lowcode-types": "1.0.13-alpha.1",
|
||||
"typescript": "^3.9.7",
|
||||
"universal-request": "^2.2.0"
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
trailingComma: 'es5',
|
||||
};
|
||||
|
||||
@ -9,10 +9,11 @@ export type DataType = 'jsonp' | 'json' | 'originaljsonp';
|
||||
// 考虑一下 mtop 类型的问题,官方没有提供 ts 文件
|
||||
export function createMtopHandler<T = unknown>(config?: MTopConfig) {
|
||||
if (config && Object.keys(config).length > 0) {
|
||||
Object.keys(config).forEach((key: string) =>
|
||||
mtopRequest.config(key, config[key]),
|
||||
);
|
||||
Object.keys(config).forEach((key: string) => {
|
||||
mtopRequest.config(key, config[key]);
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line space-before-function-paren
|
||||
return async function(options: RuntimeOptionsConfig): Promise<{ data: T }> {
|
||||
const response = await mtopRequest.request<T>({
|
||||
api: options.uri,
|
||||
@ -23,6 +24,15 @@ export function createMtopHandler<T = unknown>(config?: MTopConfig) {
|
||||
timeout: options.timeout,
|
||||
headers: options.headers,
|
||||
});
|
||||
return response;
|
||||
if (response.ret && response.ret[0].indexOf('SUCCESS::') > -1) {
|
||||
// 校验成功
|
||||
return response;
|
||||
}
|
||||
// 默认异常
|
||||
let errorMsg = '未知异常';
|
||||
if (response.ret && response.ret[0]) {
|
||||
errorMsg = response.ret[0];
|
||||
}
|
||||
throw new Error(errorMsg);
|
||||
};
|
||||
}
|
||||
|
||||
@ -6,6 +6,6 @@ declare interface MTopConfig {
|
||||
}
|
||||
|
||||
declare module '@ali/universal-mtop' {
|
||||
const request: <T>(config: any) => Promise<{ data: T }>;
|
||||
const request: <T>(config: any) => Promise<{ data: T; ret: string[] }>;
|
||||
const config: (key: string, value: unknown) => void;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user