Skip to content

Commit 49c83e1

Browse files
committed
Revert "remove all caching logic from mdx"
This reverts commit 2c2dcc9.
1 parent 6a1e895 commit 49c83e1

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

src/mdx.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1+
import {BinaryLike, createHash} from 'crypto';
2+
13
import {cache} from 'react';
24
import matter from 'gray-matter';
35
import {s} from 'hastscript';
46
import yaml from 'js-yaml';
57
import {bundleMDX} from 'mdx-bundler';
8+
import {createReadStream, createWriteStream, mkdirSync} from 'node:fs';
69
import {access, opendir, readFile} from 'node:fs/promises';
710
import path from 'node:path';
11+
// @ts-expect-error ts(2305) -- For some reason "compose" is not recognized in the types
12+
import {compose, Readable} from 'node:stream';
13+
import {json} from 'node:stream/consumers';
14+
import {pipeline} from 'node:stream/promises';
15+
import {
16+
constants as zlibConstants,
17+
createBrotliCompress,
18+
createBrotliDecompress,
19+
} from 'node:zlib';
820
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
921
import rehypePresetMinify from 'rehype-preset-minify';
1022
import rehypePrismDiff from 'rehype-prism-diff';
@@ -41,6 +53,33 @@ type SlugFile = {
4153
};
4254

4355
const root = process.cwd();
56+
const CACHE_COMPRESS_LEVEL = 4;
57+
const CACHE_DIR = path.join(root, '.next', 'cache', 'mdx-bundler');
58+
mkdirSync(CACHE_DIR, {recursive: true});
59+
60+
const md5 = (data: BinaryLike) => createHash('md5').update(data).digest('hex');
61+
62+
async function readCacheFile<T>(file: string): Promise<T> {
63+
const reader = createReadStream(file);
64+
const decompressor = createBrotliDecompress();
65+
66+
return (await json(compose(reader, decompressor))) as T;
67+
}
68+
69+
async function writeCacheFile(file: string, data: string) {
70+
await pipeline(
71+
Readable.from(data),
72+
createBrotliCompress({
73+
chunkSize: 32 * 1024,
74+
params: {
75+
[zlibConstants.BROTLI_PARAM_MODE]: zlibConstants.BROTLI_MODE_TEXT,
76+
[zlibConstants.BROTLI_PARAM_QUALITY]: CACHE_COMPRESS_LEVEL,
77+
[zlibConstants.BROTLI_PARAM_SIZE_HINT]: data.length,
78+
},
79+
}),
80+
createWriteStream(file)
81+
);
82+
}
4483

4584
function formatSlug(slug: string) {
4685
return slug.replace(/\.(mdx|md)/, '');
@@ -436,6 +475,24 @@ export async function getFileBySlug(slug: string): Promise<SlugFile> {
436475
);
437476
}
438477

478+
let cacheKey: string | null = null;
479+
let cacheFile: string | null = null;
480+
if (process.env.CI === '1') {
481+
cacheKey = md5(source);
482+
cacheFile = path.join(CACHE_DIR, cacheKey);
483+
484+
try {
485+
const cached = await readCacheFile<SlugFile>(cacheFile);
486+
return cached;
487+
} catch (err) {
488+
if (err.code !== 'ENOENT' && err.code !== 'ABORT_ERR') {
489+
// If cache is corrupted, ignore and proceed
490+
// eslint-disable-next-line no-console
491+
console.warn(`Failed to read MDX cache: ${cacheFile}`, err);
492+
}
493+
}
494+
}
495+
439496
process.env.ESBUILD_BINARY_PATH = path.join(
440497
root,
441498
'node_modules',
@@ -561,6 +618,13 @@ export async function getFileBySlug(slug: string): Promise<SlugFile> {
561618
},
562619
};
563620

621+
if (cacheFile) {
622+
writeCacheFile(cacheFile, JSON.stringify(resultObj)).catch(e => {
623+
// eslint-disable-next-line no-console
624+
console.warn(`Failed to write MDX cache: ${cacheFile}`, e);
625+
});
626+
}
627+
564628
return resultObj;
565629
}
566630

0 commit comments

Comments
 (0)