Skip to content

Commit 5e3b2e7

Browse files
authored
fix: ipni-check only runs when needed (#83)
* fix: use ipniCheck cid cache to prevent spamming * fix: ipni-check stores success in localstorage
1 parent 5993617 commit 5e3b2e7

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

src/hooks/use-ipni-check.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
import { 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+
330
interface 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

Comments
 (0)