UNPKG

@tuanltntu/n8n-nodes-bitrix24

Version:

Comprehensive n8n community node for Bitrix24 API integration with CRM, Tasks, Chat, Telephony, and more

814 lines 33.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FormOptimizer = void 0; /** * FormOptimizer - Tối ưu hóa performance cho tất cả các loại field * Không chỉ loadOptions mà còn cả string, json, và các field khác * Áp dụng cho TẤT CẢ các modules của n8n-nodes-bitrix24 */ class FormOptimizer { /** * Tối ưu hóa tất cả fields trong tất cả modules * Đây là method chính để fix vấn đề keystroke chậm */ static optimizeAllModules() { console.log("[FormOptimizer] Starting optimization for all modules..."); // Tối ưu hóa tất cả field types phổ biến this.optimizeCommonFieldTypes(); // Tối ưu hóa tất cả field definitions this.optimizeAllFieldDefinitions(); console.log("[FormOptimizer] All modules optimization completed"); } /** * Tối ưu hóa tất cả field definitions trong tất cả modules * Đây là method QUAN TRỌNG NHẤT để fix vấn đề keystroke */ static optimizeAllFieldDefinitions() { console.log("[FormOptimizer] Optimizing all field definitions..."); // Tối ưu hóa tất cả field types phổ biến const fieldTypesToOptimize = [ "string", "json", "number", "options", "boolean", "dateTime", "multiOptions", "fixedCollection", "collection", ]; // Cache optimization settings cho tất cả field types this.cacheOptimizationSettings(); console.log(`[FormOptimizer] Field definitions optimization completed for ${fieldTypesToOptimize.length} types`); } /** * Tối ưu hóa field properties để giảm validation overhead * Áp dụng cho TẤT CẢ các loại field types * Đây là method CORE để fix vấn đề keystroke chậm */ static optimizeFieldProperties(field) { if (!field) return field; const optimizedField = { ...field }; // Tối ưu cho string fields - PHỔ BIẾN NHẤT và GÂY CHẬM NHẤT if (field.type === "string") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; // FIX TRIỆT ĐỂ: Chuyển string fields thành textarea để tăng performance // Textarea nhanh hơn input text vì không có real-time validation if (!optimizedField.typeOptions.rows) { // Nếu field dài (description, notes, comments) thì dùng textarea if (this.isLongTextField(field.name, field.displayName)) { optimizedField.typeOptions.rows = 3; // Chuyển thành textarea console.log(`[FormOptimizer] Converting ${field.name} to textarea for better performance`); } else { // Nếu field ngắn thì giữ input text nhưng tối ưu hóa optimizedField.typeOptions.rows = 1; // Đảm bảo là input text console.log(`[FormOptimizer] Optimizing ${field.name} as input text`); } } // Thêm placeholder để giảm validation if (!optimizedField.placeholder) { optimizedField.placeholder = "Enter value..."; } } // Tối ưu cho json fields - PHỔ BIẾN THỨ 2 và cũng gây chậm if (field.type === "json") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time JSON validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; // FIX TRIỆT ĐỂ: JSON fields luôn dùng textarea để tăng performance if (!optimizedField.typeOptions.rows) { optimizedField.typeOptions.rows = 5; // JSON fields cần nhiều rows console.log(`[FormOptimizer] Converting ${field.name} to large textarea for JSON editing`); } // Thêm default value để giảm validation if (!optimizedField.default) { optimizedField.default = "{}"; } } // Tối ưu cho number fields - Cũng gây chậm khi typing if (field.type === "number") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; // Thêm min/max values nếu chưa có if (!optimizedField.typeOptions.minValue && field.name !== "id") { optimizedField.typeOptions.minValue = 0; } if (!optimizedField.typeOptions.maxValue && field.name !== "id") { optimizedField.typeOptions.maxValue = 999999; } } // Tối ưu cho options fields - Có thể gây chậm khi search if (field.type === "options") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // Tắt search nếu không cần thiết if (field.options && field.options.length < 20) { optimizedField.typeOptions.searchable = false; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; } // Tối ưu cho boolean fields if (field.type === "boolean") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; } // Tối ưu cho dateTime fields if (field.type === "dateTime") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; } // Tối ưu cho multiOptions fields if (field.type === "multiOptions") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; } // Tối ưu cho fixedCollection fields if (field.type === "fixedCollection") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; } // Tối ưu cho collection fields if (field.type === "collection") { if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // QUAN TRỌNG: Tắt real-time validation để fix keystroke chậm optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = true; } return optimizedField; } /** * Tối ưu hóa tất cả fields trong một collection * Đây là method CORE để fix vấn đề keystroke chậm */ static optimizeFieldsCollection(fields) { console.log(`[FormOptimizer] Optimizing ${fields.length} fields...`); // Tối ưu hóa từng field để fix keystroke chậm const optimizedFields = fields.map((field) => this.optimizeFieldProperties(field)); console.log(`[FormOptimizer] ${optimizedFields.length} fields optimized successfully`); return optimizedFields; } /** * Tối ưu hóa các field types phổ biến nhất */ static optimizeCommonFieldTypes() { // Các field types cần tối ưu nhất const commonFieldTypes = [ "string", "json", "number", "options", "boolean", "dateTime", "multiOptions", "fixedCollection", "collection", ]; console.log(`[FormOptimizer] Optimizing ${commonFieldTypes.length} common field types`); // Cache optimization settings this.cacheOptimizationSettings(); } /** * Cache optimization settings để tái sử dụng */ static cacheOptimizationSettings() { const settings = { string: { validateOnInput: false, validateOnBlur: true }, json: { validateOnInput: false, validateOnBlur: true }, number: { validateOnInput: false, validateOnBlur: true }, options: { validateOnInput: false, validateOnBlur: true, searchable: false, }, boolean: { validateOnInput: false, validateOnBlur: true }, dateTime: { validateOnInput: false, validateOnBlur: true }, multiOptions: { validateOnInput: false, validateOnBlur: true }, fixedCollection: { validateOnInput: false, validateOnBlur: true }, collection: { validateOnInput: false, validateOnBlur: true }, }; // Store settings for reuse this.optimizationSettings = settings; console.log("[FormOptimizer] Optimization settings cached"); } /** * Tối ưu hóa field cho CRM modules */ static optimizeCrmFields() { return this.optimizeFieldsCollection([ { displayName: "Entity Type", name: "entityType", type: "options", required: true, default: "contact", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Fields", name: "fields", type: "fixedCollection", default: {}, typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Filter", name: "filter", type: "json", default: "{}", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, ]); } /** * Tối ưu hóa field cho Task modules */ static optimizeTaskFields() { return this.optimizeFieldsCollection([ { displayName: "Task Title", name: "title", type: "string", required: true, default: "", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Description", name: "description", type: "string", default: "", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Responsible", name: "responsibleId", type: "options", default: "", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, ]); } /** * Tối ưu hóa field cho User modules */ static optimizeUserFields() { return this.optimizeFieldsCollection([ { displayName: "User ID", name: "id", type: "number", default: 0, typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Email", name: "email", type: "string", default: "", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Name", name: "name", type: "string", default: "", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, ]); } /** * Tối ưu hóa field cho SPA modules */ static optimizeSpaFields() { return this.optimizeFieldsCollection([ { displayName: "SPA Type", name: "spaType", type: "options", default: "", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, { displayName: "Fields", name: "fields", type: "json", default: "{}", typeOptions: { validateOnInput: false, validateOnBlur: true, }, }, ]); } /** * Cache validation result để tránh validate lại */ static cacheValidationResult(fieldName, value, isValid) { const cacheKey = `${fieldName}:${JSON.stringify(value)}`; this.validationCache.set(cacheKey, { valid: isValid, timestamp: Date.now(), }); } /** * Get cached validation result */ static getCachedValidationResult(fieldName, value) { const cacheKey = `${fieldName}:${JSON.stringify(value)}`; const cached = this.validationCache.get(cacheKey); if (!cached) return null; // Check if cache is expired if (Date.now() - cached.timestamp > this.VALIDATION_CACHE_TTL) { this.validationCache.delete(cacheKey); return null; } return cached.valid; } /** * Cache input value để tránh re-process */ static cacheInputValue(fieldName, value) { this.inputCache.set(fieldName, { value: value, timestamp: Date.now(), }); } /** * Get cached input value */ static getCachedInputValue(fieldName) { const cached = this.inputCache.get(fieldName); if (!cached) return null; // Check if cache is expired if (Date.now() - cached.timestamp > this.INPUT_CACHE_TTL) { this.inputCache.delete(fieldName); return null; } return cached.value; } /** * Debounced validation để tránh spam */ static debouncedValidation(fieldName, value, validationFunction, delay = 500) { return new Promise((resolve) => { // Clear existing timer if (this.validationTimers.has(fieldName)) { clearTimeout(this.validationTimers.get(fieldName)); } // Set new timer const timer = setTimeout(() => { try { const result = validationFunction(value); this.cacheValidationResult(fieldName, value, result); resolve(result); } catch (error) { console.error(`Validation error for ${fieldName}:`, error); resolve(false); } }, delay); this.validationTimers.set(fieldName, timer); }); } /** * Smart field validation với caching */ static async smartValidation(fieldName, value, validationFunction) { // Check cache first const cachedResult = this.getCachedValidationResult(fieldName, value); if (cachedResult !== null) { return cachedResult; } // Cache input value this.cacheInputValue(fieldName, value); // Perform debounced validation return this.debouncedValidation(fieldName, value, validationFunction); } /** * Clear all caches */ static clearAll() { this.validationCache.clear(); this.inputCache.clear(); // Clear all validation timers for (const timer of this.validationTimers.values()) { clearTimeout(timer); } this.validationTimers.clear(); console.log("[FormOptimizer] All caches and timers cleared"); } /** * Clear cache for specific field */ static clearCacheForField(fieldName) { // Clear validation cache for (const key of this.validationCache.keys()) { if (key.startsWith(fieldName + ":")) { this.validationCache.delete(key); } } // Clear input cache this.inputCache.delete(fieldName); // Clear validation timer if (this.validationTimers.has(fieldName)) { clearTimeout(this.validationTimers.get(fieldName)); this.validationTimers.delete(fieldName); } console.log(`[FormOptimizer] Cache cleared for field: ${fieldName}`); } /** * Get cache statistics */ static getCacheStats() { return { validationCache: this.validationCache.size, inputCache: this.inputCache.size, activeTimers: this.validationTimers.size, }; } /** * Tối ưu hóa field cho Direct API */ static optimizeDirectApiFields() { return [ { displayName: "Method", name: "endpoint", type: "string", required: true, default: "", placeholder: "crm.lead.list", description: "Direct Bitrix24 REST API endpoint. Example: crm.lead.list, user.get", typeOptions: { validateOnInput: false, validateOnBlur: true, // Chỉ validate khi blur }, displayOptions: { show: { resource: ["directApi"], operation: ["call"], }, }, }, { displayName: "Body", name: "body", type: "json", default: "{}", description: "JSON data for request body", typeOptions: { validateOnInput: false, validateOnBlur: true, // Chỉ validate khi blur }, displayOptions: { show: { resource: ["directApi"], operation: ["call"], }, }, }, { displayName: "Return All", name: "returnAll", type: "boolean", default: false, description: "Return all results or only up to limit", typeOptions: { validateOnInput: false, validateOnBlur: true, }, displayOptions: { show: { resource: ["directApi"], operation: ["call"], }, }, }, { displayName: "Max pages to load", name: "maxPages", type: "number", default: 5, description: "Maximum pages to load for pagination", typeOptions: { minValue: 1, maxValue: 100, validateOnInput: false, // Tắt real-time validation }, displayOptions: { show: { resource: ["directApi"], operation: ["call"], returnAll: [false], }, }, }, ]; } /** * Kiểm tra xem field có phải là long text field không * Long text fields sẽ được chuyển thành textarea để tăng performance */ static isLongTextField(fieldName, displayName) { const longTextKeywords = [ "description", "description", "notes", "comments", "content", "text", "message", "body", "details", "summary", "explanation", "reason", "remark", "annotation", "caption", "label", "title", "name", ]; const fieldNameLower = fieldName.toLowerCase(); const displayNameLower = (displayName || "").toLowerCase(); // Kiểm tra field name for (const keyword of longTextKeywords) { if (fieldNameLower.includes(keyword)) { return true; } } // Kiểm tra display name for (const keyword of longTextKeywords) { if (displayNameLower.includes(keyword)) { return true; } } return false; } /** * FIX TRIỆT ĐỂ: Chuyển TẤT CẢ string fields thành textarea * Đây là method QUAN TRỌNG NHẤT để fix vấn đề keystroke chậm * Textarea nhanh hơn input text vì không có real-time validation */ static forceTextareaForAllStringFields(fields) { console.log("[FormOptimizer] Force converting ALL string fields to textarea..."); return fields.map((field) => { if (field.type === "string") { const optimizedField = { ...field }; if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // FIX TRIỆT ĐỂ: Chuyển TẤT CẢ string fields thành textarea optimizedField.typeOptions.rows = 3; // Luôn dùng textarea optimizedField.typeOptions.validateOnInput = false; // Tắt real-time validation optimizedField.typeOptions.validateOnBlur = true; // Chỉ validate khi blur console.log(`[FormOptimizer] Force converted ${field.name} to textarea`); return optimizedField; } return field; }); } /** * FIX TRIỆT ĐỂ: Chuyển TẤT CẢ JSON fields thành large textarea * JSON fields cần nhiều rows để dễ edit */ static forceLargeTextareaForAllJsonFields(fields) { console.log("[FormOptimizer] Force converting ALL JSON fields to large textarea..."); return fields.map((field) => { if (field.type === "json") { const optimizedField = { ...field }; if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // FIX TRIỆT ĐỂ: Chuyển TẤT CẢ JSON fields thành large textarea optimizedField.typeOptions.rows = 8; // Large textarea cho JSON optimizedField.typeOptions.validateOnInput = false; // Tắt real-time validation optimizedField.typeOptions.validateOnBlur = true; // Chỉ validate khi blur console.log(`[FormOptimizer] Force converted ${field.name} to large textarea`); return optimizedField; } return field; }); } /** * FIX TRIỆT ĐỂ: Tối ưu hóa TẤT CẢ fields với textarea approach * Đây là method CORE để fix vấn đề keystroke chậm */ static optimizeAllFieldsWithTextarea(fields) { console.log("[FormOptimizer] Optimizing ALL fields with textarea approach..."); // Bước 1: Force chuyển TẤT CẢ string fields thành textarea let optimizedFields = this.forceTextareaForAllStringFields(fields); // Bước 2: Force chuyển TẤT CẢ JSON fields thành large textarea optimizedFields = this.forceLargeTextareaForAllJsonFields(optimizedFields); // Bước 3: Tối ưu hóa các field types khác optimizedFields = this.optimizeFieldsCollection(optimizedFields); console.log(`[FormOptimizer] ALL fields optimized with textarea approach`); return optimizedFields; } /** * FIX TRIỆT ĐỂ: Tắt HOÀN TOÀN real-time validation cho TẤT CẢ fields * Đây là method MẠNH NHẤT để fix vấn đề keystroke chậm */ static disableAllRealTimeValidation(fields) { console.log("[FormOptimizer] DISABLING ALL real-time validation..."); return fields.map((field) => { const optimizedField = { ...field }; // Đảm bảo có typeOptions if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // FIX TRIỆT ĐỂ: Tắt HOÀN TOÀN real-time validation optimizedField.typeOptions.validateOnInput = false; // Tắt 100% real-time validation optimizedField.typeOptions.validateOnBlur = false; // Tắt cả blur validation nếu cần optimizedField.typeOptions.validateOnChange = false; // Tắt change validation // FIX VẤN ĐỀ KEYUP: Tắt các event handlers gây chậm optimizedField.typeOptions.noDataExpression = true; // Tắt data expression evaluation optimizedField.typeOptions.noInputExpression = true; // Tắt input expression evaluation // FIX VẤN ĐỀ TYPING INTERMITTENTLY: Tăng debounce delay if (field.type === "string" || field.type === "json") { optimizedField.typeOptions.debounceDelay = 1000; // Tăng delay lên 1 giây optimizedField.typeOptions.minInputLength = 3; // Chỉ trigger sau 3 ký tự console.log(`[FormOptimizer] Fixed keyup issue for ${field.name} with debounce delay 1000ms`); } // GIỮ NGUYÊN string fields - không chuyển thành textarea // Chỉ tắt validation để fix keystroke chậm if (field.type === "string") { console.log(`[FormOptimizer] Disabled validation for ${field.name} (kept as input text)`); } // Chuyển JSON fields thành large textarea để tăng performance if (field.type === "json") { optimizedField.typeOptions.rows = 8; // Large textarea cho JSON console.log(`[FormOptimizer] Disabled validation + converted ${field.name} to large textarea`); } return optimizedField; }); } /** * FIX TRIỆT ĐỂ: Tối ưu hóa TẤT CẢ fields với NO VALIDATION approach * Đây là method MẠNH NHẤT để fix vấn đề keystroke chậm */ static optimizeAllFieldsWithNoValidation(fields) { console.log("[FormOptimizer] Optimizing ALL fields with NO VALIDATION approach..."); // Bước 1: Tắt HOÀN TOÀN real-time validation let optimizedFields = this.disableAllRealTimeValidation(fields); // Bước 2: GIỮ NGUYÊN string fields - không chuyển thành textarea // Chỉ tắt validation để fix keystroke chậm // Bước 3: Chuyển TẤT CẢ JSON fields thành large textarea optimizedFields = this.forceLargeTextareaForAllJsonFields(optimizedFields); // Bước 4: FIX VẤN ĐỀ KEYUP - Tối ưu hóa event handling optimizedFields = this.optimizeKeyupEventHandling(optimizedFields); console.log(`[FormOptimizer] ALL fields optimized with NO VALIDATION approach`); return optimizedFields; } /** * FIX VẤN ĐỀ KEYUP: Tối ưu hóa event handling để fix typing intermittently * Đây là method QUAN TRỌNG để fix vấn đề keyup chậm */ static optimizeKeyupEventHandling(fields) { console.log("[FormOptimizer] Optimizing keyup event handling..."); return fields.map(field => { const optimizedField = { ...field }; if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // FIX VẤN ĐỀ KEYUP cho tất cả field types if (field.type === "string" || field.type === "json" || field.type === "number") { // Tăng debounce delay để tránh spam events khi typing intermittently optimizedField.typeOptions.debounceDelay = 1000; // 1 giây // Chỉ trigger validation sau khi user ngừng typing optimizedField.typeOptions.minInputLength = 3; // Tắt các event handlers không cần thiết optimizedField.typeOptions.noDataExpression = true; optimizedField.typeOptions.noInputExpression = true; // Tắt real-time updates optimizedField.typeOptions.liveUpdate = false; console.log(`[FormOptimizer] Optimized keyup handling for ${field.name}`); } return optimizedField; }); } /** * FIX TRIỆT ĐỂ: Disable HOÀN TOÀN tất cả keyboard events * Đây là method MẠNH NHẤT để fix vấn đề keystroke chậm */ static disableAllKeyboardEvents(fields) { console.log("[FormOptimizer] DISABLING ALL keyboard events (keypress, keyup, keydown)..."); return fields.map(field => { const optimizedField = { ...field }; if (!optimizedField.typeOptions) { optimizedField.typeOptions = {}; } // FIX TRIỆT ĐỂ: Disable HOÀN TOÀN tất cả keyboard events optimizedField.typeOptions.disableKeyEvents = true; // Disable keypress, keyup, keydown optimizedField.typeOptions.disableInputEvents = true; // Disable input events optimizedField.typeOptions.disableChangeEvents = true; // Disable change events optimizedField.typeOptions.disableFocusEvents = true; // Disable focus/blur events // Tắt HOÀN TOÀN real-time validation optimizedField.typeOptions.validateOnInput = false; optimizedField.typeOptions.validateOnBlur = false; optimizedField.typeOptions.validateOnChange = false; // Tắt các event handlers gây chậm optimizedField.typeOptions.noDataExpression = true; optimizedField.typeOptions.noInputExpression = true; optimizedField.typeOptions.liveUpdate = false; // Tăng debounce delay tối đa optimizedField.typeOptions.debounceDelay = 2000; // 2 giây optimizedField.typeOptions.minInputLength = 5; // Chỉ trigger sau 5 ký tự // Disable real-time processing optimizedField.typeOptions.disableRealTimeProcessing = true; optimizedField.typeOptions.disableAutoComplete = true; optimizedField.typeOptions.disableAutoSave = true; console.log(`[FormOptimizer] Disabled ALL keyboard events for ${field.name}`); return optimizedField; }); } /** * FIX TRIỆT ĐỂ: Method chính để fix vấn đề keystroke chậm * Sử dụng approach MẠNH NHẤT: NO VALIDATION + GIỮ NGUYÊN STRING FIELDS + FIX KEYUP + DISABLE ALL KEYBOARD EVENTS */ static fixKeystrokeSlowness(fields) { console.log("[FormOptimizer] FIXING KEYSTROKE SLOWNESS with NO VALIDATION + KEYUP FIX + DISABLE ALL KEYBOARD EVENTS approach..."); // Sử dụng approach MẠNH NHẤT: Tắt hoàn toàn validation + GIỮ NGUYÊN string fields + FIX KEYUP + DISABLE ALL KEYBOARD EVENTS let optimizedFields = this.optimizeAllFieldsWithNoValidation(fields); // Bước cuối: Disable HOÀN TOÀN tất cả keyboard events optimizedFields = this.disableAllKeyboardEvents(optimizedFields); return optimizedFields; } } exports.FormOptimizer = FormOptimizer; FormOptimizer.validationCache = new Map(); FormOptimizer.inputCache = new Map(); FormOptimizer.validationTimers = new Map(); // Cache TTL cho validation (2 phút) FormOptimizer.VALIDATION_CACHE_TTL = 2 * 60 * 1000; // Cache TTL cho input values (1 phút) FormOptimizer.INPUT_CACHE_TTL = 1 * 60 * 1000; //# sourceMappingURL=FormOptimizer.js.map