From de861d0977007d7d41ef445532a2235e477b75e7 Mon Sep 17 00:00:00 2001 From: xion Date: Tue, 7 Jan 2025 02:57:30 +0800 Subject: [PATCH] add effect --- package.json | 25 +++++++++++++----- rollup.config.js | 33 +++++++++++++++++++++++- src/effect.ts | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 3 ++- 4 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 src/effect.ts diff --git a/package.json b/package.json index 9475e1c..98bd518 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/html", - "version": "1.0.0", + "version": "1.0.1", "description": "", "main": "index.js", "type": "module", @@ -12,18 +12,29 @@ "author": "", "license": "ISC", "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.1", - "@rollup/plugin-node-resolve": "^15.3.0", - "@rollup/plugin-typescript": "^12.1.1", + "@rollup/plugin-commonjs": "^28.0.2", + "@rollup/plugin-node-resolve": "^16.0.0", + "@rollup/plugin-typescript": "^12.1.2", "@types/crypto-js": "^4.2.2", - "@types/react": "^18.3.12", + "@types/react": "^19.0.3", "rimraf": "^6.0.1", - "rollup": "^4.24.3", + "rollup": "^4.30.0", "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.1.1", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "dependencies": { + "fast-deep-equal": "^3.1.3", "lit-html": "^3.2.1" + }, + "exports": { + ".": { + "import": "./html.js", + "require": "./html.js" + }, + "./effect": { + "import": "./effect.js", + "require": "./effect.js" + } } } \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index eb69f17..393afb9 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -44,4 +44,35 @@ const config1Dts = { include: ['node_modules/**'], }; -export default [config1, config1Dts]; +const effect = { + input: 'src/effect.ts', // TypeScript 入口文件 + output: { + file: 'dist/effect.js', // 输出文件 + format: 'es', // 输出格式设置为 ES 模块 + }, + plugins: [ + resolve({ + browser: true, // 若为浏览器环境,设为 true;若为 Node.js 环境,设为 false + preferBuiltins: true, // 优先使用内置模块 + }), // 使用 @rollup/plugin-node-resolve 解析 node_modules 中的模块 + commonjs(), // + + typescript({ + allowImportingTsExtensions: true, + noEmit: true, + declaration: false, + }), // 使用 @rollup/plugin-typescript 处理 TypeScript 文件 + ], +}; + +const effectDts = { + input: 'src/effect.ts', // TypeScript 入口文件 + output: { + file: 'dist/effect.d.ts', // 输出文件 + format: 'es', // 输出格式设置为 ES 模块 + }, + plugins: [ + dts(), // 生成 .d.ts 类型声明文件 + ], +}; +export default [config1, config1Dts, effect, effectDts]; diff --git a/src/effect.ts b/src/effect.ts new file mode 100644 index 0000000..4b5e4d1 --- /dev/null +++ b/src/effect.ts @@ -0,0 +1,66 @@ +import deepEqual from 'fast-deep-equal'; + +type EffectFn = () => void; + +type Effect = { + effect: EffectFn; + deps?: any[]; + key: string; +}; + +/** + * EffectManager,用于管理副作用 + */ +export class EffectManager { + effects: Effect[]; + constructor() { + this.effects = []; + } + addEffect(effect: Effect, opts?: { clear?: boolean }) { + const clear = opts?.clear ?? false; + if (clear) { + this.clear(effect.key); + } + this.effects.push(effect); + } + clear(key?: string) { + const clearKeys = key ? this.effects.filter((effect) => effect.key === key) : this.effects; + for (let i = 0; i < clearKeys.length; i++) { + const effect = clearKeys[i]; + try { + effect.effect(); + } catch (e) { + console.error(e, effect.key); + } + } + if (key) { + this.effects = this.effects.filter((effect) => effect.key !== key); + } else { + this.effects = []; + } + } + /** + * 必须保证key唯一 + * @param effect + * @returns + */ + useEffect(effect: Effect) { + const hasEffect = this.effects.find((item) => item.key === effect.key); + if (hasEffect) { + // check deps + if (hasEffect.deps) { + const isEqual = hasEffect.deps.every((dep, index) => { + // 如果是对象,使用deepEqual + if (typeof dep === 'object') { + return deepEqual(dep, effect.deps?.[index]); + } + return dep === effect.deps?.[index]; + }); + if (isEqual) { + return; + } + } + } + this.addEffect(effect, { clear: true }); + } +} diff --git a/tsconfig.json b/tsconfig.json index 92fb8ba..2884cd6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,8 @@ "noUnusedLocals": false, "noUnusedParameters": false, "moduleResolution": "node", - "declaration": true + "declaration": true, + "allowSyntheticDefaultImports": true, }, "include": [ "src/**/*.ts"