From 28ac52d6c37f9c36bae1135d2a974a6716eb7db2 Mon Sep 17 00:00:00 2001 From: Zane Starr Date: Fri, 19 Dec 2025 15:21:26 -0800 Subject: [PATCH 1/3] fix: live development clean up and rebuilding --- packages/docusaurus-plugin/src/index.ts | 29 ++++++---------------- packages/docusaurus-plugin/src/lib.ts | 33 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/docusaurus-plugin/src/index.ts b/packages/docusaurus-plugin/src/index.ts index 210138c..7c0fde7 100644 --- a/packages/docusaurus-plugin/src/index.ts +++ b/packages/docusaurus-plugin/src/index.ts @@ -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( @@ -61,7 +46,7 @@ export default async function openRPCDocusaurusPlugin( normalizedOptions.docOutputPath, ); - await initDocs(specPath, outputDir, normalizedOptions); + await rebuildDocs(specPath, outputDir, normalizedOptions); return { name: PluginName, @@ -95,7 +80,7 @@ export default async function openRPCDocusaurusPlugin( */ async contentLoaded({ content, actions }): Promise { logger.info(`[${PluginName}] contentLoaded called`); - await initDocs(specPath, outputDir, normalizedOptions); + await rebuildDocs(specPath, outputDir, normalizedOptions); }, /** diff --git a/packages/docusaurus-plugin/src/lib.ts b/packages/docusaurus-plugin/src/lib.ts index 10866af..5676d84 100644 --- a/packages/docusaurus-plugin/src/lib.ts +++ b/packages/docusaurus-plugin/src/lib.ts @@ -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, From 0e148677f2f2a34d285eab3fbf973f84ed13d23e Mon Sep 17 00:00:00 2001 From: Zane Starr Date: Fri, 19 Dec 2025 15:22:00 -0800 Subject: [PATCH 2/3] chore: fix bad reference slug --- packages/example-site/docs/api-reference/index.md | 2 +- packages/example-site/docusaurus.config.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/example-site/docs/api-reference/index.md b/packages/example-site/docs/api-reference/index.md index a039b85..7b4884d 100644 --- a/packages/example-site/docs/api-reference/index.md +++ b/packages/example-site/docs/api-reference/index.md @@ -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 + --- diff --git a/packages/example-site/docusaurus.config.ts b/packages/example-site/docusaurus.config.ts index 2ca590a..3819b29 100644 --- a/packages/example-site/docusaurus.config.ts +++ b/packages/example-site/docusaurus.config.ts @@ -39,7 +39,6 @@ const config: Config = { openRPCSpecPath: `./error-group-openrpc.json`, docOutputPath: `./docs/api-reference`, showPoweredBy: true, - indexSlug: '/api-reference', }]], presets: [ [ From 220d782f4b848f3b025b8a104354ced36b2f54da Mon Sep 17 00:00:00 2001 From: Zane Starr Date: Fri, 19 Dec 2025 15:23:55 -0800 Subject: [PATCH 3/3] chore: add changeset --- .changeset/beige-hounds-jump.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/beige-hounds-jump.md diff --git a/.changeset/beige-hounds-jump.md b/.changeset/beige-hounds-jump.md new file mode 100644 index 0000000..652fca3 --- /dev/null +++ b/.changeset/beige-hounds-jump.md @@ -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