Skip to content

Instantly share code, notes, and snippets.

@mdjastrzebski
Last active July 24, 2023 12:43
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdjastrzebski/6672e86f652a692575bf48a506ee1539 to your computer and use it in GitHub Desktop.
Save mdjastrzebski/6672e86f652a692575bf48a506ee1539 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import { padStart, eq, isEqual } from 'lodash';
export function useDebugDeps(name: string, deps: unknown[]): void {
const previousDepsRef = React.useRef(deps);
const countRef = React.useRef(0);
printDepsChange(name, deps, previousDepsRef.current, countRef.current);
previousDepsRef.current = deps;
countRef.current += 1;
}
type DebugDepsFn = (deps: unknown[]) => void;
export function makeDebugDeps(name: string): DebugDepsFn {
let previousDeps: unknown[] = [];
let count = 0;
return (deps: unknown[]) => {
printDepsChange(name, deps, previousDeps, count);
previousDeps = deps;
count += 1;
};
}
function printDepsChange(name: string, deps: unknown[], previousDeps: unknown[], count: number) {
const dateString = new Date().toISOString();
if (count === 0) {
console.log(`🔵 DEPS ${name}: INITIAL - ${dateString}`);
for (const [index, value] of deps.entries()) {
console.log(` - ${index}: ${formatValue(value, 100)}`);
}
console.log('');
return;
}
const areTheSame = deps.length === previousDeps.length && deps.every((_, index) => eq(deps[index], previousDeps[index]));
if (areTheSame) {
console.log(`🟢 DEPS ${name}: UPDATE ${count} - NO CHANGES ${dateString}`);
console.log('');
return;
}
console.log(`🔴 DEPS ${name}: UPDATE ${count} - ${dateString}`);
for (const [index, value] of deps.entries()) {
const previousValue = previousDeps[index];
if (eq(value, previousValue)) continue;
if (isEqual(value, previousValue)) {
console.log(` - ${padStart(index.toString(), 2)}. ❗️IDENTITY CHANGE: ${formatValue(deps[index], 100)}`);
continue;
}
console.log(` - ${padStart(index.toString(), 2)}. ${formatValue(previousDeps[index], 50)} -> ${formatValue(deps[index], 50)}`);
}
console.log('');
}
function formatValue(value: unknown, length: number) {
if (typeof value === 'function') {
return '[Function]';
}
const serializedValue = JSON.stringify(value, getCircularReplacer());
return serializedValue && serializedValue.length > length ? `${serializedValue.slice(0, length)}...` : serializedValue;
}
// See: https://stackoverflow.com/a/57615112
const getCircularReplacer = () => {
const seen = new WeakSet();
return (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment