playbook/antigravity-awesome-skills/skills/vercel-optimize/lib/dedup-recs.mjs

326 lines
9.9 KiB
JavaScript

const NO_VALUE = '<none>';
export function dedupeRecommendations(recommendations = []) {
if (!Array.isArray(recommendations)) {
throw new TypeError('dedupeRecommendations recommendations must be an array');
}
const byKey = new Map();
const order = [];
for (const rec of recommendations) {
if (!rec || typeof rec !== 'object' || rec.abstain === true) {
order.push(rec);
continue;
}
const key = recommendationKey(rec);
if (!byKey.has(key)) {
const normalized = withDedupMetadata(rec);
byKey.set(key, normalized);
order.push({ __dedupKey: key });
continue;
}
const current = byKey.get(key);
const merged = mergeDuplicateRecs(current, rec);
byKey.set(key, merged);
}
return order.map((entry) => entry?.__dedupKey ? byKey.get(entry.__dedupKey) : entry);
}
export function recommendationKey(rec) {
const intent = dedupIntent(rec);
const bucket = intent === 'cache-control:s-maxage'
? NO_VALUE
: String(rec?.bucket ?? NO_VALUE);
return JSON.stringify([
bucket,
dedupEditTarget(rec),
primarySkillRule(rec),
intent,
]);
}
export function normalizePath(path) {
if (typeof path !== 'string' || path.trim() === '') return NO_VALUE;
return path
.trim()
.replace(/\\/g, '/')
.replace(/^\.\//, '')
.replace(/\/+/g, '/')
.replace(/:(\d+)(?::\d+)?$/, '');
}
export function primarySkillRule(rec) {
const citations = Array.isArray(rec?.citations) ? rec.citations : [];
return citations.find((c) => typeof c === 'string' && /^[A-Za-z][\w-]*:[A-Za-z][\w-]*$/.test(c)) ?? NO_VALUE;
}
export function fixShape(rec) {
if (typeof rec?.fixShape === 'string' && rec.fixShape.trim()) {
return normalizeFixText(rec.fixShape);
}
const primaryText = [rec?.fix, rec?.desiredBehavior]
.filter((v) => typeof v === 'string' && v.trim())
.join('\n');
const text = primaryText || rec?.what;
return normalizeFixText(text);
}
export function dedupIntent(rec) {
if (isSMaxageCacheHeaderRec(rec)) return 'cache-control:s-maxage';
if (isCacheLifeRec(rec)) return cacheLifeIntent(rec);
const sharedFunction = sharedFunctionTarget(rec);
if (sharedFunction) return `parallel-shared-helper:${sharedFunction}`;
return fixShape(rec);
}
export function dedupEditTarget(rec) {
return sharedFunctionTarget(rec) ?? normalizePath(firstAffectedFile(rec));
}
function firstAffectedFile(rec) {
const direct = affectedFiles(rec);
const editTarget = referencedCodeFiles(rec, ['fix', 'desiredBehavior', 'currentBehavior'])[0];
if (editTarget) return editTarget;
const referenced = referencedCodeFiles(rec)
.find((file) => direct.includes(file));
if (referenced) return referenced;
return Array.isArray(rec?.affectedFiles) ? rec.affectedFiles[0] : null;
}
function affectedFiles(rec) {
return Array.isArray(rec?.affectedFiles)
? rec.affectedFiles.map(normalizePath).filter((file) => file !== NO_VALUE)
: [];
}
function referencedCodeFiles(rec, fields = ['what', 'why', 'fix', 'currentBehavior', 'desiredBehavior', 'verify']) {
const text = fields
.map((field) => rec?.[field])
.filter((v) => typeof v === 'string' && v.trim())
.join('\n');
const matches = text.match(/(?:^|[\s`'"(])((?:\.{1,2}\/|[A-Za-z0-9_.@-]+\/)[A-Za-z0-9_./@[\]()-]+\.(?:mjs|cjs|js|jsx|ts|tsx))/g) ?? [];
return unique(matches.map((m) =>
normalizePath(m.replace(/^[\s`'"(]+/, ''))
).filter((file) => file !== NO_VALUE));
}
function isSMaxageCacheHeaderRec(rec) {
const text = [
rec?.what,
rec?.why,
rec?.fix,
rec?.desiredBehavior,
...(Array.isArray(rec?.citations) ? rec.citations : []),
].filter(Boolean).join('\n');
return /\bs-maxage\b/i.test(text) &&
/\b(?:Cache-Control|CDN cache|cdn-cache|caching\/cdn-cache)\b/i.test(text);
}
function isCacheLifeRec(rec) {
const text = [
rec?.candidateRef,
rec?.what,
rec?.why,
rec?.fix,
rec?.desiredBehavior,
...(Array.isArray(rec?.citations) ? rec.citations : []),
].filter(Boolean).join('\n');
return /^isr_overrevalidation:/.test(String(rec?.candidateRef ?? '')) &&
/\bcacheLife\s*\(|\bcacheLife\b/i.test(text);
}
function sharedFunctionTarget(rec) {
const rule = primarySkillRule(rec);
if (!/(?:^|:)async-parallel$|(?:^|:)server-parallel-fetching$|(?:^|:)async-suspense-boundaries$/.test(rule)) {
return null;
}
const text = [
rec?.what,
rec?.why,
rec?.fix,
rec?.currentBehavior,
rec?.desiredBehavior,
].filter((v) => typeof v === 'string' && v.trim()).join('\n');
const names = [
...text.matchAll(/\b(?:get|fetch|load|read|render|create|generate|filter|resolve)[A-Z][A-Za-z0-9_]*\b/g),
].map((m) => m[0]);
const stop = new Set([
'getPayload',
'draftMode',
'notFound',
'redirect',
'Promise',
'Response',
'NextResponse',
]);
const candidates = names.filter((name) => !stop.has(name));
if (candidates.length === 0) return null;
const score = new Map();
for (const name of candidates) {
score.set(name, (score.get(name) ?? 0) + 1);
}
return [...score.entries()]
.sort((a, b) => b[1] - a[1] || text.indexOf(a[0]) - text.indexOf(b[0]))
.map(([name]) => `function:${name}`)[0] ?? null;
}
function cacheLifeIntent(rec) {
const text = [
rec?.what,
rec?.why,
rec?.fix,
rec?.desiredBehavior,
rec?.verify,
].filter(Boolean).join('\n');
const profiles = unique(
[...text.matchAll(/\bcacheLife\s*\(\s*['"`]([^'"`]+)['"`]/g)]
.map((m) => m[1])
);
const tags = unique([
...[...text.matchAll(/\bcacheTag\s*\(([^)]*)\)/gs)].flatMap((m) => {
const args = m[1] ?? '';
return [
...[...args.matchAll(/['"]([^'"]+)['"]/g)].map((x) => x[1]),
...[...args.matchAll(/`([^`]+)`/g)].map((x) => x[1].includes('${') ? `${x[1].split('${')[0]}*` : x[1]),
];
}),
]);
const invalidation = /\b(?:revalidateTag|updateTag)\s*\(/.test(text) ? 'with-invalidation-api' : 'no-invalidation-api';
return [
'next-cache:cache-life',
profiles.join('|') || NO_VALUE,
tags.join('|') || NO_VALUE,
invalidation,
].join(':');
}
function unique(values) {
return Array.from(new Set(values.filter((v) => typeof v === 'string' && v.trim()).map((v) => v.trim()))).sort();
}
function normalizeFixText(text) {
if (typeof text !== 'string' || text.trim() === '') return NO_VALUE;
return text
.toLowerCase()
.replace(/```[\s\S]*?```/g, ' codeblock ')
.replace(/`[^`]*`/g, ' code ')
.replace(/\b\d+(?:\.\d+)?(?:ms|s|%|kb|mb|gb|k|m)?\b/g, '#')
.replace(/[^a-z0-9#]+/g, ' ')
.trim()
.split(/\s+/)
.slice(0, 80)
.join(' ') || NO_VALUE;
}
function withDedupMetadata(rec) {
const existing = normalizedAppliesAlsoTo(rec.appliesAlsoTo);
const count = Math.max(
numericCount(rec.corroborationCount),
1 + existing.length,
);
return existing.length > 0 || count > 1
? { ...rec, appliesAlsoTo: existing, corroborationCount: count }
: { ...rec };
}
function mergeDuplicateRecs(a, b) {
const aScore = recScore(a);
const bScore = recScore(b);
const winner = bScore > aScore ? b : a;
const loser = winner === a ? b : a;
const winnerExisting = normalizedAppliesAlsoTo(winner.appliesAlsoTo);
const loserExisting = normalizedAppliesAlsoTo(loser.appliesAlsoTo);
const appliesAlsoTo = uniqueAppliesAlsoTo([
...winnerExisting,
appliesAlsoEntry(loser),
...loserExisting,
]);
const corroborationCount =
numericCount(winner.corroborationCount) + numericCount(loser.corroborationCount);
return {
...winner,
appliesAlsoTo,
corroborationCount: Math.max(corroborationCount, 1 + appliesAlsoTo.length),
};
}
function recScore(rec) {
const priority = typeof rec?.priority === 'number' ? rec.priority : 0;
const quality = typeof rec?.quality?.overall === 'number' ? rec.quality.overall : 0;
return (priority * 1_000_000_000_000) + signalMagnitude(rec) + quality;
}
function signalMagnitude(rec) {
const text = [
rec?.o11ySignal,
rec?.why,
rec?.what,
rec?.impact,
].filter((v) => typeof v === 'string' && v.trim()).join('\n');
const inv = parseNumber(text, /(?:inv|invocations?|function invocations?|requests?)[:=]\s*([\d,]+)/i);
const p95 = parseNumber(text, /(?:p95|95th percentile(?: duration)?)[:=]?\s*([\d,]+)\s*ms/i);
const errors = parseNumber(text, /(?:errs|errors?)[:=]\s*([\d,]+)/i);
const writes = parseNumber(text, /writes[:=]\s*([\d,]+)/i);
const reads = parseNumber(text, /reads[:=]\s*([\d,]+)/i);
if (inv != null && p95 != null) return inv * p95;
if (errors != null) return errors;
if (writes != null && reads != null) return writes + reads;
if (inv != null) return inv;
return 0;
}
function parseNumber(text, re) {
const match = re.exec(text);
if (!match) return null;
const value = Number(String(match[1]).replace(/,/g, ''));
return Number.isFinite(value) ? value : null;
}
function numericCount(value) {
return Number.isFinite(value) && value > 0 ? value : 1;
}
function appliesAlsoEntry(rec) {
return {
candidateRef: rec?.candidateRef ?? null,
affectedFiles: Array.isArray(rec?.affectedFiles)
? rec.affectedFiles.map(normalizePath).filter((p) => p !== NO_VALUE)
: [],
o11ySignal: rec?.o11ySignal ?? null,
what: rec?.what ?? null,
};
}
function normalizedAppliesAlsoTo(entries) {
if (!Array.isArray(entries)) return [];
return entries
.filter((e) => e && typeof e === 'object')
.map((e) => ({
candidateRef: e.candidateRef ?? null,
affectedFiles: Array.isArray(e.affectedFiles)
? e.affectedFiles.map(normalizePath).filter((p) => p !== NO_VALUE)
: [],
o11ySignal: e.o11ySignal ?? null,
what: e.what ?? null,
}));
}
function uniqueAppliesAlsoTo(entries) {
const seen = new Set();
const out = [];
for (const entry of entries) {
const key = JSON.stringify([
entry.candidateRef ?? NO_VALUE,
entry.affectedFiles?.join(',') ?? NO_VALUE,
entry.what ?? NO_VALUE,
]);
if (seen.has(key)) continue;
seen.add(key);
out.push(entry);
}
return out;
}