Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions app/[[...path]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {isDeveloperDocs} from 'sentry-docs/isDeveloperDocs';
import {
getDevDocsFrontMatter,
getDocsFrontMatter,
getFileBySlug,
getFileBySlugWithCache,
getVersionsFromDoc,
} from 'sentry-docs/mdx';
import {mdxComponents} from 'sentry-docs/mdxComponents';
Expand Down Expand Up @@ -106,9 +106,9 @@ export default async function Page(props: {params: Promise<{path?: string[]}>})

if (isDeveloperDocs) {
// get the MDX for the current doc and render it
let doc: Awaited<ReturnType<typeof getFileBySlug>> | null = null;
let doc: Awaited<ReturnType<typeof getFileBySlugWithCache>>;
try {
doc = await getFileBySlug(`develop-docs/${params.path?.join('/') ?? ''}`);
doc = await getFileBySlugWithCache(`develop-docs/${params.path?.join('/') ?? ''}`);
} catch (e) {
if (e.code === 'ENOENT') {
// eslint-disable-next-line no-console
Expand Down Expand Up @@ -144,9 +144,9 @@ export default async function Page(props: {params: Promise<{path?: string[]}>})
}

// get the MDX for the current doc and render it
let doc: Awaited<ReturnType<typeof getFileBySlug>> | null = null;
let doc: Awaited<ReturnType<typeof getFileBySlugWithCache>>;
try {
doc = await getFileBySlug(`docs/${pageNode.path}`);
doc = await getFileBySlugWithCache(`docs/${pageNode.path}`);
} catch (e) {
if (e.code === 'ENOENT') {
// eslint-disable-next-line no-console
Expand Down
15 changes: 8 additions & 7 deletions src/components/include.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {useMemo} from 'react';
import {getMDXComponent} from 'mdx-bundler/client';

import {getFileBySlug} from 'sentry-docs/mdx';
import {getFileBySlugWithCache} from 'sentry-docs/mdx';
import {mdxComponents} from 'sentry-docs/mdxComponents';

import {PlatformContent} from './platformContent';
Expand All @@ -10,23 +10,24 @@ type Props = {
name: string;
};

function MDXLayoutRenderer({mdxSource: source, ...rest}) {
const MDXLayout = useMemo(() => getMDXComponent(source), [source]);
return <MDXLayout components={mdxComponents({Include, PlatformContent})} {...rest} />;
}

export async function Include({name}: Props) {
let doc: Awaited<ReturnType<typeof getFileBySlug>> | null = null;
let doc: Awaited<ReturnType<typeof getFileBySlugWithCache>>;
if (name.endsWith('.mdx')) {
name = name.slice(0, name.length - '.mdx'.length);
}
try {
doc = await getFileBySlug(`includes/${name}`);
doc = await getFileBySlugWithCache(`includes/${name}`);
} catch (e) {
if (e.code === 'ENOENT') {
return null;
}
throw e;
}
const {mdxSource} = doc;
function MDXLayoutRenderer({mdxSource: source, ...rest}) {
const MDXLayout = useMemo(() => getMDXComponent(source), [source]);
return <MDXLayout components={mdxComponents({Include, PlatformContent})} {...rest} />;
}
return <MDXLayoutRenderer mdxSource={mdxSource} />;
}
45 changes: 28 additions & 17 deletions src/components/platformContent.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import fs from 'fs';

import {useMemo} from 'react';
import {cache, useMemo} from 'react';
import {getMDXComponent} from 'mdx-bundler/client';

import {getCurrentGuide, getDocsRootNode, getPlatform} from 'sentry-docs/docTree';
import {getFileBySlug} from 'sentry-docs/mdx';
import {getFileBySlugWithCache} from 'sentry-docs/mdx';
import {mdxComponents} from 'sentry-docs/mdxComponents';
import {serverContext} from 'sentry-docs/serverContext';
import {
Expand All @@ -24,7 +24,7 @@ type Props = {
platform?: string;
};

const udpatePathIfVersionedFileDoesNotExist = (path: string): string => {
const updatePathIfVersionedFileDoesNotExist = (path: string): string => {
if (!isVersioned(path)) {
return path;
}
Expand All @@ -39,6 +39,21 @@ const udpatePathIfVersionedFileDoesNotExist = (path: string): string => {
return path;
};

/**
* Cache the result of updatePathIfVersionedFileDoesNotExist
* to avoid calling it multiple times for the same path.
*
* This is important because we want to skip the `fs.existsSync` call if possible.
*/
const updatePathIfVersionedFileDoesNotExistWithCache = cache(
updatePathIfVersionedFileDoesNotExist
);

function MDXLayoutRenderer({mdxSource: source, ...rest}) {
const MDXLayout = useMemo(() => getMDXComponent(source), [source]);
return <MDXLayout components={mdxComponentsWithWrapper} {...rest} />;
}

export async function PlatformContent({includePath, platform, noGuides}: Props) {
const {path} = serverContext();

Expand All @@ -54,15 +69,15 @@ export async function PlatformContent({includePath, platform, noGuides}: Props)
guide = `${platform}.${path[3]}`;
}

let doc: Awaited<ReturnType<typeof getFileBySlug>> | null = null;
let doc: Awaited<ReturnType<typeof getFileBySlugWithCache>> | undefined;

if (guide) {
const guidePath = udpatePathIfVersionedFileDoesNotExist(
const guidePath = updatePathIfVersionedFileDoesNotExistWithCache(
`platform-includes/${includePath}/${guide}`
);

try {
doc = await getFileBySlug(guidePath);
doc = await getFileBySlugWithCache(guidePath);
} catch (e) {
// It's fine - keep looking.
}
Expand All @@ -72,13 +87,13 @@ export async function PlatformContent({includePath, platform, noGuides}: Props)
const rootNode = await getDocsRootNode();
const guideObject = getCurrentGuide(rootNode, path);

const fallbackGuidePath = udpatePathIfVersionedFileDoesNotExist(
const fallbackGuidePath = updatePathIfVersionedFileDoesNotExistWithCache(
`platform-includes/${includePath}/${guideObject?.fallbackGuide}${VERSION_INDICATOR}${getVersion(guide || '')}`
);

if (guideObject?.fallbackGuide) {
try {
doc = await getFileBySlug(fallbackGuidePath);
doc = await getFileBySlugWithCache(fallbackGuidePath);
} catch (e) {
// It's fine - keep looking.
}
Expand All @@ -87,11 +102,11 @@ export async function PlatformContent({includePath, platform, noGuides}: Props)

if (!doc) {
try {
const platformPath = udpatePathIfVersionedFileDoesNotExist(
const platformPath = updatePathIfVersionedFileDoesNotExistWithCache(
`platform-includes/${includePath}/${platform}`
);

doc = await getFileBySlug(platformPath);
doc = await getFileBySlugWithCache(platformPath);
} catch (e) {
// It's fine - keep looking.
}
Expand All @@ -101,13 +116,13 @@ export async function PlatformContent({includePath, platform, noGuides}: Props)
const rootNode = await getDocsRootNode();
const platformObject = getPlatform(rootNode, platform);

const fallbackPlatformPath = udpatePathIfVersionedFileDoesNotExist(
const fallbackPlatformPath = updatePathIfVersionedFileDoesNotExistWithCache(
`platform-includes/${includePath}/${platformObject?.fallbackPlatform}`
);

if (platformObject?.fallbackPlatform) {
try {
doc = await getFileBySlug(fallbackPlatformPath);
doc = await getFileBySlugWithCache(fallbackPlatformPath);
} catch (e) {
// It's fine - keep looking.
}
Expand All @@ -116,18 +131,14 @@ export async function PlatformContent({includePath, platform, noGuides}: Props)

if (!doc) {
try {
doc = await getFileBySlug(`platform-includes/${includePath}/_default`);
doc = await getFileBySlugWithCache(`platform-includes/${includePath}/_default`);
} catch (e) {
// Couldn't find anything.
return null;
}
}

const {mdxSource} = doc;
function MDXLayoutRenderer({mdxSource: source, ...rest}) {
const MDXLayout = useMemo(() => getMDXComponent(source), [source]);
return <MDXLayout components={mdxComponentsWithWrapper} {...rest} />;
}
return <MDXLayoutRenderer mdxSource={mdxSource} />;
}

Expand Down
8 changes: 8 additions & 0 deletions src/mdx.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from 'fs';
import path from 'path';

import {cache} from 'react';
import matter from 'gray-matter';
import {s} from 'hastscript';
import yaml from 'js-yaml';
Expand Down Expand Up @@ -474,3 +475,10 @@ export async function getFileBySlug(slug: string) {
},
};
}

/**
* Cache the result of {@link getFileBySlug}.
*
* This is useful for performance when rendering the same file multiple times.
*/
export const getFileBySlugWithCache = cache(getFileBySlug);
Loading