@rspress/plugin-preview 1.13.1 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { RspressPlugin } from '@rspress/shared';
2
+ import { RsbuildConfig } from '@rsbuild/core';
2
3
 
3
4
  type Options = {
4
5
  /**
@@ -44,6 +45,7 @@ type IframeOptions = {
44
45
  * @default 7890
45
46
  */
46
47
  devPort?: number;
48
+ builderConfig?: RsbuildConfig;
47
49
  };
48
50
 
49
51
  /**
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ __export(src_exports, {
35
35
  module.exports = __toCommonJS(src_exports);
36
36
  var import_path4 = require("path");
37
37
  var import_node_net = __toESM(require("net"));
38
+ var import_shared3 = require("@rspress/shared");
38
39
  var import_core = require("@rsbuild/core");
39
40
  var import_plugin_solid = require("@rsbuild/plugin-solid");
40
41
  var import_plugin_babel = require("@rsbuild/plugin-babel");
@@ -272,26 +273,21 @@ var virtualDir = import_path.default.join(
272
273
  "virtual-demo"
273
274
  );
274
275
 
275
- // src/virtual-module.ts
276
- var import_rspack_plugin_virtual_module = __toESM(require("rspack-plugin-virtual-module"));
277
- var demos = {};
278
- var demoRuntimeModule = new import_rspack_plugin_virtual_module.default({
279
- "virtual-meta": "export const demos = {}"
280
- });
281
-
282
276
  // src/remarkPlugin.ts
283
- var remarkCodeToDemo = ({
277
+ var demos = {};
278
+ var remarkCodeToDemo = function({
284
279
  getRouteMeta,
285
280
  previewMode,
286
281
  defaultRenderMode,
287
282
  position
288
- }) => {
283
+ }) {
289
284
  const routeMeta2 = getRouteMeta();
290
285
  import_fs_extra.default.ensureDirSync(virtualDir);
286
+ const data = this.data();
291
287
  return (tree, vfile) => {
292
288
  const demoMdx = [];
293
289
  const route = routeMeta2.find(
294
- (meta2) => (0, import_shared2.normalizePosixPath)(meta2.absolutePath) === (0, import_shared2.normalizePosixPath)(vfile.path || vfile.history[0])
290
+ (meta) => (0, import_shared2.normalizePosixPath)(meta.absolutePath) === (0, import_shared2.normalizePosixPath)(vfile.path || vfile.history[0])
295
291
  );
296
292
  if (!route) {
297
293
  return;
@@ -303,10 +299,11 @@ var remarkCodeToDemo = ({
303
299
  let externalDemoIndex = 0;
304
300
  function constructDemoNode(demoId, demoPath, currentNode, isMobileMode, externalDemoIndex2) {
305
301
  if (isMobileMode) {
302
+ const relativePathReg = new RegExp(/^\.\.?\/.*$/);
306
303
  demos[pageName].push({
307
304
  title,
308
305
  id: demoId,
309
- path: (0, import_path2.isAbsolute)(demoPath) ? demoPath : (0, import_path2.join)(vfile.dirname || (0, import_path2.dirname)(vfile.path), demoPath)
306
+ path: relativePathReg.test(demoPath) ? (0, import_path2.resolve)(vfile.dirname || (0, import_path2.dirname)(vfile.path), demoPath) : demoPath
310
307
  });
311
308
  } else {
312
309
  demoMdx.push(getASTNodeImport(`Demo${demoId}`, demoPath));
@@ -406,10 +403,9 @@ var remarkCodeToDemo = ({
406
403
  }
407
404
  });
408
405
  tree.children.unshift(...demoMdx);
409
- const meta = `
410
- export const demos = ${JSON.stringify(demos)}
411
- `;
412
- demoRuntimeModule.writeModule("virtual-meta", meta);
406
+ if (demos[pageName].length > 0) {
407
+ data.pageMeta.haveDemos = true;
408
+ }
413
409
  };
414
410
  };
415
411
  var getASTNodeImport = (name, from) => ({
@@ -581,12 +577,14 @@ function pluginPreview(options) {
581
577
  const {
582
578
  devPort = 7890,
583
579
  framework = "react",
584
- position = iframePosition
580
+ position = iframePosition,
581
+ builderConfig = {}
585
582
  } = iframeOptions;
586
583
  const globalUIComponents = iframePosition === "fixed" ? [(0, import_path4.join)(staticPath, "global-components", "Device.tsx")] : [];
587
584
  const getRouteMeta = () => routeMeta;
588
585
  let lastDemos;
589
586
  let devServer;
587
+ let clientConfig;
590
588
  const port = devPort;
591
589
  return {
592
590
  name: "@rspress/plugin-preview",
@@ -601,12 +599,12 @@ function pluginPreview(options) {
601
599
  async beforeBuild(_, isProd) {
602
600
  if (!isProd) {
603
601
  try {
604
- await new Promise((resolve, reject) => {
602
+ await new Promise((resolve2, reject) => {
605
603
  const server = import_node_net.default.createServer();
606
604
  server.unref();
607
605
  server.on("error", reject);
608
606
  server.listen({ port, host: "0.0.0.0" }, () => {
609
- server.close(resolve);
607
+ server.close(resolve2);
610
608
  });
611
609
  });
612
610
  } catch (e) {
@@ -631,8 +629,9 @@ function pluginPreview(options) {
631
629
  if (Object.keys(sourceEntry).length === 0) {
632
630
  return;
633
631
  }
634
- const rsbuildInstance = await (0, import_core.createRsbuild)({
635
- rsbuildConfig: {
632
+ const { html, source, output, performance } = clientConfig ?? {};
633
+ const rsbuildConfig = (0, import_core.mergeRsbuildConfig)(
634
+ {
636
635
  dev: {
637
636
  progressBar: false
638
637
  },
@@ -642,24 +641,28 @@ function pluginPreview(options) {
642
641
  strictPort: true
643
642
  },
644
643
  performance: {
644
+ ...performance,
645
645
  printFileSize: false
646
646
  },
647
+ html,
647
648
  source: {
649
+ ...source,
648
650
  entry: sourceEntry
649
651
  },
650
652
  output: {
653
+ ...output,
654
+ assetPrefix: output?.assetPrefix ? `${(0, import_shared3.removeTrailingSlash)(output.assetPrefix)}/~demo` : "/~demo",
651
655
  distPath: {
652
656
  root: outDir
653
- }
654
- },
655
- tools: {
656
- rspack: {
657
- output: {
658
- publicPath: "/~demo"
659
- }
660
- }
657
+ },
658
+ // not copy files again
659
+ copy: void 0
661
660
  }
662
- }
661
+ },
662
+ builderConfig
663
+ );
664
+ const rsbuildInstance = await (0, import_core.createRsbuild)({
665
+ rsbuildConfig
663
666
  });
664
667
  if (framework === "solid") {
665
668
  rsbuildInstance.addPlugins([
@@ -683,9 +686,6 @@ function pluginPreview(options) {
683
686
  include: [(0, import_path4.join)(__dirname, "..")]
684
687
  },
685
688
  tools: {
686
- rspack: {
687
- plugins: [demoRuntimeModule]
688
- },
689
689
  bundlerChain(chain) {
690
690
  chain.module.rule("Raw").resourceQuery(/raw/).type("asset/source").end();
691
691
  chain.resolve.extensions.prepend(".md").prepend(".mdx");
@@ -695,6 +695,11 @@ function pluginPreview(options) {
695
695
  {
696
696
  name: "close-demo-server",
697
697
  setup: (api) => {
698
+ api.modifyRsbuildConfig((config) => {
699
+ if (config.output?.targets?.every((target) => target === "web")) {
700
+ clientConfig = config;
701
+ }
702
+ });
698
703
  api.onCloseDevServer(async () => {
699
704
  await devServer?.server?.close();
700
705
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["import_path","index","is","visit","import_shared","path","RspackVirtualModulePlugin","routeMeta","fs","meta","externalDemoIndex","demos","net"],"sources":["../src/index.ts","../src/remarkPlugin.ts","../../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/lib/index.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/color.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/index.js","../../../node_modules/.pnpm/unist-util-visit@4.1.1/node_modules/unist-util-visit/index.js","../src/utils.ts","../src/constant.ts","../src/virtual-module.ts","../src/generate-entry.ts"],"sourcesContent":["import { join } from 'path';\nimport net from 'node:net';\nimport { type RouteMeta, type RspressPlugin } from '@rspress/shared';\nimport { createRsbuild } from '@rsbuild/core';\nimport { pluginSolid } from '@rsbuild/plugin-solid';\nimport { pluginBabel } from '@rsbuild/plugin-babel';\nimport { pluginReact } from '@rsbuild/plugin-react';\nimport { isEqual, cloneDeep } from 'lodash';\nimport { remarkCodeToDemo } from './remarkPlugin';\nimport { staticPath } from './constant';\nimport type { Options, StartServerResult } from './types';\nimport { generateEntry } from './generate-entry';\nimport { demoRuntimeModule, demos } from './virtual-module';\n\n// global variables which need to be initialized in plugin\nlet routeMeta: RouteMeta[];\n\n/**\n * The plugin is used to preview component.\n */\nexport function pluginPreview(options?: Options): RspressPlugin {\n const {\n isMobile = false,\n iframeOptions = {},\n iframePosition = 'follow',\n defaultRenderMode = 'preview',\n } = options ?? {};\n const previewMode = options?.previewMode ?? isMobile ? 'iframe' : 'internal';\n const {\n devPort = 7890,\n framework = 'react',\n position = iframePosition,\n } = iframeOptions;\n const globalUIComponents =\n iframePosition === 'fixed'\n ? [join(staticPath, 'global-components', 'Device.tsx')]\n : [];\n const getRouteMeta = () => routeMeta;\n let lastDemos: typeof demos;\n let devServer: StartServerResult;\n const port = devPort;\n return {\n name: '@rspress/plugin-preview',\n config(config) {\n config.markdown = config.markdown || {};\n config.markdown.mdxRs = false;\n return config;\n },\n routeGenerated(routes: RouteMeta[]) {\n // init routeMeta\n routeMeta = routes;\n },\n async beforeBuild(_, isProd) {\n if (!isProd) {\n try {\n await new Promise((resolve, reject) => {\n const server = net.createServer();\n server.unref();\n server.on('error', reject);\n server.listen({ port, host: '0.0.0.0' }, () => {\n server.close(resolve);\n });\n });\n } catch (e: any) {\n if (e.code !== 'EADDRINUSE') {\n throw e;\n } else {\n throw new Error(\n `Port \"${port}\" is occupied, please choose another one.`,\n );\n }\n }\n }\n },\n async afterBuild(config, isProd) {\n if (isEqual(demos, lastDemos)) {\n return;\n }\n lastDemos = cloneDeep(demos);\n await devServer?.server?.close();\n const sourceEntry = generateEntry(demos, framework, position);\n const outDir = join(config.outDir ?? 'doc_build', '~demo');\n if (Object.keys(sourceEntry).length === 0) {\n return;\n }\n const rsbuildInstance = await createRsbuild({\n rsbuildConfig: {\n dev: {\n progressBar: false,\n },\n server: {\n port: devPort,\n printUrls: () => undefined,\n strictPort: true,\n },\n performance: {\n printFileSize: false,\n },\n source: {\n entry: sourceEntry,\n },\n output: {\n distPath: {\n root: outDir,\n },\n },\n tools: {\n rspack: {\n output: {\n publicPath: '/~demo',\n },\n },\n },\n },\n });\n if (framework === 'solid') {\n rsbuildInstance.addPlugins([\n pluginBabel({\n include: /\\.(?:jsx|tsx)$/,\n }),\n pluginSolid(),\n ]);\n }\n if (framework === 'react') {\n rsbuildInstance.addPlugins([pluginReact()]);\n }\n if (isProd) {\n rsbuildInstance.build();\n } else {\n devServer = await rsbuildInstance.startDevServer();\n }\n },\n builderConfig: {\n source: {\n include: [join(__dirname, '..')],\n },\n tools: {\n rspack: {\n plugins: [demoRuntimeModule],\n },\n bundlerChain(chain) {\n chain.module\n .rule('Raw')\n .resourceQuery(/raw/)\n .type('asset/source')\n .end();\n\n chain.resolve.extensions.prepend('.md').prepend('.mdx');\n },\n },\n plugins: [\n {\n name: 'close-demo-server',\n setup: api => {\n api.onCloseDevServer(async () => {\n await devServer?.server?.close();\n });\n },\n },\n ],\n },\n extendPageData(pageData, isProd) {\n if (!isProd) {\n pageData.devPort = port;\n }\n },\n markdown: {\n remarkPlugins: [\n [\n remarkCodeToDemo,\n {\n getRouteMeta,\n position,\n previewMode,\n defaultRenderMode,\n },\n ],\n ],\n globalComponents: [\n join(staticPath, 'global-components', 'Container.tsx'),\n ],\n },\n globalUIComponents,\n globalStyles: join(staticPath, 'global-styles', `${previewMode}.css`),\n };\n}\n\nexport type { Options };\n","import { join, isAbsolute, dirname } from 'path';\nimport { visit } from 'unist-util-visit';\nimport { normalizePosixPath } from '@rspress/shared';\nimport fs from '@rspress/shared/fs-extra';\nimport type { Plugin } from 'unified';\nimport type { Root } from 'mdast';\nimport type { MdxjsEsm } from 'mdast-util-mdxjs-esm';\nimport type { RemarkPluginOptions } from './types';\nimport { injectDemoBlockImport, generateId } from './utils';\nimport { demoBlockComponentPath, virtualDir } from './constant';\nimport { demoRuntimeModule, demos } from './virtual-module';\n\n/**\n * remark plugin to transform code to demo\n */\nexport const remarkCodeToDemo: Plugin<[RemarkPluginOptions], Root> = ({\n getRouteMeta,\n previewMode,\n defaultRenderMode,\n position,\n}) => {\n const routeMeta = getRouteMeta();\n fs.ensureDirSync(virtualDir);\n return (tree, vfile) => {\n const demoMdx: MdxjsEsm[] = [];\n const route = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(vfile.path || vfile.history[0]),\n );\n if (!route) {\n return;\n }\n const { pageName } = route;\n // clear all demo in this pageName and recollect, bacause we may delete the demo\n demos[pageName] = [];\n let title = pageName;\n let index = 1;\n let externalDemoIndex = 0;\n\n function constructDemoNode(\n demoId: string,\n demoPath: string,\n currentNode: any,\n isMobileMode: boolean,\n // Only for external demo\n externalDemoIndex?: number,\n ) {\n if (isMobileMode) {\n demos[pageName].push({\n title,\n id: demoId,\n path: isAbsolute(demoPath)\n ? demoPath\n : join(vfile.dirname || dirname(vfile.path), demoPath),\n });\n } else {\n demoMdx.push(getASTNodeImport(`Demo${demoId}`, demoPath));\n }\n\n // get external demo content\n const tempVar = `externalDemoContent${externalDemoIndex}`;\n if (externalDemoIndex !== undefined) {\n // Such as `import externalDemoContent0 from '!!xxx?raw'`\n // `!!` prefix is used to avoid other loaders in rspack\n demoMdx.push(getASTNodeImport(tempVar, `!!${demoPath}?raw`));\n }\n\n if (isMobileMode && position === 'fixed') {\n // Only show the code block\n externalDemoIndex !== undefined &&\n Object.assign(currentNode, getExternalDemoContent(tempVar));\n } else {\n // Use container to show the code and view\n Object.assign(currentNode, {\n type: 'mdxJsxFlowElement',\n name: 'Container',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'isMobile',\n value: isMobileMode,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'demoId',\n value: demoId,\n },\n ],\n children: [\n externalDemoIndex === undefined\n ? {\n ...currentNode,\n hasVisited: true,\n }\n : getExternalDemoContent(tempVar),\n isMobileMode\n ? {\n type: 'mdxJsxFlowElement',\n name: null,\n }\n : {\n type: 'mdxJsxFlowElement',\n name: `Demo${demoId}`,\n },\n ],\n });\n }\n }\n visit(tree, 'heading', node => {\n if (node.depth === 1) {\n if (node.children) {\n title = (node.children[0] as any)?.value || title;\n }\n }\n });\n\n // 1. External demo , use <code src=\"xxx\" /> to declare demo\n visit(tree, 'mdxJsxFlowElement', (node: any) => {\n if (node.name === 'code') {\n const src = node.attributes.find(\n (attr: { name: string; value: string }) => attr.name === 'src',\n )?.value;\n if (!src) {\n return;\n }\n\n // don't support expression syntax\n const currtentMode =\n node.attributes.find(\n (attr: { name: string; value: boolean }) =>\n attr.name === 'previewMode',\n )?.value ?? previewMode;\n\n // TODO: remove isMobileAttribute\n let isMobileMode = node.attributes.find(\n (attr: { name: string; value: boolean }) => attr.name === 'isMobile',\n )?.value;\n if (isMobileMode === undefined) {\n // isMobile is not specified, eg: <code />\n isMobileMode = currtentMode === 'iframe';\n } else if (isMobileMode === null) {\n // true by default, eg: <code isMobile />\n isMobileMode = true;\n } else if (typeof isMobileMode === 'object') {\n // jsx value, isMobileMode.value now must be string, even if input is\n // any complex struct rather than primitive type\n // eg: <code isMobile={ anyOfOrOther([true, false, 'true', 'false', {}]) } />\n isMobileMode = isMobileMode.value !== 'false';\n } else {\n // string value, eg: <code isMobile=\"true\" />\n isMobileMode = isMobileMode !== 'false';\n }\n\n const id = generateId(pageName, index++);\n constructDemoNode(id, src, node, isMobileMode, externalDemoIndex++);\n }\n });\n\n // 2. Internal demo, use ```j/tsx to declare demo\n visit(tree, 'code', node => {\n // hasVisited is a custom property\n if ('hasVisited' in node) {\n return;\n }\n\n if (node.lang === 'jsx' || node.lang === 'tsx') {\n const value = injectDemoBlockImport(node.value, demoBlockComponentPath);\n\n // do not anything for pure mode\n if (\n node?.meta?.includes('pure') ||\n (!node?.meta?.includes('preview') && defaultRenderMode === 'pure')\n ) {\n return;\n }\n\n // every code block can change their preview mode by meta\n const isMobileMode =\n node?.meta?.includes('mobile') ||\n node?.meta?.includes('iframe') ||\n (!node?.meta?.includes('web') &&\n !node?.meta?.includes('internal') &&\n previewMode === 'iframe');\n\n const id = generateId(pageName, index++);\n const virtualModulePath = join(virtualDir, `${id}.tsx`);\n constructDemoNode(id, virtualModulePath, node, isMobileMode);\n // Only when the content of the file changes, the file will be written\n // Avoid to trigger the hmr indefinitely\n if (fs.existsSync(virtualModulePath)) {\n const content = fs.readFileSync(virtualModulePath, 'utf-8');\n if (content === value) {\n return;\n }\n }\n fs.writeFileSync(virtualModulePath, value);\n }\n });\n\n tree.children.unshift(...demoMdx);\n\n // maybe rewrite, but it is necessary\n const meta = `\n export const demos = ${JSON.stringify(demos)}\n `;\n demoRuntimeModule.writeModule('virtual-meta', meta);\n };\n};\n\nconst getASTNodeImport = (name: string, from: string) =>\n ({\n type: 'mdxjsEsm',\n value: `import ${name} from ${JSON.stringify(from)}`,\n data: {\n estree: {\n type: 'Program',\n sourceType: 'module',\n body: [\n {\n type: 'ImportDeclaration',\n specifiers: [\n {\n type: 'ImportDefaultSpecifier',\n local: { type: 'Identifier', name },\n },\n ],\n source: {\n type: 'Literal',\n value: from,\n raw: `${JSON.stringify(from)}`,\n },\n },\n ],\n },\n },\n } as MdxjsEsm);\n\nconst getExternalDemoContent = (tempVar: string) => ({\n /**\n * We create a empty parent node here. If we don't do this, the `pre` tag won't be rendered as our custom mdx component and will be rendered as a normal `pre` tag, which will cause the code block to be displayed incorrectly.\n */\n type: 'mdxJsxFlowElement',\n name: '',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'pre',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'code',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'className',\n value: 'language-tsx',\n },\n {\n type: 'mdxJsxAttribute',\n name: 'children',\n value: {\n type: 'mdxJsxExpressionAttribute',\n value: tempVar,\n data: {\n estree: {\n type: 'Program',\n body: [\n {\n type: 'ExpressionStatement',\n expression: {\n type: 'Identifier',\n name: tempVar,\n },\n },\n ],\n },\n },\n },\n },\n ],\n },\n ],\n },\n ],\n});\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n */\n\n/**\n * @typedef {Record<string, unknown>} Props\n * @typedef {null | undefined | string | Props | TestFunctionAnything | Array<string | Props | TestFunctionAnything>} Test\n * Check for an arbitrary node, unaware of TypeScript inferral.\n *\n * @callback TestFunctionAnything\n * Check if a node passes a test, unaware of TypeScript inferral.\n * @param {unknown} this\n * The given context.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean | void}\n * Whether this node passes the test.\n */\n\n/**\n * @template {Node} Kind\n * Node type.\n * @typedef {Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind> | Array<Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind>>} PredicateTest\n * Check for a node that can be inferred by TypeScript.\n */\n\n/**\n * Check if a node passes a certain test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback TestFunctionPredicate\n * Complex test function for a node that can be inferred by TypeScript.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this node passes the test.\n */\n\n/**\n * @callback AssertAnything\n * Check that an arbitrary value is a node, unaware of TypeScript inferral.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if a node is a node and passes a certain node test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback AssertPredicate\n * Check that an arbitrary value is a specific node, aware of TypeScript.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if `node` is a `Node` and whether it passes the given test.\n *\n * @param node\n * Thing to check, typically `Node`.\n * @param test\n * A check for a specific node.\n * @param index\n * The node’s position in its parent.\n * @param parent\n * The node’s parent.\n * @returns\n * Whether `node` is a node and passes a test.\n */\nexport const is =\n /**\n * @type {(\n * (() => false) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index: number, parent: Parent, context?: unknown) => node is Kind) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index?: null | undefined, parent?: null | undefined, context?: unknown) => node is Kind) &\n * ((node: unknown, test: Test, index: number, parent: Parent, context?: unknown) => boolean) &\n * ((node: unknown, test?: Test, index?: null | undefined, parent?: null | undefined, context?: unknown) => boolean)\n * )}\n */\n (\n /**\n * @param {unknown} [node]\n * @param {Test} [test]\n * @param {number | null | undefined} [index]\n * @param {Parent | null | undefined} [parent]\n * @param {unknown} [context]\n * @returns {boolean}\n */\n // eslint-disable-next-line max-params\n function is(node, test, index, parent, context) {\n const check = convert(test)\n\n if (\n index !== undefined &&\n index !== null &&\n (typeof index !== 'number' ||\n index < 0 ||\n index === Number.POSITIVE_INFINITY)\n ) {\n throw new Error('Expected positive finite index')\n }\n\n if (\n parent !== undefined &&\n parent !== null &&\n (!is(parent) || !parent.children)\n ) {\n throw new Error('Expected parent node')\n }\n\n if (\n (parent === undefined || parent === null) !==\n (index === undefined || index === null)\n ) {\n throw new Error('Expected both parent and index')\n }\n\n // @ts-expect-error Looks like a node.\n return node && node.type && typeof node.type === 'string'\n ? Boolean(check.call(context, node, index, parent))\n : false\n }\n )\n\n/**\n * Generate an assertion from a test.\n *\n * Useful if you’re going to test many nodes, for example when creating a\n * utility where something else passes a compatible test.\n *\n * The created function is a bit faster because it expects valid input only:\n * a `node`, `index`, and `parent`.\n *\n * @param test\n * * when nullish, checks if `node` is a `Node`.\n * * when `string`, works like passing `(node) => node.type === test`.\n * * when `function` checks if function passed the node is true.\n * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.\n * * when `array`, checks if any one of the subtests pass.\n * @returns\n * An assertion.\n */\nexport const convert =\n /**\n * @type {(\n * (<Kind extends Node>(test: PredicateTest<Kind>) => AssertPredicate<Kind>) &\n * ((test?: Test) => AssertAnything)\n * )}\n */\n (\n /**\n * @param {Test} [test]\n * @returns {AssertAnything}\n */\n function (test) {\n if (test === undefined || test === null) {\n return ok\n }\n\n if (typeof test === 'string') {\n return typeFactory(test)\n }\n\n if (typeof test === 'object') {\n return Array.isArray(test) ? anyFactory(test) : propsFactory(test)\n }\n\n if (typeof test === 'function') {\n return castFactory(test)\n }\n\n throw new Error('Expected function, string, or object as test')\n }\n )\n\n/**\n * @param {Array<string | Props | TestFunctionAnything>} tests\n * @returns {AssertAnything}\n */\nfunction anyFactory(tests) {\n /** @type {Array<AssertAnything>} */\n const checks = []\n let index = -1\n\n while (++index < tests.length) {\n checks[index] = convert(tests[index])\n }\n\n return castFactory(any)\n\n /**\n * @this {unknown}\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function any(...parameters) {\n let index = -1\n\n while (++index < checks.length) {\n if (checks[index].call(this, ...parameters)) return true\n }\n\n return false\n }\n}\n\n/**\n * Turn an object into a test for a node with a certain fields.\n *\n * @param {Props} check\n * @returns {AssertAnything}\n */\nfunction propsFactory(check) {\n return castFactory(all)\n\n /**\n * @param {Node} node\n * @returns {boolean}\n */\n function all(node) {\n /** @type {string} */\n let key\n\n for (key in check) {\n // @ts-expect-error: hush, it sure works as an index.\n if (node[key] !== check[key]) return false\n }\n\n return true\n }\n}\n\n/**\n * Turn a string into a test for a node with a certain type.\n *\n * @param {string} check\n * @returns {AssertAnything}\n */\nfunction typeFactory(check) {\n return castFactory(type)\n\n /**\n * @param {Node} node\n */\n function type(node) {\n return node && node.type === check\n }\n}\n\n/**\n * Turn a custom test into a test for a node that passes that test.\n *\n * @param {TestFunctionAnything} check\n * @returns {AssertAnything}\n */\nfunction castFactory(check) {\n return assertion\n\n /**\n * @this {unknown}\n * @param {unknown} node\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function assertion(node, ...parameters) {\n return Boolean(\n node &&\n typeof node === 'object' &&\n 'type' in node &&\n // @ts-expect-error: fine.\n Boolean(check.call(this, node, ...parameters))\n )\n }\n}\n\nfunction ok() {\n return true\n}\n","/**\n * @param {string} d\n * @returns {string}\n */\nexport function color(d) {\n return '\\u001B[33m' + d + '\\u001B[39m'\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n */\n\n/**\n * @typedef {boolean | 'skip'} Action\n * Union of the action types.\n *\n * @typedef {number} Index\n * Move to the sibling at `index` next (after node itself is completely\n * traversed).\n *\n * Useful if mutating the tree, such as removing the node the visitor is\n * currently on, or any of its previous siblings.\n * Results less than 0 or greater than or equal to `children.length` stop\n * traversing the parent.\n *\n * @typedef {[(Action | null | undefined | void)?, (Index | null | undefined)?]} ActionTuple\n * List with one or two values, the first an action, the second an index.\n *\n * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult\n * Any value that can be returned from a visitor.\n */\n\n/**\n * @template {Node} [Visited=Node]\n * Visited node type.\n * @template {Parent} [Ancestor=Parent]\n * Ancestor type.\n * @callback Visitor\n * Handle a node (matching `test`, if given).\n *\n * Visitors are free to transform `node`.\n * They can also transform the parent of node (the last of `ancestors`).\n *\n * Replacing `node` itself, if `SKIP` is not returned, still causes its\n * descendants to be walked (which is a bug).\n *\n * When adding or removing previous siblings of `node` (or next siblings, in\n * case of reverse), the `Visitor` should return a new `Index` to specify the\n * sibling to traverse after `node` is traversed.\n * Adding or removing next siblings of `node` (or previous siblings, in case\n * of reverse) is handled as expected without needing to return a new `Index`.\n *\n * Removing the children property of an ancestor still results in them being\n * traversed.\n * @param {Visited} node\n * Found node.\n * @param {Array<Ancestor>} ancestors\n * Ancestors of `node`.\n * @returns {VisitorResult}\n * What to do next.\n *\n * An `Index` is treated as a tuple of `[CONTINUE, Index]`.\n * An `Action` is treated as a tuple of `[Action]`.\n *\n * Passing a tuple back only makes sense if the `Action` is `SKIP`.\n * When the `Action` is `EXIT`, that action can be returned.\n * When the `Action` is `CONTINUE`, `Index` can be returned.\n */\n\n/**\n * @template {Node} [Tree=Node]\n * Tree type.\n * @template {Test} [Check=string]\n * Test type.\n * @typedef {Visitor<import('./complex-types.js').Matches<import('./complex-types.js').InclusiveDescendant<Tree>, Check>, Extract<import('./complex-types.js').InclusiveDescendant<Tree>, Parent>>} BuildVisitor\n * Build a typed `Visitor` function from a tree and a test.\n *\n * It will infer which values are passed as `node` and which as `parents`.\n */\n\nimport {convert} from 'unist-util-is'\nimport {color} from './color.js'\n\n/**\n * Continue traversing as normal.\n */\nexport const CONTINUE = true\n\n/**\n * Stop traversing immediately.\n */\nexport const EXIT = false\n\n/**\n * Do not traverse this node’s children.\n */\nexport const SKIP = 'skip'\n\n/**\n * Visit nodes, with ancestral information.\n *\n * This algorithm performs *depth-first* *tree traversal* in *preorder*\n * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).\n *\n * You can choose for which nodes `visitor` is called by passing a `test`.\n * For complex tests, you should test yourself in `visitor`, as it will be\n * faster and will have improved type information.\n *\n * Walking the tree is an intensive task.\n * Make use of the return values of the visitor when possible.\n * Instead of walking a tree multiple times, walk it once, use `unist-util-is`\n * to check if a node matches, and then perform different operations.\n *\n * You can change the tree.\n * See `Visitor` for more info.\n *\n * @param tree\n * Tree to traverse.\n * @param test\n * `unist-util-is`-compatible test\n * @param visitor\n * Handle each node.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).\n * @returns\n * Nothing.\n */\nexport const visitParents =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean | null | undefined) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean | null | undefined) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {Visitor<Node>} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {void}\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n // @ts-expect-error no visitor given, so `visitor` is test.\n visitor = test\n test = null\n }\n\n const is = convert(test)\n const step = reverse ? -1 : 1\n\n factory(tree, undefined, [])()\n\n /**\n * @param {Node} node\n * @param {number | undefined} index\n * @param {Array<Parent>} parents\n */\n function factory(node, index, parents) {\n /** @type {Record<string, unknown>} */\n // @ts-expect-error: hush\n const value = node && typeof node === 'object' ? node : {}\n\n if (typeof value.type === 'string') {\n const name =\n // `hast`\n typeof value.tagName === 'string'\n ? value.tagName\n : // `xast`\n typeof value.name === 'string'\n ? value.name\n : undefined\n\n Object.defineProperty(visit, 'name', {\n value:\n 'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'\n })\n }\n\n return visit\n\n function visit() {\n /** @type {ActionTuple} */\n let result = []\n /** @type {ActionTuple} */\n let subresult\n /** @type {number} */\n let offset\n /** @type {Array<Parent>} */\n let grandparents\n\n if (!test || is(node, index, parents[parents.length - 1] || null)) {\n result = toResult(visitor(node, parents))\n\n if (result[0] === EXIT) {\n return result\n }\n }\n\n // @ts-expect-error looks like a parent.\n if (node.children && result[0] !== SKIP) {\n // @ts-expect-error looks like a parent.\n offset = (reverse ? node.children.length : -1) + step\n // @ts-expect-error looks like a parent.\n grandparents = parents.concat(node)\n\n // @ts-expect-error looks like a parent.\n while (offset > -1 && offset < node.children.length) {\n // @ts-expect-error looks like a parent.\n subresult = factory(node.children[offset], offset, grandparents)()\n\n if (subresult[0] === EXIT) {\n return subresult\n }\n\n offset =\n typeof subresult[1] === 'number' ? subresult[1] : offset + step\n }\n }\n\n return result\n }\n }\n }\n )\n\n/**\n * Turn a return value into a clean result.\n *\n * @param {VisitorResult} value\n * Valid return values from visitors.\n * @returns {ActionTuple}\n * Clean result.\n */\nfunction toResult(value) {\n if (Array.isArray(value)) {\n return value\n }\n\n if (typeof value === 'number') {\n return [CONTINUE, value]\n }\n\n return [value]\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult\n * @typedef {import('./complex-types.js').Visitor} Visitor\n */\n\nimport {visitParents} from 'unist-util-visit-parents'\n\n/**\n * Visit children of tree which pass test.\n *\n * @param tree\n * Tree to walk\n * @param [test]\n * `unist-util-is`-compatible test\n * @param visitor\n * Function called for nodes that pass `test`.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).\n */\nexport const visit =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {import('./complex-types.js').Visitor} visitor\n * @param {boolean} [reverse]\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n visitor = test\n test = null\n }\n\n visitParents(tree, test, overload, reverse)\n\n /**\n * @param {Node} node\n * @param {Array<Parent>} parents\n */\n function overload(node, parents) {\n const parent = parents[parents.length - 1]\n return visitor(\n node,\n parent ? parent.children.indexOf(node) : null,\n parent\n )\n }\n }\n )\n\nexport {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'\n","/**\n * Converts a string to a valid variable name. If the string is already a valid variable name, returns the original string.\n * @param str - The string to convert.\n * @returns The converted string.\n */\nexport const toValidVarName = (str: string): string => {\n // Check if the string is a valid variable name\n if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(str)) {\n return str; // If it is a valid variable name, return the original string\n } else {\n // If it is not a valid variable name, convert it to a valid variable name\n return str.replace(/[^0-9a-zA-Z_$]/g, '_').replace(/^([0-9])/, '_$1');\n }\n};\n\nexport const generateId = (pageName: string, index: number) => {\n return `_${toValidVarName(pageName)}_${index}`;\n};\n\n/**\n * remove .html extension and validate\n * @param routePath id from pathname\n * @returns normalized id\n */\nexport const normalizeId = (routePath: string) => {\n const result = routePath.replace(/\\.(.*)?$/, '');\n return toValidVarName(result);\n};\n\nexport const injectDemoBlockImport = (str: string, path: string): string => {\n return `\n import DemoBlock from ${JSON.stringify(path)};\n ${str}\n `;\n};\n","import path from 'path';\nimport { RSPRESS_TEMP_DIR } from '@rspress/shared';\n\nexport const staticPath = path.join(__dirname, '..', 'static');\n\nexport const demoBlockComponentPath = path.join(\n staticPath,\n 'global-components',\n 'DemoBlock.tsx',\n);\n\nexport const virtualDir = path.join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n 'virtual-demo',\n);\n","import RspackVirtualModulePlugin from 'rspack-plugin-virtual-module';\nimport type { DemoInfo } from './types';\n\nexport const demos: DemoInfo = {};\n\nexport const demoRuntimeModule = new RspackVirtualModulePlugin({\n 'virtual-meta': 'export const demos = {}',\n});\n","import { join } from 'path';\nimport { writeFileSync } from 'fs';\nimport { virtualDir, staticPath } from './constant';\nimport type { DemoInfo } from './types';\nimport { toValidVarName } from './utils';\n\n// TODO: Support custom entry template files\nexport function generateEntry(\n demos: DemoInfo,\n framework: 'react' | 'solid',\n position: 'follow' | 'fixed',\n) {\n const sourceEntry: Record<string, string> = {};\n const entryCssPath = join(staticPath, 'global-styles', 'entry.css');\n if (position === 'follow') {\n Object.values(demos).forEach(routes => {\n routes.forEach(route => {\n const { id, path: demoPath } = route;\n const entry = join(virtualDir, `${id}.entry.tsx`);\n const solidEntry = `\n import { render } from 'solid-js/web';\n import ${JSON.stringify(entryCssPath)};\n import Demo from ${JSON.stringify(demoPath)};\n render(() => <Demo />, document.getElementById('root'));\n `;\n\n const reactEntry = `\n import { render } from 'react-dom';\n import ${JSON.stringify(entryCssPath)};\n import Demo from ${JSON.stringify(demoPath)};\n render(<Demo />, document.getElementById('root'));\n `;\n const entryContent = framework === 'react' ? reactEntry : solidEntry;\n writeFileSync(entry, entryContent);\n sourceEntry[id] = entry;\n });\n });\n } else {\n Object.entries(demos).forEach(([key, routes]) => {\n if (routes.length === 0) {\n return;\n }\n const reactContent = `\n import { render } from 'react-dom';\n import ${JSON.stringify(entryCssPath)};\n ${routes\n .map((demo, index) => {\n return `import Demo_${index} from ${JSON.stringify(demo.path)}`;\n })\n .join('\\n')}\n function App() {\n return (\n <div className=\"preview-container\">\n <div className=\"preview-nav\">{\"${routes[0].title}\"}</div>\n ${routes\n .map((demo, index) => {\n return `<Demo_${index} />`;\n })\n .join('\\n')}\n </div>\n )\n }\n render(<App /> , document.getElementById('root'));\n `;\n const solidContent = `\n import { render } from 'solid-js/web';\n import ${JSON.stringify(entryCssPath)};\n ${routes\n .map((demo, index) => {\n return `import Demo_${index} from ${JSON.stringify(demo.path)}`;\n })\n .join('\\n')}\n function App() {\n return (\n <div class=\"preview-container\">\n <div class=\"preview-nav\">{\"${routes[0].title}\"}</div>\n ${routes\n .map((_, index) => {\n return `<Demo_${index} />`;\n })\n .join('\\n')}\n </div>\n )\n }\n render(() => <App /> , document.getElementById('root'));\n `;\n const renderContent = framework === 'solid' ? solidContent : reactContent;\n const id = `_${toValidVarName(key)}`;\n const entry = join(virtualDir, `${id}.entry.tsx`);\n writeFileSync(entry, renderContent);\n sourceEntry[id] = entry;\n });\n }\n return sourceEntry;\n}\n"]}
1
+ {"version":3,"mappings":"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","names":["import_path","import_shared","index","is","visit","path","routeMeta","fs","externalDemoIndex","demos","resolve","net"],"sources":["../src/index.ts","../src/remarkPlugin.ts","../../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/lib/index.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/color.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/index.js","../../../node_modules/.pnpm/unist-util-visit@4.1.1/node_modules/unist-util-visit/index.js","../src/utils.ts","../src/constant.ts","../src/generate-entry.ts"],"sourcesContent":["import { join } from 'path';\nimport net from 'node:net';\nimport { type RouteMeta, type RspressPlugin, removeTrailingSlash } from '@rspress/shared';\nimport { type RsbuildConfig, createRsbuild, mergeRsbuildConfig } from '@rsbuild/core';\nimport { pluginSolid } from '@rsbuild/plugin-solid';\nimport { pluginBabel } from '@rsbuild/plugin-babel';\nimport { pluginReact } from '@rsbuild/plugin-react';\nimport { isEqual, cloneDeep } from 'lodash';\nimport { remarkCodeToDemo, demos } from './remarkPlugin';\nimport { staticPath } from './constant';\nimport type { Options, StartServerResult } from './types';\nimport { generateEntry } from './generate-entry';\n\n// global variables which need to be initialized in plugin\nlet routeMeta: RouteMeta[];\n\n/**\n * The plugin is used to preview component.\n */\nexport function pluginPreview(options?: Options): RspressPlugin {\n const {\n isMobile = false,\n iframeOptions = {},\n iframePosition = 'follow',\n defaultRenderMode = 'preview',\n } = options ?? {};\n const previewMode = options?.previewMode ?? isMobile ? 'iframe' : 'internal';\n const {\n devPort = 7890,\n framework = 'react',\n position = iframePosition,\n builderConfig = {},\n } = iframeOptions;\n const globalUIComponents =\n iframePosition === 'fixed'\n ? [join(staticPath, 'global-components', 'Device.tsx')]\n : [];\n const getRouteMeta = () => routeMeta;\n let lastDemos: typeof demos;\n let devServer: StartServerResult;\n let clientConfig: RsbuildConfig;\n const port = devPort;\n return {\n name: '@rspress/plugin-preview',\n config(config) {\n config.markdown = config.markdown || {};\n config.markdown.mdxRs = false;\n return config;\n },\n routeGenerated(routes: RouteMeta[]) {\n // init routeMeta\n routeMeta = routes;\n },\n async beforeBuild(_, isProd) {\n if (!isProd) {\n try {\n await new Promise((resolve, reject) => {\n const server = net.createServer();\n server.unref();\n server.on('error', reject);\n server.listen({ port, host: '0.0.0.0' }, () => {\n server.close(resolve);\n });\n });\n } catch (e: any) {\n if (e.code !== 'EADDRINUSE') {\n throw e;\n } else {\n throw new Error(\n `Port \"${port}\" is occupied, please choose another one.`,\n );\n }\n }\n }\n },\n async afterBuild(config, isProd) {\n if (isEqual(demos, lastDemos)) {\n return;\n }\n lastDemos = cloneDeep(demos);\n await devServer?.server?.close();\n const sourceEntry = generateEntry(demos, framework, position);\n const outDir = join(config.outDir ?? 'doc_build', '~demo');\n if (Object.keys(sourceEntry).length === 0) {\n return;\n }\n const { html, source, output, performance } = clientConfig ?? {};\n const rsbuildConfig = mergeRsbuildConfig(\n {\n dev: {\n progressBar: false,\n },\n server: {\n port: devPort,\n printUrls: () => undefined,\n strictPort: true,\n },\n performance: {\n ...performance,\n printFileSize: false,\n },\n html,\n source: {\n ...source,\n entry: sourceEntry,\n },\n output: {\n ...output,\n assetPrefix: output?.assetPrefix ? `${removeTrailingSlash(output.assetPrefix)}/~demo` : '/~demo',\n distPath: {\n root: outDir,\n },\n // not copy files again\n copy: undefined,\n },\n },\n builderConfig,\n );\n const rsbuildInstance = await createRsbuild({\n rsbuildConfig,\n });\n if (framework === 'solid') {\n rsbuildInstance.addPlugins([\n pluginBabel({\n include: /\\.(?:jsx|tsx)$/,\n }),\n pluginSolid(),\n ]);\n }\n if (framework === 'react') {\n rsbuildInstance.addPlugins([pluginReact()]);\n }\n if (isProd) {\n rsbuildInstance.build();\n } else {\n devServer = await rsbuildInstance.startDevServer();\n }\n },\n builderConfig: {\n source: {\n include: [join(__dirname, '..')],\n },\n tools: {\n bundlerChain(chain) {\n chain.module\n .rule('Raw')\n .resourceQuery(/raw/)\n .type('asset/source')\n .end();\n\n chain.resolve.extensions.prepend('.md').prepend('.mdx');\n },\n },\n plugins: [\n {\n name: 'close-demo-server',\n setup: api => {\n api.modifyRsbuildConfig(config => {\n if (config.output?.targets?.every(target => target ==='web')) {\n // client build config\n clientConfig = config;\n }\n })\n api.onCloseDevServer(async () => {\n await devServer?.server?.close();\n });\n },\n },\n ],\n },\n extendPageData(pageData, isProd) {\n if (!isProd) {\n pageData.devPort = port;\n }\n },\n markdown: {\n remarkPlugins: [\n [\n remarkCodeToDemo,\n {\n getRouteMeta,\n position,\n previewMode,\n defaultRenderMode,\n },\n ],\n ],\n globalComponents: [\n join(staticPath, 'global-components', 'Container.tsx'),\n ],\n },\n globalUIComponents,\n globalStyles: join(staticPath, 'global-styles', `${previewMode}.css`),\n };\n}\n\nexport type { Options };\n","import { join, resolve, dirname } from 'path';\nimport { visit } from 'unist-util-visit';\nimport { normalizePosixPath } from '@rspress/shared';\nimport fs from '@rspress/shared/fs-extra';\nimport type { Plugin } from 'unified';\nimport type { Root } from 'mdast';\nimport type { MdxjsEsm } from 'mdast-util-mdxjs-esm';\nimport type { RemarkPluginOptions, DemoInfo } from './types';\nimport { injectDemoBlockImport, generateId } from './utils';\nimport { demoBlockComponentPath, virtualDir } from './constant';\n\nexport const demos: DemoInfo = {};\n\n/**\n * remark plugin to transform code to demo\n */\nexport const remarkCodeToDemo: Plugin<[RemarkPluginOptions], Root> = function ({\n getRouteMeta,\n previewMode,\n defaultRenderMode,\n position,\n}) {\n const routeMeta = getRouteMeta();\n fs.ensureDirSync(virtualDir);\n const data = this.data() as {\n pageMeta: Record<string, any>;\n };\n return (tree, vfile) => {\n const demoMdx: MdxjsEsm[] = [];\n const route = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(vfile.path || vfile.history[0]),\n );\n if (!route) {\n return;\n }\n const { pageName } = route;\n // clear all demo in this pageName and recollect, bacause we may delete the demo\n demos[pageName] = [];\n let title = pageName;\n let index = 1;\n let externalDemoIndex = 0;\n\n function constructDemoNode(\n demoId: string,\n demoPath: string,\n currentNode: any,\n isMobileMode: boolean,\n // Only for external demo\n externalDemoIndex?: number,\n ) {\n if (isMobileMode) {\n const relativePathReg = new RegExp(/^\\.\\.?\\/.*$/);\n demos[pageName].push({\n title,\n id: demoId,\n path: relativePathReg.test(demoPath)\n ? resolve(vfile.dirname || dirname(vfile.path), demoPath)\n : demoPath,\n });\n } else {\n demoMdx.push(getASTNodeImport(`Demo${demoId}`, demoPath));\n }\n\n // get external demo content\n const tempVar = `externalDemoContent${externalDemoIndex}`;\n if (externalDemoIndex !== undefined) {\n // Such as `import externalDemoContent0 from '!!xxx?raw'`\n // `!!` prefix is used to avoid other loaders in rspack\n demoMdx.push(getASTNodeImport(tempVar, `!!${demoPath}?raw`));\n }\n\n if (isMobileMode && position === 'fixed') {\n // Only show the code block\n externalDemoIndex !== undefined &&\n Object.assign(currentNode, getExternalDemoContent(tempVar));\n } else {\n // Use container to show the code and view\n Object.assign(currentNode, {\n type: 'mdxJsxFlowElement',\n name: 'Container',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'isMobile',\n value: isMobileMode,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'demoId',\n value: demoId,\n },\n ],\n children: [\n externalDemoIndex === undefined\n ? {\n ...currentNode,\n hasVisited: true,\n }\n : getExternalDemoContent(tempVar),\n isMobileMode\n ? {\n type: 'mdxJsxFlowElement',\n name: null,\n }\n : {\n type: 'mdxJsxFlowElement',\n name: `Demo${demoId}`,\n },\n ],\n });\n }\n }\n visit(tree, 'heading', node => {\n if (node.depth === 1) {\n if (node.children) {\n title = (node.children[0] as any)?.value || title;\n }\n }\n });\n\n // 1. External demo , use <code src=\"xxx\" /> to declare demo\n visit(tree, 'mdxJsxFlowElement', (node: any) => {\n if (node.name === 'code') {\n const src = node.attributes.find(\n (attr: { name: string; value: string }) => attr.name === 'src',\n )?.value;\n if (!src) {\n return;\n }\n\n // don't support expression syntax\n const currtentMode =\n node.attributes.find(\n (attr: { name: string; value: boolean }) =>\n attr.name === 'previewMode',\n )?.value ?? previewMode;\n\n // TODO: remove isMobileAttribute\n let isMobileMode = node.attributes.find(\n (attr: { name: string; value: boolean }) => attr.name === 'isMobile',\n )?.value;\n if (isMobileMode === undefined) {\n // isMobile is not specified, eg: <code />\n isMobileMode = currtentMode === 'iframe';\n } else if (isMobileMode === null) {\n // true by default, eg: <code isMobile />\n isMobileMode = true;\n } else if (typeof isMobileMode === 'object') {\n // jsx value, isMobileMode.value now must be string, even if input is\n // any complex struct rather than primitive type\n // eg: <code isMobile={ anyOfOrOther([true, false, 'true', 'false', {}]) } />\n isMobileMode = isMobileMode.value !== 'false';\n } else {\n // string value, eg: <code isMobile=\"true\" />\n isMobileMode = isMobileMode !== 'false';\n }\n\n const id = generateId(pageName, index++);\n constructDemoNode(id, src, node, isMobileMode, externalDemoIndex++);\n }\n });\n\n // 2. Internal demo, use ```j/tsx to declare demo\n visit(tree, 'code', node => {\n // hasVisited is a custom property\n if ('hasVisited' in node) {\n return;\n }\n\n if (node.lang === 'jsx' || node.lang === 'tsx') {\n const value = injectDemoBlockImport(node.value, demoBlockComponentPath);\n\n // do not anything for pure mode\n if (\n node?.meta?.includes('pure') ||\n (!node?.meta?.includes('preview') && defaultRenderMode === 'pure')\n ) {\n return;\n }\n\n // every code block can change their preview mode by meta\n const isMobileMode =\n node?.meta?.includes('mobile') ||\n node?.meta?.includes('iframe') ||\n (!node?.meta?.includes('web') &&\n !node?.meta?.includes('internal') &&\n previewMode === 'iframe');\n\n const id = generateId(pageName, index++);\n const virtualModulePath = join(virtualDir, `${id}.tsx`);\n constructDemoNode(id, virtualModulePath, node, isMobileMode);\n // Only when the content of the file changes, the file will be written\n // Avoid to trigger the hmr indefinitely\n if (fs.existsSync(virtualModulePath)) {\n const content = fs.readFileSync(virtualModulePath, 'utf-8');\n if (content === value) {\n return;\n }\n }\n fs.writeFileSync(virtualModulePath, value);\n }\n });\n\n tree.children.unshift(...demoMdx);\n\n if (demos[pageName].length > 0) {\n data.pageMeta.haveDemos = true;\n }\n };\n};\n\nconst getASTNodeImport = (name: string, from: string) =>\n ({\n type: 'mdxjsEsm',\n value: `import ${name} from ${JSON.stringify(from)}`,\n data: {\n estree: {\n type: 'Program',\n sourceType: 'module',\n body: [\n {\n type: 'ImportDeclaration',\n specifiers: [\n {\n type: 'ImportDefaultSpecifier',\n local: { type: 'Identifier', name },\n },\n ],\n source: {\n type: 'Literal',\n value: from,\n raw: `${JSON.stringify(from)}`,\n },\n },\n ],\n },\n },\n }) as MdxjsEsm;\n\nconst getExternalDemoContent = (tempVar: string) => ({\n /**\n * We create a empty parent node here. If we don't do this, the `pre` tag won't be rendered as our custom mdx component and will be rendered as a normal `pre` tag, which will cause the code block to be displayed incorrectly.\n */\n type: 'mdxJsxFlowElement',\n name: '',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'pre',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'code',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'className',\n value: 'language-tsx',\n },\n {\n type: 'mdxJsxAttribute',\n name: 'children',\n value: {\n type: 'mdxJsxExpressionAttribute',\n value: tempVar,\n data: {\n estree: {\n type: 'Program',\n body: [\n {\n type: 'ExpressionStatement',\n expression: {\n type: 'Identifier',\n name: tempVar,\n },\n },\n ],\n },\n },\n },\n },\n ],\n },\n ],\n },\n ],\n});\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n */\n\n/**\n * @typedef {Record<string, unknown>} Props\n * @typedef {null | undefined | string | Props | TestFunctionAnything | Array<string | Props | TestFunctionAnything>} Test\n * Check for an arbitrary node, unaware of TypeScript inferral.\n *\n * @callback TestFunctionAnything\n * Check if a node passes a test, unaware of TypeScript inferral.\n * @param {unknown} this\n * The given context.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean | void}\n * Whether this node passes the test.\n */\n\n/**\n * @template {Node} Kind\n * Node type.\n * @typedef {Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind> | Array<Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind>>} PredicateTest\n * Check for a node that can be inferred by TypeScript.\n */\n\n/**\n * Check if a node passes a certain test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback TestFunctionPredicate\n * Complex test function for a node that can be inferred by TypeScript.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this node passes the test.\n */\n\n/**\n * @callback AssertAnything\n * Check that an arbitrary value is a node, unaware of TypeScript inferral.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if a node is a node and passes a certain node test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback AssertPredicate\n * Check that an arbitrary value is a specific node, aware of TypeScript.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if `node` is a `Node` and whether it passes the given test.\n *\n * @param node\n * Thing to check, typically `Node`.\n * @param test\n * A check for a specific node.\n * @param index\n * The node’s position in its parent.\n * @param parent\n * The node’s parent.\n * @returns\n * Whether `node` is a node and passes a test.\n */\nexport const is =\n /**\n * @type {(\n * (() => false) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index: number, parent: Parent, context?: unknown) => node is Kind) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index?: null | undefined, parent?: null | undefined, context?: unknown) => node is Kind) &\n * ((node: unknown, test: Test, index: number, parent: Parent, context?: unknown) => boolean) &\n * ((node: unknown, test?: Test, index?: null | undefined, parent?: null | undefined, context?: unknown) => boolean)\n * )}\n */\n (\n /**\n * @param {unknown} [node]\n * @param {Test} [test]\n * @param {number | null | undefined} [index]\n * @param {Parent | null | undefined} [parent]\n * @param {unknown} [context]\n * @returns {boolean}\n */\n // eslint-disable-next-line max-params\n function is(node, test, index, parent, context) {\n const check = convert(test)\n\n if (\n index !== undefined &&\n index !== null &&\n (typeof index !== 'number' ||\n index < 0 ||\n index === Number.POSITIVE_INFINITY)\n ) {\n throw new Error('Expected positive finite index')\n }\n\n if (\n parent !== undefined &&\n parent !== null &&\n (!is(parent) || !parent.children)\n ) {\n throw new Error('Expected parent node')\n }\n\n if (\n (parent === undefined || parent === null) !==\n (index === undefined || index === null)\n ) {\n throw new Error('Expected both parent and index')\n }\n\n // @ts-expect-error Looks like a node.\n return node && node.type && typeof node.type === 'string'\n ? Boolean(check.call(context, node, index, parent))\n : false\n }\n )\n\n/**\n * Generate an assertion from a test.\n *\n * Useful if you’re going to test many nodes, for example when creating a\n * utility where something else passes a compatible test.\n *\n * The created function is a bit faster because it expects valid input only:\n * a `node`, `index`, and `parent`.\n *\n * @param test\n * * when nullish, checks if `node` is a `Node`.\n * * when `string`, works like passing `(node) => node.type === test`.\n * * when `function` checks if function passed the node is true.\n * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.\n * * when `array`, checks if any one of the subtests pass.\n * @returns\n * An assertion.\n */\nexport const convert =\n /**\n * @type {(\n * (<Kind extends Node>(test: PredicateTest<Kind>) => AssertPredicate<Kind>) &\n * ((test?: Test) => AssertAnything)\n * )}\n */\n (\n /**\n * @param {Test} [test]\n * @returns {AssertAnything}\n */\n function (test) {\n if (test === undefined || test === null) {\n return ok\n }\n\n if (typeof test === 'string') {\n return typeFactory(test)\n }\n\n if (typeof test === 'object') {\n return Array.isArray(test) ? anyFactory(test) : propsFactory(test)\n }\n\n if (typeof test === 'function') {\n return castFactory(test)\n }\n\n throw new Error('Expected function, string, or object as test')\n }\n )\n\n/**\n * @param {Array<string | Props | TestFunctionAnything>} tests\n * @returns {AssertAnything}\n */\nfunction anyFactory(tests) {\n /** @type {Array<AssertAnything>} */\n const checks = []\n let index = -1\n\n while (++index < tests.length) {\n checks[index] = convert(tests[index])\n }\n\n return castFactory(any)\n\n /**\n * @this {unknown}\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function any(...parameters) {\n let index = -1\n\n while (++index < checks.length) {\n if (checks[index].call(this, ...parameters)) return true\n }\n\n return false\n }\n}\n\n/**\n * Turn an object into a test for a node with a certain fields.\n *\n * @param {Props} check\n * @returns {AssertAnything}\n */\nfunction propsFactory(check) {\n return castFactory(all)\n\n /**\n * @param {Node} node\n * @returns {boolean}\n */\n function all(node) {\n /** @type {string} */\n let key\n\n for (key in check) {\n // @ts-expect-error: hush, it sure works as an index.\n if (node[key] !== check[key]) return false\n }\n\n return true\n }\n}\n\n/**\n * Turn a string into a test for a node with a certain type.\n *\n * @param {string} check\n * @returns {AssertAnything}\n */\nfunction typeFactory(check) {\n return castFactory(type)\n\n /**\n * @param {Node} node\n */\n function type(node) {\n return node && node.type === check\n }\n}\n\n/**\n * Turn a custom test into a test for a node that passes that test.\n *\n * @param {TestFunctionAnything} check\n * @returns {AssertAnything}\n */\nfunction castFactory(check) {\n return assertion\n\n /**\n * @this {unknown}\n * @param {unknown} node\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function assertion(node, ...parameters) {\n return Boolean(\n node &&\n typeof node === 'object' &&\n 'type' in node &&\n // @ts-expect-error: fine.\n Boolean(check.call(this, node, ...parameters))\n )\n }\n}\n\nfunction ok() {\n return true\n}\n","/**\n * @param {string} d\n * @returns {string}\n */\nexport function color(d) {\n return '\\u001B[33m' + d + '\\u001B[39m'\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n */\n\n/**\n * @typedef {boolean | 'skip'} Action\n * Union of the action types.\n *\n * @typedef {number} Index\n * Move to the sibling at `index` next (after node itself is completely\n * traversed).\n *\n * Useful if mutating the tree, such as removing the node the visitor is\n * currently on, or any of its previous siblings.\n * Results less than 0 or greater than or equal to `children.length` stop\n * traversing the parent.\n *\n * @typedef {[(Action | null | undefined | void)?, (Index | null | undefined)?]} ActionTuple\n * List with one or two values, the first an action, the second an index.\n *\n * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult\n * Any value that can be returned from a visitor.\n */\n\n/**\n * @template {Node} [Visited=Node]\n * Visited node type.\n * @template {Parent} [Ancestor=Parent]\n * Ancestor type.\n * @callback Visitor\n * Handle a node (matching `test`, if given).\n *\n * Visitors are free to transform `node`.\n * They can also transform the parent of node (the last of `ancestors`).\n *\n * Replacing `node` itself, if `SKIP` is not returned, still causes its\n * descendants to be walked (which is a bug).\n *\n * When adding or removing previous siblings of `node` (or next siblings, in\n * case of reverse), the `Visitor` should return a new `Index` to specify the\n * sibling to traverse after `node` is traversed.\n * Adding or removing next siblings of `node` (or previous siblings, in case\n * of reverse) is handled as expected without needing to return a new `Index`.\n *\n * Removing the children property of an ancestor still results in them being\n * traversed.\n * @param {Visited} node\n * Found node.\n * @param {Array<Ancestor>} ancestors\n * Ancestors of `node`.\n * @returns {VisitorResult}\n * What to do next.\n *\n * An `Index` is treated as a tuple of `[CONTINUE, Index]`.\n * An `Action` is treated as a tuple of `[Action]`.\n *\n * Passing a tuple back only makes sense if the `Action` is `SKIP`.\n * When the `Action` is `EXIT`, that action can be returned.\n * When the `Action` is `CONTINUE`, `Index` can be returned.\n */\n\n/**\n * @template {Node} [Tree=Node]\n * Tree type.\n * @template {Test} [Check=string]\n * Test type.\n * @typedef {Visitor<import('./complex-types.js').Matches<import('./complex-types.js').InclusiveDescendant<Tree>, Check>, Extract<import('./complex-types.js').InclusiveDescendant<Tree>, Parent>>} BuildVisitor\n * Build a typed `Visitor` function from a tree and a test.\n *\n * It will infer which values are passed as `node` and which as `parents`.\n */\n\nimport {convert} from 'unist-util-is'\nimport {color} from './color.js'\n\n/**\n * Continue traversing as normal.\n */\nexport const CONTINUE = true\n\n/**\n * Stop traversing immediately.\n */\nexport const EXIT = false\n\n/**\n * Do not traverse this node’s children.\n */\nexport const SKIP = 'skip'\n\n/**\n * Visit nodes, with ancestral information.\n *\n * This algorithm performs *depth-first* *tree traversal* in *preorder*\n * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).\n *\n * You can choose for which nodes `visitor` is called by passing a `test`.\n * For complex tests, you should test yourself in `visitor`, as it will be\n * faster and will have improved type information.\n *\n * Walking the tree is an intensive task.\n * Make use of the return values of the visitor when possible.\n * Instead of walking a tree multiple times, walk it once, use `unist-util-is`\n * to check if a node matches, and then perform different operations.\n *\n * You can change the tree.\n * See `Visitor` for more info.\n *\n * @param tree\n * Tree to traverse.\n * @param test\n * `unist-util-is`-compatible test\n * @param visitor\n * Handle each node.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).\n * @returns\n * Nothing.\n */\nexport const visitParents =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean | null | undefined) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean | null | undefined) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {Visitor<Node>} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {void}\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n // @ts-expect-error no visitor given, so `visitor` is test.\n visitor = test\n test = null\n }\n\n const is = convert(test)\n const step = reverse ? -1 : 1\n\n factory(tree, undefined, [])()\n\n /**\n * @param {Node} node\n * @param {number | undefined} index\n * @param {Array<Parent>} parents\n */\n function factory(node, index, parents) {\n /** @type {Record<string, unknown>} */\n // @ts-expect-error: hush\n const value = node && typeof node === 'object' ? node : {}\n\n if (typeof value.type === 'string') {\n const name =\n // `hast`\n typeof value.tagName === 'string'\n ? value.tagName\n : // `xast`\n typeof value.name === 'string'\n ? value.name\n : undefined\n\n Object.defineProperty(visit, 'name', {\n value:\n 'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'\n })\n }\n\n return visit\n\n function visit() {\n /** @type {ActionTuple} */\n let result = []\n /** @type {ActionTuple} */\n let subresult\n /** @type {number} */\n let offset\n /** @type {Array<Parent>} */\n let grandparents\n\n if (!test || is(node, index, parents[parents.length - 1] || null)) {\n result = toResult(visitor(node, parents))\n\n if (result[0] === EXIT) {\n return result\n }\n }\n\n // @ts-expect-error looks like a parent.\n if (node.children && result[0] !== SKIP) {\n // @ts-expect-error looks like a parent.\n offset = (reverse ? node.children.length : -1) + step\n // @ts-expect-error looks like a parent.\n grandparents = parents.concat(node)\n\n // @ts-expect-error looks like a parent.\n while (offset > -1 && offset < node.children.length) {\n // @ts-expect-error looks like a parent.\n subresult = factory(node.children[offset], offset, grandparents)()\n\n if (subresult[0] === EXIT) {\n return subresult\n }\n\n offset =\n typeof subresult[1] === 'number' ? subresult[1] : offset + step\n }\n }\n\n return result\n }\n }\n }\n )\n\n/**\n * Turn a return value into a clean result.\n *\n * @param {VisitorResult} value\n * Valid return values from visitors.\n * @returns {ActionTuple}\n * Clean result.\n */\nfunction toResult(value) {\n if (Array.isArray(value)) {\n return value\n }\n\n if (typeof value === 'number') {\n return [CONTINUE, value]\n }\n\n return [value]\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult\n * @typedef {import('./complex-types.js').Visitor} Visitor\n */\n\nimport {visitParents} from 'unist-util-visit-parents'\n\n/**\n * Visit children of tree which pass test.\n *\n * @param tree\n * Tree to walk\n * @param [test]\n * `unist-util-is`-compatible test\n * @param visitor\n * Function called for nodes that pass `test`.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).\n */\nexport const visit =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {import('./complex-types.js').Visitor} visitor\n * @param {boolean} [reverse]\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n visitor = test\n test = null\n }\n\n visitParents(tree, test, overload, reverse)\n\n /**\n * @param {Node} node\n * @param {Array<Parent>} parents\n */\n function overload(node, parents) {\n const parent = parents[parents.length - 1]\n return visitor(\n node,\n parent ? parent.children.indexOf(node) : null,\n parent\n )\n }\n }\n )\n\nexport {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'\n","/**\n * Converts a string to a valid variable name. If the string is already a valid variable name, returns the original string.\n * @param str - The string to convert.\n * @returns The converted string.\n */\nexport const toValidVarName = (str: string): string => {\n // Check if the string is a valid variable name\n if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(str)) {\n return str; // If it is a valid variable name, return the original string\n } else {\n // If it is not a valid variable name, convert it to a valid variable name\n return str.replace(/[^0-9a-zA-Z_$]/g, '_').replace(/^([0-9])/, '_$1');\n }\n};\n\nexport const generateId = (pageName: string, index: number) => {\n return `_${toValidVarName(pageName)}_${index}`;\n};\n\n/**\n * remove .html extension and validate\n * @param routePath id from pathname\n * @returns normalized id\n */\nexport const normalizeId = (routePath: string) => {\n const result = routePath.replace(/\\.(.*)?$/, '');\n return toValidVarName(result);\n};\n\nexport const injectDemoBlockImport = (str: string, path: string): string => {\n return `\n import DemoBlock from ${JSON.stringify(path)};\n ${str}\n `;\n};\n","import path from 'path';\nimport { RSPRESS_TEMP_DIR } from '@rspress/shared';\n\nexport const staticPath = path.join(__dirname, '..', 'static');\n\nexport const demoBlockComponentPath = path.join(\n staticPath,\n 'global-components',\n 'DemoBlock.tsx',\n);\n\nexport const virtualDir = path.join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n 'virtual-demo',\n);\n","import { join } from 'path';\nimport { writeFileSync } from 'fs';\nimport { virtualDir, staticPath } from './constant';\nimport type { DemoInfo } from './types';\nimport { toValidVarName } from './utils';\n\n// TODO: Support custom entry template files\nexport function generateEntry(\n demos: DemoInfo,\n framework: 'react' | 'solid',\n position: 'follow' | 'fixed',\n) {\n const sourceEntry: Record<string, string> = {};\n const entryCssPath = join(staticPath, 'global-styles', 'entry.css');\n if (position === 'follow') {\n Object.values(demos).forEach(routes => {\n routes.forEach(route => {\n const { id, path: demoPath } = route;\n const entry = join(virtualDir, `${id}.entry.tsx`);\n const solidEntry = `\n import { render } from 'solid-js/web';\n import ${JSON.stringify(entryCssPath)};\n import Demo from ${JSON.stringify(demoPath)};\n render(() => <Demo />, document.getElementById('root'));\n `;\n\n const reactEntry = `\n import { render } from 'react-dom';\n import ${JSON.stringify(entryCssPath)};\n import Demo from ${JSON.stringify(demoPath)};\n render(<Demo />, document.getElementById('root'));\n `;\n const entryContent = framework === 'react' ? reactEntry : solidEntry;\n writeFileSync(entry, entryContent);\n sourceEntry[id] = entry;\n });\n });\n } else {\n Object.entries(demos).forEach(([key, routes]) => {\n if (routes.length === 0) {\n return;\n }\n const reactContent = `\n import { render } from 'react-dom';\n import ${JSON.stringify(entryCssPath)};\n ${routes\n .map((demo, index) => {\n return `import Demo_${index} from ${JSON.stringify(demo.path)}`;\n })\n .join('\\n')}\n function App() {\n return (\n <div className=\"preview-container\">\n <div className=\"preview-nav\">{\"${routes[0].title}\"}</div>\n ${routes\n .map((demo, index) => {\n return `<Demo_${index} />`;\n })\n .join('\\n')}\n </div>\n )\n }\n render(<App /> , document.getElementById('root'));\n `;\n const solidContent = `\n import { render } from 'solid-js/web';\n import ${JSON.stringify(entryCssPath)};\n ${routes\n .map((demo, index) => {\n return `import Demo_${index} from ${JSON.stringify(demo.path)}`;\n })\n .join('\\n')}\n function App() {\n return (\n <div class=\"preview-container\">\n <div class=\"preview-nav\">{\"${routes[0].title}\"}</div>\n ${routes\n .map((_, index) => {\n return `<Demo_${index} />`;\n })\n .join('\\n')}\n </div>\n )\n }\n render(() => <App /> , document.getElementById('root'));\n `;\n const renderContent = framework === 'solid' ? solidContent : reactContent;\n const id = `_${toValidVarName(key)}`;\n const entry = join(virtualDir, `${id}.entry.tsx`);\n writeFileSync(entry, renderContent);\n sourceEntry[id] = entry;\n });\n }\n return sourceEntry;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/plugin-preview",
3
- "version": "1.13.1",
3
+ "version": "1.14.0",
4
4
  "description": "A plugin for rspress to preview the code block in markdown/mdx file.",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -15,22 +15,18 @@
15
15
  "engines": {
16
16
  "node": ">=14.17.6"
17
17
  },
18
- "eslintIgnore": [
19
- "node_modules/",
20
- "dist/"
21
- ],
22
18
  "dependencies": {
23
19
  "@mdx-js/mdx": "2.2.1",
24
- "@rsbuild/core": "0.4.0",
25
- "@rsbuild/plugin-solid": "0.4.0",
26
- "@rsbuild/plugin-babel": "0.4.0",
27
- "@rsbuild/plugin-react": "0.4.0",
20
+ "@rsbuild/core": "0.4.11",
21
+ "@rsbuild/plugin-solid": "0.4.11",
22
+ "@rsbuild/plugin-babel": "0.4.11",
23
+ "@rsbuild/plugin-react": "0.4.11",
28
24
  "get-port": "6.1.2",
29
25
  "qrcode.react": "^3.1.0",
30
26
  "remark-gfm": "3.0.1",
31
- "rspack-plugin-virtual-module": "0.1.12",
32
27
  "lodash": "4.17.21",
33
- "@rspress/shared": "1.13.1"
28
+ "@rspress/shared": "1.14.0",
29
+ "@rspress/theme-default": "1.14.0"
34
30
  },
35
31
  "devDependencies": {
36
32
  "@types/mdast": "^3.0.10",
@@ -39,7 +35,6 @@
39
35
  "@types/react": "^18",
40
36
  "@types/react-dom": "^18",
41
37
  "mdast-util-mdxjs-esm": "^1.3.0",
42
- "@biomejs/biome": "1.5.2",
43
38
  "react": "^18",
44
39
  "react-dom": "^18",
45
40
  "react-router-dom": "^6.8.1",
@@ -1,6 +1,5 @@
1
- import { usePageData, withBase } from '@rspress/core/runtime';
2
- import { useCallback, useEffect, useState } from 'react';
3
- import { demos } from 'virtual-meta';
1
+ import { usePageData, withBase, NoSSR } from '@rspress/core/runtime';
2
+ import { useCallback, useEffect, useState, useMemo } from 'react';
4
3
  import { normalizeId } from '../../dist/utils';
5
4
  import MobileOperation from './common/mobile-operation';
6
5
  import './Device.scss';
@@ -10,7 +9,7 @@ export default () => {
10
9
  const pageName = `${normalizeId(page.pagePath)}`;
11
10
  const demoId = `_${pageName}`;
12
11
  const url = `~demo/${demoId}`;
13
- const haveDemos = demos[pageName]?.length > 0;
12
+ const { haveDemos } = page;
14
13
 
15
14
  const getPageUrl = (url: string) => {
16
15
  if (page?.devPort) {
@@ -75,11 +74,14 @@ export default () => {
75
74
 
76
75
  return haveDemos ? (
77
76
  <div className="fixed-device">
78
- <iframe
79
- src={getPageUrl(url)}
80
- className="fixed-iframe"
81
- key={iframeKey}
82
- ></iframe>
77
+ <NoSSR>
78
+ <iframe
79
+ // refresh when load the iframe, then remove NoSSR
80
+ src={getPageUrl(url)}
81
+ className="fixed-iframe"
82
+ key={iframeKey}
83
+ ></iframe>
84
+ </NoSSR>
83
85
  <MobileOperation
84
86
  url={getPageUrl(url)}
85
87
  className="fixed-operation"
@@ -1,4 +1,4 @@
1
- @import url(@rspress/core/theme.css);
1
+ @import url(@rspress/theme-default/bundle.css);
2
2
 
3
3
  :root {
4
4
  --rp-iframe-bg: var(--rp-code-block-bg);