fix: eslint

This commit is contained in:
guokai.jgk 2020-10-27 12:24:18 +08:00
parent 17289d466a
commit 98f3a17c3c
7 changed files with 18 additions and 226 deletions

View File

@ -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,
},
};

View File

@ -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));
}

View File

@ -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;
}
}
}

View File

@ -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"
},

View File

@ -1,4 +1,4 @@
module.exports = {
singleQuote: true,
trailingComma: 'all',
trailingComma: 'es5',
};

View File

@ -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);
};
}

View File

@ -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;
}