Compare commits

...

3 Commits

Author SHA1 Message Date
roymondchen
18524d89fb feat(core): 支持自定义Node类 2025-04-02 17:24:02 +08:00
roymondchen
840c2c3c7d fix(data-source): 数据源初始化时机比注册早回出现死循环 2025-04-02 17:17:30 +08:00
roymondchen
9b546645f3 chore: update deps 2025-03-31 20:31:29 +08:00
54 changed files with 1346 additions and 1172 deletions

View File

@ -49,22 +49,22 @@
"@types/node": "18.19.61",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vitest/coverage-v8": "^2.1.8",
"@vitejs/plugin-vue": "^5.2.3",
"@vitest/coverage-v8": "^2.1.9",
"@vue/compiler-sfc": "^3.5.13",
"c8": "^7.14.0",
"commitizen": "^4.3.1",
"conventional-changelog-cli": "^4.1.0",
"cosmiconfig": "^8.3.6",
"cz-conventional-changelog": "^3.3.0",
"element-plus": "^2.9.3",
"element-plus": "^2.9.7",
"enquirer": "^2.4.1",
"eslint": "^8.57.1",
"eslint-config-tencent": "^1.1.2",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-vue": "^9.32.0",
"eslint-plugin-vue": "^9.33.0",
"execa": "^4.1.0",
"highlight.js": "^11.11.1",
"husky": "^7.0.4",
@ -73,19 +73,19 @@
"minimist": "^1.2.8",
"picocolors": "^1.1.1",
"prettier": "^2.8.8",
"recast": "^0.20.5",
"recast": "^0.23.11",
"rimraf": "^3.0.2",
"rollup": "^4.31.0",
"rollup-plugin-dts": "^6.1.1",
"semver": "^7.6.3",
"rollup": "^4.38.0",
"rollup-plugin-dts": "^6.2.1",
"semver": "^7.7.1",
"serialize-javascript": "^6.0.2",
"shx": "^0.3.4",
"typescript": "^5.7.3",
"vite": "^6.2.3",
"vitepress": "^1.6.1",
"vitest": "^3.0.2",
"typescript": "^5.8.2",
"vite": "^6.2.4",
"vitepress": "^1.6.3",
"vitest": "^3.1.1",
"vue": "^3.5.13",
"vue-tsc": "^2.2.0"
"vue-tsc": "^2.2.8"
},
"config": {
"commitizen": {

View File

@ -31,7 +31,7 @@
"esbuild": "^0.21.5",
"fs-extra": "^11.2.0",
"picocolors": "^1.1.1",
"recast": "^0.23.9",
"recast": "^0.23.11",
"tslib": "^2.8.0"
},
"devDependencies": {

View File

@ -7,6 +7,7 @@
"rootDir": "./src",
"outDir": "./lib",
"declaration": true,
"types": ["node"],
},
"include": ["./src"],

View File

@ -49,6 +49,12 @@ export interface AppOptionsConfig {
class App extends EventEmitter {
[x: string]: any;
static nodeClassMap = new Map<string, typeof Node>();
public static registerNode<T extends typeof Node = typeof Node>(type: string, NodeClass: T) {
App.nodeClassMap.set(type, NodeClass);
}
public env: Env = new Env();
public dsl?: MApp;
public codeDsl?: CodeBlockDSL;

View File

@ -30,7 +30,11 @@ class Env {
isWeb = false;
isOpenHarmony = false;
constructor(ua = globalThis.navigator.userAgent, options: Record<string, boolean | string> = {}) {
constructor(ua = globalThis.navigator?.userAgent ?? '', options: Record<string, boolean | string> = {}) {
if (!ua) {
return;
}
this.isIphone = ua.indexOf('iPhone') >= 0;
this.isIpad = /(iPad).*OS\s([\d_]+)/.test(ua);

View File

@ -18,7 +18,7 @@
import type { Id, MComponent, MContainer, MPage, MPageFragment } from '@tmagic/schema';
import type App from './App';
import App from './App';
import IteratorContainer from './IteratorContainer';
import type { default as TMagicNode } from './Node';
import Node from './Node';
@ -53,7 +53,7 @@ class Page extends Node {
return;
}
const node = new Node({
const node = new ((config.type && App.nodeClassMap.get(config.type)) || Node)({
config,
parent,
page: this,

View File

@ -32,11 +32,12 @@ import { compiledNodeField, compliedConditions, compliedIteratorItem, createIter
class DataSourceManager extends EventEmitter {
private static dataSourceClassMap = new Map<string, typeof DataSource>();
private static ObservedDataClass: ObservedDataClass = SimpleObservedData;
private static waitInitSchemaList = new Map<DataSourceManager, DataSourceSchema[]>();
private static waitInitSchemaList = new Map<DataSourceManager, Record<string, DataSourceSchema[]>>();
public static register<T extends typeof DataSource = typeof DataSource>(type: string, dataSource: T) {
DataSourceManager.dataSourceClassMap.set(type, dataSource);
DataSourceManager.waitInitSchemaList?.forEach((list, app) => {
DataSourceManager.waitInitSchemaList?.forEach((listMap, app) => {
const list = listMap[type] || [];
for (let config = list.shift(); config; config = list.shift()) {
app.addDataSource(config);
}
@ -61,7 +62,7 @@ class DataSourceManager extends EventEmitter {
constructor({ app, useMock, initialData }: DataSourceManagerOptions) {
super();
DataSourceManager.waitInitSchemaList.set(this, []);
DataSourceManager.waitInitSchemaList.set(this, {});
this.app = app;
this.useMock = useMock;
@ -144,7 +145,19 @@ class DataSourceManager extends EventEmitter {
const DataSourceClass = DataSourceManager.dataSourceClassMap.get(config.type);
if (!DataSourceClass) {
DataSourceManager.waitInitSchemaList.get(this)?.push(config);
let listMap = DataSourceManager.waitInitSchemaList.get(this);
if (!listMap) {
listMap = {};
DataSourceManager.waitInitSchemaList.set(this, listMap);
}
if (listMap[config.type]) {
listMap[config.type].push(config);
} else {
listMap[config.type] = [config];
}
return;
}

View File

@ -42,7 +42,7 @@ const ui = getDesignConfig('components')?.autocomplete;
const uiComponent = ui?.component || 'el-autocomplete';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<AutocompleteProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'select', 'update:modelValue']);

View File

@ -19,5 +19,5 @@ const props = defineProps<BadgeProps>();
const ui = getDesignConfig('components')?.badge;
const uiComponent = ui?.component || 'el-badge';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<BadgeProps>(() => ui?.props(props) || props);
</script>

View File

@ -22,7 +22,7 @@ const ui = getDesignConfig('components')?.button;
const uiComponent = ui?.component || 'el-button';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<ButtonProps>(() => ui?.props(props) || props);
const emit = defineEmits(['click']);

View File

@ -26,5 +26,5 @@ const ui = getDesignConfig('components')?.card;
const uiComponent = ui?.component || 'el-card';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<CardProps>(() => ui?.props(props) || props);
</script>

View File

@ -25,7 +25,7 @@ const ui = getDesignConfig('components')?.cascader;
const uiComponent = ui?.component || 'el-cascader';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<CascaderProps>(() => ui?.props(props) || props);
const cascader = ref<any>();

View File

@ -31,7 +31,7 @@ const ui = getDesignConfig('components')?.checkbox;
const uiComponent = ui?.component || 'el-checkbox';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<CheckboxProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -26,7 +26,7 @@ const ui = getDesignConfig('components')?.checkboxGroup;
const uiComponent = ui?.component || 'el-checkbox-group';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<CheckboxGroupProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.col;
const uiComponent = ui?.component || 'el-col';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<ColProps>(() => ui?.props(props) || props);
</script>

View File

@ -26,7 +26,7 @@ const ui = getDesignConfig('components')?.collapse;
const uiComponent = ui?.component || 'el-collapse';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<CollapseProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -32,7 +32,7 @@ const ui = getDesignConfig('components')?.collapseItem;
const uiComponent = ui?.component || 'el-collapse-item';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<CollapseItemProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -28,7 +28,7 @@ const ui = getDesignConfig('components')?.colorPicker;
const uiComponent = ui?.component || 'el-color-picker';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<ColorPickerProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -27,7 +27,7 @@ const ui = getDesignConfig('components')?.datePicker;
const uiComponent = ui?.component || 'el-date-picker';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<DatePickerProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -32,7 +32,7 @@ const ui = getDesignConfig('components')?.dialog;
const uiComponent = ui?.component || 'el-dialog';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<DialogProps>(() => ui?.props(props) || props);
const closeHandler = (...args: any[]) => {
emit('close', ...args);

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.divider;
const uiComponent = ui?.component || 'el-divider';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<DividerProps>(() => ui?.props(props) || props);
</script>

View File

@ -40,7 +40,7 @@ const ui = getDesignConfig('components')?.drawer;
const uiComponent = ui?.component || 'el-drawer';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<DrawerProps>(() => ui?.props(props) || props);
const drawer = ref<any>();

View File

@ -24,7 +24,7 @@ const ui = getDesignConfig('components')?.dropdown;
const uiComponent = ui?.component || 'el-dropdown';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<DropdownProps>(() => ui?.props(props) || props);
const emit = defineEmits(['command']);

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.dropdownItem;
const uiComponent = ui?.component || 'el-dropdown-item';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<DropdownItemProps>(() => ui?.props(props) || props);
</script>

View File

@ -26,7 +26,7 @@ const ui = getDesignConfig('components')?.form;
const uiComponent = ui?.component || 'el-form';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<FormProps>(() => ui?.props(props) || props);
const form = ref<any>();

View File

@ -23,5 +23,5 @@ const ui = getDesignConfig('components')?.formItem;
const uiComponent = ui?.component || 'el-form-item';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<FormItemProps>(() => ui?.props(props) || props);
</script>

View File

@ -17,5 +17,5 @@ defineOptions({
const ui = getDesignConfig('components')?.icon;
const uiComponent = ui?.component || 'el-icon';
const props = defineProps<IconProps>();
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<IconProps>(() => ui?.props(props) || props);
</script>

View File

@ -39,7 +39,7 @@ const ui = getDesignConfig('components')?.input;
const uiComponent = ui?.component || 'el-input';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<InputProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'input', 'update:modelValue']);

View File

@ -25,7 +25,7 @@ const ui = getDesignConfig('components')?.inputNumber;
const uiComponent = ui?.component || 'el-input-number';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<InputNumberProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'input', 'update:modelValue']);

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.option;
const uiComponent = ui?.component || 'el-option';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<OptionProps>(() => ui?.props(props) || props);
</script>

View File

@ -20,7 +20,7 @@ const ui = getDesignConfig('components')?.optionGroup;
const uiComponent = ui?.component || 'el-option-group';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<OptionGroupProps>(() => ui?.props(props) || props);
const optionGroup = ref<any>();
</script>

View File

@ -27,7 +27,7 @@ const ui = getDesignConfig('components')?.pagination;
const uiComponent = ui?.component || 'el-pagination';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<PaginationProps>(() => ui?.props(props) || props);
const handleSizeChange = (...args: any[]) => {
emit('size-change', ...args);

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.radio;
const uiComponent = ui?.component || 'el-radio';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<RadioProps>(() => ui?.props(props) || props);
</script>

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.radioButton;
const uiComponent = ui?.component || 'el-radio-button';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<RadioButtonProps>(() => ui?.props(props) || props);
</script>

View File

@ -26,7 +26,7 @@ const ui = getDesignConfig('components')?.radioGroup;
const uiComponent = ui?.component || 'el-radio-group';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<RadioGroupProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -31,7 +31,7 @@ const ui = getDesignConfig('components')?.select;
const uiComponent = ui?.component || 'el-select';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<SelectProps>(() => ui?.props(props) || props);
const select = ref<any>();

View File

@ -26,5 +26,5 @@ const ui = getDesignConfig('components')?.step;
const uiComponent = ui?.component || 'el-step';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<StepProps>(() => ui?.props(props) || props);
</script>

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.steps;
const uiComponent = ui?.component || 'el-steps';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<StepsProps>(() => ui?.props(props) || props);
</script>

View File

@ -28,7 +28,7 @@ const ui = getDesignConfig('components')?.switch;
const uiComponent = ui?.component || 'el-switch';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<SwitchProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -26,5 +26,5 @@ const ui = getDesignConfig('components')?.tabPane;
const uiComponent = ui?.component || 'el-tab-pane';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TabPaneProps>(() => ui?.props(props) || props);
</script>

View File

@ -33,7 +33,7 @@ const ui = getDesignConfig('components')?.table;
const uiComponent = ui?.component || 'el-table';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TableProps>(() => ui?.props(props) || props);
const emit = defineEmits(['select', 'sort-change', 'expand-change', 'cell-click']);

View File

@ -23,5 +23,5 @@ const ui = getDesignConfig('components')?.tableColumn;
const uiComponent = ui?.component || 'el-table-column';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TableColumnProps>(() => ui?.props(props) || props);
</script>

View File

@ -30,7 +30,7 @@ const ui = getDesignConfig('components')?.tabs;
const uiComponent = ui?.component || 'el-tabs';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TabsProps>(() => ui?.props(props) || props);
const emit = defineEmits(['tab-click', 'tab-add', 'tab-remove', 'update:model-value']);

View File

@ -20,5 +20,5 @@ const ui = getDesignConfig('components')?.tag;
const uiComponent = ui?.component || 'el-tag';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TagProps>(() => ui?.props(props) || props);
</script>

View File

@ -25,7 +25,7 @@ const ui = getDesignConfig('components')?.timePicker;
const uiComponent = ui?.component || 'el-time-picker';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TimePickerProps>(() => ui?.props(props) || props);
const emit = defineEmits(['change', 'update:modelValue']);

View File

@ -23,5 +23,5 @@ const ui = getDesignConfig('components')?.tooltip;
const uiComponent = ui?.component || 'el-tooltip';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TooltipProps>(() => ui?.props(props) || props);
</script>

View File

@ -35,7 +35,7 @@ const ui = getDesignConfig('components')?.tree;
const uiComponent = ui?.component || 'el-tree';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<TreeProps>(() => ui?.props(props) || props);
const emit = defineEmits([
'node-click',

View File

@ -29,7 +29,7 @@ const ui = getDesignConfig('components')?.upload;
const uiComponent = ui?.component || 'el-upload';
const uiProps = computed(() => ui?.props(props) || props);
const uiProps = computed<UploadProps>(() => ui?.props(props) || props);
const upload = ref<any>();

View File

@ -37,7 +37,7 @@
</template>
<script lang="ts" setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref, useTemplateRef } from 'vue';
import { computed, nextTick, onBeforeUnmount, onMounted, type Ref, ref, useTemplateRef } from 'vue';
import { useZIndex } from '@tmagic/design';
@ -73,7 +73,7 @@ const menuEl = useTemplateRef<HTMLDivElement>('menu');
const buttonRefs = useTemplateRef<InstanceType<typeof ToolButton>[]>('buttons');
const subMenuRef = useTemplateRef<any>('subMenu');
const visible = ref(false);
const subMenuData = ref<(MenuButton | MenuComponent)[]>([]);
const subMenuData: Ref<(MenuButton | MenuComponent)[]> = ref<(MenuButton | MenuComponent)[]>([]);
const zIndex = useZIndex();
const curZIndex = ref<number>(0);

View File

@ -17,7 +17,7 @@
"@tmagic/editor": "1.5.12",
"@tmagic/element-plus-adapter": "1.5.12",
"@tmagic/tmagic-form-runtime": "1.1.3",
"element-plus": "^2.9.3",
"element-plus": "^2.9.7",
"lodash-es": "^4.17.21",
"monaco-editor": "^0.48.0",
"serialize-javascript": "^6.0.0",
@ -29,14 +29,14 @@
"@types/node": "^18.19.0",
"@types/serialize-javascript": "^5.0.1",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue": "^5.2.3",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"@vue/compiler-sfc": "^3.5.13",
"sass": "^1.83.0",
"terser": "^5.31.6",
"typescript": "^5.7.3",
"typescript": "^5.8.2",
"unplugin-auto-import": "^0.12.0",
"unplugin-vue-components": "^0.22.11",
"vite": "^6.2.3"
"vite": "^6.2.4"
}
}

2342
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-react-refresh": "^1.3.1",
"typescript": "^5.7.3",
"vite": "^6.2.3"
"typescript": "^5.8.2",
"vite": "^6.2.4"
}
}

View File

@ -30,10 +30,10 @@
"@tmagic/cli": "1.5.12",
"@types/events": "^3.0.0",
"axios": "^0.27.2",
"rollup": "^4.31.0",
"rollup": "^4.38.0",
"rollup-plugin-external-globals": "^0.10.0",
"sass": "^1.83.0",
"vite": "^6.2.3",
"vite": "^6.2.4",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue2": "^2.3.1",
"vue-template-compiler": "^2.7.4"

View File

@ -29,14 +29,14 @@
"@tmagic/cli": "1.5.12",
"@types/node": "^18.19.0",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue": "5.2.1",
"@vitejs/plugin-vue": "5.2.3",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-sfc": "^3.5.13",
"rollup": "^4.31.0",
"rollup": "^4.38.0",
"rollup-plugin-external-globals": "^0.10.0",
"sass": "^1.83.0",
"terser": "^5.31.6",
"typescript": "^5.7.3",
"vite": "^6.2.3"
"typescript": "^5.8.2",
"vite": "^6.2.4"
}
}