UNPKG

form-chain-effect-engine

Version:

A dependency-driven form effect engine for React + Ant Design

166 lines (162 loc) 6.55 kB
'use strict'; var react = require('react'); function createChain(source, enableAdvanced, _triggerFn) { const chain = { source, path: [source], }; if (enableAdvanced) { chain.isStopped = false; chain.stop = () => { chain.isStopped = true; }; } return chain; } function extendChain(chain, nextField) { return Object.assign(Object.assign({}, chain), { path: [...chain.path, nextField] }); } // =============核心 Hook============= function useFormChainEffectEngine({ form, config, options = {}, onEffectResult, }) { var _a, _b, _c; const enableAdvanced = (_a = options.enableAdvancedControl) !== null && _a !== void 0 ? _a : false; const debugLog = (_b = options.debugLog) !== null && _b !== void 0 ? _b : false; const effectActions = (_c = options.effectActions) !== null && _c !== void 0 ? _c : {}; const trigger = react.useCallback((field, chain, visited, overrideValue) => { // 参数验证 if (!field || typeof field !== "string") { console.error("[form-chain-effect-engine] 无效的字段名称:", field); return; } if (visited.has(field)) { if (debugLog) { console.warn(`[form-chain-effect-engine] 检测到循环依赖,链路已终止: ${[...chain.path, field].join(" → ")}`); } return; } visited.add(field); const item = config[field]; if (!item) { if (debugLog) { console.log(`[form-chain-effect-engine] 字段 ${field} 未在配置中找到`); } return; } // 安全地获取表单值 let currentVal; let allValues; try { currentVal = overrideValue !== undefined ? overrideValue : form.getFieldValue(field); allValues = form.getFieldsValue(); } catch (err) { console.error(`[form-chain-effect-engine] 获取表单值失败: 字段 ${field}, 错误:`, err); return; } if (debugLog) { console.log(`[form-chain-effect-engine] 触发 effect: ${field}, 当前值:`, currentVal, ", 链路:", chain.path); } let result; if (item.effect && typeof item.effect === "function") { try { result = item.effect(currentVal, allValues, chain, effectActions); } catch (err) { console.error(`[form-chain-effect-engine] effect 执行异常: 字段 ${field}, 错误:`, err); // 不中断链路,继续执行依赖字段 } } if (result) { // 处理异步 effect 的返回值 if (result instanceof Promise) { result .then((resolvedResult) => { if (resolvedResult) { try { onEffectResult === null || onEffectResult === void 0 ? void 0 : onEffectResult({ fieldName: field, field: item, result: resolvedResult, chain, currentVal, allValues, }); } catch (err) { console.error(`[form-chain-effect-engine] onEffectResult 回调执行异常: 字段 ${field}, 错误:`, err); } } }) .catch((err) => { console.error(`[form-chain-effect-engine] 异步 effect 执行异常: 字段 ${field}, 错误:`, err); }); } else { try { onEffectResult === null || onEffectResult === void 0 ? void 0 : onEffectResult({ fieldName: field, field: item, result, chain, currentVal, allValues, }); } catch (err) { console.error(`[form-chain-effect-engine] onEffectResult 回调执行异常: 字段 ${field}, 错误:`, err); } } } if (enableAdvanced && chain.isStopped) { if (debugLog) { console.log(`[form-chain-effect-engine] 链路已停止: ${field}`); } return; } if (item.dependents && item.dependents.length > 0) { for (const dep of item.dependents) { // 验证依赖字段名称 if (!dep || typeof dep !== "string") { console.error(`[form-chain-effect-engine] 无效的依赖字段名称: ${dep}, 来源字段: ${field}`); continue; } trigger(dep, extendChain(chain, dep), visited); } } }, [form, config, enableAdvanced, debugLog, effectActions, onEffectResult]); const onValuesChange = react.useCallback((changed) => { if (!changed || typeof changed !== "object") { console.error("[form-chain-effect-engine] 无效的 changed 参数:", changed); return; } const visited = new Set(); const changedKeys = Object.keys(changed); if (changedKeys.length === 0) { if (debugLog) { console.log("[form-chain-effect-engine] 没有检测到字段变更"); } return; } // 只处理第一个变更的字段(保持原有逻辑) const changedKey = changedKeys[0]; trigger(changedKey, createChain(changedKey, enableAdvanced), visited); }, [trigger, enableAdvanced, debugLog]); const manualTrigger = react.useCallback((field, value) => { if (!field || typeof field !== "string") { console.error("[form-chain-effect-engine] 无效的字段名称:", field); return; } const visited = new Set(); const chain = createChain(field, enableAdvanced); trigger(field, chain, visited, value); }, [trigger, enableAdvanced]); return { onValuesChange, manualTrigger, }; } exports.useFormChainEffectEngine = useFormChainEffectEngine; //# sourceMappingURL=index.cjs.js.map