dumi 2.4.37 → 2.4.38-beta.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.
@@ -1,11 +1,52 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
5
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
6
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
7
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
2
8
  import { SP_ROUTE_PREFIX } from "../../../constants";
3
9
  import { useAppData, useDemo, useSiteData } from 'dumi';
4
- import React, { createElement } from 'react';
10
+ import React, { createElement, useEffect, useRef, useState } from 'react';
5
11
  import Previewer from 'dumi/theme/builtins/Previewer';
6
12
  import { useRenderer } from "../useRenderer";
7
13
  import DemoErrorBoundary from "./DemoErrorBoundary";
8
- var InternalDumiDemo = function InternalDumiDemo(props) {
14
+ var LazyDemoPlaceholder = function LazyDemoPlaceholder(_ref) {
15
+ var id = _ref.id,
16
+ onVisible = _ref.onVisible;
17
+ var ref = useRef(null);
18
+ useEffect(function () {
19
+ if (typeof IntersectionObserver === 'undefined') {
20
+ onVisible();
21
+ return;
22
+ }
23
+ var observer = new IntersectionObserver(function (_ref2) {
24
+ var _ref3 = _slicedToArray(_ref2, 1),
25
+ entry = _ref3[0];
26
+ if (entry.isIntersecting) {
27
+ observer.disconnect();
28
+ onVisible();
29
+ }
30
+ }, {
31
+ rootMargin: '1000px 0px'
32
+ });
33
+ if (ref.current) {
34
+ observer.observe(ref.current);
35
+ }
36
+ return function () {
37
+ return observer.disconnect();
38
+ };
39
+ }, [onVisible]);
40
+ return /*#__PURE__*/React.createElement("div", {
41
+ id: id,
42
+ ref: ref,
43
+ "data-dumi-demo-lazy": true,
44
+ style: {
45
+ minHeight: 160
46
+ }
47
+ });
48
+ };
49
+ var LoadedDumiDemo = function LoadedDumiDemo(props) {
9
50
  var _useSiteData = useSiteData(),
10
51
  historyType = _useSiteData.historyType;
11
52
  var _useAppData = useAppData(),
@@ -43,9 +84,25 @@ var InternalDumiDemo = function InternalDumiDemo(props) {
43
84
  "".concat(isHashRoute ? "#" : '').concat(basename).concat(SP_ROUTE_PREFIX, "demos/").concat(props.demo.id).concat(routeQuery)
44
85
  }, props.previewerProps), props.previewerProps.iframe ? null : demoNode);
45
86
  };
87
+ var InternalDumiDemo = function InternalDumiDemo(props) {
88
+ var shouldLazyLoad = process.env.NODE_ENV !== 'production' && Boolean(props.demo.loader) && !props.demo.inline;
89
+ var _useState = useState(!shouldLazyLoad),
90
+ _useState2 = _slicedToArray(_useState, 2),
91
+ visible = _useState2[0],
92
+ setVisible = _useState2[1];
93
+ if (!visible) {
94
+ return /*#__PURE__*/React.createElement(LazyDemoPlaceholder, {
95
+ id: props.demo.id,
96
+ onVisible: function onVisible() {
97
+ return setVisible(true);
98
+ }
99
+ });
100
+ }
101
+ return /*#__PURE__*/React.createElement(LoadedDumiDemo, props);
102
+ };
46
103
  export var DumiDemo = /*#__PURE__*/React.memo(InternalDumiDemo, function (prev, next) {
47
104
  // compare length for performance
48
- return JSON.stringify(prev).length === JSON.stringify(next).length;
105
+ return prev.demo.id === next.demo.id && prev.demo.inline === next.demo.inline && prev.demo.version === next.demo.version && JSON.stringify(prev.previewerProps).length === JSON.stringify(next.previewerProps).length;
49
106
  });
50
107
  if (process.env.NODE_ENV !== 'production') {
51
108
  InternalDumiDemo.displayName = 'DumiDemo';
@@ -40,6 +40,8 @@ var import_utils = require("@umijs/utils");
40
40
  var import_path = __toESM(require("path"));
41
41
  var import_utils2 = require("./utils");
42
42
  var mdLoaderPath = require.resolve("../../loaders/markdown");
43
+ var utilsRegisterPath = require.resolve("@umijs/utils");
44
+ var esbuildImplementorPath = require.resolve("@umijs/bundler-utils/compiled/esbuild");
43
45
  var UTOOPACK_LOADER_CTX_KEY = "__dumiLoaderContextPath";
44
46
  var LOADER_CTX_FILENAME = "dumi-loader-ctx.cjs";
45
47
  function toSerializable(value) {
@@ -115,6 +117,129 @@ function toRequireRef(found) {
115
117
  const modRef = `require(${JSON.stringify(found.modulePath)})`;
116
118
  return found.exportName === "module.exports" ? modRef : `(${modRef})[${JSON.stringify(found.exportName)}]`;
117
119
  }
120
+ function createTechStackMockApi(onRegister) {
121
+ const api = {
122
+ cwd: process.cwd(),
123
+ config: {},
124
+ userConfig: {},
125
+ pkg: {},
126
+ paths: {},
127
+ service: {},
128
+ registerTechStack: onRegister,
129
+ register(opts) {
130
+ if ((opts == null ? void 0 : opts.key) === "registerTechStack" && typeof opts.fn === "function") {
131
+ onRegister(opts.fn);
132
+ }
133
+ }
134
+ };
135
+ return new Proxy(api, {
136
+ get(target, key) {
137
+ if (key in target) {
138
+ return target[key];
139
+ }
140
+ return () => {
141
+ };
142
+ }
143
+ });
144
+ }
145
+ function isSameTechStack(a, b) {
146
+ return a === b || a.name === b.name && a.constructor.name === b.constructor.name;
147
+ }
148
+ function collectTechStacksFromPlugin(plugin) {
149
+ if (typeof plugin !== "function")
150
+ return [];
151
+ const ret = [];
152
+ const api = createTechStackMockApi((fn) => {
153
+ try {
154
+ const techStack = fn();
155
+ if (techStack)
156
+ ret.push(techStack);
157
+ } catch {
158
+ }
159
+ });
160
+ try {
161
+ plugin(api);
162
+ } catch {
163
+ }
164
+ return ret;
165
+ }
166
+ function findTechStackPluginInModule(target, mod) {
167
+ const exp = mod.exports;
168
+ if (!exp)
169
+ return null;
170
+ const candidates = [
171
+ ["module.exports", exp],
172
+ ["default", exp == null ? void 0 : exp.default],
173
+ ...Object.entries(exp)
174
+ ];
175
+ for (const [exportName, plugin] of candidates) {
176
+ const techStacks = collectTechStacksFromPlugin(plugin);
177
+ if (techStacks.some((techStack) => isSameTechStack(techStack, target))) {
178
+ return { modulePath: mod.filename, exportName };
179
+ }
180
+ }
181
+ return null;
182
+ }
183
+ function findTechStackPluginInSourceFiles(target, sourceFiles) {
184
+ import_utils.register.register({ implementor: import_esbuild.default });
185
+ import_utils.register.clearFiles();
186
+ try {
187
+ for (const file of sourceFiles) {
188
+ try {
189
+ require(file);
190
+ const mod = require.cache[file];
191
+ if (!(mod == null ? void 0 : mod.exports))
192
+ continue;
193
+ const found = findTechStackPluginInModule(target, mod);
194
+ if (found)
195
+ return found;
196
+ } catch {
197
+ }
198
+ }
199
+ return null;
200
+ } finally {
201
+ for (const file of import_utils.register.getFiles()) {
202
+ delete require.cache[file];
203
+ }
204
+ for (const file of sourceFiles) {
205
+ delete require.cache[file];
206
+ }
207
+ import_utils.register.restore();
208
+ }
209
+ }
210
+ function toTechStackRefs(techStacks, sourceFiles = []) {
211
+ const refs = [];
212
+ for (const ts of techStacks) {
213
+ const ctor = ts.constructor;
214
+ let ref;
215
+ if (ctor !== Object) {
216
+ const found = findInRequireCache(ctor);
217
+ if (found) {
218
+ ref = `new (${toRequireRef(found)})()`;
219
+ }
220
+ } else {
221
+ const found = findInRequireCache(ts);
222
+ if (found) {
223
+ ref = toRequireRef(found);
224
+ }
225
+ }
226
+ if (!ref) {
227
+ const found = findTechStackPluginInSourceFiles(ts, sourceFiles);
228
+ if (found) {
229
+ ref = `...loadTechStacksFromPlugin(${toRequireRef(found)})`;
230
+ }
231
+ }
232
+ if (ref) {
233
+ refs.push(ref);
234
+ } else {
235
+ const name = ts.constructor.name ? ` (${ts.constructor.name})` : "";
236
+ console.warn(
237
+ `[dumi] Utoopack markdown loader cannot serialize tech stack "${ts.name}"${name}. Please export the tech stack class or register it from an exported dumi plugin.`
238
+ );
239
+ }
240
+ }
241
+ return refs;
242
+ }
118
243
  function toPluginTargetRef(target, sourceFiles) {
119
244
  if (typeof target === "string")
120
245
  return JSON.stringify(target);
@@ -141,25 +266,53 @@ function toPluginRefs(plugins = [], sourceFiles = []) {
141
266
  }).join(", ")}]`;
142
267
  }
143
268
  function buildLoaderContextContent(techStacks, builtins = {}, routes = {}, extraRemarkPlugins = [], extraRehypePlugins = [], sourceFiles = []) {
144
- const refs = [];
145
- for (const ts of techStacks) {
146
- const ctor = ts.constructor;
147
- if (ctor !== Object) {
148
- const found = findInRequireCache(ctor);
149
- if (found) {
150
- refs.push(`new (${toRequireRef(found)})()`);
151
- }
152
- } else {
153
- const found = findInRequireCache(ts);
154
- if (found) {
155
- refs.push(toRequireRef(found));
156
- }
157
- }
158
- }
269
+ const refs = toTechStackRefs(techStacks, sourceFiles);
159
270
  return `'use strict';
160
271
  try {
161
- require('@umijs/utils').register.register({ implementor: require('@umijs/bundler-utils/compiled/esbuild') });
162
- } catch (_) {}
272
+ require(${JSON.stringify(
273
+ utilsRegisterPath
274
+ )}).register.register({ implementor: require(${JSON.stringify(
275
+ esbuildImplementorPath
276
+ )}) });
277
+ } catch (e) {
278
+ console.warn('[dumi] failed to register TS require hook for utoopack loader context:', e);
279
+ }
280
+ function loadTechStacksFromPlugin(plugin) {
281
+ if (typeof plugin !== 'function') return [];
282
+ const techStacks = [];
283
+ const registerTechStack = (fn) => {
284
+ try {
285
+ const techStack = fn();
286
+ if (techStack) techStacks.push(techStack);
287
+ } catch (e) {
288
+ console.warn('[dumi] failed to register tech stack from utoopack loader context:', e);
289
+ }
290
+ };
291
+ const api = new Proxy({
292
+ cwd: process.cwd(),
293
+ config: {},
294
+ userConfig: {},
295
+ pkg: {},
296
+ paths: {},
297
+ service: {},
298
+ registerTechStack,
299
+ register(opts) {
300
+ if (opts && opts.key === 'registerTechStack' && typeof opts.fn === 'function') {
301
+ registerTechStack(opts.fn);
302
+ }
303
+ },
304
+ }, {
305
+ get(target, key) {
306
+ return key in target ? target[key] : () => {};
307
+ },
308
+ });
309
+ try {
310
+ plugin(api);
311
+ } catch (e) {
312
+ console.warn('[dumi] failed to load tech stack plugin in utoopack loader context:', e);
313
+ }
314
+ return techStacks;
315
+ }
163
316
  exports.techStacks = [${refs.join(", ")}];
164
317
  exports.builtins = ${JSON.stringify(builtins)};
165
318
  exports.routes = ${JSON.stringify(routes)};
@@ -311,7 +464,7 @@ var getUtoopackRules = (api, config = api.config) => {
311
464
  },
312
465
  // compile inline demo code blocks
313
466
  {
314
- condition: { query: /^\?type=demo$/ },
467
+ condition: { query: /^\?type=demo(?:&.*)?$/ },
315
468
  loaders: [
316
469
  {
317
470
  loader: mdLoaderPath,
@@ -50,6 +50,13 @@ function getDemoSourceFiles(demos = []) {
50
50
  return ret;
51
51
  }, []);
52
52
  }
53
+ function getDemoIdFromQuery(resourceQuery = "") {
54
+ return new URLSearchParams(resourceQuery.replace(/^\?/, "")).get("demoId");
55
+ }
56
+ function filterDemosByQuery(demos, resourceQuery) {
57
+ const demoId = getDemoIdFromQuery(resourceQuery);
58
+ return demoId ? demos == null ? void 0 : demos.filter((demo) => demo.id === demoId) : demos;
59
+ }
53
60
  function isRelativePath(path2) {
54
61
  return /^\.{1,2}(?!\w)/.test(path2);
55
62
  }
@@ -105,7 +112,7 @@ function DumiMarkdownContent() {
105
112
  export default DumiMarkdownContent;`;
106
113
  }
107
114
  function emitDemo(opts, ret) {
108
- const { demos } = ret.meta;
115
+ const demos = filterDemosByQuery(ret.meta.demos, this.resourceQuery);
109
116
  const shareDepsMap = {};
110
117
  const demoDepsMap = {};
111
118
  const relativeDepsMap = {};
@@ -306,9 +313,12 @@ function emitText(opts, ret) {
306
313
  }
307
314
  function emit(opts, ret) {
308
315
  const { demos, embeds } = ret.meta;
316
+ const dependencyDemos = opts.mode === "demo" ? filterDemosByQuery(demos, this.resourceQuery) : demos;
309
317
  embeds.forEach((file) => this.addDependency(file));
310
318
  if (opts.mode !== "demo-index") {
311
- getDemoSourceFiles(demos).forEach((file) => this.addDependency(file));
319
+ getDemoSourceFiles(dependencyDemos).forEach(
320
+ (file) => this.addDependency(file)
321
+ );
312
322
  }
313
323
  if (this.resourceQuery.includes("watch=parent"))
314
324
  return null;
@@ -48,7 +48,13 @@ var isElement;
48
48
  var DEMO_NODE_CONTAINER = "$demo-container";
49
49
  var DEMO_PROP_VALUE_KEY = "$demo-prop-value-key";
50
50
  var DEMO_LOADER_PLACEHOLDER = "__DUMI_DEMO_LOADER__";
51
- var DEMO_LOADER_PLACEHOLDER_VALUE = DEMO_LOADER_PLACEHOLDER;
51
+ var DEMO_LOADER_PLACEHOLDER_RE = new RegExp(
52
+ `"${DEMO_LOADER_PLACEHOLDER}:([^"]+)"`,
53
+ "g"
54
+ );
55
+ var getDemoLoaderPlaceholder = (id) => `${DEMO_LOADER_PLACEHOLDER}:${encodeURIComponent(
56
+ id
57
+ )}`;
52
58
  var DUMI_DEMO_TAG = "DumiDemo";
53
59
  var DUMI_DEMO_GRID_TAG = "DumiDemoGrid";
54
60
  var SKIP_DEMO_PARSE = "pure";
@@ -252,106 +258,97 @@ function rehypeDemo(opts) {
252
258
  }
253
259
  const propDemo = { id: parseOpts.id };
254
260
  if (opts.useUtoopackDemoHMR) {
255
- propDemo.loader = DEMO_LOADER_PLACEHOLDER_VALUE;
261
+ propDemo.loader = getDemoLoaderPlaceholder(parseOpts.id);
256
262
  }
257
263
  demoIds.push(parseOpts.id);
258
264
  deferrers.push(
259
265
  (0, import_block.default)({
260
266
  ...parseOpts,
261
267
  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.
268
+ }).then(async ({ asset, resolveMap, frontmatter }) => {
269
+ var _a2, _b2, _c2;
270
+ if (demoIds.indexOf(parseOpts.id) !== demoIds.lastIndexOf(parseOpts.id)) {
271
+ const startLine = (_a2 = node.position) == null ? void 0 : _a2.start.line;
272
+ const suffix = startLine ? `:${startLine}` : "";
273
+ import_plugin_utils.logger.warn(
274
+ `Duplicate demo id found due to filename conflicts, please consider adding a unique id to code tag to resolve this.
270
275
  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
276
  );
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
277
+ }
278
+ const { src, className, ...restAttrs } = codeNode.properties || {};
279
+ const validAssetAttrs = [
280
+ "title",
281
+ "snapshot",
282
+ "keywords"
283
+ ];
284
+ const techStackOpts = {
285
+ type: codeType,
286
+ mdAbsPath: opts.fileAbsPath,
287
+ fileAbsPath: codeType === "external" ? parseOpts.fileAbsPath : void 0,
288
+ entryPointCode: parseOpts.entryPointCode
289
+ };
290
+ Object.keys(restAttrs).forEach((key) => {
291
+ if (restAttrs[key] === "")
292
+ restAttrs[key] = true;
293
+ });
294
+ const originalProps = Object.assign({}, frontmatter, restAttrs);
295
+ validAssetAttrs.forEach((key) => {
296
+ if (originalProps[key])
297
+ asset[key] = originalProps[key];
298
+ });
299
+ if (opts.useUtoopackDemoHMR) {
300
+ propDemo.version = (0, import_utils.getContentHash)(
301
+ JSON.stringify(asset.dependencies)
322
302
  );
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
- }
303
+ }
304
+ if (/ inline/.test(String((_b2 = codeNode.data) == null ? void 0 : _b2.meta)) || originalProps.inline) {
305
+ propDemo.inline = true;
336
306
  return {
307
+ // TODO: special id for inline demo
337
308
  id: asset.id,
338
309
  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
310
  renderOpts: {
348
311
  rendererPath: runtimeOpts == null ? void 0 : runtimeOpts.rendererPath,
349
- compilePath: runtimeOpts == null ? void 0 : runtimeOpts.compilePath,
350
312
  preflightPath: runtimeOpts == null ? void 0 : runtimeOpts.preflightPath
351
313
  }
352
314
  };
353
315
  }
354
- )
316
+ Object.assign(
317
+ previewerProps,
318
+ await ((_c2 = techStack.generatePreviewerProps) == null ? void 0 : _c2.call(
319
+ techStack,
320
+ originalProps,
321
+ techStackOpts
322
+ )) || originalProps
323
+ );
324
+ if (previewerProps.description) {
325
+ const { unified } = await import("unified");
326
+ const { default: remarkParse } = await import("remark-parse");
327
+ const { default: remarkGfm } = await import("remark-gfm");
328
+ const { default: remarkRehype } = await import("remark-rehype");
329
+ const { default: rehypeStringify } = await import("rehype-stringify");
330
+ const { convert } = require("html-to-text");
331
+ const result = await unified().use(remarkParse).use(remarkGfm).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeStringify, { allowDangerousHtml: true }).process(previewerProps.description);
332
+ previewerProps.description = String(result.value);
333
+ asset.description = convert(result.value, {
334
+ wordwrap: false
335
+ });
336
+ }
337
+ return {
338
+ id: asset.id,
339
+ component,
340
+ asset: techStack.generateMetadata ? await techStack.generateMetadata(asset, techStackOpts) : asset,
341
+ /**
342
+ * keep `generateSources` rather than `generateResolveMap` for compatibility
343
+ */
344
+ resolveMap: techStack.generateSources ? await techStack.generateSources(resolveMap, techStackOpts) : resolveMap,
345
+ renderOpts: {
346
+ rendererPath: runtimeOpts == null ? void 0 : runtimeOpts.rendererPath,
347
+ compilePath: runtimeOpts == null ? void 0 : runtimeOpts.compilePath,
348
+ preflightPath: runtimeOpts == null ? void 0 : runtimeOpts.preflightPath
349
+ }
350
+ };
351
+ })
355
352
  );
356
353
  demosPropData.push({
357
354
  demo: propDemo,
@@ -381,15 +378,13 @@ function rehypeDemo(opts) {
381
378
  await Promise.all(deferrers).then((demos) => {
382
379
  vFile.data.demos = demos;
383
380
  replaceNodes.forEach((node) => {
384
- const demoLoader = `() => import('${(0, import_plugin_utils.winPath)(
385
- opts.fileAbsPath
386
- )}?type=demo')`;
387
381
  let value = JSON.stringify(node.data[DEMO_PROP_VALUE_KEY]);
388
382
  if (opts.useUtoopackDemoHMR) {
389
- value = value.replace(
390
- new RegExp(`"${DEMO_LOADER_PLACEHOLDER}"`, "g"),
391
- demoLoader
392
- );
383
+ value = value.replace(DEMO_LOADER_PLACEHOLDER_RE, (_, demoId) => {
384
+ return `() => import('${(0, import_plugin_utils.winPath)(
385
+ opts.fileAbsPath
386
+ )}?type=demo&demoId=${demoId}')`;
387
+ });
393
388
  }
394
389
  if (node.JSXAttributes[0].type === "JSXAttribute") {
395
390
  node.JSXAttributes[0].value = value;
@@ -201,14 +201,18 @@ export function useDemo(
201
201
  /**
202
202
  * get all demos
203
203
  */
204
- export async function getFullDemos() {
205
- const demoIndexMap = await loadDemoIndexMap();
206
- const lazyDemoIndexes = await Promise.all(
207
- Object.entries(demoIndexMap).map(async ([id, demoIndexGetter]) => ({
208
- id,
209
- demoIndex: await demoIndexGetter?.().catch(() => undefined),
210
- })),
211
- );
204
+ export async function getFullDemos(opts: { loadLazy?: boolean } = {}) {
205
+ const loadLazy = opts.loadLazy ?? process.env.NODE_ENV === 'production';
206
+ const lazyDemoIndexes = loadLazy
207
+ ? await loadDemoIndexMap().then((demoIndexMap) =>
208
+ Promise.all(
209
+ Object.entries(demoIndexMap).map(async ([id, demoIndexGetter]) => ({
210
+ id,
211
+ demoIndex: await demoIndexGetter?.().catch(() => undefined),
212
+ })),
213
+ ),
214
+ )
215
+ : [];
212
216
  const allDemoIndexes = [
213
217
  ...demoIndexes,
214
218
  ...lazyDemoIndexes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.4.37",
3
+ "version": "2.4.38-beta.0",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
package/theme-api.d.ts CHANGED
@@ -309,7 +309,9 @@ export declare const useTabMeta: () =>
309
309
  export declare const openCodeSandbox: (data: IPreviewerProps) => void;
310
310
  export declare const openStackBlitz: (data: IPreviewerProps) => void;
311
311
  export declare function useDemo(id: string): IDemoData | undefined;
312
- export declare function getFullDemos(): Promise<Record<string, IDemoData>>;
312
+ export declare function getFullDemos(opts?: {
313
+ loadLazy?: boolean;
314
+ }): Promise<Record<string, IDemoData>>;
313
315
  export declare function getRouteMetaById<T extends { syncOnly?: boolean }>(
314
316
  id: string,
315
317
  opts?: T,