dumi 2.3.0-alpha.9 → 2.3.0-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.
Files changed (86) hide show
  1. package/dist/assetParsers/block.d.ts +7 -1
  2. package/dist/assetParsers/block.js +14 -6
  3. package/dist/client/pages/Demo/index.js +19 -5
  4. package/dist/client/pages/Loading.d.ts +1 -0
  5. package/dist/client/pages/Loading.js +2 -0
  6. package/dist/client/theme-api/DumiDemo/index.js +4 -4
  7. package/dist/client/theme-api/{context/index.d.ts → context.d.ts} +4 -12
  8. package/dist/client/theme-api/context.js +16 -0
  9. package/dist/client/theme-api/index.d.ts +2 -3
  10. package/dist/client/theme-api/index.js +2 -3
  11. package/dist/client/theme-api/types.d.ts +6 -4
  12. package/dist/client/theme-api/useLiveDemo.d.ts +6 -0
  13. package/dist/client/theme-api/useLiveDemo.js +70 -0
  14. package/dist/client/theme-api/useRouteMeta.js +73 -20
  15. package/dist/client/theme-api/useSiteSearch/index.d.ts +1 -1
  16. package/dist/client/theme-api/useSiteSearch/index.js +20 -48
  17. package/dist/client/theme-api/useSiteSearch/useSearchData.d.ts +9 -6
  18. package/dist/client/theme-api/useSiteSearch/useSearchData.js +55 -60
  19. package/dist/client/theme-api/useTabMeta.js +1 -1
  20. package/dist/client/theme-api/utils.d.ts +10 -0
  21. package/dist/client/theme-api/utils.js +25 -0
  22. package/dist/constants.d.ts +0 -1
  23. package/dist/constants.js +0 -4
  24. package/dist/features/compile/index.js +11 -18
  25. package/dist/features/exports.js +3 -3
  26. package/dist/features/meta.js +12 -31
  27. package/dist/features/theme/index.js +8 -5
  28. package/dist/loaders/markdown/index.d.ts +1 -7
  29. package/dist/loaders/markdown/index.js +39 -113
  30. package/dist/loaders/markdown/transformer/index.d.ts +1 -1
  31. package/dist/loaders/markdown/transformer/rehypeDemo.js +8 -2
  32. package/dist/loaders/page/index.js +1 -3
  33. package/dist/preset.js +1 -2
  34. package/dist/templates/ContextWrapper.ts.tpl +2 -10
  35. package/dist/templates/meta/exports.ts.tpl +160 -0
  36. package/dist/templates/meta/index.ts.tpl +26 -0
  37. package/dist/templates/{meta-runtime.ts.tpl → meta/runtime.ts.tpl} +11 -22
  38. package/dist/types.d.ts +2 -2
  39. package/index.d.ts +1 -4
  40. package/package.json +2 -1
  41. package/theme-default/builtins/Previewer/index.d.ts +1 -1
  42. package/theme-default/builtins/Previewer/index.js +35 -33
  43. package/theme-default/builtins/Previewer/index.less +34 -0
  44. package/theme-default/builtins/SourceCode/index.d.ts +2 -1
  45. package/theme-default/builtins/SourceCode/index.js +3 -3
  46. package/theme-default/builtins/SourceCode/index.less +1 -0
  47. package/theme-default/locales/en-US.json +2 -0
  48. package/theme-default/locales/zh-CN.json +2 -0
  49. package/theme-default/slots/Loading/index.d.ts +5 -0
  50. package/theme-default/slots/Loading/index.js +18 -0
  51. package/theme-default/slots/Loading/index.less +20 -0
  52. package/theme-default/slots/PreviewerActions/index.d.ts +7 -1
  53. package/theme-default/slots/PreviewerActions/index.js +49 -6
  54. package/theme-default/slots/PreviewerActions/index.less +58 -14
  55. package/theme-default/slots/SearchBar/Mask.js +1 -1
  56. package/theme-default/slots/SearchBar/index.js +1 -1
  57. package/theme-default/slots/SearchResult/index.js +1 -10
  58. package/theme-default/slots/SourceCodeEditor/index.d.ts +18 -0
  59. package/theme-default/slots/SourceCodeEditor/index.js +106 -0
  60. package/theme-default/slots/SourceCodeEditor/index.less +45 -0
  61. package/dist/client/theme-api/context/index.js +0 -50
  62. package/dist/client/theme-api/context/use.d.ts +0 -10
  63. package/dist/client/theme-api/context/use.js +0 -25
  64. package/dist/client/theme-api/evalCode.d.ts +0 -2
  65. package/dist/client/theme-api/evalCode.js +0 -17
  66. package/dist/client/theme-api/live/LiveProvider.d.ts +0 -16
  67. package/dist/client/theme-api/live/LiveProvider.js +0 -74
  68. package/dist/client/theme-api/live/index.d.ts +0 -3
  69. package/dist/client/theme-api/live/index.js +0 -3
  70. package/dist/client/theme-api/live/useDemoScopes.d.ts +0 -2
  71. package/dist/client/theme-api/live/useDemoScopes.js +0 -15
  72. package/dist/features/live.d.ts +0 -3
  73. package/dist/features/live.js +0 -74
  74. package/dist/templates/live/demo-scopes.ts.tpl +0 -22
  75. package/dist/templates/live/disabled.ts.tpl +0 -1
  76. package/dist/templates/meta-demos.ts.tpl +0 -34
  77. package/dist/templates/meta-frontmatter.ts.tpl +0 -9
  78. package/dist/templates/meta-route.ts.tpl +0 -43
  79. package/dist/templates/meta-search.ts.tpl +0 -41
  80. package/theme-default/slots/LiveDemo/index.d.ts +0 -3
  81. package/theme-default/slots/LiveDemo/index.js +0 -8
  82. package/theme-default/slots/LiveEditor/index.d.ts +0 -4
  83. package/theme-default/slots/LiveEditor/index.js +0 -20
  84. package/theme-default/slots/LiveError/index.d.ts +0 -4
  85. package/theme-default/slots/LiveError/index.js +0 -15
  86. package/theme-default/slots/LiveError/index.less +0 -22
@@ -3,7 +3,13 @@ import type { ExampleBlockAsset } from 'dumi-assets-types';
3
3
  import type { sync } from 'enhanced-resolve';
4
4
  export interface IParsedBlockAsset {
5
5
  asset: ExampleBlockAsset;
6
- sources: Record<string, string>;
6
+ /**
7
+ * resolveMap: {
8
+ * '@/constants': '/path/to/constants.ts',
9
+ * 'antd/es/button': '/path/to/antd/es/button/index.jsx',
10
+ * }
11
+ */
12
+ resolveMap: Record<string, string>;
7
13
  frontmatter: ReturnType<typeof parseCodeFrontmatter>['frontmatter'];
8
14
  }
9
15
  declare function parseBlockAsset(opts: {
@@ -47,7 +47,7 @@ async function parseBlockAsset(opts) {
47
47
  };
48
48
  const result = {
49
49
  asset,
50
- sources: {},
50
+ resolveMap: {},
51
51
  frontmatter: null
52
52
  };
53
53
  const deferrer = (0, import_esbuild.build)({
@@ -81,12 +81,17 @@ async function parseBlockAsset(opts) {
81
81
  type: "NPM",
82
82
  value: pkg.version
83
83
  };
84
+ result.resolveMap[args.path] = resolved;
84
85
  }
85
86
  return { path: args.path, external: true };
86
87
  }
87
88
  return {
88
89
  path: args.kind !== "entry-point" ? opts.resolver(args.resolveDir, args.path) : import_path.default.join(args.resolveDir, args.path),
89
- pluginData: { kind: args.kind, resolveDir: args.resolveDir }
90
+ pluginData: {
91
+ kind: args.kind,
92
+ resolveDir: args.resolveDir,
93
+ source: args.path
94
+ }
90
95
  };
91
96
  });
92
97
  builder.onLoad({ filter: /.*/ }, (args) => {
@@ -101,9 +106,12 @@ async function parseBlockAsset(opts) {
101
106
  ".json"
102
107
  ].includes(ext);
103
108
  const isEntryPoint = args.pluginData.kind === "entry-point";
104
- const filename = isEntryPoint ? `index${ext}` : (0, import_plugin_utils.winPath)(
105
- import_path.default.relative(import_path.default.dirname(opts.fileAbsPath), args.path)
106
- ).replace(/^(\.?\.\/)+/g, "");
109
+ const filename = `${isEntryPoint ? "index" : (0, import_plugin_utils.winPath)(
110
+ import_path.default.format({
111
+ ...import_path.default.parse(args.pluginData.source),
112
+ ext: ""
113
+ })
114
+ )}${ext}`;
107
115
  if (isModule || isPlainText) {
108
116
  asset.dependencies[filename] = {
109
117
  type: "FILE",
@@ -124,7 +132,7 @@ async function parseBlockAsset(opts) {
124
132
  }
125
133
  }
126
134
  if (!isEntryPoint || !opts.entryPointCode) {
127
- result.sources[filename] = args.path;
135
+ result.resolveMap[filename] = args.path;
128
136
  }
129
137
  return {
130
138
  // only continue to load for module files
@@ -1,12 +1,26 @@
1
- import { useDemoData, useParams } from 'dumi';
2
- import { createElement } from 'react';
1
+ import { useDemo, useLiveDemo, useParams } from 'dumi';
2
+ import { createElement, useEffect } from 'react';
3
3
  import "./index.less";
4
4
  var DemoRenderPage = function DemoRenderPage() {
5
5
  var _useParams = useParams(),
6
6
  id = _useParams.id;
7
- var demoInfo = useDemoData(id);
8
- var _ref = demoInfo,
7
+ var _ref = useDemo(id) || {},
9
8
  component = _ref.component;
10
- return component && /*#__PURE__*/createElement(component);
9
+ var _useLiveDemo = useLiveDemo(id),
10
+ liveDemoNode = _useLiveDemo.node,
11
+ setSources = _useLiveDemo.setSources;
12
+ var finalNode = liveDemoNode || component && /*#__PURE__*/createElement(component);
13
+ useEffect(function () {
14
+ var handler = function handler(ev) {
15
+ if (ev.data.type === 'dumi.liveDemo.setSources') {
16
+ setSources(ev.data.value);
17
+ }
18
+ };
19
+ window.addEventListener('message', handler);
20
+ return function () {
21
+ return window.removeEventListener('message', handler);
22
+ };
23
+ }, [setSources]);
24
+ return finalNode;
11
25
  };
12
26
  export default DemoRenderPage;
@@ -0,0 +1 @@
1
+ export { default } from 'dumi/theme/slots/Loading';
@@ -0,0 +1,2 @@
1
+ // allow customize loading via theme slots or ./dumi/loading.tsx
2
+ export { default } from 'dumi/theme/slots/Loading';
@@ -1,6 +1,6 @@
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
2
  import { SP_ROUTE_PREFIX } from "../../../constants";
3
- import { useAppData, useDemoData, useSiteData } from 'dumi';
3
+ import { useAppData, useDemo, useSiteData } from 'dumi';
4
4
  import React, { createElement } from 'react';
5
5
  import Previewer from 'dumi/theme/builtins/Previewer';
6
6
  import DemoErrorBoundary from "./DemoErrorBoundary";
@@ -9,12 +9,12 @@ var InternalDumiDemo = function InternalDumiDemo(props) {
9
9
  historyType = _useSiteData.historyType;
10
10
  var _useAppData = useAppData(),
11
11
  basename = _useAppData.basename;
12
- var demoInfo = useDemoData(props.demo.id);
12
+ var _ref = useDemo(props.demo.id),
13
+ component = _ref.component,
14
+ asset = _ref.asset;
13
15
 
14
16
  // hide debug demo in production
15
17
  if (process.env.NODE_ENV === 'production' && props.previewerProps.debug) return null;
16
- var component = demoInfo.component,
17
- asset = demoInfo.asset;
18
18
  var demoNode = /*#__PURE__*/React.createElement(DemoErrorBoundary, null, /*#__PURE__*/createElement(component));
19
19
  if (props.demo.inline) {
20
20
  return demoNode;
@@ -1,19 +1,13 @@
1
- import type { PICKED_PKG_FIELDS } from "../../../constants";
1
+ /// <reference types="react" />
2
+ import type { PICKED_PKG_FIELDS } from "../../constants";
2
3
  import type { AtomComponentAsset } from 'dumi-assets-types';
3
- import { type ComponentType } from 'react';
4
- import type { ILocalesConfig, IPreviewerProps, IRouteMeta, IThemeConfig } from '../types';
5
- export type DemoInfo = {
6
- component: ComponentType;
7
- asset: IPreviewerProps['asset'];
8
- routeId: string;
9
- };
4
+ import type { IDemoData, ILocalesConfig, IThemeConfig } from './types';
10
5
  interface ISiteContext {
11
6
  pkg: Partial<Record<keyof typeof PICKED_PKG_FIELDS, any>>;
12
7
  historyType: 'browser' | 'hash' | 'memory';
13
8
  entryExports: Record<string, any>;
14
- demos: Record<string, DemoInfo>;
9
+ demos: Record<string, IDemoData>;
15
10
  components: Record<string, AtomComponentAsset>;
16
- tabs: IRouteMeta['tabs'];
17
11
  locales: ILocalesConfig;
18
12
  themeConfig: IThemeConfig;
19
13
  hostname?: string;
@@ -23,9 +17,7 @@ interface ISiteContext {
23
17
  * private field, do not use it in your code
24
18
  */
25
19
  _2_level_nav_available: boolean;
26
- getDemoById: (id: string) => Promise<DemoInfo | null>;
27
20
  }
28
21
  export declare const SiteContext: import("react").Context<ISiteContext>;
29
22
  export declare const useSiteData: () => ISiteContext;
30
- export declare function useDemoData(demoId: string): DemoInfo | null;
31
23
  export {};
@@ -0,0 +1,16 @@
1
+ import { createContext, useContext } from 'react';
2
+ export var SiteContext = /*#__PURE__*/createContext({
3
+ pkg: {},
4
+ historyType: 'browser',
5
+ entryExports: {},
6
+ demos: {},
7
+ components: {},
8
+ locales: [],
9
+ themeConfig: {},
10
+ loading: false,
11
+ setLoading: function setLoading() {},
12
+ _2_level_nav_available: true
13
+ });
14
+ export var useSiteData = function useSiteData() {
15
+ return useContext(SiteContext);
16
+ };
@@ -3,13 +3,12 @@ export { AtomRenderer } from './AtomRenderer';
3
3
  export { DumiDemo } from './DumiDemo';
4
4
  export { DumiDemoGrid } from './DumiDemoGrid';
5
5
  export { DumiPage } from './DumiPage';
6
- export { useDemoData, useSiteData } from './context';
7
- export { evalCode } from './evalCode';
8
- export { LiveContext, LiveProvider, isLiveEnabled } from './live';
6
+ export { useSiteData } from './context';
9
7
  export { openCodeSandbox } from './openCodeSandbox';
10
8
  export { openStackBlitz } from './openStackBlitz';
11
9
  export type { IPreviewerProps } from './types';
12
10
  export { useAtomAssets } from './useAtomAssets';
11
+ export { useLiveDemo } from './useLiveDemo';
13
12
  export { useLocale } from './useLocale';
14
13
  export { useNavData } from './useNavData';
15
14
  export { usePrefersColor } from './usePrefersColor';
@@ -3,12 +3,11 @@ export { AtomRenderer } from "./AtomRenderer";
3
3
  export { DumiDemo } from "./DumiDemo";
4
4
  export { DumiDemoGrid } from "./DumiDemoGrid";
5
5
  export { DumiPage } from "./DumiPage";
6
- export { useDemoData, useSiteData } from "./context";
7
- export { evalCode } from "./evalCode";
8
- export { LiveContext, LiveProvider, isLiveEnabled } from "./live";
6
+ export { useSiteData } from "./context";
9
7
  export { openCodeSandbox } from "./openCodeSandbox";
10
8
  export { openStackBlitz } from "./openStackBlitz";
11
9
  export { useAtomAssets } from "./useAtomAssets";
10
+ export { useLiveDemo } from "./useLiveDemo";
12
11
  export { useLocale } from "./useLocale";
13
12
  export { useNavData } from "./useNavData";
14
13
  export { usePrefersColor } from "./usePrefersColor";
@@ -41,10 +41,6 @@ export interface IPreviewerProps {
41
41
  * background color for demo content
42
42
  */
43
43
  background?: string;
44
- /**
45
- * enable live demo
46
- */
47
- live?: boolean;
48
44
  /**
49
45
  * asset metadata of current demo
50
46
  */
@@ -223,4 +219,10 @@ export type IRoutesById = Record<string, {
223
219
  redirect?: string;
224
220
  [key: string]: any;
225
221
  }>;
222
+ export type IDemoData = {
223
+ component: ComponentType;
224
+ asset: IPreviewerProps['asset'];
225
+ routeId: string;
226
+ context?: Record<string, unknown>;
227
+ };
226
228
  export {};
@@ -0,0 +1,6 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare const useLiveDemo: (id: string) => {
3
+ node: ReactNode;
4
+ error: Error | null;
5
+ setSources: (sources: Record<string, string>) => void;
6
+ };
@@ -0,0 +1,70 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ 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."); }
3
+ 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); }
4
+ 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; }
5
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { useDemo } from 'dumi';
8
+ import { createElement, useCallback, useState } from 'react';
9
+ import DemoErrorBoundary from "./DumiDemo/DemoErrorBoundary";
10
+ export var useLiveDemo = function useLiveDemo(id) {
11
+ var _ref = useDemo(id),
12
+ context = _ref.context,
13
+ asset = _ref.asset;
14
+ var _useState = useState(),
15
+ _useState2 = _slicedToArray(_useState, 2),
16
+ demoNode = _useState2[0],
17
+ setDemoNode = _useState2[1];
18
+ var _useState3 = useState(null),
19
+ _useState4 = _slicedToArray(_useState3, 2),
20
+ error = _useState4[0],
21
+ setError = _useState4[1];
22
+ var setSources = useCallback(function (sources) {
23
+ var entryFileName = Object.keys(asset.dependencies).find(function (k) {
24
+ return asset.dependencies[k].type === 'FILE';
25
+ });
26
+ var entryFileCode = sources[entryFileName];
27
+ var require = function require(v) {
28
+ if (v in context) return context[v];
29
+ throw new Error("Cannot find module: ".concat(v));
30
+ };
31
+ var exports = {};
32
+ var module = {
33
+ exports: exports
34
+ };
35
+
36
+ // lazy load react-dom/server
37
+ import('react-dom/server').then(function (_ref2) {
38
+ var renderToStaticMarkup = _ref2.renderToStaticMarkup;
39
+ try {
40
+ // initial component with fake runtime
41
+ new Function('module', 'exports', 'require', entryFileCode)(module, exports, require);
42
+ var newDemoNode = /*#__PURE__*/createElement(DemoErrorBoundary, null, /*#__PURE__*/createElement(exports.default));
43
+ var oError = console.error;
44
+
45
+ // hijack console.error to avoid useLayoutEffect error
46
+ console.error = function () {
47
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
48
+ args[_key] = arguments[_key];
49
+ }
50
+ return !args[0].includes('useLayoutEffect does nothing on the server') && oError.apply(console, args);
51
+ };
52
+
53
+ // check component is renderable, to avoid show react overlay error
54
+ renderToStaticMarkup(newDemoNode);
55
+ console.error = oError;
56
+
57
+ // set new demo node with passing sources
58
+ setDemoNode(newDemoNode);
59
+ setError(null);
60
+ } catch (err) {
61
+ setError(err);
62
+ }
63
+ });
64
+ }, [context]);
65
+ return {
66
+ node: demoNode,
67
+ error: error,
68
+ setSources: setSources
69
+ };
70
+ };
@@ -1,19 +1,69 @@
1
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ 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."); }
3
+ 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); }
4
+ 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; }
5
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
2
7
  import { getRouteMetaById, matchRoutes, useAppData, useLocation, useRouteData } from 'dumi';
3
- import { useMemo } from 'react';
4
- import use from "./context/use";
8
+ import { useCallback, useState } from 'react';
9
+ import { use, useIsomorphicLayoutEffect } from "./utils";
5
10
  var cache = new Map();
6
- var useAsyncRouteMeta = function useAsyncRouteMeta(id) {
7
- if (!cache.has(id)) {
8
- cache.set(id, getRouteMetaById(id));
9
- }
10
- return use(cache.get(id));
11
- };
12
- var emptyMeta = {
11
+ var EMPTY_META = {
13
12
  frontmatter: {},
14
13
  toc: [],
15
14
  texts: []
16
15
  };
16
+ var ASYNC_META_PROPS = ['texts'];
17
+ function getCachedRouteMeta(route) {
18
+ var cacheKey = route.id;
19
+ var pendingCacheKey = "".concat(cacheKey, ":pending");
20
+ if (!cache.get(cacheKey)) {
21
+ var _meta$tabs;
22
+ var merge = function merge() {
23
+ var meta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_META;
24
+ if (route.meta) {
25
+ Object.keys(route.meta).forEach(function (key) {
26
+ var _ref, _ref$key;
27
+ (_ref$key = (_ref = meta)[key]) !== null && _ref$key !== void 0 ? _ref$key : _ref[key] = route.meta[key];
28
+ });
29
+ }
30
+ return meta;
31
+ };
32
+ var meta = merge(getRouteMetaById(route.id, {
33
+ syncOnly: true
34
+ }));
35
+ var ret = Promise.resolve(meta);
36
+ var proxyGetter = function proxyGetter(target, prop) {
37
+ if (ASYNC_META_PROPS.includes(prop)) {
38
+ if (!cache.get(pendingCacheKey)) {
39
+ // load async meta then replace cache
40
+ cache.set(pendingCacheKey, getRouteMetaById(route.id).then(function (full) {
41
+ return cache.set(cacheKey, Promise.resolve(merge(full))).get(cacheKey);
42
+ }));
43
+ }
44
+
45
+ // throw promise to trigger suspense
46
+ throw cache.get(pendingCacheKey);
47
+ }
48
+ return target[prop];
49
+ };
50
+
51
+ // return sync meta by default
52
+ ret.status = 'fulfilled';
53
+
54
+ // load async meta if property accessed
55
+ (_meta$tabs = meta.tabs) === null || _meta$tabs === void 0 ? void 0 : _meta$tabs.forEach(function (tab) {
56
+ tab.meta = new Proxy(tab.meta, {
57
+ get: proxyGetter
58
+ });
59
+ });
60
+ ret.value = new Proxy(meta, {
61
+ get: proxyGetter
62
+ });
63
+ cache.set(cacheKey, ret);
64
+ }
65
+ return cache.get(cacheKey);
66
+ }
17
67
 
18
68
  /**
19
69
  * hook for get matched route meta
@@ -25,23 +75,26 @@ export var useRouteMeta = function useRouteMeta() {
25
75
  pathname = _useLocation.pathname;
26
76
  var _useAppData = useAppData(),
27
77
  clientRoutes = _useAppData.clientRoutes;
28
- var curRoute = useMemo(function () {
78
+ var getter = useCallback(function () {
79
+ var ret;
29
80
  if (route.path === pathname && !('isLayout' in route)) {
30
81
  // use `useRouteData` result if matched, for performance
31
- return route;
82
+ ret = route;
32
83
  } else {
33
84
  var _matchRoutes;
34
85
  // match manually for dynamic route & layout component
35
86
  var matched = (_matchRoutes = matchRoutes(clientRoutes, pathname)) === null || _matchRoutes === void 0 ? void 0 : _matchRoutes.pop();
36
- return matched === null || matched === void 0 ? void 0 : matched.route;
87
+ ret = matched === null || matched === void 0 ? void 0 : matched.route;
37
88
  }
89
+ return ret;
90
+ }, [clientRoutes.length, pathname]);
91
+ var _useState = useState(getter),
92
+ _useState2 = _slicedToArray(_useState, 2),
93
+ matchedRoute = _useState2[0],
94
+ setMatchedRoute = _useState2[1];
95
+ var meta = use(getCachedRouteMeta(matchedRoute));
96
+ useIsomorphicLayoutEffect(function () {
97
+ setMatchedRoute(getter);
38
98
  }, [clientRoutes.length, pathname]);
39
- var meta = useAsyncRouteMeta(curRoute === null || curRoute === void 0 ? void 0 : curRoute.id) || emptyMeta;
40
- if (curRoute && 'meta' in curRoute && _typeof(curRoute.meta) === 'object') {
41
- Object.keys(curRoute.meta).forEach(function (key) {
42
- var _ref, _ref$key;
43
- (_ref$key = (_ref = meta)[key]) !== null && _ref$key !== void 0 ? _ref$key : _ref[key] = curRoute.meta[key];
44
- });
45
- }
46
99
  return meta;
47
100
  };
@@ -20,5 +20,5 @@ export declare const useSiteSearch: () => {
20
20
  setKeywords: (val: string) => void;
21
21
  result: ISearchResult;
22
22
  loading: boolean;
23
- loadSearchData: () => void;
23
+ load: () => Promise<void>;
24
24
  };
@@ -1,9 +1,3 @@
1
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
3
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
6
- function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
1
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
2
  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."); }
9
3
  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); }
@@ -26,7 +20,7 @@ if (typeof window !== 'undefined') {
26
20
  }
27
21
  export var useSiteSearch = function useSiteSearch() {
28
22
  var debounceTimer = useRef();
29
- var _useState = useState(true),
23
+ var _useState = useState(false),
30
24
  _useState2 = _slicedToArray(_useState, 2),
31
25
  loading = _useState2[0],
32
26
  setLoading = _useState2[1];
@@ -34,27 +28,22 @@ export var useSiteSearch = function useSiteSearch() {
34
28
  _useState4 = _slicedToArray(_useState3, 2),
35
29
  keywords = _useState4[0],
36
30
  setKeywords = _useState4[1];
37
- var _useState5 = useState(false),
38
- _useState6 = _slicedToArray(_useState5, 2),
39
- enabled = _useState6[0],
40
- setEnabled = _useState6[1];
41
31
  var navData = useNavData();
42
- var _useState7 = useState([]),
43
- _useState8 = _slicedToArray(_useState7, 2),
44
- result = _useState8[0],
45
- setResult = _useState8[1];
32
+ var _useState5 = useState([]),
33
+ _useState6 = _slicedToArray(_useState5, 2),
34
+ result = _useState6[0],
35
+ setResult = _useState6[1];
36
+ var _useSearchData = useSearchData(),
37
+ _useSearchData2 = _slicedToArray(_useSearchData, 2),
38
+ data = _useSearchData2[0],
39
+ load = _useSearchData2[1];
46
40
  var setter = useCallback(function (val) {
41
+ load();
47
42
  setLoading(true);
48
43
  setKeywords(val);
49
44
  }, []);
50
- var loadSearchData = function loadSearchData() {
51
- return setEnabled(true);
52
- };
53
- var _useSearchData = useSearchData(enabled),
54
- _useSearchData2 = _slicedToArray(_useSearchData, 2),
55
- filledRoutes = _useSearchData2[0],
56
- demos = _useSearchData2[1];
57
- var mergedLoading = loading || !filledRoutes;
45
+ var routes = data === null || data === void 0 ? void 0 : data[0];
46
+ var demos = data === null || data === void 0 ? void 0 : data[1];
58
47
  useEffect(function () {
59
48
  worker.onmessage = function (e) {
60
49
  setResult(e.data);
@@ -62,35 +51,18 @@ export var useSiteSearch = function useSiteSearch() {
62
51
  };
63
52
  }, []);
64
53
  useEffect(function () {
65
- if (!filledRoutes || !demos) {
66
- return;
67
- }
68
-
69
- // omit demo component for postmessage
70
- var demoData = Object.entries(demos).reduce(function (acc, _ref) {
71
- var _ref2 = _slicedToArray(_ref, 2),
72
- key = _ref2[0],
73
- _ref2$ = _ref2[1],
74
- asset = _ref2$.asset,
75
- routeId = _ref2$.routeId;
76
- return _objectSpread(_objectSpread({}, acc), {}, _defineProperty({}, key, {
77
- asset: asset,
78
- routeId: routeId
79
- }));
80
- }, {});
54
+ if (!routes || !demos) return;
81
55
  worker.postMessage({
82
56
  action: 'generate-metadata',
83
57
  args: {
84
- routes: JSON.parse(JSON.stringify(filledRoutes)),
58
+ routes: JSON.parse(JSON.stringify(routes)),
85
59
  nav: navData,
86
- demos: demoData
60
+ demos: demos
87
61
  }
88
62
  });
89
- }, [demos, navData, filledRoutes]);
63
+ }, [routes, demos, navData]);
90
64
  useEffect(function () {
91
- if (!filledRoutes) {
92
- return;
93
- }
65
+ if (!routes) return;
94
66
  var str = keywords.trim();
95
67
  if (str) {
96
68
  clearTimeout(debounceTimer.current);
@@ -105,12 +77,12 @@ export var useSiteSearch = function useSiteSearch() {
105
77
  } else {
106
78
  setResult([]);
107
79
  }
108
- }, [keywords, filledRoutes]);
80
+ }, [keywords, routes]);
109
81
  return {
110
82
  keywords: keywords,
111
83
  setKeywords: setter,
112
84
  result: result,
113
- loading: mergedLoading,
114
- loadSearchData: loadSearchData
85
+ loading: loading,
86
+ load: load
115
87
  };
116
88
  };
@@ -1,9 +1,12 @@
1
- import type { DemoInfo } from '../context';
1
+ import { getFullDemos } from 'dumi';
2
2
  import { useLocaleDocRoutes } from '../utils';
3
- type Demos = Record<string, DemoInfo>;
4
- type ReturnData = [
5
- routes: ReturnType<typeof useLocaleDocRoutes> | null,
6
- demo: Demos | null
3
+ type IDemosData = Record<string, Partial<Awaited<ReturnType<typeof getFullDemos>>[string]>>;
4
+ type ISearchData = [
5
+ routes: ReturnType<typeof useLocaleDocRoutes>,
6
+ demos: IDemosData
7
+ ];
8
+ export default function useSearchData(): [
9
+ ISearchData | null,
10
+ () => Promise<void>
7
11
  ];
8
- export default function useSearchData(enabled: boolean): ReturnData;
9
12
  export {};