Skip to content

Commit a30e71c

Browse files
committed
Fix computed revision cache in v1
1 parent a3e1125 commit a30e71c

File tree

4 files changed

+89
-17
lines changed

4 files changed

+89
-17
lines changed

packages/cache-tags/src/index.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export function getCacheTag(
4343
tag: 'revision';
4444
space: string;
4545
revision: string;
46+
tags?: string[];
4647
}
4748
/**
4849
* Immutable data related to a document
@@ -102,8 +103,13 @@ export function getCacheTag(
102103
return `space:${spec.space}`;
103104
case 'change-request':
104105
return `space:${spec.space}:change-request:${spec.changeRequest}`;
105-
case 'revision':
106-
return `space:${spec.space}:revision:${spec.revision}`;
106+
case 'revision': {
107+
const key = `space:${spec.space}:revision:${spec.revision}`;
108+
if (spec.tags) {
109+
return `${key}:${spec.tags.join(':')}`;
110+
}
111+
return key;
112+
}
107113
case 'document':
108114
return `space:${spec.space}:document:${spec.document}`;
109115
case 'computed-document':

packages/gitbook/src/lib/api.ts

+39-10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
type CacheFunctionOptions,
2727
cache,
2828
cacheResponse,
29+
getResponseCacheTags,
2930
noCacheFetchOptions,
3031
parseCacheResponse,
3132
} from './cache';
@@ -370,6 +371,18 @@ interface GetRevisionOptions {
370371
* These options don't impact the cache key and it means revisions can be shared between different fetches with different metadata options.
371372
*/
372373
metadata: boolean;
374+
375+
/**
376+
* Whether to fetch the revision as a computed revision.
377+
* @default true
378+
*/
379+
computed?: boolean;
380+
381+
/**
382+
* Additional tags to add to the cache entry.
383+
* It's only used for v1, once in v2 we can get rid of it.
384+
*/
385+
tags?: string[];
373386
}
374387

375388
const getAPIContextId = async () => {
@@ -381,9 +394,14 @@ const getAPIContextId = async () => {
381394
* Get a revision by its ID.
382395
*/
383396
export const getRevision = cache({
384-
name: 'api.getRevision.v2',
385-
tag: (spaceId, revisionId) =>
386-
getCacheTag({ tag: 'revision', space: spaceId, revision: revisionId }),
397+
name: 'api.getRevision.v3',
398+
tag: (spaceId, revisionId, fetchOptions) =>
399+
getCacheTag({
400+
tag: 'revision',
401+
space: spaceId,
402+
revision: revisionId,
403+
tags: fetchOptions.tags,
404+
}),
387405
tagImmutable: true,
388406
getKeySuffix: getAPIContextId,
389407
get: async (
@@ -405,7 +423,13 @@ export const getRevision = cache({
405423
}
406424
);
407425

408-
return cacheResponse(response, fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day);
426+
return cacheResponse(response, {
427+
...(fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day),
428+
data: {
429+
revision: response.data,
430+
tags: getResponseCacheTags(response),
431+
},
432+
});
409433
},
410434
getKeyArgs: (args) => [args[0], args[1]],
411435
});
@@ -414,9 +438,14 @@ export const getRevision = cache({
414438
* Get all the pages in a revision of a space.
415439
*/
416440
export const getRevisionPages = cache({
417-
name: 'api.getRevisionPages.v4',
418-
tag: (spaceId, revisionId) =>
419-
getCacheTag({ tag: 'revision', space: spaceId, revision: revisionId }),
441+
name: 'api.getRevisionPages.v5',
442+
tag: (spaceId, revisionId, fetchOptions) =>
443+
getCacheTag({
444+
tag: 'revision',
445+
space: spaceId,
446+
revision: revisionId,
447+
tags: fetchOptions.tags,
448+
}),
420449
tagImmutable: true,
421450
getKeySuffix: getAPIContextId,
422451
get: async (
@@ -440,7 +469,7 @@ export const getRevisionPages = cache({
440469

441470
return cacheResponse(response, {
442471
...(fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day),
443-
data: response.data.pages,
472+
data: { pages: response.data.pages, tags: getResponseCacheTags(response) },
444473
});
445474
},
446475
getKeyArgs: (args) => [args[0], args[1]],
@@ -632,7 +661,7 @@ export const getRevisionFile = batch<[string, string, string], RevisionFile | nu
632661
let files: Record<string, RevisionFile> = {};
633662

634663
if (hasRevisionInMemory) {
635-
const revision = await getRevision(spaceId, revisionId, { metadata: false });
664+
const { revision } = await getRevision(spaceId, revisionId, { metadata: false });
636665
files = {};
637666
revision.files.forEach((file) => {
638667
files[file.id] = file;
@@ -678,7 +707,7 @@ export const getReusableContent = async (
678707
});
679708

680709
if (hasRevisionInMemory) {
681-
const revision = await getRevision(spaceId, revisionId, { metadata: false });
710+
const { revision } = await getRevision(spaceId, revisionId, { metadata: false });
682711
return (
683712
revision.reusableContents.find(
684713
(reusableContent) => reusableContent.id === reusableContentId

packages/gitbook/src/lib/cache/http.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ export const noCacheFetchOptions: Partial<RequestInit> = {
1313
},
1414
};
1515

16+
/**
17+
* Return the cache tags from the response.
18+
*/
19+
export function getResponseCacheTags(response: Response): string[] {
20+
const cacheTagHeader = response.headers.get('x-gitbook-cache-tag');
21+
return !cacheTagHeader ? [] : cacheTagHeader.split(',');
22+
}
23+
1624
/**
1725
* Parse an HTTP response into a cache entry.
1826
*/
@@ -26,8 +34,7 @@ export function parseCacheResponse(response: Response): {
2634
const cacheControlHeader = response.headers.get('cache-control');
2735
const cacheControl = cacheControlHeader ? parseCacheControl(cacheControlHeader) : null;
2836

29-
const cacheTagHeader = response.headers.get('x-gitbook-cache-tag');
30-
const tags = !cacheTagHeader ? [] : cacheTagHeader.split(',');
37+
const tags = getResponseCacheTags(response);
3138

3239
const entry = {
3340
ttl: 60 * 60 * 24,
@@ -47,7 +54,7 @@ export function parseCacheResponse(response: Response): {
4754
export function cacheResponse<Result, DefaultData = Result>(
4855
response: Response & { data: Result },
4956
defaultEntry: Partial<CacheResult<DefaultData>> = {}
50-
): CacheResult<DefaultData extends Result ? Result : DefaultData> {
57+
): CacheResult<DefaultData extends undefined ? Result : DefaultData> {
5158
const parsed = parseCacheResponse(response);
5259

5360
return {

packages/gitbook/src/lib/v1.ts

+32-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { GitBookDataFetcher } from '@v2/lib/data/types';
88
import { createImageResizer } from '@v2/lib/images';
99
import { createLinker } from '@v2/lib/links';
1010

11+
import { RevisionPageType } from '@gitbook/api';
1112
import { DataFetcherError, wrapDataFetcherError } from '@v2/lib/data';
1213
import { headers } from 'next/headers';
1314
import {
@@ -134,9 +135,25 @@ async function getDataFetcherV1(): Promise<GitBookDataFetcher> {
134135

135136
getRevision(params) {
136137
return wrapDataFetcherError(async () => {
137-
return getRevision(params.spaceId, params.revisionId, {
138+
const { revision, tags } = await getRevision(params.spaceId, params.revisionId, {
138139
metadata: params.metadata,
140+
computed: false,
139141
});
142+
143+
if (
144+
Object.values(revision.pages).some(
145+
(page) => page.type === RevisionPageType.Computed
146+
)
147+
) {
148+
const { revision } = await getRevision(params.spaceId, params.revisionId, {
149+
metadata: params.metadata,
150+
computed: true,
151+
tags,
152+
});
153+
return revision;
154+
}
155+
156+
return revision;
140157
});
141158
},
142159

@@ -183,9 +200,22 @@ async function getDataFetcherV1(): Promise<GitBookDataFetcher> {
183200

184201
getRevisionPages(params) {
185202
return wrapDataFetcherError(async () => {
186-
return getRevisionPages(params.spaceId, params.revisionId, {
203+
const { pages, tags } = await getRevisionPages(params.spaceId, params.revisionId, {
187204
metadata: params.metadata,
205+
computed: false,
188206
});
207+
208+
if (pages.some((page) => page.type === RevisionPageType.Computed)) {
209+
const { pages } = await getRevisionPages(params.spaceId, params.revisionId, {
210+
metadata: params.metadata,
211+
computed: true,
212+
tags,
213+
});
214+
215+
return pages;
216+
}
217+
218+
return pages;
189219
});
190220
},
191221

0 commit comments

Comments
 (0)