Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 821bd12

Browse files
maxisameneajaho
authored andcommitted
feat(isr): add custom cache key generation logic
1 parent 8609cc9 commit 821bd12

File tree

6 files changed

+43
-14
lines changed

6 files changed

+43
-14
lines changed

libs/isr/models/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export {
77
VariantRebuildItem,
88
} from './cache-handler';
99
export {
10+
CacheKeyGeneratorFn,
1011
InvalidateConfig,
1112
ISRHandlerConfig,
1213
ModifyHtmlCallbackFn,

libs/isr/models/src/isr-handler-config.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ export interface ISRHandlerConfig {
124124
* If set to true, the server will provide the cached HTML as soon as possible and will revalidate the cache in the background.
125125
*/
126126
backgroundRevalidation?: boolean;
127+
128+
/**
129+
* This callback lets you use custom cache key generation logic. If not provided, it will use the default cache key generation logic.
130+
*/
131+
cacheKeyGenerator?: CacheKeyGeneratorFn;
127132
}
128133

129134
export interface ServeFromCacheConfig {
@@ -144,6 +149,12 @@ export interface InvalidateConfig {
144149
providers?: Provider[];
145150
}
146151

152+
export type CacheKeyGeneratorFn = (
153+
url: string,
154+
allowedQueryParams: string[] | null | undefined,
155+
variant: RenderVariant | null,
156+
) => string;
157+
147158
export type ModifyHtmlCallbackFn = (
148159
req: Request,
149160
html: string,

libs/isr/server/src/cache-generation.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { Provider } from '@angular/core';
2-
import { CacheHandler, ISRHandlerConfig } from '@rx-angular/isr/models';
2+
import {
3+
CacheHandler,
4+
CacheKeyGeneratorFn,
5+
ISRHandlerConfig,
6+
RenderVariant,
7+
} from '@rx-angular/isr/models';
38
import { Request, Response } from 'express';
49
import { ISRLogger } from './isr-logger';
510
import { defaultModifyGeneratedHtml } from './modify-generated-html';
6-
import { getCacheKey, getVariant } from './utils/cache-utils';
11+
import { defaultCacheKeyGenerator, getVariant } from './utils/cache-utils';
712
import { getRouteISRDataFromHTML } from './utils/get-isr-options';
813
import { renderUrl, RenderUrlConfig } from './utils/render-url';
914

@@ -21,7 +26,19 @@ export class CacheGeneration {
2126
public isrConfig: ISRHandlerConfig,
2227
public cache: CacheHandler,
2328
public logger: ISRLogger,
24-
) {}
29+
) {
30+
if (!this.isrConfig.cacheKeyGenerator) {
31+
this.isrConfig.cacheKeyGenerator = defaultCacheKeyGenerator;
32+
}
33+
}
34+
getCacheKey: CacheKeyGeneratorFn = (
35+
url: string,
36+
allowedQueryParams: string[] | null | undefined,
37+
variant: RenderVariant | null,
38+
) => {
39+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
40+
return this.isrConfig.cacheKeyGenerator!(url, allowedQueryParams, variant);
41+
};
2542

2643
async generate(
2744
req: Request,
@@ -31,7 +48,7 @@ export class CacheGeneration {
3148
): Promise<IGeneratedResult | void> {
3249
const { url } = req;
3350
const variant = getVariant(req, this.isrConfig.variants);
34-
const cacheKey = getCacheKey(
51+
const cacheKey = this.getCacheKey(
3552
url,
3653
this.isrConfig.allowedQueryParams,
3754
variant,

libs/isr/server/src/isr-handler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { NextFunction, Request, Response } from 'express';
1111
import { CacheGeneration } from './cache-generation';
1212
import { InMemoryCacheHandler } from './cache-handlers/in-memory-cache-handler';
1313
import { ISRLogger } from './isr-logger';
14-
import { getCacheKey, getVariant } from './utils/cache-utils';
14+
import { getVariant } from './utils/cache-utils';
1515

1616
export class ISRHandler {
1717
protected cache!: CacheHandler;
@@ -148,7 +148,7 @@ export class ISRHandler {
148148
for (const variant of variants) {
149149
result.push({
150150
url,
151-
cacheKey: getCacheKey(
151+
cacheKey: this.cacheGeneration.getCacheKey(
152152
url,
153153
this.isrConfig.allowedQueryParams,
154154
variant,
@@ -171,7 +171,7 @@ export class ISRHandler {
171171
): Promise<Response | void> {
172172
try {
173173
const variant = getVariant(req, this.isrConfig.variants);
174-
const cacheKey = getCacheKey(
174+
const cacheKey = this.cacheGeneration.getCacheKey(
175175
req.url,
176176
this.isrConfig.allowedQueryParams,
177177
variant,
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
import { RenderVariant } from '../../../models/src';
2-
import { getCacheKey } from './cache-utils';
2+
import { defaultCacheKeyGenerator } from './cache-utils';
33

44
describe('getCacheKey', () => {
55
it('should return the URL without query parameters when none are allowed', () => {
66
const url = '/page?param1=value1&param2=value2';
7-
const result = getCacheKey(url, [], null);
7+
const result = defaultCacheKeyGenerator(url, [], null);
88
expect(result).toBe('/page');
99
});
1010

1111
it('should return the URL with query parameters when it is null or undefined', () => {
1212
const url = '/page?param1=value1&param2=value2';
13-
const result = getCacheKey(url, null, null);
13+
const result = defaultCacheKeyGenerator(url, null, null);
1414
expect(result).toBe('/page?param1=value1&param2=value2');
1515
});
1616

1717
it('should include only allowed query parameters in the result', () => {
1818
const url = '/page?allowed=value&disallowed=value';
19-
const result = getCacheKey(url, ['allowed'], null);
19+
const result = defaultCacheKeyGenerator(url, ['allowed'], null);
2020
expect(result).toBe('/page?allowed=value');
2121
});
2222

2323
it('should exclude disallowed query parameters', () => {
2424
const url = '/page?allowed=value&disallowed=value';
25-
const result = getCacheKey(url, ['allowed'], null);
25+
const result = defaultCacheKeyGenerator(url, ['allowed'], null);
2626
expect(result).not.toContain('disallowed=value');
2727
});
2828

@@ -32,7 +32,7 @@ describe('getCacheKey', () => {
3232
identifier: 'variant123',
3333
detectVariant: () => true,
3434
};
35-
const result = getCacheKey(url, ['param'], variant);
35+
const result = defaultCacheKeyGenerator(url, ['param'], variant);
3636
expect(result).toBe('/page?param=value<variantId:variant123>');
3737
});
3838
});

libs/isr/server/src/utils/cache-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { RenderVariant } from '@rx-angular/isr/models';
22
import { Request } from 'express';
33

4-
export const getCacheKey = (
4+
export const defaultCacheKeyGenerator = (
55
url: string,
66
allowedQueryParams: string[] | null | undefined,
77
variant: RenderVariant | null,

0 commit comments

Comments
 (0)