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
6 changes: 6 additions & 0 deletions .changeset/beige-hounds-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@open-rpc/markdown-generator": patch
"@open-rpc/docusaurus-plugin": patch
---

Fixes a race condition when running in active development mode. This set of changes now allows for incremental deletion and proper removal ordering
29 changes: 7 additions & 22 deletions packages/docusaurus-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,22 @@ import type { LoadContext, Plugin } from "@docusaurus/types";
import type { PluginContent } from "./types";
import type { Options, PluginOptions } from "./options";
import { normalizeOptions } from "./options";
import { generateDocs } from "./lib";
import { cleanUpExistingDocs, generateDocs } from "./lib";
import fs from "fs/promises";
import path from "path";
import { parseOpenRPCDocument } from "@open-rpc/schema-utils-js";
import { DereffedOpenrpcDocument } from "@open-rpc/markdown-generator";

const PluginName = "@open-rpc/docusaurus-plugin";

async function initDocs(
async function rebuildDocs(
specPath: string,
outputDir: string,
options: PluginOptions,
) {
if (!(await fs.stat(specPath)).isFile()) {
throw new Error(`OpenRPC spec file not found: ${specPath}`);
}

try {
const entries = await fs.readdir(outputDir, { withFileTypes: true });
await Promise.all(
entries
.filter((entry) => entry.name !== "index.md")
.map((entry) => {
const fullPath = `${outputDir}/${entry.name}`;
return fs.rm(fullPath, { recursive: true, force: true });
}),
);
} catch {
// Directory doesn't exist yet, that's fine
}

try {
await generateDocs(specPath, outputDir, options);
await cleanUpExistingDocs(specPath, outputDir);
} catch (err) {
logger.error(`[${PluginName}] generateDocs failed: ${err}`);
logger.error(
Expand All @@ -61,7 +46,7 @@ export default async function openRPCDocusaurusPlugin(
normalizedOptions.docOutputPath,
);

await initDocs(specPath, outputDir, normalizedOptions);
await rebuildDocs(specPath, outputDir, normalizedOptions);

return {
name: PluginName,
Expand Down Expand Up @@ -95,7 +80,7 @@ export default async function openRPCDocusaurusPlugin(
*/
async contentLoaded({ content, actions }): Promise<void> {
logger.info(`[${PluginName}] contentLoaded called`);
await initDocs(specPath, outputDir, normalizedOptions);
await rebuildDocs(specPath, outputDir, normalizedOptions);
},

/**
Expand Down
33 changes: 33 additions & 0 deletions packages/docusaurus-plugin/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,39 @@ methodEdits.editMethod = (content, method) => {
] as OpenRPCMdContent[];
};

export async function cleanUpExistingDocs(specPath: string, outputDir: string) {
if (!(await fs.stat(specPath)).isFile()) {
throw new Error(`OpenRPC spec file not found: ${specPath}`);
}
const raw = await fs.readFile(specPath, "utf8");
const doc: DereffedOpenrpcDocument = (await parseOpenRPCDocument(
raw,
)) as DereffedOpenrpcDocument;

const methodFileNamesToGenerate = new Set(
doc.methods.map((method) => `${method.name}.mdx`),
);
const entries = await fs.readdir(outputDir, {
withFileTypes: true,
recursive: true,
});

const entriesToDelete = entries
.filter(
(entry) =>
entry.isFile() &&
methodFileNamesToGenerate.has(entry.name) === false &&
entry.name !== "index.md",
)
.map((entry) => `${entry.parentPath}/${entry.name}`);

await Promise.all(
entriesToDelete.map((entry) =>
fs.rm(entry, { recursive: true, force: true }),
),
);
}

export async function generateDocs(
inputPath: string,
outputPath: string,
Expand Down
2 changes: 1 addition & 1 deletion packages/example-site/docs/api-reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# GENERATED DOCUMENTATION - DO NOT EDIT THIS FILE
title: "Ethereum JSON-RPC Specification"
description: "A specification of the standard interface for Ethereum clients."
slug: /api-reference


---

Expand Down
1 change: 0 additions & 1 deletion packages/example-site/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const config: Config = {
openRPCSpecPath: `./error-group-openrpc.json`,
docOutputPath: `./docs/api-reference`,
showPoweredBy: true,
indexSlug: '/api-reference',
}]],
presets: [
[
Expand Down
Loading