feat(ajax): add an option to initialize the cache interceptors even when useCache is turned off in the global options
This commit is contained in:
parent
a28686ee72
commit
56af96f1da
6 changed files with 64 additions and 18 deletions
5
.changeset/silent-ravens-smell.md
Normal file
5
.changeset/silent-ravens-smell.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/ajax': minor
|
||||
---
|
||||
|
||||
Add an option "addCaching" to the Ajax config, in order to add cache interceptors when useCache is turned off. In this situation, all requests are cached proactively.
|
||||
|
|
@ -23,11 +23,12 @@ export class Ajax {
|
|||
*/
|
||||
constructor(config = {}) {
|
||||
/**
|
||||
* @type {Partial<AjaxConfig>}
|
||||
* @type {AjaxConfig}
|
||||
* @private
|
||||
*/
|
||||
this.__config = {
|
||||
addAcceptLanguage: true,
|
||||
addCaching: false,
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
xsrfHeaderName: 'X-XSRF-TOKEN',
|
||||
jsonPrefix: '',
|
||||
|
|
@ -53,7 +54,7 @@ export class Ajax {
|
|||
}
|
||||
|
||||
const { cacheOptions } = this.__config;
|
||||
if (cacheOptions?.useCache) {
|
||||
if (cacheOptions.useCache || this.__config.addCaching) {
|
||||
const { cacheRequestInterceptor, cacheResponseInterceptor } = createCacheInterceptors(
|
||||
cacheOptions.getCacheIdentifier,
|
||||
cacheOptions,
|
||||
|
|
@ -65,7 +66,7 @@ export class Ajax {
|
|||
|
||||
/**
|
||||
* Configures the Ajax instance
|
||||
* @param {Partial<AjaxConfig>} config configuration for the Ajax instance
|
||||
* @param {AjaxConfig} config configuration for the Ajax instance
|
||||
*/
|
||||
set options(config) {
|
||||
this.__config = config;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,15 @@ import {
|
|||
isCurrentSessionId,
|
||||
} from '../cacheManager.js';
|
||||
|
||||
/**
|
||||
* Tests whether the request method is supported according to the `cacheOptions`
|
||||
* @param {ValidatedCacheOptions} cacheOptions
|
||||
* @param {string} method
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isMethodSupported = (cacheOptions, method) =>
|
||||
cacheOptions.methods.includes(method.toLowerCase());
|
||||
|
||||
/**
|
||||
* Request interceptor to return relevant cached requests
|
||||
* @param {function(): string} getCacheId used to invalidate cache if identifier is changed
|
||||
|
|
@ -36,9 +45,8 @@ const createCacheRequestInterceptor =
|
|||
}
|
||||
|
||||
const requestId = cacheOptions.requestIdFunction(request);
|
||||
const isMethodSupported = cacheOptions.methods.includes(request.method.toLowerCase());
|
||||
|
||||
if (!isMethodSupported) {
|
||||
if (!isMethodSupported(cacheOptions, request.method)) {
|
||||
invalidateMatchingCache(requestId, cacheOptions);
|
||||
return request;
|
||||
}
|
||||
|
|
@ -81,12 +89,9 @@ const createCacheResponseInterceptor =
|
|||
...response.request.cacheOptions,
|
||||
});
|
||||
|
||||
const requestId = cacheOptions.requestIdFunction(response.request);
|
||||
const isAlreadyFromCache = !!response.fromCache;
|
||||
const isCacheActive = cacheOptions.useCache;
|
||||
const isMethodSupported = cacheOptions.methods.includes(response.request?.method.toLowerCase());
|
||||
if (!response.fromCache && isMethodSupported(cacheOptions, response.request.method)) {
|
||||
const requestId = cacheOptions.requestIdFunction(response.request);
|
||||
|
||||
if (!isAlreadyFromCache && isCacheActive && isMethodSupported) {
|
||||
if (isCurrentSessionId(response.request.cacheSessionId)) {
|
||||
// Cache the response
|
||||
ajaxCache.set(requestId, response.clone());
|
||||
|
|
@ -95,6 +100,7 @@ const createCacheResponseInterceptor =
|
|||
// Mark the pending request as resolved
|
||||
pendingRequestStore.resolve(requestId);
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ describe('Ajax', () => {
|
|||
};
|
||||
const expected = {
|
||||
addAcceptLanguage: true,
|
||||
addCaching: false,
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
xsrfHeaderName: 'X-XSRF-TOKEN',
|
||||
jsonPrefix: ")]}',",
|
||||
|
|
@ -303,6 +304,44 @@ describe('Ajax', () => {
|
|||
getCacheIdentifier = () => String(cacheId);
|
||||
});
|
||||
|
||||
it('does not add cache interceptors when useCache is turned off', () => {
|
||||
const customAjax = new Ajax({
|
||||
cacheOptions: {
|
||||
maxAge: 100,
|
||||
getCacheIdentifier,
|
||||
},
|
||||
});
|
||||
|
||||
expect(customAjax._requestInterceptors.length).to.equal(2);
|
||||
expect(customAjax._responseInterceptors.length).to.equal(0);
|
||||
});
|
||||
|
||||
it('adds cache interceptors when useCache is turned on', () => {
|
||||
const customAjax = new Ajax({
|
||||
cacheOptions: {
|
||||
useCache: true,
|
||||
maxAge: 100,
|
||||
getCacheIdentifier,
|
||||
},
|
||||
});
|
||||
|
||||
expect(customAjax._requestInterceptors.length).to.equal(3);
|
||||
expect(customAjax._responseInterceptors.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('adds cache interceptors when addCaching is turned on', () => {
|
||||
const customAjax = new Ajax({
|
||||
addCaching: true,
|
||||
cacheOptions: {
|
||||
maxAge: 100,
|
||||
getCacheIdentifier,
|
||||
},
|
||||
});
|
||||
|
||||
expect(customAjax._requestInterceptors.length).to.equal(3);
|
||||
expect(customAjax._responseInterceptors.length).to.equal(1);
|
||||
});
|
||||
|
||||
describe('caching interceptors', async () => {
|
||||
/**
|
||||
* @type {Ajax}
|
||||
|
|
|
|||
|
|
@ -150,14 +150,12 @@ describe('cache interceptors', () => {
|
|||
expect(fetchStub.callCount).to.equal(1);
|
||||
});
|
||||
|
||||
// TODO: Check if this is the behaviour we want
|
||||
it('all calls with non-default `maxAge` are cached proactively', async () => {
|
||||
it('all calls are cached proactively', async () => {
|
||||
// Given
|
||||
newCacheId();
|
||||
|
||||
addCacheInterceptors(ajax, {
|
||||
useCache: false,
|
||||
maxAge: 100,
|
||||
});
|
||||
|
||||
// When
|
||||
|
|
@ -169,11 +167,7 @@ describe('cache interceptors', () => {
|
|||
expect(fetchStub.callCount).to.equal(1);
|
||||
|
||||
// When
|
||||
await ajax.fetch('/test', {
|
||||
cacheOptions: {
|
||||
useCache: true,
|
||||
},
|
||||
});
|
||||
await ajax.fetch('/test');
|
||||
|
||||
// Then
|
||||
expect(fetchStub.callCount).to.equal(2);
|
||||
|
|
|
|||
1
packages/ajax/types/types.d.ts
vendored
1
packages/ajax/types/types.d.ts
vendored
|
|
@ -12,6 +12,7 @@ export interface LionRequestInit extends Omit<RequestInit, 'body'> {
|
|||
|
||||
export interface AjaxConfig {
|
||||
addAcceptLanguage: boolean;
|
||||
addCaching: boolean;
|
||||
xsrfCookieName: string | null;
|
||||
xsrfHeaderName: string | null;
|
||||
cacheOptions: CacheOptionsWithIdentifier;
|
||||
|
|
|
|||
Loading…
Reference in a new issue