dumi 2.4.47 → 2.4.48-alpha.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.
@@ -53,6 +53,17 @@ var DUMI_DEMO_TAG = "DumiDemo";
53
53
  var DUMI_DEMO_GRID_TAG = "DumiDemoGrid";
54
54
  var SKIP_DEMO_PARSE = "pure";
55
55
  var ALWAYS_DEMO_PARSE = "demo";
56
+ function getStableContentHash(value) {
57
+ const serialized = JSON.stringify(value, (_key, nestedValue) => {
58
+ if (nestedValue && typeof nestedValue === "object" && !Array.isArray(nestedValue)) {
59
+ return Object.fromEntries(
60
+ Object.keys(nestedValue).sort().map((key) => [key, nestedValue[key]])
61
+ );
62
+ }
63
+ return nestedValue;
64
+ });
65
+ return (0, import_utils.getContentHash)(serialized);
66
+ }
56
67
  var skipDemoRE = new RegExp(
57
68
  /** 注意前面有空格 ==> */
58
69
  ` ${SKIP_DEMO_PARSE}`
@@ -259,99 +270,135 @@ function rehypeDemo(opts) {
259
270
  (0, import_block.default)({
260
271
  ...parseOpts,
261
272
  cacheable: opts.useUtoopackDemoHMR
262
- }).then(
263
- async ({ asset, resolveMap, frontmatter }) => {
264
- var _a2, _b2, _c2;
265
- if (demoIds.indexOf(parseOpts.id) !== demoIds.lastIndexOf(parseOpts.id)) {
266
- const startLine = (_a2 = node.position) == null ? void 0 : _a2.start.line;
267
- const suffix = startLine ? `:${startLine}` : "";
268
- import_plugin_utils.logger.warn(
269
- `Duplicate demo id found due to filename conflicts, please consider adding a unique id to code tag to resolve this.
273
+ }).then(async ({ asset, resolveMap, frontmatter }) => {
274
+ var _a2, _b2, _c2, _d;
275
+ if (demoIds.indexOf(parseOpts.id) !== demoIds.lastIndexOf(parseOpts.id)) {
276
+ const startLine = (_a2 = node.position) == null ? void 0 : _a2.start.line;
277
+ const suffix = startLine ? `:${startLine}` : "";
278
+ import_plugin_utils.logger.warn(
279
+ `Duplicate demo id found due to filename conflicts, please consider adding a unique id to code tag to resolve this.
270
280
  at ${opts.fileAbsPath}${suffix}`
271
- );
272
- }
273
- const { src, className, ...restAttrs } = codeNode.properties || {};
274
- const validAssetAttrs = [
275
- "title",
276
- "snapshot",
277
- "keywords"
278
- ];
279
- const techStackOpts = {
280
- type: codeType,
281
- mdAbsPath: opts.fileAbsPath,
282
- fileAbsPath: codeType === "external" ? parseOpts.fileAbsPath : void 0,
283
- entryPointCode: parseOpts.entryPointCode
284
- };
285
- Object.keys(restAttrs).forEach((key) => {
286
- if (restAttrs[key] === "")
287
- restAttrs[key] = true;
288
- });
289
- const originalProps = Object.assign(
290
- {},
291
- frontmatter,
292
- restAttrs
293
281
  );
294
- validAssetAttrs.forEach((key) => {
295
- if (originalProps[key])
296
- asset[key] = originalProps[key];
297
- });
298
- if (opts.useUtoopackDemoHMR) {
299
- propDemo.version = (0, import_utils.getContentHash)(
300
- JSON.stringify(asset.dependencies)
301
- );
302
- }
303
- if (/ inline/.test(String((_b2 = codeNode.data) == null ? void 0 : _b2.meta)) || originalProps.inline) {
304
- propDemo.inline = true;
305
- return {
306
- // TODO: special id for inline demo
307
- id: asset.id,
308
- component,
309
- renderOpts: {
310
- rendererPath: runtimeOpts == null ? void 0 : runtimeOpts.rendererPath,
311
- preflightPath: runtimeOpts == null ? void 0 : runtimeOpts.preflightPath
312
- }
313
- };
314
- }
315
- Object.assign(
316
- previewerProps,
317
- await ((_c2 = techStack.generatePreviewerProps) == null ? void 0 : _c2.call(
318
- techStack,
319
- originalProps,
320
- techStackOpts
321
- )) || originalProps
322
- );
323
- if (previewerProps.description) {
324
- const { unified } = await import("unified");
325
- const { default: remarkParse } = await import("remark-parse");
326
- const { default: remarkGfm } = await import("remark-gfm");
327
- const { default: remarkRehype } = await import("remark-rehype");
328
- const { default: rehypeStringify } = await import("rehype-stringify");
329
- const { convert } = require("html-to-text");
330
- const result = await unified().use(remarkParse).use(remarkGfm).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeStringify, { allowDangerousHtml: true }).process(previewerProps.description);
331
- previewerProps.description = String(result.value);
332
- asset.description = convert(result.value, {
333
- wordwrap: false
334
- });
335
- }
282
+ }
283
+ const { src, className, ...restAttrs } = codeNode.properties || {};
284
+ const validAssetAttrs = [
285
+ "title",
286
+ "snapshot",
287
+ "keywords"
288
+ ];
289
+ const techStackOpts = {
290
+ type: codeType,
291
+ mdAbsPath: opts.fileAbsPath,
292
+ fileAbsPath: codeType === "external" ? parseOpts.fileAbsPath : void 0,
293
+ entryPointCode: parseOpts.entryPointCode
294
+ };
295
+ Object.keys(restAttrs).forEach((key) => {
296
+ if (restAttrs[key] === "")
297
+ restAttrs[key] = true;
298
+ });
299
+ const originalProps = Object.assign({}, frontmatter, restAttrs);
300
+ validAssetAttrs.forEach((key) => {
301
+ if (originalProps[key])
302
+ asset[key] = originalProps[key];
303
+ });
304
+ const isInlineDemo = Boolean(
305
+ / inline/.test(String((_b2 = codeNode.data) == null ? void 0 : _b2.meta)) || originalProps.inline
306
+ );
307
+ const shouldDeferPreviewerProps = Boolean(
308
+ opts.useUtoopackDemoHMR && codeType === "external" && !isInlineDemo && !(runtimeOpts == null ? void 0 : runtimeOpts.rendererPath) && ((_c2 = runtimeOpts == null ? void 0 : runtimeOpts.deferPreviewerProps) == null ? void 0 : _c2.length)
309
+ );
310
+ if (opts.useUtoopackDemoHMR && !shouldDeferPreviewerProps) {
311
+ propDemo.version = getStableContentHash(asset.dependencies);
312
+ }
313
+ if (isInlineDemo) {
314
+ propDemo.inline = true;
336
315
  return {
316
+ // TODO: special id for inline demo
337
317
  id: asset.id,
338
318
  component,
339
- asset: techStack.generateMetadata ? await techStack.generateMetadata(asset, techStackOpts) : asset,
340
- /**
341
- * keep `generateSources` rather than `generateResolveMap` for compatibility
342
- */
343
- resolveMap: techStack.generateSources ? await techStack.generateSources(
344
- resolveMap,
345
- techStackOpts
346
- ) : resolveMap,
347
319
  renderOpts: {
348
320
  rendererPath: runtimeOpts == null ? void 0 : runtimeOpts.rendererPath,
349
- compilePath: runtimeOpts == null ? void 0 : runtimeOpts.compilePath,
350
321
  preflightPath: runtimeOpts == null ? void 0 : runtimeOpts.preflightPath
351
322
  }
352
323
  };
353
324
  }
354
- )
325
+ Object.assign(
326
+ previewerProps,
327
+ await ((_d = techStack.generatePreviewerProps) == null ? void 0 : _d.call(
328
+ techStack,
329
+ originalProps,
330
+ techStackOpts
331
+ )) || originalProps
332
+ );
333
+ if (previewerProps.description) {
334
+ const { unified } = await import("unified");
335
+ const { default: remarkParse } = await import("remark-parse");
336
+ const { default: remarkGfm } = await import("remark-gfm");
337
+ const { default: remarkRehype } = await import("remark-rehype");
338
+ const { default: rehypeStringify } = await import("rehype-stringify");
339
+ const { convert } = require("html-to-text");
340
+ const result = await unified().use(remarkParse).use(remarkGfm).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeStringify, { allowDangerousHtml: true }).process(previewerProps.description);
341
+ previewerProps.description = String(result.value);
342
+ asset.description = convert(result.value, {
343
+ wordwrap: false
344
+ });
345
+ }
346
+ const finalAsset = techStack.generateMetadata ? await techStack.generateMetadata(asset, techStackOpts) : asset;
347
+ const finalResolveMap = techStack.generateSources ? await techStack.generateSources(resolveMap, techStackOpts) : resolveMap;
348
+ const deferredPreviewerProps = {};
349
+ const renderOpts = {
350
+ rendererPath: runtimeOpts == null ? void 0 : runtimeOpts.rendererPath,
351
+ compilePath: runtimeOpts == null ? void 0 : runtimeOpts.compilePath,
352
+ preflightPath: runtimeOpts == null ? void 0 : runtimeOpts.preflightPath
353
+ };
354
+ if (shouldDeferPreviewerProps) {
355
+ runtimeOpts.deferPreviewerProps.forEach((key) => {
356
+ if (key in previewerProps) {
357
+ deferredPreviewerProps[key] = previewerProps[key];
358
+ delete previewerProps[key];
359
+ }
360
+ });
361
+ const versionDependencies = Object.fromEntries(
362
+ Object.entries(finalAsset.dependencies).map(
363
+ ([key, dependency]) => {
364
+ const resolved = finalResolveMap[key];
365
+ return [
366
+ key,
367
+ dependency.type === "FILE" && typeof resolved === "string" && import_path.default.isAbsolute(resolved) ? { ...dependency, value: "<dumi-raw>" } : dependency
368
+ ];
369
+ }
370
+ )
371
+ );
372
+ propDemo.version = getStableContentHash({
373
+ component,
374
+ asset: {
375
+ ...finalAsset,
376
+ dependencies: versionDependencies
377
+ },
378
+ resolveMap: finalResolveMap,
379
+ renderOpts
380
+ });
381
+ propDemo.__dumiUtoopackHMR = (0, import_plugin_utils.winPath)(
382
+ `${opts.fileAbsPath}?type=demo`
383
+ );
384
+ }
385
+ const dumiUtoopackHMRVersion = shouldDeferPreviewerProps ? getStableContentHash({
386
+ component,
387
+ asset: finalAsset,
388
+ resolveMap: finalResolveMap,
389
+ previewerProps: deferredPreviewerProps,
390
+ renderOpts
391
+ }) : void 0;
392
+ return {
393
+ id: asset.id,
394
+ component,
395
+ asset: finalAsset,
396
+ resolveMap: finalResolveMap,
397
+ ...Object.keys(deferredPreviewerProps).length ? { previewerProps: deferredPreviewerProps } : {},
398
+ ...dumiUtoopackHMRVersion ? { __dumiUtoopackHMRVersion: dumiUtoopackHMRVersion } : {},
399
+ renderOpts
400
+ };
401
+ })
355
402
  );
356
403
  demosPropData.push({
357
404
  demo: propDemo,
@@ -37,7 +37,8 @@ var ReactTechStack = class {
37
37
  constructor() {
38
38
  this.name = "react";
39
39
  this.runtimeOpts = {
40
- compilePath: require.resolve("../client/misc/reactDemoCompiler")
40
+ compilePath: require.resolve("../client/misc/reactDemoCompiler"),
41
+ deferPreviewerProps: ["jsx"]
41
42
  };
42
43
  }
43
44
  isSupported(...[, lang]) {
package/dist/types.d.ts CHANGED
@@ -76,6 +76,12 @@ export interface IDumiTechStackRuntimeOpts {
76
76
  * path to runtime plugin for this tech stack
77
77
  */
78
78
  pluginPath?: string;
79
+ /**
80
+ * Previewer props that are derived from demo source code and may be loaded
81
+ * with the demo runtime instead of being embedded in the Markdown page.
82
+ * This is only used by the utoopack development HMR fast path.
83
+ */
84
+ deferPreviewerProps?: string[];
79
85
  }
80
86
  export declare abstract class IDumiTechStack {
81
87
  /**
package/dist/utils.d.ts CHANGED
@@ -28,7 +28,8 @@ export declare function parseCodeFrontmatter(raw: string): {
28
28
  };
29
29
  declare const caches: Record<string, ReturnType<typeof Cache>>;
30
30
  export declare function _setFSCacheDir(dir: string): void;
31
- export declare function getCache(ns: string): (typeof caches)['0'];
31
+ export declare function resolveDumiCacheDir(cwd: string, cacheDirectoryPath?: string | false): string;
32
+ export declare function getCache(ns: string, baseDir?: string): (typeof caches)['0'];
32
33
  /**
33
34
  * try to get father config
34
35
  */
package/dist/utils.js CHANGED
@@ -41,6 +41,7 @@ __export(utils_exports, {
41
41
  getProjectRoot: () => getProjectRoot,
42
42
  isVersionInRange: () => isVersionInRange,
43
43
  parseCodeFrontmatter: () => parseCodeFrontmatter,
44
+ resolveDumiCacheDir: () => resolveDumiCacheDir,
44
45
  runLoaders: () => runLoaders,
45
46
  toImportSpecifier: () => toImportSpecifier,
46
47
  tryFatherBuildConfigs: () => tryFatherBuildConfigs
@@ -94,7 +95,10 @@ var caches = {};
94
95
  function _setFSCacheDir(dir) {
95
96
  cacheDir = dir;
96
97
  }
97
- function getCache(ns) {
98
+ function resolveDumiCacheDir(cwd, cacheDirectoryPath) {
99
+ return cacheDirectoryPath ? import_path.default.resolve(cwd, cacheDirectoryPath, "dumi") : import_path.default.resolve(cwd, import_constants.FS_CACHE_DIR);
100
+ }
101
+ function getCache(ns, baseDir = cacheDir) {
98
102
  if (process.env.DUMI_CACHE === "none") {
99
103
  return { set() {
100
104
  }, get() {
@@ -102,7 +106,8 @@ function getCache(ns) {
102
106
  }, getSync() {
103
107
  } };
104
108
  }
105
- return caches[ns] ?? (caches[ns] = (0, import_file_system_cache.default)({ basePath: import_path.default.resolve(cacheDir, ns) }));
109
+ const basePath = import_path.default.resolve(baseDir, ns);
110
+ return caches[basePath] ?? (caches[basePath] = (0, import_file_system_cache.default)({ basePath }));
106
111
  }
107
112
  async function tryFatherBuildConfigs(cwd) {
108
113
  let configs = [];
@@ -203,6 +208,7 @@ function toImportSpecifier(source) {
203
208
  getProjectRoot,
204
209
  isVersionInRange,
205
210
  parseCodeFrontmatter,
211
+ resolveDumiCacheDir,
206
212
  runLoaders,
207
213
  toImportSpecifier,
208
214
  tryFatherBuildConfigs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.4.47",
3
+ "version": "2.4.48-alpha.0",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -101,6 +101,7 @@
101
101
  "prism-react-renderer": "^1.3.5",
102
102
  "prism-themes": "^1.9.0",
103
103
  "prismjs": "^1.29.0",
104
+ "proper-lockfile": "^4.1.2",
104
105
  "raw-loader": "^4.0.2",
105
106
  "rc-motion": "^2.7.3",
106
107
  "rc-tabs": "^12.10.0",
@@ -143,6 +144,7 @@
143
144
  "@types/node": "^18.17.1",
144
145
  "@types/pluralize": "^0.0.30",
145
146
  "@types/prismjs": "^1.26.0",
147
+ "@types/proper-lockfile": "^4.1.4",
146
148
  "@types/react": "^18.2.17",
147
149
  "@types/react-copy-to-clipboard": "^5.0.4",
148
150
  "@types/react-dom": "^18.2.7",
@@ -21,6 +21,9 @@ var SourceCodeEditor = function SourceCodeEditor(props) {
21
21
  _useState4 = _slicedToArray(_useState3, 2),
22
22
  code = _useState4[0],
23
23
  setCode = _useState4[1];
24
+ useEffect(function () {
25
+ setCode(props.initialValue);
26
+ }, [props.initialValue]);
24
27
 
25
28
  // generate style from pre element, for adapting to the custom theme
26
29
  useEffect(function () {