Skip to content

Commit

Permalink
fix(shared): avoid regeneration of markdown or mdx
Browse files Browse the repository at this point in the history
Avoid regeneration of Markdown or MDX if non-relevant fields have changed
  • Loading branch information
sdorra committed Sep 1, 2024
1 parent 8bc2da4 commit 7a407f3
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 14 deletions.
6 changes: 6 additions & 0 deletions .changeset/thirty-eels-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@content-collections/markdown": patch
"@content-collections/mdx": patch
---

Avoid regeneration of markdown or mdx if non relevant fields have changed
23 changes: 22 additions & 1 deletion packages/markdown/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it, vitest } from "vitest";
import { compileMarkdown } from ".";
import { Context, Meta } from "@content-collections/core";

Expand Down Expand Up @@ -112,4 +112,25 @@ describe("markdown", () => {

expect(html).toBe("<h1>Hello <strong>World</strong>!</h1>");
});

it("should only use required props for caching", async () => {
const cacheFn = vitest.fn();

const doc = {
title: "Hello World",
content: "# hello world",
_meta: sampleMeta,
};

await compileMarkdown({ cache: cacheFn }, doc);

const call = cacheFn.mock.calls[0];
if (!call) {
throw new Error("cache function was not called");
}

const [input] = call;

expect(Object.keys(input)).toEqual(["content", "_meta"]);
});
});
11 changes: 10 additions & 1 deletion packages/markdown/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,19 @@ async function compile(document: Document, options?: Options) {
return String(html);
}

// Remove all unnecessary keys from the document
// and return a new object containing only the keys
// that should trigger a regeneration if changed.
function createCacheKey(document: Document): Document {
const { content, _meta } = document;
return { content, _meta };
}

export function compileMarkdown(
{ cache }: Pick<Context, "cache">,
document: Document,
options?: Options
) {
return cache(document, (doc) => compile(doc, options));
const cacheKey = createCacheKey(document);
return cache(cacheKey, (doc) => compile(doc, options));
}
32 changes: 28 additions & 4 deletions packages/mdx/src/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { describe, expect, it, beforeEach } from "vitest";
import { describe, expect, it, beforeEach, vitest } from "vitest";
import { Options, compileMDX } from ".";
import { Context, Meta } from "@content-collections/core";
import { MDXContent, useMDXComponent } from "./react/server";
import { useMDXComponent as useClientMDXComponent, MDXContent as MDXClientContent } from "./react/client";
import {
useMDXComponent as useClientMDXComponent,
MDXContent as MDXClientContent,
} from "./react/client";
import { cleanup, render, renderHook, screen } from "@testing-library/react";
import { Pluggable, Transformer } from "unified";
import { Node, Parent } from "mdast";
Expand All @@ -29,7 +32,7 @@ describe("MDX tests", () => {
{ cache },
{
content,
_meta: sampleMeta
_meta: sampleMeta,
},
options
);
Expand Down Expand Up @@ -155,7 +158,7 @@ describe("MDX tests", () => {
{ cache },
{
content: "<HelloWorld />",
_meta: sampleMeta
_meta: sampleMeta,
}
);

Expand Down Expand Up @@ -213,4 +216,25 @@ describe("/react (client)", () => {

expect(screen.getByRole("heading")).toHaveTextContent("Hello World!");
});

it("should only use required props for caching", async () => {
const cacheFn = vitest.fn();

const doc = {
title: "Hello World",
content: "# hello world",
_meta: sampleMeta,
};

await compileMDX({ cache: cacheFn }, doc);

const call = cacheFn.mock.calls[0];
if (!call) {
throw new Error("cache function was not called");
}

const [input] = call;

expect(Object.keys(input)).toEqual(["content", "_meta"]);
});
});
34 changes: 26 additions & 8 deletions packages/mdx/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Document = {
content: string;
};

type FileAppender = ReturnType<typeof createFileAppender>
type FileAppender = ReturnType<typeof createFileAppender>;

export type Options = {
cwd?: string;
Expand All @@ -19,11 +19,19 @@ export type Options = {
rehypePlugins?: Pluggable[];
};

async function appendFile(files: Record<string, string>, importPath: string, filePath: string) {
async function appendFile(
files: Record<string, string>,
importPath: string,
filePath: string
) {
files[importPath] = await fs.readFile(filePath, "utf-8");
}

async function appendDirectory(files: Record<string, string>, importPathPrefix: string, directoryPath: string) {
async function appendDirectory(
files: Record<string, string>,
importPathPrefix: string,
directoryPath: string
) {
if (!existsSync(directoryPath)) {
return;
}
Expand All @@ -35,7 +43,10 @@ async function appendDirectory(files: Record<string, string>, importPathPrefix:
}
}

function createFileAppender(tasks: Promise<void>[], files: Record<string, string>) {
function createFileAppender(
tasks: Promise<void>[],
files: Record<string, string>
) {
return {
content: (importPath: string, content: string) => {
files[importPath] = content;
Expand Down Expand Up @@ -82,9 +93,7 @@ async function compile(document: Document, options: Options = {}) {
return options;
},
mdxOptions(mdxOptions) {
mdxOptions.rehypePlugins = [
...(options.rehypePlugins ?? []),
];
mdxOptions.rehypePlugins = [...(options.rehypePlugins ?? [])];

mdxOptions.remarkPlugins = [
addMetaToVFile(document._meta),
Expand All @@ -97,10 +106,19 @@ async function compile(document: Document, options: Options = {}) {
return code;
}

// Remove all unnecessary keys from the document
// and return a new object containing only the keys
// that should trigger a regeneration if changed.
function createCacheKey(document: Document): Document {
const { content, _meta } = document;
return { content, _meta };
}

export function compileMDX(
{ cache }: Pick<Context, "cache">,
document: Document,
options?: Options
) {
return cache(document, (doc) => compile(doc, options));
const cacheKey = createCacheKey(document);
return cache(cacheKey, (doc) => compile(doc, options));
}

0 comments on commit 7a407f3

Please sign in to comment.