mirror of
https://github.com/arthurfiorette/axios-cache-interceptor.git
synced 2025-12-08 17:36:16 +00:00
fix: support max-stale on header interpreter (#543)
This commit is contained in:
parent
82182bf7f8
commit
683dbe0f22
@ -8,7 +8,7 @@ export const defaultHeaderInterpreter: HeaderInterpreter = (headers) => {
|
||||
const cacheControl: unknown = headers[Header.CacheControl];
|
||||
|
||||
if (cacheControl) {
|
||||
const { noCache, noStore, maxAge, immutable, staleWhileRevalidate } = parse(
|
||||
const { noCache, noStore, maxAge, maxStale, immutable, staleWhileRevalidate } = parse(
|
||||
String(cacheControl)
|
||||
);
|
||||
|
||||
@ -19,7 +19,8 @@ export const defaultHeaderInterpreter: HeaderInterpreter = (headers) => {
|
||||
|
||||
if (immutable) {
|
||||
// 1 year is sufficient, as Infinity may cause problems with certain storages.
|
||||
// It might not be the best way, but a year is better than none.
|
||||
// It might not be the best way, but a year is better than none. Facebook shows
|
||||
// that a browser session stays at the most 1 month.
|
||||
return {
|
||||
cache: 1000 * 60 * 60 * 24 * 365
|
||||
};
|
||||
@ -33,8 +34,18 @@ export const defaultHeaderInterpreter: HeaderInterpreter = (headers) => {
|
||||
? // If age is present, we must subtract it from maxAge
|
||||
(maxAge - Number(age)) * 1000
|
||||
: maxAge * 1000,
|
||||
// Already out of date, for cache can be saved, but must be requested again
|
||||
stale: staleWhileRevalidate !== undefined ? staleWhileRevalidate * 1000 : 0
|
||||
// Already out of date, must be requested again
|
||||
stale:
|
||||
// I couldn't find any documentation about who should be used, as they
|
||||
// are not meant to overlap each other. But, as we cannot request in the
|
||||
// background, as the stale-while-revalidate says, and we just increase
|
||||
// its staleTtl when its present, max-stale is being preferred over
|
||||
// stale-while-revalidate.
|
||||
maxStale !== undefined
|
||||
? maxStale * 1000
|
||||
: staleWhileRevalidate !== undefined
|
||||
? staleWhileRevalidate * 1000
|
||||
: undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,6 +196,7 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
||||
}
|
||||
|
||||
// Hydrates any UI temporarily, if cache is available
|
||||
/* istanbul ignore if 'really hard to test' */
|
||||
if (cache.data) {
|
||||
await config.cache.hydrate?.(cache);
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ describe('test Cache-Control header', () => {
|
||||
});
|
||||
|
||||
// 10 Seconds in milliseconds
|
||||
expect(result).toEqual({ cache: 10 * 1000, stale: 0 });
|
||||
expect(result).toEqual({ cache: 10 * 1000, stale: undefined });
|
||||
});
|
||||
|
||||
it('tests with max-age of 0', () => {
|
||||
@ -36,7 +36,7 @@ describe('test Cache-Control header', () => {
|
||||
[Header.CacheControl]: 'max-age=0'
|
||||
});
|
||||
|
||||
expect(result).toEqual({ cache: 0, stale: 0 });
|
||||
expect(result).toEqual({ cache: 0, stale:undefined });
|
||||
});
|
||||
|
||||
it('tests stale values with age', () => {
|
||||
|
||||
@ -23,7 +23,7 @@ describe('tests header interpreter', () => {
|
||||
[Header.Age]: '3'
|
||||
});
|
||||
|
||||
expect(result).toEqual({ cache: 7 * 1000, stale: 0 });
|
||||
expect(result).toEqual({ cache: 7 * 1000, stale: undefined });
|
||||
});
|
||||
|
||||
it('tests with expires and cache-control present', () => {
|
||||
@ -34,7 +34,7 @@ describe('tests header interpreter', () => {
|
||||
|
||||
// expires should be ignored
|
||||
// 10 Seconds in milliseconds
|
||||
expect(result).toEqual({ cache: 10 * 1000, stale: 0 });
|
||||
expect(result).toEqual({ cache: 10 * 1000, stale: undefined });
|
||||
});
|
||||
|
||||
it('tests with immutable', () => {
|
||||
@ -75,4 +75,34 @@ describe('tests header interpreter', () => {
|
||||
|
||||
expect(result.cached).toBe(true);
|
||||
});
|
||||
|
||||
it('tests header interpreter stale with staleWhileRevalidate and maxStale', () => {
|
||||
// only staleWhileRevalidate
|
||||
expect(
|
||||
defaultHeaderInterpreter({
|
||||
[Header.CacheControl]: 'max-age=10, stale-while-revalidate=5'
|
||||
})
|
||||
).toEqual({ cache: 10 * 1000, stale: 5 * 1000 });
|
||||
|
||||
// only maxStale
|
||||
expect(
|
||||
defaultHeaderInterpreter({
|
||||
[Header.CacheControl]: 'max-age=10, max-stale=4'
|
||||
})
|
||||
).toEqual({ cache: 10 * 1000, stale: 4 * 1000 });
|
||||
|
||||
// both should use max-stale
|
||||
expect(
|
||||
defaultHeaderInterpreter({
|
||||
[Header.CacheControl]: 'max-age=10, stale-while-revalidate=5, max-stale=4'
|
||||
})
|
||||
).toEqual({ cache: 10 * 1000, stale: 4 * 1000 });
|
||||
|
||||
// none should return undefined
|
||||
expect(
|
||||
defaultHeaderInterpreter({
|
||||
[Header.CacheControl]: 'max-age=10'
|
||||
})
|
||||
).toEqual({ cache: 10 * 1000, stale: undefined });
|
||||
});
|
||||
});
|
||||
|
||||
@ -19,6 +19,7 @@ export function mockAxios(
|
||||
const should304: unknown =
|
||||
config.headers?.[Header.IfNoneMatch] || config.headers?.[Header.IfModifiedSince];
|
||||
const status = should304 ? 304 : 200;
|
||||
const statusText = should304 ? '304 Not Modified' : '200 OK';
|
||||
|
||||
if (config.validateStatus?.(status) === false) {
|
||||
throw {
|
||||
@ -28,7 +29,7 @@ export function mockAxios(
|
||||
response: {
|
||||
data: true,
|
||||
status,
|
||||
statusText: should304 ? '304 Not Modified' : '200 OK',
|
||||
statusText,
|
||||
headers: {
|
||||
...responseHeaders,
|
||||
// Random header for every request made
|
||||
@ -43,7 +44,7 @@ export function mockAxios(
|
||||
return {
|
||||
data: true,
|
||||
status,
|
||||
statusText: should304 ? '304 Not Modified' : '200 OK',
|
||||
statusText,
|
||||
headers: {
|
||||
...responseHeaders,
|
||||
// Random header for every request made
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user