mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-10-13 00:13:40 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 617e3854f3 |
@@ -26,6 +26,7 @@ import {
|
|||||||
type CacheFunctionOptions,
|
type CacheFunctionOptions,
|
||||||
cache,
|
cache,
|
||||||
cacheResponse,
|
cacheResponse,
|
||||||
|
getResponseCacheTags,
|
||||||
noCacheFetchOptions,
|
noCacheFetchOptions,
|
||||||
parseCacheResponse,
|
parseCacheResponse,
|
||||||
} from './cache';
|
} from './cache';
|
||||||
@@ -370,6 +371,17 @@ interface GetRevisionOptions {
|
|||||||
* These options don't impact the cache key and it means revisions can be shared between different fetches with different metadata options.
|
* These options don't impact the cache key and it means revisions can be shared between different fetches with different metadata options.
|
||||||
*/
|
*/
|
||||||
metadata: boolean;
|
metadata: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to fetch the revision as a computed revision.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
computed?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional tags to add to the cache entry.
|
||||||
|
*/
|
||||||
|
tags?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAPIContextId = async () => {
|
const getAPIContextId = async () => {
|
||||||
@@ -382,8 +394,14 @@ const getAPIContextId = async () => {
|
|||||||
*/
|
*/
|
||||||
export const getRevision = cache({
|
export const getRevision = cache({
|
||||||
name: 'api.getRevision.v2',
|
name: 'api.getRevision.v2',
|
||||||
tag: (spaceId, revisionId) =>
|
tag: (spaceId, revisionId, fetchOptions) =>
|
||||||
getCacheTag({ tag: 'revision', space: spaceId, revision: revisionId }),
|
// Temporary hack to make it work with OpenAPI on v1
|
||||||
|
fetchOptions.tags?.[0] ??
|
||||||
|
getCacheTag({
|
||||||
|
tag: 'revision',
|
||||||
|
space: spaceId,
|
||||||
|
revision: revisionId,
|
||||||
|
}),
|
||||||
tagImmutable: true,
|
tagImmutable: true,
|
||||||
getKeySuffix: getAPIContextId,
|
getKeySuffix: getAPIContextId,
|
||||||
get: async (
|
get: async (
|
||||||
@@ -405,9 +423,20 @@ export const getRevision = cache({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return cacheResponse(response, fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day);
|
return cacheResponse(response, {
|
||||||
|
...(fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day),
|
||||||
|
data: {
|
||||||
|
...response.data,
|
||||||
|
tags: getResponseCacheTags(response),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getKeyArgs: ([spaceId, revisionId, fetchOptions]) => {
|
||||||
|
if (fetchOptions.computed === true) {
|
||||||
|
return [spaceId, revisionId, { computed: true }];
|
||||||
|
}
|
||||||
|
return [spaceId, revisionId];
|
||||||
},
|
},
|
||||||
getKeyArgs: (args) => [args[0], args[1]],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -415,8 +444,14 @@ export const getRevision = cache({
|
|||||||
*/
|
*/
|
||||||
export const getRevisionPages = cache({
|
export const getRevisionPages = cache({
|
||||||
name: 'api.getRevisionPages.v4',
|
name: 'api.getRevisionPages.v4',
|
||||||
tag: (spaceId, revisionId) =>
|
tag: (spaceId, revisionId, fetchOptions) =>
|
||||||
getCacheTag({ tag: 'revision', space: spaceId, revision: revisionId }),
|
// Temporary hack to make it work with OpenAPI on v1
|
||||||
|
fetchOptions.tags?.[0] ??
|
||||||
|
getCacheTag({
|
||||||
|
tag: 'revision',
|
||||||
|
space: spaceId,
|
||||||
|
revision: revisionId,
|
||||||
|
}),
|
||||||
tagImmutable: true,
|
tagImmutable: true,
|
||||||
getKeySuffix: getAPIContextId,
|
getKeySuffix: getAPIContextId,
|
||||||
get: async (
|
get: async (
|
||||||
@@ -440,10 +475,15 @@ export const getRevisionPages = cache({
|
|||||||
|
|
||||||
return cacheResponse(response, {
|
return cacheResponse(response, {
|
||||||
...(fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day),
|
...(fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day),
|
||||||
data: response.data.pages,
|
data: { ...response.data, tags: getResponseCacheTags(response) },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getKeyArgs: (args) => [args[0], args[1]],
|
getKeyArgs: ([spaceId, revisionId, fetchOptions]) => {
|
||||||
|
if (fetchOptions.computed === true) {
|
||||||
|
return [spaceId, revisionId, { computed: true }];
|
||||||
|
}
|
||||||
|
return [spaceId, revisionId];
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+10
-3
@@ -13,6 +13,14 @@ export const noCacheFetchOptions: Partial<RequestInit> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cache tags from the response.
|
||||||
|
*/
|
||||||
|
export function getResponseCacheTags(response: Response): string[] {
|
||||||
|
const cacheTagHeader = response.headers.get('x-gitbook-cache-tag');
|
||||||
|
return !cacheTagHeader ? [] : cacheTagHeader.split(',');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an HTTP response into a cache entry.
|
* Parse an HTTP response into a cache entry.
|
||||||
*/
|
*/
|
||||||
@@ -26,8 +34,7 @@ export function parseCacheResponse(response: Response): {
|
|||||||
const cacheControlHeader = response.headers.get('cache-control');
|
const cacheControlHeader = response.headers.get('cache-control');
|
||||||
const cacheControl = cacheControlHeader ? parseCacheControl(cacheControlHeader) : null;
|
const cacheControl = cacheControlHeader ? parseCacheControl(cacheControlHeader) : null;
|
||||||
|
|
||||||
const cacheTagHeader = response.headers.get('x-gitbook-cache-tag');
|
const tags = getResponseCacheTags(response);
|
||||||
const tags = !cacheTagHeader ? [] : cacheTagHeader.split(',');
|
|
||||||
|
|
||||||
const entry = {
|
const entry = {
|
||||||
ttl: 60 * 60 * 24,
|
ttl: 60 * 60 * 24,
|
||||||
@@ -47,7 +54,7 @@ export function parseCacheResponse(response: Response): {
|
|||||||
export function cacheResponse<Result, DefaultData = Result>(
|
export function cacheResponse<Result, DefaultData = Result>(
|
||||||
response: Response & { data: Result },
|
response: Response & { data: Result },
|
||||||
defaultEntry: Partial<CacheResult<DefaultData>> = {}
|
defaultEntry: Partial<CacheResult<DefaultData>> = {}
|
||||||
): CacheResult<DefaultData extends Result ? Result : DefaultData> {
|
): CacheResult<DefaultData extends undefined ? Result : DefaultData> {
|
||||||
const parsed = parseCacheResponse(response);
|
const parsed = parseCacheResponse(response);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import type { GitBookDataFetcher } from '@v2/lib/data/types';
|
|||||||
import { createImageResizer } from '@v2/lib/images';
|
import { createImageResizer } from '@v2/lib/images';
|
||||||
import { createLinker } from '@v2/lib/links';
|
import { createLinker } from '@v2/lib/links';
|
||||||
|
|
||||||
|
import { RevisionPageType } from '@gitbook/api';
|
||||||
import { DataFetcherError, wrapDataFetcherError } from '@v2/lib/data';
|
import { DataFetcherError, wrapDataFetcherError } from '@v2/lib/data';
|
||||||
import { headers } from 'next/headers';
|
import { headers } from 'next/headers';
|
||||||
import {
|
import {
|
||||||
@@ -134,9 +135,29 @@ async function getDataFetcherV1(): Promise<GitBookDataFetcher> {
|
|||||||
|
|
||||||
getRevision(params) {
|
getRevision(params) {
|
||||||
return wrapDataFetcherError(async () => {
|
return wrapDataFetcherError(async () => {
|
||||||
return getRevision(params.spaceId, params.revisionId, {
|
const { tags, ...revision } = await getRevision(params.spaceId, params.revisionId, {
|
||||||
metadata: params.metadata,
|
metadata: params.metadata,
|
||||||
|
computed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
Object.values(revision.pages).some(
|
||||||
|
(page) => page.type === RevisionPageType.Computed
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const { tags: _tags, ...revision } = await getRevision(
|
||||||
|
params.spaceId,
|
||||||
|
params.revisionId,
|
||||||
|
{
|
||||||
|
metadata: params.metadata,
|
||||||
|
computed: true,
|
||||||
|
tags,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
return revision;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -183,9 +204,22 @@ async function getDataFetcherV1(): Promise<GitBookDataFetcher> {
|
|||||||
|
|
||||||
getRevisionPages(params) {
|
getRevisionPages(params) {
|
||||||
return wrapDataFetcherError(async () => {
|
return wrapDataFetcherError(async () => {
|
||||||
return getRevisionPages(params.spaceId, params.revisionId, {
|
const { pages, tags } = await getRevisionPages(params.spaceId, params.revisionId, {
|
||||||
metadata: params.metadata,
|
metadata: params.metadata,
|
||||||
|
computed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (pages.some((page) => page.type === RevisionPageType.Computed)) {
|
||||||
|
const { pages } = await getRevisionPages(params.spaceId, params.revisionId, {
|
||||||
|
metadata: params.metadata,
|
||||||
|
computed: true,
|
||||||
|
tags,
|
||||||
|
});
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user