11import { useCallback , useEffect , useRef } from 'react'
22
3+ // Session-scoped cache to prevent repeated IPNI checks per CID within a page session
4+ // Value indicates the last known result of the IPNI listing check
5+ const ipniSessionResultByCid : Map < string , 'success' | 'failed' > = new Map ( )
6+
7+ // LocalStorage helpers for success-only persistence across tabs/sessions
8+ const LS_SUCCESS_PREFIX = 'ipni-check-success-v1:'
9+
10+ function getLocalStorageSuccess ( cid : string ) : boolean {
11+ try {
12+ const key = `${ LS_SUCCESS_PREFIX } ${ cid } `
13+ return typeof window !== 'undefined' && window . localStorage . getItem ( key ) === '1'
14+ } catch {
15+ return false
16+ }
17+ }
18+
19+ function setLocalStorageSuccess ( cid : string ) : void {
20+ try {
21+ const key = `${ LS_SUCCESS_PREFIX } ${ cid } `
22+ if ( typeof window !== 'undefined' ) {
23+ window . localStorage . setItem ( key , '1' )
24+ }
25+ } catch {
26+ // ignore storage write errors (quota/disabled/private mode)
27+ }
28+ }
29+
330interface UseIpniCheckOptions {
431 cid : string | null
532 isActive : boolean
@@ -75,6 +102,8 @@ export const useIpniCheck = ({
75102
76103 if ( success ) {
77104 isCheckingRef . current = false
105+ ipniSessionResultByCid . set ( cid , 'success' )
106+ setLocalStorageSuccess ( cid )
78107 onSuccessRef . current ( )
79108 return
80109 }
@@ -83,6 +112,7 @@ export const useIpniCheck = ({
83112 if ( attemptRef . current >= maxAttempts ) {
84113 console . debug ( `[IpniCheck] Max attempts (${ maxAttempts } ) reached for CID ${ cid } ` )
85114 isCheckingRef . current = false
115+ ipniSessionResultByCid . set ( cid , 'failed' )
86116 onErrorRef . current ?.( new Error ( `IPNI check failed after ${ maxAttempts } attempts` ) )
87117 return
88118 }
@@ -101,6 +131,30 @@ export const useIpniCheck = ({
101131 // Start polling when isActive becomes true
102132 useEffect ( ( ) => {
103133 if ( isActive && cid ) {
134+ // If we've already checked this CID in the current page session, reuse the result and skip polling
135+ const prior = ipniSessionResultByCid . get ( cid )
136+ if ( prior === 'success' ) {
137+ console . debug ( '[IpniCheck] Session cache hit (success) for CID:' , cid )
138+ if ( ! getLocalStorageSuccess ( cid ) ) {
139+ setLocalStorageSuccess ( cid )
140+ }
141+ onSuccessRef . current ( )
142+ return
143+ }
144+ if ( prior === 'failed' ) {
145+ console . debug ( '[IpniCheck] Session cache hit (failed) for CID:' , cid )
146+ onErrorRef . current ?.( new Error ( 'IPNI check previously failed in this session' ) )
147+ return
148+ }
149+
150+ // Check cross-tab/session success cache in localStorage
151+ if ( getLocalStorageSuccess ( cid ) ) {
152+ console . debug ( '[IpniCheck] LocalStorage cache hit (success) for CID:' , cid )
153+ ipniSessionResultByCid . set ( cid , 'success' )
154+ onSuccessRef . current ( )
155+ return
156+ }
157+
104158 console . debug ( '[IpniCheck] Starting polling for CID:' , cid )
105159 pollWithBackoff ( )
106160 }
0 commit comments