diff --git a/packages/gitbook-v2/src/lib/data/api.ts b/packages/gitbook-v2/src/lib/data/api.ts index 88c95c4016..02c550646b 100644 --- a/packages/gitbook-v2/src/lib/data/api.ts +++ b/packages/gitbook-v2/src/lib/data/api.ts @@ -51,7 +51,7 @@ export function createDataFetcher( // getPublishedContentSite(params) { return trace('getPublishedContentSite', () => - getPublishedContentSite(input, { + getPublishedContentSite(this)(input, { organizationId: params.organizationId, siteId: params.siteId, siteShareKey: params.siteShareKey, @@ -60,7 +60,7 @@ export function createDataFetcher( }, getSiteRedirectBySource(params) { return trace('getSiteRedirectBySource', () => - getSiteRedirectBySource(input, { + getSiteRedirectBySource(this)(input, { organizationId: params.organizationId, siteId: params.siteId, siteShareKey: params.siteShareKey, @@ -70,7 +70,7 @@ export function createDataFetcher( }, getRevision(params) { return trace('getRevision', () => - getRevision(input, { + getRevision(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, metadata: params.metadata, @@ -79,7 +79,7 @@ export function createDataFetcher( }, getRevisionPages(params) { return trace('getRevisionPages', () => - getRevisionPages(input, { + getRevisionPages(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, metadata: params.metadata, @@ -88,7 +88,7 @@ export function createDataFetcher( }, getRevisionFile(params) { return trace('getRevisionFile', () => - getRevisionFile(input, { + getRevisionFile(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, fileId: params.fileId, @@ -97,7 +97,7 @@ export function createDataFetcher( }, getRevisionPageByPath(params) { return trace('getRevisionPageByPath', () => - getRevisionPageByPath(input, { + getRevisionPageByPath(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, path: params.path, @@ -106,7 +106,7 @@ export function createDataFetcher( }, getRevisionPageMarkdown(params) { return trace('getRevisionPageMarkdown', () => - getRevisionPageMarkdown(input, { + getRevisionPageMarkdown(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, pageId: params.pageId, @@ -115,7 +115,7 @@ export function createDataFetcher( }, getRevisionPageDocument(params) { return trace('getRevisionPageDocument', () => - getRevisionPageDocument(input, { + getRevisionPageDocument(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, pageId: params.pageId, @@ -124,7 +124,7 @@ export function createDataFetcher( }, getReusableContent(params) { return trace('getReusableContent', () => - getReusableContent(input, { + getReusableContent(this)(input, { spaceId: params.spaceId, revisionId: params.revisionId, reusableContentId: params.reusableContentId, @@ -133,7 +133,7 @@ export function createDataFetcher( }, getLatestOpenAPISpecVersionContent(params) { return trace('getLatestOpenAPISpecVersionContent', () => - getLatestOpenAPISpecVersionContent(input, { + getLatestOpenAPISpecVersionContent(this)(input, { organizationId: params.organizationId, slug: params.slug, }) @@ -141,7 +141,7 @@ export function createDataFetcher( }, getSpace(params) { return trace('getSpace', () => - getSpace(input, { + getSpace(this)(input, { spaceId: params.spaceId, shareKey: params.shareKey, }) @@ -149,7 +149,7 @@ export function createDataFetcher( }, getChangeRequest(params) { return trace('getChangeRequest', () => - getChangeRequest(input, { + getChangeRequest(this)(input, { spaceId: params.spaceId, changeRequestId: params.changeRequestId, }) @@ -157,7 +157,7 @@ export function createDataFetcher( }, getDocument(params) { return trace('getDocument', () => - getDocument(input, { + getDocument(this)(input, { spaceId: params.spaceId, documentId: params.documentId, }) @@ -165,7 +165,7 @@ export function createDataFetcher( }, getComputedDocument(params) { return trace('getComputedDocument', () => - getComputedDocument(input, { + getComputedDocument(this)(input, { organizationId: params.organizationId, spaceId: params.spaceId, source: params.source, @@ -175,19 +175,19 @@ export function createDataFetcher( }, getEmbedByUrl(params) { return trace('getEmbedByUrl', () => - getEmbedByUrl(input, { + getEmbedByUrl(this)(input, { url: params.url, spaceId: params.spaceId, }) ); }, searchSiteContent(params) { - return trace('searchSiteContent', () => searchSiteContent(input, params)); + return trace('searchSiteContent', () => searchSiteContent(this)(input, params)); }, renderIntegrationUi(params) { return trace('renderIntegrationUi', () => - renderIntegrationUi(input, { + renderIntegrationUi(this)(input, { integrationName: params.integrationName, request: params.request, }) @@ -195,7 +195,7 @@ export function createDataFetcher( }, getUserById(userId) { - return trace('getUserById', () => getUserById(input, { userId })); + return trace('getUserById', () => getUserById(this)(input, { userId })); }, streamAIResponse(params) { @@ -204,387 +204,332 @@ export function createDataFetcher( }; } -const getUserById = withCacheKey( - withoutConcurrentExecution(async (_, input: DataFetcherInput, params: { userId: string }) => { - 'use cache'; - return trace(`getUserById(${params.userId})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.users.getUserById(params.userId, { - ...noCacheFetchOptions, - }); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('days'); - return res.data; - }); - }); - }) -); - -const getSpace = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; shareKey: string | undefined } - ) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'space', - space: params.spaceId, - }) - ); - - return trace(`getSpace(${params.spaceId}, ${params.shareKey})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getSpaceById( - params.spaceId, - { - shareKey: params.shareKey, - }, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('days'); - return res.data; - }); - }); - } - ) -); - -const getChangeRequest = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; changeRequestId: string } - ) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'change-request', - space: params.spaceId, - changeRequest: params.changeRequestId, - }) - ); - - return trace( - `getChangeRequest(${params.spaceId}, ${params.changeRequestId})`, - async () => { +const getUserById = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async (_, input: DataFetcherInput, params: { userId: string }) => { + 'use cache'; + return trace(`getUserById(${params.userId})`, async () => { return wrapDataFetcherError(async () => { const api = apiClient(input); - const res = await api.spaces.getChangeRequestById( - params.spaceId, - params.changeRequestId, - { - ...noCacheFetchOptions, - } - ); + const res = await api.users.getUserById(params.userId, { + ...noCacheFetchOptions, + }); cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('minutes'); + cacheLife('days'); return res.data; }); - } - ); - } - ) -); - -const getRevision = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; metadata: boolean } - ) => { - 'use cache'; - return trace(`getRevision(${params.spaceId}, ${params.revisionId})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getRevisionById( - params.spaceId, - params.revisionId, - { - metadata: params.metadata, - }, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); - return res.data; - }); - }); - } - ) -); - -const getRevisionPages = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; metadata: boolean } - ) => { - 'use cache'; - return trace(`getRevisionPages(${params.spaceId}, ${params.revisionId})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.listPagesInRevisionById( - params.spaceId, - params.revisionId, - { - metadata: params.metadata, - }, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); - return res.data.pages; }); - }); - } - ) -); - -const getRevisionFile = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; fileId: string } - ) => { - 'use cache'; - return trace( - `getRevisionFile(${params.spaceId}, ${params.revisionId}, ${params.fileId})`, - async () => { + } + ) + ); + +const getSpace = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; shareKey: string | undefined } + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'space', + space: params.spaceId, + }) + ); + + return trace(`getSpace(${params.spaceId}, ${params.shareKey})`, async () => { return wrapDataFetcherError(async () => { const api = apiClient(input); - const res = await api.spaces.getFileInRevisionById( + const res = await api.spaces.getSpaceById( params.spaceId, - params.revisionId, - params.fileId, - {}, + { + shareKey: params.shareKey, + }, { ...noCacheFetchOptions, } ); cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); + cacheLife('days'); return res.data; }); - } - ); - } - ) -); - -const getRevisionPageMarkdown = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; pageId: string } - ) => { - 'use cache'; - return trace( - `getRevisionPageMarkdown(${params.spaceId}, ${params.revisionId}, ${params.pageId})`, - async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getPageInRevisionById( - params.spaceId, - params.revisionId, - params.pageId, - { - format: 'markdown', - }, - { - ...noCacheFetchOptions, - } - ); + }); + } + ) + ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); +const getChangeRequest = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; changeRequestId: string } + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'change-request', + space: params.spaceId, + changeRequest: params.changeRequestId, + }) + ); + + return trace( + `getChangeRequest(${params.spaceId}, ${params.changeRequestId})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getChangeRequestById( + params.spaceId, + params.changeRequestId, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('minutes'); + return res.data; + }); + } + ); + } + ) + ); - if (!('markdown' in res.data)) { - throw new DataFetcherError('Page is not a document', 404); - } - return res.data.markdown; - }); - } - ); - } - ) -); - -const getRevisionPageDocument = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; pageId: string } - ) => { - 'use cache'; - return trace( - `getRevisionPageDocument(${params.spaceId}, ${params.revisionId}, ${params.pageId})`, - async () => { +const getRevision = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; metadata: boolean } + ) => { + 'use cache'; + return trace(`getRevision(${params.spaceId}, ${params.revisionId})`, async () => { return wrapDataFetcherError(async () => { const api = apiClient(input); - const res = await api.spaces.getPageDocumentInRevisionById( + const res = await api.spaces.getRevisionById( params.spaceId, params.revisionId, - params.pageId, { - evaluated: true, + metadata: params.metadata, }, { ...noCacheFetchOptions, } ); - cacheTag(...getCacheTagsFromResponse(res)); cacheLife('max'); - return res.data; }); - } - ); - } - ) -); - -const getRevisionPageByPath = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; path: string } - ) => { - 'use cache'; - return trace( - `getRevisionPageByPath(${params.spaceId}, ${params.revisionId}, ${params.path})`, - async () => { - const encodedPath = encodeURIComponent(params.path); - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getPageInRevisionByPath( - params.spaceId, - params.revisionId, - encodedPath, - {}, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); - return res.data; - }); - } - ); - } - ) -); - -const getDocument = withCacheKey( - withoutConcurrentExecution( - async (_, input: DataFetcherInput, params: { spaceId: string; documentId: string }) => { - 'use cache'; - return trace(`getDocument(${params.spaceId}, ${params.documentId})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getDocumentById( - params.spaceId, - params.documentId, - {}, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); - return res.data; }); - }); - } - ) -); - -const getComputedDocument = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { - spaceId: string; - organizationId: string; - source: ComputedContentSource; - seed: string; } - ) => { - 'use cache'; - cacheTag( - ...getComputedContentSourceCacheTags( - { - spaceId: params.spaceId, - organizationId: params.organizationId, - }, - params.source - ) - ); + ) + ); - return trace( - `getComputedDocument(${params.spaceId}, ${params.organizationId}, ${params.source.type}, ${params.seed})`, - async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getComputedDocument( - params.spaceId, - { - source: params.source, - seed: params.seed, - }, - {}, - { - ...noCacheFetchOptions, +const getRevisionPages = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; metadata: boolean } + ) => { + 'use cache'; + return trace( + `getRevisionPages(${params.spaceId}, ${params.revisionId})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.listPagesInRevisionById( + params.spaceId, + params.revisionId, + { + metadata: params.metadata, + }, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + return res.data.pages; + }); + } + ); + } + ) + ); + +const getRevisionFile = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; fileId: string } + ) => { + 'use cache'; + return trace( + `getRevisionFile(${params.spaceId}, ${params.revisionId}, ${params.fileId})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getFileInRevisionById( + params.spaceId, + params.revisionId, + params.fileId, + {}, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + return res.data; + }); + } + ); + } + ) + ); + +const getRevisionPageMarkdown = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; pageId: string } + ) => { + 'use cache'; + return trace( + `getRevisionPageMarkdown(${params.spaceId}, ${params.revisionId}, ${params.pageId})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getPageInRevisionById( + params.spaceId, + params.revisionId, + params.pageId, + { + format: 'markdown', + }, + { + ...noCacheFetchOptions, + } + ); + + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + + if (!('markdown' in res.data)) { + throw new DataFetcherError('Page is not a document', 404); } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); - return res.data; - }); - } - ); - } - ) -); - -const getReusableContent = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { spaceId: string; revisionId: string; reusableContentId: string } - ) => { - 'use cache'; - return trace( - `getReusableContent(${params.spaceId}, ${params.revisionId}, ${params.reusableContentId})`, - async () => { + return res.data.markdown; + }); + } + ); + } + ) + ); + +const getRevisionPageDocument = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; pageId: string } + ) => { + 'use cache'; + return trace( + `getRevisionPageDocument(${params.spaceId}, ${params.revisionId}, ${params.pageId})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getPageDocumentInRevisionById( + params.spaceId, + params.revisionId, + params.pageId, + { + evaluated: true, + }, + { + ...noCacheFetchOptions, + } + ); + + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + + return res.data; + }); + } + ); + } + ) + ); + +const getRevisionPageByPath = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; path: string } + ) => { + 'use cache'; + return trace( + `getRevisionPageByPath(${params.spaceId}, ${params.revisionId}, ${params.path})`, + async () => { + const encodedPath = encodeURIComponent(params.path); + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getPageInRevisionByPath( + params.spaceId, + params.revisionId, + encodedPath, + {}, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + return res.data; + }); + } + ); + } + ) + ); + +const getDocument = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async (_, input: DataFetcherInput, params: { spaceId: string; documentId: string }) => { + 'use cache'; + return trace(`getDocument(${params.spaceId}, ${params.documentId})`, async () => { return wrapDataFetcherError(async () => { const api = apiClient(input); - const res = await api.spaces.getReusableContentInRevisionById( + const res = await api.spaces.getDocumentById( params.spaceId, - params.revisionId, - params.reusableContentId, + params.documentId, {}, { ...noCacheFetchOptions, @@ -594,240 +539,340 @@ const getReusableContent = withCacheKey( cacheLife('max'); return res.data; }); - } - ); - } - ) -); - -const getLatestOpenAPISpecVersionContent = withCacheKey( - withoutConcurrentExecution( - async (_, input: DataFetcherInput, params: { organizationId: string; slug: string }) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'openapi', - organization: params.organizationId, - openAPISpec: params.slug, - }) - ); + }); + } + ) + ); - return trace( - `getLatestOpenAPISpecVersionContent(${params.organizationId}, ${params.slug})`, - async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.orgs.getLatestOpenApiSpecVersionContent( - params.organizationId, - params.slug, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('max'); - return res.data; - }); +const getComputedDocument = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { + spaceId: string; + organizationId: string; + source: ComputedContentSource; + seed: string; } - ); - } - ) -); - -const getPublishedContentSite = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { organizationId: string; siteId: string; siteShareKey: string | undefined } - ) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'site', - site: params.siteId, - }) - ); + ) => { + 'use cache'; + cacheTag( + ...getComputedContentSourceCacheTags( + { + spaceId: params.spaceId, + organizationId: params.organizationId, + }, + params.source + ) + ); + + return trace( + `getComputedDocument(${params.spaceId}, ${params.organizationId}, ${params.source.type}, ${params.seed})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getComputedDocument( + params.spaceId, + { + source: params.source, + seed: params.seed, + }, + {}, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + return res.data; + }); + } + ); + } + ) + ); - return trace( - `getPublishedContentSite(${params.organizationId}, ${params.siteId}, ${params.siteShareKey})`, - async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.orgs.getPublishedContentSite( - params.organizationId, - params.siteId, - { - shareKey: params.siteShareKey, - }, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('days'); - return res.data; - }); +const getReusableContent = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { spaceId: string; revisionId: string; reusableContentId: string } + ) => { + 'use cache'; + return trace( + `getReusableContent(${params.spaceId}, ${params.revisionId}, ${params.reusableContentId})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.spaces.getReusableContentInRevisionById( + params.spaceId, + params.revisionId, + params.reusableContentId, + {}, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + return res.data; + }); + } + ); + } + ) + ); + +const getLatestOpenAPISpecVersionContent = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { organizationId: string; slug: string } + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'openapi', + organization: params.organizationId, + openAPISpec: params.slug, + }) + ); + + return trace( + `getLatestOpenAPISpecVersionContent(${params.organizationId}, ${params.slug})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.orgs.getLatestOpenApiSpecVersionContent( + params.organizationId, + params.slug, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('max'); + return res.data; + }); + } + ); + } + ) + ); + +const getPublishedContentSite = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { organizationId: string; siteId: string; siteShareKey: string | undefined } + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'site', + site: params.siteId, + }) + ); + + return trace( + `getPublishedContentSite(${params.organizationId}, ${params.siteId}, ${params.siteShareKey})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.orgs.getPublishedContentSite( + params.organizationId, + params.siteId, + { + shareKey: params.siteShareKey, + }, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('days'); + return res.data; + }); + } + ); + } + ) + ); + +const getSiteRedirectBySource = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { + organizationId: string; + siteId: string; + siteShareKey: string | undefined; + source: string; } - ); - } - ) -); - -const getSiteRedirectBySource = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { - organizationId: string; - siteId: string; - siteShareKey: string | undefined; - source: string; + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'site', + site: params.siteId, + }) + ); + + return trace( + `getSiteRedirectBySource(${params.organizationId}, ${params.siteId}, ${params.siteShareKey}, ${params.source})`, + async () => { + return wrapDataFetcherError(async () => { + const api = apiClient(input); + const res = await api.orgs.getSiteRedirectBySource( + params.organizationId, + params.siteId, + { + shareKey: params.siteShareKey, + source: params.source, + }, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('days'); + return res.data; + }); + } + ); } - ) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'site', - site: params.siteId, - }) - ); + ) + ); - return trace( - `getSiteRedirectBySource(${params.organizationId}, ${params.siteId}, ${params.siteShareKey}, ${params.source})`, - async () => { +const getEmbedByUrl = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async (_, input: DataFetcherInput, params: { spaceId: string; url: string }) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'space', + space: params.spaceId, + }) + ); + + return trace(`getEmbedByUrl(${params.spaceId}, ${params.url})`, async () => { return wrapDataFetcherError(async () => { const api = apiClient(input); - const res = await api.orgs.getSiteRedirectBySource( - params.organizationId, - params.siteId, + const res = await api.spaces.getEmbedByUrlInSpace( + params.spaceId, { - shareKey: params.siteShareKey, - source: params.source, + url: params.url, }, { ...noCacheFetchOptions, } ); cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('days'); + cacheLife('weeks'); return res.data; }); - } - ); - } - ) -); - -const getEmbedByUrl = withCacheKey( - withoutConcurrentExecution( - async (_, input: DataFetcherInput, params: { spaceId: string; url: string }) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'space', - space: params.spaceId, - }) - ); - - return trace(`getEmbedByUrl(${params.spaceId}, ${params.url})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.spaces.getEmbedByUrlInSpace( - params.spaceId, - { - url: params.url, - }, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('weeks'); - return res.data; }); - }); - } - ) -); - -const searchSiteContent = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: Parameters[0] - ) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'site', - site: params.siteId, - }) - ); + } + ) + ); - return trace( - `searchSiteContent(${params.organizationId}, ${params.siteId}, ${params.query})`, - async () => { +const searchSiteContent = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: Parameters[0] + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'site', + site: params.siteId, + }) + ); + + return trace( + `searchSiteContent(${params.organizationId}, ${params.siteId}, ${params.query})`, + async () => { + return wrapDataFetcherError(async () => { + const { organizationId, siteId, query, scope } = params; + const api = apiClient(input); + const res = await api.orgs.searchSiteContent( + organizationId, + siteId, + { + query, + ...scope, + }, + {}, + { + ...noCacheFetchOptions, + } + ); + cacheTag(...getCacheTagsFromResponse(res)); + cacheLife('hours'); + return res.data.items; + }); + } + ); + } + ) + ); + +const renderIntegrationUi = (dataFetcher: GitBookDataFetcher) => + withCacheKey( + withoutConcurrentExecution( + dataFetcher, + async ( + _, + input: DataFetcherInput, + params: { integrationName: string; request: RenderIntegrationUI } + ) => { + 'use cache'; + cacheTag( + getCacheTag({ + tag: 'integration', + integration: params.integrationName, + }) + ); + + return trace(`renderIntegrationUi(${params.integrationName})`, async () => { return wrapDataFetcherError(async () => { - const { organizationId, siteId, query, scope } = params; const api = apiClient(input); - const res = await api.orgs.searchSiteContent( - organizationId, - siteId, - { - query, - ...scope, - }, - {}, + const res = await api.integrations.renderIntegrationUiWithPost( + params.integrationName, + params.request, { ...noCacheFetchOptions, } ); cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('hours'); - return res.data.items; + cacheLife('days'); + return res.data; }); - } - ); - } - ) -); - -const renderIntegrationUi = withCacheKey( - withoutConcurrentExecution( - async ( - _, - input: DataFetcherInput, - params: { integrationName: string; request: RenderIntegrationUI } - ) => { - 'use cache'; - cacheTag( - getCacheTag({ - tag: 'integration', - integration: params.integrationName, - }) - ); - - return trace(`renderIntegrationUi(${params.integrationName})`, async () => { - return wrapDataFetcherError(async () => { - const api = apiClient(input); - const res = await api.integrations.renderIntegrationUiWithPost( - params.integrationName, - params.request, - { - ...noCacheFetchOptions, - } - ); - cacheTag(...getCacheTagsFromResponse(res)); - cacheLife('days'); - return res.data; }); - }); - } - ) -); + } + ) + ); async function* streamAIResponse( input: DataFetcherInput, diff --git a/packages/gitbook-v2/src/lib/data/memoize.ts b/packages/gitbook-v2/src/lib/data/memoize.ts index 5110d015fa..0f36763e86 100644 --- a/packages/gitbook-v2/src/lib/data/memoize.ts +++ b/packages/gitbook-v2/src/lib/data/memoize.ts @@ -1,20 +1,17 @@ -import { cache } from 'react'; - -// This is used to create a context specific to the current request. -// This version works both in cloudflare and in vercel. -const getRequestContext = cache(() => ({})); +import type { GitBookDataFetcher } from './types'; /** * Wrap a function by preventing concurrent executions of the same function. * With a logic to work per-request in Cloudflare Workers. */ export function withoutConcurrentExecution( + dataFetcherObject: GitBookDataFetcher, wrapped: (key: string, ...args: ArgsType) => Promise ): (cacheKey: string, ...args: ArgsType) => Promise { const globalPromiseCache = new WeakMap>>(); return (key: string, ...args: ArgsType) => { - const globalContext = getRequestContext(); + const globalContext = dataFetcherObject; /** * Cache storage that is scoped to the current request when executed in Cloudflare Workers,