flowchart TB Start([Request Interceptor Entry]) --> GenKey[Generate cache key via generateKey] GenKey --> CheckDisabled{config.cache === false?} CheckDisabled -->|Yes| Debug1[Debug: 'Ignoring cache because config.cache === false'] Debug1 --> ReturnConfig[Return config unchanged] CheckDisabled -->|No| MergeConfig[Merge defaults with per-request config] MergeConfig --> CheckIgnoreUrls{ignoreUrls
configured?} CheckIgnoreUrls -->|Yes| TestIgnore{URL matches
ignoreUrls?} TestIgnore -->|Yes| Debug2[Debug: 'Ignored because url matches ignoreUrls'] Debug2 --> ReturnConfig TestIgnore -->|No| CheckAllowUrls CheckIgnoreUrls -->|No| CheckAllowUrls{allowUrls
configured?} CheckAllowUrls -->|Yes| TestAllow{URL matches
allowUrls?} TestAllow -->|Yes| Debug3[Debug: 'Cached because url matches allowUrls'] Debug3 --> ApplyCacheTakeover TestAllow -->|No| Debug4[Debug: 'Ignored because url does not match any allowUrls'] Debug4 --> ReturnConfig CheckAllowUrls -->|No| ApplyCacheTakeover{cacheTakeover
enabled?} ApplyCacheTakeover -->|Yes| SetHeaders[Set headers:
Cache-Control: no-cache, no-store
Pragma: no-cache
Expires: 0] ApplyCacheTakeover -->|No| CheckMethod SetHeaders --> CheckMethod CheckMethod{Method in
cache.methods?} CheckMethod -->|No| Debug5[Debug: 'Ignored because method not in cache.methods'] Debug5 --> ReturnConfig CheckMethod -->|Yes| GetCache[Get cache from storage] GetCache --> CheckCacheState{Cache state?} CheckCacheState -->|cached & fresh| IsCached[Cache is fresh] CheckCacheState -->|empty| IsEmpty CheckCacheState -->|stale| IsStale CheckCacheState -->|must-revalidate| IsMustRevalidate CheckCacheState -->|loading| IsLoading IsEmpty[State: empty] --> CheckOverride1{override === true?} IsStale[State: stale] --> CheckOverride1 IsMustRevalidate[State: must-revalidate] --> CheckOverride1 CheckOverride1 -->|No| CheckWaiting{Request ID in
waiting map?} CheckOverride1 -->|Yes| CreateDeferred CheckWaiting -->|No| CreateDeferred[Create new deferred promise] CheckWaiting -->|Yes| GetCacheAgain[Get cache from storage again] GetCacheAgain --> DoubleCheckState{Still empty/
must-revalidate?} DoubleCheckState -->|No| Debug6[Debug: 'Waiting list had a deferred, waiting for it'] Debug6 --> WaitForDeferred[Wait for deferred & use cached response] WaitForDeferred --> PrepareReturn DoubleCheckState -->|Yes| CreateDeferred CreateDeferred --> AddToWaiting[Add deferred to waiting map] AddToWaiting --> SetLoading[Set storage state to 'loading'] SetLoading --> CheckStale{Previous state
was stale/must-revalidate
AND not override?} CheckStale -->|Yes| UpdateStaleRequest[Add conditional headers:
If-None-Match etag
If-Modified-Since timestamp] CheckStale -->|No| SetValidateStatus UpdateStaleRequest --> Debug7[Debug: 'Updated stale request'] Debug7 --> SetValidateStatus SetValidateStatus[Update validateStatus to accept 304] --> CheckHydrate{Has stale data
& hydrate function?} CheckHydrate -->|Yes| Hydrate[Call hydrate function with stale data] CheckHydrate -->|No| Debug8 Hydrate --> Debug8 Debug8[Debug: 'Sending request, waiting for response'] --> ReturnConfig IsLoading[State: loading] --> GetDeferred{Deferred exists
in waiting map?} GetDeferred -->|No| CheckLoadingHydrate{Has stale data
& hydrate function?} CheckLoadingHydrate -->|Yes| HydrateLoading[Call hydrate function] CheckLoadingHydrate -->|No| ReturnConfig HydrateLoading --> ReturnConfig GetDeferred -->|Yes| Debug9[Debug: 'Detected concurrent request, waiting'] Debug9 --> WaitDeferred[Wait for deferred promise] WaitDeferred --> DeferredResult{Promise resolved?} DeferredResult -->|Rejected| Debug10[Debug: 'Deferred rejected, requesting again'] Debug10 --> CheckLoadingHydrate2{Has stale data
& hydrate function?} CheckLoadingHydrate2 -->|Yes| HydrateRejected[Call hydrate function] CheckLoadingHydrate2 -->|No| RetryRequest HydrateRejected --> RetryRequest[Retry: Call onFulfilled again] RetryRequest --> Start DeferredResult -->|Resolved| GetStorageAgain[Get cache from storage again] GetStorageAgain --> CheckData{Data exists?} CheckData -->|No| Debug11[Debug: 'Deferred resolved but no data, requesting again'] Debug11 --> RetryRequest CheckData -->|Yes| PrepareReturn IsCached --> PrepareReturn[Prepare cached response] PrepareReturn --> ClearTransform[Clear transformResponse
to avoid double transformation] ClearTransform --> SetCachedAdapter[Set custom cachedAdapter that
returns cached data immediately] SetCachedAdapter --> Debug12[Debug: 'Returning cached response'] Debug12 --> ReturnConfig ReturnConfig --> End([Config returned,
proceeds to adapter]) style Start fill:#e1f5e1 style End fill:#e1f5e1 style ReturnConfig fill:#e1f0ff style Debug1 fill:#fff4e1 style Debug2 fill:#fff4e1 style Debug3 fill:#fff4e1 style Debug4 fill:#fff4e1 style Debug5 fill:#fff4e1 style Debug6 fill:#fff4e1 style Debug7 fill:#fff4e1 style Debug8 fill:#fff4e1 style Debug9 fill:#fff4e1 style Debug10 fill:#fff4e1 style Debug11 fill:#fff4e1 style Debug12 fill:#fff4e1 style IsEmpty fill:#ffe1e1 style IsStale fill:#ffe8d1 style IsMustRevalidate fill:#ffe8d1 style IsLoading fill:#fff4e1 style IsCached fill:#d1ffe1