diff --git a/packages/cli/src/utils/prepareEntryFile.ts b/packages/cli/src/utils/prepareEntryFile.ts index e2f1f6132..75d4187d4 100644 --- a/packages/cli/src/utils/prepareEntryFile.ts +++ b/packages/cli/src/utils/prepareEntryFile.ts @@ -22,6 +22,13 @@ export const prepareEntryFile = async (app: App) => { 'value-entry': generateContent(useTs, EntryType.VALUE, moduleMainFilePath.valueMap), 'event-entry': generateContent(useTs, EntryType.EVENT, moduleMainFilePath.eventMap), 'datasource-entry': generateContent(useTs, EntryType.DATASOURCE, moduleMainFilePath.datasourceMap), + 'async-datasource-entry': generateContent( + useTs, + EntryType.DATASOURCE, + moduleMainFilePath.datasourceMap, + '', + dynamicImport, + ), 'ds-config-entry': generateContent(useTs, EntryType.DS_CONFIG, moduleMainFilePath.dsConfigMap), 'ds-value-entry': generateContent(useTs, EntryType.DS_VALUE, moduleMainFilePath.dsValueMap), 'ds-event-entry': generateContent(useTs, EntryType.DS_EVENT, moduleMainFilePath.dsEventMap), @@ -43,7 +50,7 @@ export const prepareEntryFile = async (app: App) => { }); }; -const generateContent = ( +export const generateContent = ( useTs: boolean, type: EntryType, map: Record = {}, diff --git a/packages/data-source/src/types.ts b/packages/data-source/src/types.ts index a3c473d76..d09229b7c 100644 --- a/packages/data-source/src/types.ts +++ b/packages/data-source/src/types.ts @@ -1,6 +1,7 @@ import type { AppCore, DataSourceSchema, HttpOptions, RequestFunction } from '@tmagic/schema'; -import HttpDataSource from './data-sources/Http'; +import type DataSource from './data-sources/Base'; +import type HttpDataSource from './data-sources/Http'; export interface DataSourceOptions { schema: T; @@ -42,3 +43,7 @@ export interface ChangeEvent { path?: string; updateData: any; } + +export type AsyncDataSourceResolveResult = { + default: T; +}; diff --git a/packages/data-source/src/utils.ts b/packages/data-source/src/utils.ts index cf428ce33..57163bdf2 100644 --- a/packages/data-source/src/utils.ts +++ b/packages/data-source/src/utils.ts @@ -13,7 +13,7 @@ import { replaceChildNode, } from '@tmagic/utils'; -import type { DataSourceManagerData } from './types'; +import type { AsyncDataSourceResolveResult, DataSourceManagerData } from './types'; export const compliedConditions = (node: MNode, data: DataSourceManagerData) => { if (!node.displayConds || !Array.isArray(node.displayConds) || !node.displayConds.length) return true; @@ -151,3 +151,34 @@ export const compliedIteratorItems = (itemData: any, items: MNode[], dsId: strin ); }); }; + +export const registerDataSourceOnDemand = async ( + dsl: MApp, + dataSourceModules: Record Promise>, +) => { + const { dataSourceCondDeps = {}, dataSourceDeps = {}, dataSources = [] } = dsl; + + const dsModuleMap: Record Promise> = {}; + + dataSources.forEach((ds) => { + let dep = dataSourceCondDeps[ds.id] || {}; + + if (!Object.keys(dep).length) { + dep = dataSourceDeps[ds.id] || {}; + } + + if (Object.keys(dep).length && dataSourceModules[ds.type]) { + dsModuleMap[ds.type] = dataSourceModules[ds.type]; + } + }); + + const modules = await Promise.all(Object.values(dsModuleMap).map((asyncModule) => asyncModule())); + + const moduleMap: Record = {}; + modules.forEach((module, index) => { + const type = Object.keys(dsModuleMap)[index]; + moduleMap[type] = module.default; + }); + + return moduleMap; +}; diff --git a/runtime/react/page/main.tsx b/runtime/react/page/main.tsx index 7adec9f8a..074ea82cc 100644 --- a/runtime/react/page/main.tsx +++ b/runtime/react/page/main.tsx @@ -25,7 +25,7 @@ import { AppContent } from '@tmagic/ui-react'; import { getUrlParam } from '@tmagic/utils'; import components from '../.tmagic/comp-entry'; -import datasources from '../.tmagic/datasource-entry'; +import dataSources from '../.tmagic/datasource-entry'; import plugins from '../.tmagic/plugin-entry'; import App from './App'; @@ -53,7 +53,7 @@ const getLocalConfig = (): MApp[] => { window.magicDSL = []; -Object.entries(datasources).forEach(([type, ds]: [string, any]) => { +Object.entries(dataSources).forEach(([type, ds]: [string, any]) => { DataSourceManager.register(type, ds); }); diff --git a/runtime/react/playground/main.tsx b/runtime/react/playground/main.tsx index ebd207fe7..4cdd834de 100644 --- a/runtime/react/playground/main.tsx +++ b/runtime/react/playground/main.tsx @@ -28,7 +28,7 @@ import { AppContent } from '@tmagic/ui-react'; import { replaceChildNode } from '@tmagic/utils'; import components from '../.tmagic/comp-entry'; -import datasources from '../.tmagic/datasource-entry'; +import dataSources from '../.tmagic/datasource-entry'; import plugins from '../.tmagic/plugin-entry'; import App from './App'; @@ -41,8 +41,8 @@ declare global { } } -Object.entries(datasources).forEach(([type, ds]: [string, any]) => { - DataSourceManager.registe(type, ds); +Object.entries(dataSources).forEach(([type, ds]: [string, any]) => { + DataSourceManager.register(type, ds); }); const app = new Core({ diff --git a/runtime/vue2/page/main.ts b/runtime/vue2/page/main.ts index 7c9be82b5..2b220ad0a 100644 --- a/runtime/vue2/page/main.ts +++ b/runtime/vue2/page/main.ts @@ -23,7 +23,7 @@ import { DataSourceManager } from '@tmagic/data-source'; import { getUrlParam } from '@tmagic/utils'; import components from '../.tmagic/comp-entry'; -import datasources from '../.tmagic/datasource-entry'; +import dataSources from '../.tmagic/datasource-entry'; import plugins from '../.tmagic/plugin-entry'; import request from './utils/request'; @@ -38,7 +38,7 @@ Object.keys(components).forEach((type: string) => { Vue.component(`magic-ui-${type}`, components[type]); }); -Object.entries(datasources).forEach(([type, ds]: [string, any]) => { +Object.entries(dataSources).forEach(([type, ds]: [string, any]) => { DataSourceManager.register(type, ds); }); diff --git a/runtime/vue2/playground/main.ts b/runtime/vue2/playground/main.ts index fe159346a..6ea7505b2 100644 --- a/runtime/vue2/playground/main.ts +++ b/runtime/vue2/playground/main.ts @@ -29,13 +29,13 @@ Promise.all([ import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry'), import('../.tmagic/datasource-entry'), -]).then(([components, plugins, datasources]) => { +]).then(([components, plugins, dataSources]) => { Object.entries(components.default).forEach(([type, component]: [string, any]) => { Vue.component(`magic-ui-${type}`, component); }); - Object.entries(datasources).forEach(([type, ds]: [string, any]) => { - DataSourceManager.registe(type, ds); + Object.entries(dataSources).forEach(([type, ds]: [string, any]) => { + DataSourceManager.register(type, ds); }); Object.values(plugins.default).forEach((plugin: any) => { diff --git a/runtime/vue3/page/index.html b/runtime/vue3/page/index.html index 20fda93ef..f391eb74c 100644 --- a/runtime/vue3/page/index.html +++ b/runtime/vue3/page/index.html @@ -23,7 +23,7 @@ display: none; } - +
diff --git a/runtime/vue3/page/main.ts b/runtime/vue3/page/main.ts index 09813f3f6..06a2c8cc0 100644 --- a/runtime/vue3/page/main.ts +++ b/runtime/vue3/page/main.ts @@ -19,11 +19,11 @@ import { createApp, defineAsyncComponent } from 'vue'; import Core from '@tmagic/core'; -import { DataSourceManager } from '@tmagic/data-source'; +import { DataSourceManager, registerDataSourceOnDemand } from '@tmagic/data-source'; import { getUrlParam } from '@tmagic/utils'; import components from '../.tmagic/async-comp-entry'; -import datasources from '../.tmagic/datasource-entry'; +import asyncDataSources from '../.tmagic/async-datasource-entry'; import plugins from '../.tmagic/plugin-entry'; import request from './utils/request'; @@ -40,24 +40,28 @@ Object.entries(components).forEach(([type, component]: [string, any]) => { magicApp.component(`magic-ui-${type}`, defineAsyncComponent(component)); }); -Object.entries(datasources).forEach(([type, ds]: [string, any]) => { - DataSourceManager.register(type, ds); -}); - Object.values(plugins).forEach((plugin: any) => { magicApp.use(plugin); }); -const app = new Core({ - ua: window.navigator.userAgent, - config: ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {}, - curPage: getUrlParam('page'), - useMock: Boolean(getUrlParam('useMock')), -}); +const dsl = ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {}; -app.setDesignWidth(app.env.isWeb ? window.document.documentElement.getBoundingClientRect().width : 375); +registerDataSourceOnDemand(dsl, asyncDataSources).then((dataSources) => { + Object.entries(dataSources).forEach(([type, ds]: [string, any]) => { + DataSourceManager.register(type, ds); + }); -magicApp.config.globalProperties.app = app; -magicApp.provide('app', app); + const app = new Core({ + ua: window.navigator.userAgent, + config: dsl, + curPage: getUrlParam('page'), + useMock: Boolean(getUrlParam('useMock')), + }); -magicApp.mount('#app'); + app.setDesignWidth(app.env.isWeb ? window.document.documentElement.getBoundingClientRect().width : 375); + + magicApp.config.globalProperties.app = app; + magicApp.provide('app', app); + + magicApp.mount('#app'); +}); diff --git a/runtime/vue3/playground/index.html b/runtime/vue3/playground/index.html index 5f92589e2..98c324a35 100644 --- a/runtime/vue3/playground/index.html +++ b/runtime/vue3/playground/index.html @@ -42,7 +42,7 @@
- + diff --git a/runtime/vue3/playground/main.ts b/runtime/vue3/playground/main.ts index f92df1f04..9c8d60f61 100644 --- a/runtime/vue3/playground/main.ts +++ b/runtime/vue3/playground/main.ts @@ -29,15 +29,15 @@ Promise.all([ import('../.tmagic/comp-entry'), import('../.tmagic/plugin-entry'), import('../.tmagic/datasource-entry'), -]).then(([components, plugins, datasources]) => { +]).then(([components, plugins, dataSources]) => { const magicApp = createApp(App); Object.entries(components.default).forEach(([type, component]: [string, any]) => { magicApp.component(`magic-ui-${type}`, component); }); - Object.entries(datasources).forEach(([type, ds]: [string, any]) => { - DataSourceManager.registe(type, ds); + Object.entries(dataSources.default).forEach(([type, ds]: [string, any]) => { + DataSourceManager.register(type, ds); }); Object.values(plugins.default).forEach((plugin: any) => {