refactor(serverUtils.js): highly optimise deep clone and json processing functions

This commit is contained in:
Rim 2025-04-17 06:43:05 -04:00
parent 565e1dd3cb
commit 3774a4265c

View File

@ -26,40 +26,41 @@ try {
} }
// Optimized replaceJsonKeys function // Optimized replaceJsonKeys function
const replaceJsonKeys = (obj) => { const replaceJsonKeys = (obj, replacements) => {
// Handle non-objects early
if (!obj || typeof obj !== 'object') return obj; if (!obj || typeof obj !== 'object') return obj;
// Fast-path for arrays // Fast path for arrays
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
// Only process array if it has items return obj.length === 0 ?
return obj.length > 0 ? obj.map(replaceJsonKeys) : obj; obj
: obj.map((item) => replaceJsonKeys(item, replacements));
} }
// Fast path for empty objects
const keys = Object.keys(obj);
if (keys.length === 0) return obj;
// Process normal objects
const newObj = {}; const newObj = {};
const objKeys = Object.keys(obj); for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// Fast-path for empty objects const newKey = replacements[key] || key;
if (objKeys.length === 0) return obj;
// Cache key check
const hasKeyReplacements = Object.keys(keyReplacements).length > 0;
for (const key of objKeys) {
// Replace key if replacements exist
const newKey = hasKeyReplacements && keyReplacements[key] ? keyReplacements[key] : key;
let value = obj[key]; let value = obj[key];
// Replace string values if needed // Replace string values if they match a key in replacements
if (hasKeyReplacements && typeof value === 'string' && keyReplacements[value]) { if (typeof value === 'string' && replacements[value]) {
value = keyReplacements[value]; value = replacements[value];
} else if (value && typeof value === 'object') {
// Only recurse for objects/arrays
value = replaceJsonKeys(value, replacements);
} }
// Process recursively only if object/array newObj[newKey] = value;
newObj[newKey] = (value && typeof value === 'object') ? replaceJsonKeys(value) : value;
} }
return newObj; return newObj;
}; };
// Utility regex function // Utility regex function
const sanitizeJsonOutput = (data) => { const sanitizeJsonOutput = (data) => {
@ -87,27 +88,18 @@ const sanitizeJsonOutput = (data) => {
// Replace the processJsonOutput function with this more efficient version // Replace the processJsonOutput function with this more efficient version
const processJsonOutput = ( const processJsonOutput = (
data, data,
options = { sanitize: true, replaceKeys: true } options = {
sanitize: true,
replaceKeys: true,
keyReplacements: {},
}
) => { ) => {
// Use a more efficient deep clone approach instead of JSON.parse(JSON.stringify()) // Early return for null or non-objects
function deepClone(obj) { if (data === null || typeof data !== 'object') {
if (obj === null || typeof obj !== 'object') { return data;
return obj;
} }
if (Array.isArray(obj)) { // Copy data first to avoid reference issues
return obj.map((item) => deepClone(item));
}
const clone = {};
Object.keys(obj).forEach((key) => {
clone[key] = deepClone(obj[key]);
});
return clone;
}
// Create a deep copy of the data to avoid reference issues
let processedData = deepClone(data); let processedData = deepClone(data);
// Apply sanitization if needed // Apply sanitization if needed
@ -115,14 +107,48 @@ const processJsonOutput = (
processedData = sanitizeJsonOutput(processedData); processedData = sanitizeJsonOutput(processedData);
} }
// Apply key replacement if needed // Apply key replacement if needed - pass replacements directly
if (options.replaceKeys) { if (
processedData = replaceJsonKeys(processedData); options.replaceKeys &&
Object.keys(options.keyReplacements || {}).length > 0
) {
processedData = replaceJsonKeys(processedData, options.keyReplacements);
} }
return processedData; return processedData;
}; };
/**
* Optimized deep clone function
* @param {any} obj - The object to clone
* @returns {any} - The cloned object
*/
const deepClone = (obj) => {
if (obj === null || typeof obj !== 'object') {
return obj;
}
// Fast path for arrays
if (Array.isArray(obj)) {
const length = obj.length;
const clone = new Array(length);
for (let i = 0; i < length; i++) {
clone[i] = deepClone(obj[i]);
}
return clone;
}
// Fast path for objects
const clone = {};
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
clone[key] = deepClone(obj[key]);
}
return clone;
};
// Store active sessions to avoid repeated logins // Store active sessions to avoid repeated logins
const activeSessions = new Map(); const activeSessions = new Map();
@ -248,5 +274,5 @@ module.exports = {
ensureLogin, ensureLogin,
handleApiError, handleApiError,
sanitizeHeaders, sanitizeHeaders,
processJsonOutput processJsonOutput,
}; };