()
| 284 | Date.now() - candidate.fetchedAt < staleMaxMs; |
| 285 | |
| 286 | const refresh = (): Promise<CacheEntry> => { |
| 287 | if (inflight) return inflight; |
| 288 | const startedAt = Date.now(); |
| 289 | fetchCount += 1; |
| 290 | inflight = (async () => { |
| 291 | const jwks = await fetchJwksOnce(url, fetchImpl(), timeoutMs); |
| 292 | const next = entryFrom({ jwks, fetchedAt: Date.now() }); |
| 293 | entry = next; |
| 294 | if (store) { |
| 295 | await ignoreFailure(store.put(url, { jwks: next.jwks, fetchedAt: next.fetchedAt })); |
| 296 | } |
| 297 | return next; |
| 298 | })() |
| 299 | .then( |
| 300 | (next) => next, |
| 301 | (error: unknown) => { |
| 302 | fetchFailureCount += 1; |
| 303 | // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: counting a fetch failure must preserve the original rejection for jose |
| 304 | throw error; |
| 305 | }, |
| 306 | ) |
| 307 | .finally(() => { |
| 308 | lastFetchDurationMs = Date.now() - startedAt; |
| 309 | inflight = null; |
| 310 | }); |
| 311 | return inflight; |
| 312 | }; |
| 313 | |
| 314 | /** Fire-and-forget revalidation behind a stale hit. */ |
| 315 | const refreshInBackground = (): void => { |
no test coverage detected