UNPKG

use-s-react

Version:

useS is a minimal yet powerful React hook for managing both local and global state — with zero boilerplate

83 lines (82 loc) 2.35 kB
import { TypeCheck } from "full-copy"; function isSamePrimitive(a, b) { return Object.is(a, b); } function isSameDate(a, b) { return a.getTime() === b.getTime(); } function isSameRegExp(a, b) { return a.source === b.source && a.flags === b.flags; } function isSameSet(a, b) { if (a.size !== b.size) return false; for (const item of a) { if (!b.has(item)) return false; } return true; } function isSameMap(a, b) { if (a.size !== b.size) return false; for (const [key, val] of a) { if (!b.has(key) || !Object.is(val, b.get(key))) return false; } return true; } function isSameArray(a, b) { return a.length === b.length && a.every((val, i) => Object.is(val, b[i])); } function hasMeaningfulChange(current, patch) { for (const key in patch) { const patchVal = patch[key]; const currentVal = current[key]; if (typeof patchVal === "object" && patchVal !== null && typeof currentVal === "object" && currentVal !== null) { if (hasMeaningfulChange(currentVal, patchVal)) { return true; } continue; } if (!Object.is(patchVal, currentVal)) return true; } return false; } export function hasChanged(prev, next) { const typePrev = TypeCheck(prev)[0]; const typeNext = TypeCheck(next)[0]; if (typePrev !== typeNext) { return { changed: true, type: typeNext }; } const type = typePrev; const changed = (() => { switch (type) { case "number": case "string": case "boolean": case "undefined": case "null": return !isSamePrimitive(prev, next); case "date": return !isSameDate(prev, next); case "regexp": return !isSameRegExp(prev, next); case "set": return !isSameSet(prev, next); case "map": return !isSameMap(prev, next); case "array": return !isSameArray(prev, next); case "object": return hasMeaningfulChange(prev, next); default: return false; } })(); return { changed, type }; }