import { ref } from 'vue'
import TinyVue from '@opentiny/vue'
import * as TinyVueIcon from '@opentiny/vue-icon'
import { generateFunction } from '../data-utils'
import { globalNotify } from '../canvas-function'
export interface IUtil {
name: string
type: 'function' | string
content: {
exportName?: string
[props: string]: any
}
[props: string]: any
}
export function useUtils(context: Record<string, any>) {
const refreshKey = ref<number>(0)
const utils: Record<string, (...args: any) => any | any> = {}
const getUtils = () => utils
const setUtils = async (data: Array<IUtil>) => {
if (!Array.isArray(data)) {
return
}
const newKeys = new Set(data.map(({ name }) => name))
const currentKeys = Object.keys(utils)
const deletedUtilsKeys = currentKeys.filter((item) => !newKeys.has(item))
for (const key of deletedUtilsKeys) {
delete utils[key]
}
const utilsCollection = {}
data?.forEach((item) => {
const util = TinyVue[item.content.exportName]
if (util) {
utilsCollection[item.name] = util
}
const utilIcon = TinyVueIcon[item.content.exportName]
if (utilIcon) {
utilsCollection[item.name] = utilIcon
}
if (item.type === 'function') {
const defaultFn = () => {}
utilsCollection[item.name] = generateFunction(item.content.value, context) || defaultFn
}
})
const validNPMUtils = data.filter((item) => item.type === 'npm' && item.content.cdnLink)
const npmUtilsImports = validNPMUtils.map((item) => import( item.content.cdnLink))
const npmUtils = await Promise.allSettled(npmUtilsImports)
npmUtils.forEach((res, index) => {
const { name, content } = validNPMUtils[index]
const { exportName, destructuring, cdnLink } = content
if (res.status !== 'fulfilled') {
globalNotify({
type: 'error',
message: `加载工具类“${name}”失败,请检查cdn链接是否正确,${cdnLink}`
})
return
}
const module = res.value
utilsCollection[name] = destructuring ? module[exportName] : module.default
})
Object.assign(utils, utilsCollection)
refreshKey.value++
}
return {
refreshKey,
utils,
getUtils,
setUtils
}
}