From 0655370c830a309d8808ef365dff611725ea73b1 Mon Sep 17 00:00:00 2001 From: Barry Pollard Date: Tue, 21 Apr 2026 12:43:38 +0100 Subject: [PATCH] Add onEachInteraction to onINP options This adds an "onEachInteraction" option to onINP, which exposes to us each interaction. It also calls attributeINP on each value given to the callback. --- src/attribution/onINP.ts | 35 ++++++++++++++++++++++++++++++++++- src/types/inp.ts | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/attribution/onINP.ts b/src/attribution/onINP.ts index 0d6d098..3fe5050 100644 --- a/src/attribution/onINP.ts +++ b/src/attribution/onINP.ts @@ -260,7 +260,40 @@ export const onINP = ( cleanupPending = false; }; - interactionManager._onBeforeProcessingEntry = groupEntriesByRenderTime; + async function handleOnEachInteractionCallback( + entry: PerformanceEventTiming, + ) { + if (!opts.onEachInteraction) { + return; + } + + // Wait a microtask so this "pre" processing callback actually + // becomes a "post" processing callback. + void (await Promise.resolve()); + if (!entry.interactionId) { + return; + } + + const interaction = attributeINP({ + entries: [entry], + // The only value we really need for `attributeINP` is `entries` + // Everything else is included to fill out the type. + name: 'INP', + rating: 'good', + value: entry.duration, + delta: entry.duration, + navigationType: 'navigate', + id: 'N/A', + }); + opts.onEachInteraction(interaction); + } + + interactionManager._onBeforeProcessingEntry = ( + entry: PerformanceEventTiming, + ) => { + void handleOnEachInteractionCallback(entry); + groupEntriesByRenderTime(entry); + }; interactionManager._onAfterProcessingINPCandidate = saveInteractionTarget; const getIntersectingLoAFs = ( diff --git a/src/types/inp.ts b/src/types/inp.ts index 6041b2d..9b6bd2e 100644 --- a/src/types/inp.ts +++ b/src/types/inp.ts @@ -28,6 +28,7 @@ export interface INPReportOpts extends ReportOpts { export interface INPAttributionReportOpts extends AttributionReportOpts { durationThreshold?: number; includeProcessedEventEntries?: boolean; + onEachInteraction?: (interaction: INPMetricWithAttribution) => void; } /** -- 2.50.1 (Apple Git-155)