From 44e47fb3316c5452d277166215bc7522b404047f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 2 Oct 2023 10:41:42 -0300 Subject: data: custom cache for validateWikiData --- src/data/things/validators.js | 72 ++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 29 deletions(-) (limited to 'src/data') diff --git a/src/data/things/validators.js b/src/data/things/validators.js index bdb22058..ee301f15 100644 --- a/src/data/things/validators.js +++ b/src/data/things/validators.js @@ -405,6 +405,8 @@ export function validateReferenceList(type = '') { return validateArrayItems(validateReference(type)); } +const validateWikiData_cache = {}; + export function validateWikiData({ referenceType = '', allowMixedTypes = false, @@ -413,51 +415,63 @@ export function validateWikiData({ throw new TypeError(`Don't specify both referenceType and allowMixedTypes`); } + validateWikiData_cache[referenceType] ??= {}; + validateWikiData_cache[referenceType][allowMixedTypes] ??= new WeakMap(); + const isArrayOfObjects = validateArrayItems(isObject); return (array) => { - isArrayOfObjects(array); + const subcache = validateWikiData_cache[referenceType][allowMixedTypes]; + if (subcache.has(array)) return subcache.get(array); - if (empty(array)) { - return true; - } + let OK = false; - const allRefTypes = - new Set(array.map(object => - object.constructor[Symbol.for('Thing.referenceType')])); + try { + isArrayOfObjects(array); - if (allRefTypes.has(undefined)) { - if (allRefTypes.size === 1) { - throw new TypeError(`Expected array of wiki data objects, got array of other objects`); - } else { - throw new TypeError(`Expected array of wiki data objects, got mixed items`); + if (empty(array)) { + OK = true; return true; } - } - if (allRefTypes.size > 1) { - if (allowMixedTypes) { - return true; + const allRefTypes = + new Set(array.map(object => + object.constructor[Symbol.for('Thing.referenceType')])); + + if (allRefTypes.has(undefined)) { + if (allRefTypes.size === 1) { + throw new TypeError(`Expected array of wiki data objects, got array of other objects`); + } else { + throw new TypeError(`Expected array of wiki data objects, got mixed items`); + } } - const types = () => Array.from(allRefTypes).join(', '); + if (allRefTypes.size > 1) { + if (allowMixedTypes) { + OK = true; return true; + } - if (referenceType) { - if (allRefTypes.has(referenceType)) { - allRefTypes.remove(referenceType); - throw new TypeError(`Expected array of only ${referenceType}, also got other types: ${types()}`) - } else { - throw new TypeError(`Expected array of only ${referenceType}, got other types: ${types()}`); + const types = () => Array.from(allRefTypes).join(', '); + + if (referenceType) { + if (allRefTypes.has(referenceType)) { + allRefTypes.remove(referenceType); + throw new TypeError(`Expected array of only ${referenceType}, also got other types: ${types()}`) + } else { + throw new TypeError(`Expected array of only ${referenceType}, got other types: ${types()}`); + } } + + throw new TypeError(`Expected array of unmixed reference types, got multiple: ${types()}`); } - throw new TypeError(`Expected array of unmixed reference types, got multiple: ${types()}`); - } + if (referenceType && !allRefTypes.has(referenceType)) { + throw new TypeError(`Expected array of ${referenceType}, got array of ${allRefTypes[0]}`) + } - if (referenceType && !allRefTypes.has(referenceType)) { - throw new TypeError(`Expected array of ${referenceType}, got array of ${allRefTypes[0]}`) + OK = true; return true; + } finally { + subcache.set(array, OK); } - - return true; }; } -- cgit 1.3.0-6-gf8a5