dumi 2.4.35 → 2.4.36
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/assetParsers/block.d.ts +4 -2
- package/dist/assetParsers/block.js +73 -0
- package/dist/client/theme-api/DumiDemo/index.d.ts +7 -1
- package/dist/client/theme-api/DumiDemo/index.js +5 -2
- package/dist/features/meta.js +1 -0
- package/dist/loaders/markdown/index.js +4 -1
- package/dist/loaders/markdown/transformer/index.d.ts +1 -0
- package/dist/loaders/markdown/transformer/index.js +1 -0
- package/dist/loaders/markdown/transformer/rehypeDemo.d.ts +1 -0
- package/dist/loaders/markdown/transformer/rehypeDemo.js +24 -2
- package/dist/templates/meta/exports.ts.tpl +19 -5
- package/dist/templates/meta/index.ts.tpl +6 -6
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ export interface IParsedBlockAsset {
|
|
|
13
13
|
resolveMap: Record<string, string>;
|
|
14
14
|
frontmatter: ReturnType<typeof parseCodeFrontmatter>['frontmatter'];
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
interface IParseBlockAssetOptions {
|
|
17
17
|
fileAbsPath: string;
|
|
18
18
|
fileLocale?: string;
|
|
19
19
|
id: string;
|
|
@@ -21,5 +21,7 @@ declare function parseBlockAsset(opts: {
|
|
|
21
21
|
entryPointCode?: string;
|
|
22
22
|
resolver: typeof sync;
|
|
23
23
|
techStack: IDumiTechStack;
|
|
24
|
-
|
|
24
|
+
cacheable?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare function parseBlockAsset(opts: IParseBlockAssetOptions): Promise<IParsedBlockAsset>;
|
|
25
27
|
export default parseBlockAsset;
|
|
@@ -39,7 +39,71 @@ var import_fs = __toESM(require("fs"));
|
|
|
39
39
|
var import_path = __toESM(require("path"));
|
|
40
40
|
var import_plugin_utils = require("umi/plugin-utils");
|
|
41
41
|
var import_constants = require("../constants");
|
|
42
|
+
var MAX_BLOCK_ASSET_CACHE_SIZE = 512;
|
|
43
|
+
var blockAssetCache = /* @__PURE__ */ new Map();
|
|
44
|
+
function cloneParsedBlockAsset(ret) {
|
|
45
|
+
return {
|
|
46
|
+
asset: JSON.parse(JSON.stringify(ret.asset)),
|
|
47
|
+
resolveMap: { ...ret.resolveMap },
|
|
48
|
+
frontmatter: ret.frontmatter ? JSON.parse(JSON.stringify(ret.frontmatter)) : ret.frontmatter
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function getContentHashFromFile(file) {
|
|
52
|
+
try {
|
|
53
|
+
return (0, import_utils.getContentHash)(import_fs.default.readFileSync(file, "utf-8"));
|
|
54
|
+
} catch {
|
|
55
|
+
return "missing";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function getDepsKey(deps) {
|
|
59
|
+
return JSON.stringify(
|
|
60
|
+
Array.from(new Set(deps)).sort().map((file) => `${(0, import_plugin_utils.winPath)(file)}:${getContentHashFromFile(file)}`)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function getParseCacheKey(opts) {
|
|
64
|
+
const entryContent = opts.entryPointCode ?? import_fs.default.readFileSync(opts.fileAbsPath, "utf-8");
|
|
65
|
+
return JSON.stringify({
|
|
66
|
+
file: (0, import_plugin_utils.winPath)(opts.fileAbsPath),
|
|
67
|
+
fileLocale: opts.fileLocale,
|
|
68
|
+
id: opts.id,
|
|
69
|
+
refAtomIds: opts.refAtomIds,
|
|
70
|
+
entryHash: (0, import_utils.getContentHash)(entryContent),
|
|
71
|
+
techStack: opts.techStack.name,
|
|
72
|
+
runtimeOpts: opts.techStack.runtimeOpts,
|
|
73
|
+
hasOnBlockLoad: Boolean(opts.techStack.onBlockLoad),
|
|
74
|
+
hasGenerateMetadata: Boolean(opts.techStack.generateMetadata),
|
|
75
|
+
hasGenerateSources: Boolean(opts.techStack.generateSources)
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function getParseDeps(ret, entryFile) {
|
|
79
|
+
return Object.values(ret.resolveMap).filter(
|
|
80
|
+
(file) => import_path.default.isAbsolute(file) && file !== entryFile
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function getCachedBlockAsset(cacheKey) {
|
|
84
|
+
const cached = blockAssetCache.get(cacheKey);
|
|
85
|
+
if (cached && cached.depsKey === getDepsKey(cached.deps)) {
|
|
86
|
+
return cloneParsedBlockAsset(cached.result);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function setCachedBlockAsset(cacheKey, ret, deps) {
|
|
90
|
+
if (blockAssetCache.size >= MAX_BLOCK_ASSET_CACHE_SIZE) {
|
|
91
|
+
const firstKey = blockAssetCache.keys().next().value;
|
|
92
|
+
if (firstKey)
|
|
93
|
+
blockAssetCache.delete(firstKey);
|
|
94
|
+
}
|
|
95
|
+
blockAssetCache.set(cacheKey, {
|
|
96
|
+
deps,
|
|
97
|
+
depsKey: getDepsKey(deps),
|
|
98
|
+
result: cloneParsedBlockAsset(ret)
|
|
99
|
+
});
|
|
100
|
+
}
|
|
42
101
|
async function parseBlockAsset(opts) {
|
|
102
|
+
const cacheKey = opts.cacheable ? getParseCacheKey(opts) : "";
|
|
103
|
+
const cached = cacheKey ? getCachedBlockAsset(cacheKey) : void 0;
|
|
104
|
+
if (cached) {
|
|
105
|
+
return cached;
|
|
106
|
+
}
|
|
43
107
|
const asset = {
|
|
44
108
|
type: "BLOCK",
|
|
45
109
|
id: opts.id,
|
|
@@ -163,9 +227,18 @@ async function parseBlockAsset(opts) {
|
|
|
163
227
|
}
|
|
164
228
|
]
|
|
165
229
|
});
|
|
230
|
+
let hasError = false;
|
|
166
231
|
try {
|
|
167
232
|
await deferrer;
|
|
168
233
|
} catch {
|
|
234
|
+
hasError = true;
|
|
235
|
+
}
|
|
236
|
+
if (!hasError && cacheKey) {
|
|
237
|
+
setCachedBlockAsset(
|
|
238
|
+
cacheKey,
|
|
239
|
+
result,
|
|
240
|
+
getParseDeps(result, opts.fileAbsPath)
|
|
241
|
+
);
|
|
169
242
|
}
|
|
170
243
|
return result;
|
|
171
244
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
|
-
import type { IPreviewerProps } from '../types';
|
|
2
|
+
import type { IDemoData, IPreviewerProps } from '../types';
|
|
3
|
+
type DemoGetter = () => Promise<{
|
|
4
|
+
demos: Record<string, IDemoData>;
|
|
5
|
+
}>;
|
|
3
6
|
export interface IDumiDemoProps {
|
|
4
7
|
demo: {
|
|
5
8
|
id: string;
|
|
6
9
|
inline?: boolean;
|
|
10
|
+
loader?: DemoGetter;
|
|
11
|
+
version?: string;
|
|
7
12
|
};
|
|
8
13
|
previewerProps: Omit<IPreviewerProps, 'asset' | 'children'>;
|
|
9
14
|
}
|
|
10
15
|
export declare const DumiDemo: FC<IDumiDemoProps>;
|
|
16
|
+
export {};
|
|
@@ -10,8 +10,11 @@ var InternalDumiDemo = function InternalDumiDemo(props) {
|
|
|
10
10
|
historyType = _useSiteData.historyType;
|
|
11
11
|
var _useAppData = useAppData(),
|
|
12
12
|
basename = _useAppData.basename;
|
|
13
|
-
var
|
|
14
|
-
|
|
13
|
+
var _props$demo = props.demo,
|
|
14
|
+
id = _props$demo.id,
|
|
15
|
+
loader = _props$demo.loader,
|
|
16
|
+
version = _props$demo.version;
|
|
17
|
+
var demo = useDemo(id, loader, version);
|
|
15
18
|
var component = demo.component,
|
|
16
19
|
asset = demo.asset,
|
|
17
20
|
renderOpts = demo.renderOpts;
|
package/dist/features/meta.js
CHANGED
|
@@ -73,6 +73,7 @@ var meta_default = (api) => {
|
|
|
73
73
|
});
|
|
74
74
|
parsedMetaFiles.forEach((metaFile) => {
|
|
75
75
|
metaFile.isMarkdown = metaFile.file.endsWith(".md");
|
|
76
|
+
metaFile.loadDemoIndex = metaFile.isMarkdown && !(api.env === "development" && Boolean(api.config.utoopack));
|
|
76
77
|
});
|
|
77
78
|
api.writeTmpFile({
|
|
78
79
|
noPluginDir: true,
|
|
@@ -320,6 +320,7 @@ function mdLoader(content) {
|
|
|
320
320
|
var _a, _b, _c;
|
|
321
321
|
let opts = this.getOptions();
|
|
322
322
|
const loaderContextPath = opts[import_utoopackLoaders.UTOOPACK_LOADER_CTX_KEY];
|
|
323
|
+
const useUtoopackDemoHMR = process.env.NODE_ENV === "development" && Boolean(loaderContextPath);
|
|
323
324
|
if (loaderContextPath) {
|
|
324
325
|
const ctx = require(loaderContextPath);
|
|
325
326
|
if (!((_a = opts.techStacks) == null ? void 0 : _a.length)) {
|
|
@@ -346,6 +347,7 @@ function mdLoader(content) {
|
|
|
346
347
|
const baseCacheKey = [
|
|
347
348
|
this.resourcePath,
|
|
348
349
|
(0, import_utils.getContentHash)(content),
|
|
350
|
+
useUtoopackDemoHMR,
|
|
349
351
|
JSON.stringify(import_plugin_utils.lodash.omit(opts, ["mode", "builtins", "onResolveDemos"]))
|
|
350
352
|
].join(":");
|
|
351
353
|
const cacheKey = [
|
|
@@ -364,7 +366,8 @@ function mdLoader(content) {
|
|
|
364
366
|
}
|
|
365
367
|
deferrer[cacheKey] = (0, import_transformer.default)(content, {
|
|
366
368
|
...import_plugin_utils.lodash.omit(opts, ["mode", "builtins", "onResolveDemos"]),
|
|
367
|
-
fileAbsPath: (0, import_plugin_utils.winPath)(this.resourcePath)
|
|
369
|
+
fileAbsPath: (0, import_plugin_utils.winPath)(this.resourcePath),
|
|
370
|
+
useUtoopackDemoHMR
|
|
368
371
|
});
|
|
369
372
|
deferrer[cacheKey].then((ret) => {
|
|
370
373
|
depsMapping[this.resourcePath] = ret.meta.embeds.concat(
|
|
@@ -113,6 +113,7 @@ var transformer_default = async (raw, opts) => {
|
|
|
113
113
|
fileAbsPath: opts.fileAbsPath,
|
|
114
114
|
fileLocaleLessPath,
|
|
115
115
|
fileLocale,
|
|
116
|
+
useUtoopackDemoHMR: opts.useUtoopackDemoHMR,
|
|
116
117
|
resolve: opts.resolve,
|
|
117
118
|
resolver
|
|
118
119
|
}).use(import_rehypeSlug.default).use(import_rehypeLink.default, {
|
|
@@ -10,6 +10,7 @@ type IRehypeDemoOptions = Pick<IMdTransformerOptions, 'techStacks' | 'cwd' | 'fi
|
|
|
10
10
|
resolver: typeof sync;
|
|
11
11
|
fileLocaleLessPath: string;
|
|
12
12
|
fileLocale?: string;
|
|
13
|
+
useUtoopackDemoHMR?: boolean;
|
|
13
14
|
};
|
|
14
15
|
export default function rehypeDemo(opts: IRehypeDemoOptions): Transformer<Root>;
|
|
15
16
|
export {};
|
|
@@ -47,6 +47,8 @@ var toString;
|
|
|
47
47
|
var isElement;
|
|
48
48
|
var DEMO_NODE_CONTAINER = "$demo-container";
|
|
49
49
|
var DEMO_PROP_VALUE_KEY = "$demo-prop-value-key";
|
|
50
|
+
var DEMO_LOADER_PLACEHOLDER = "__DUMI_DEMO_LOADER__";
|
|
51
|
+
var DEMO_LOADER_PLACEHOLDER_VALUE = DEMO_LOADER_PLACEHOLDER;
|
|
50
52
|
var DUMI_DEMO_TAG = "DumiDemo";
|
|
51
53
|
var DUMI_DEMO_GRID_TAG = "DumiDemoGrid";
|
|
52
54
|
var SKIP_DEMO_PARSE = "pure";
|
|
@@ -249,9 +251,15 @@ function rehypeDemo(opts) {
|
|
|
249
251
|
});
|
|
250
252
|
}
|
|
251
253
|
const propDemo = { id: parseOpts.id };
|
|
254
|
+
if (opts.useUtoopackDemoHMR) {
|
|
255
|
+
propDemo.loader = DEMO_LOADER_PLACEHOLDER_VALUE;
|
|
256
|
+
}
|
|
252
257
|
demoIds.push(parseOpts.id);
|
|
253
258
|
deferrers.push(
|
|
254
|
-
(0, import_block.default)(
|
|
259
|
+
(0, import_block.default)({
|
|
260
|
+
...parseOpts,
|
|
261
|
+
cacheable: opts.useUtoopackDemoHMR
|
|
262
|
+
}).then(
|
|
255
263
|
async ({ asset, resolveMap, frontmatter }) => {
|
|
256
264
|
var _a2, _b2, _c2;
|
|
257
265
|
if (demoIds.indexOf(parseOpts.id) !== demoIds.lastIndexOf(parseOpts.id)) {
|
|
@@ -287,6 +295,11 @@ function rehypeDemo(opts) {
|
|
|
287
295
|
if (originalProps[key])
|
|
288
296
|
asset[key] = originalProps[key];
|
|
289
297
|
});
|
|
298
|
+
if (opts.useUtoopackDemoHMR) {
|
|
299
|
+
propDemo.version = (0, import_utils.getContentHash)(
|
|
300
|
+
JSON.stringify(asset.dependencies)
|
|
301
|
+
);
|
|
302
|
+
}
|
|
290
303
|
if (/ inline/.test(String((_b2 = codeNode.data) == null ? void 0 : _b2.meta)) || originalProps.inline) {
|
|
291
304
|
propDemo.inline = true;
|
|
292
305
|
return {
|
|
@@ -368,7 +381,16 @@ function rehypeDemo(opts) {
|
|
|
368
381
|
await Promise.all(deferrers).then((demos) => {
|
|
369
382
|
vFile.data.demos = demos;
|
|
370
383
|
replaceNodes.forEach((node) => {
|
|
371
|
-
const
|
|
384
|
+
const demoLoader = `() => import('${(0, import_plugin_utils.winPath)(
|
|
385
|
+
opts.fileAbsPath
|
|
386
|
+
)}?type=demo')`;
|
|
387
|
+
let value = JSON.stringify(node.data[DEMO_PROP_VALUE_KEY]);
|
|
388
|
+
if (opts.useUtoopackDemoHMR) {
|
|
389
|
+
value = value.replace(
|
|
390
|
+
new RegExp(`"${DEMO_LOADER_PLACEHOLDER}"`, "g"),
|
|
391
|
+
demoLoader
|
|
392
|
+
);
|
|
393
|
+
}
|
|
372
394
|
if (node.JSXAttributes[0].type === "JSXAttribute") {
|
|
373
395
|
node.JSXAttributes[0].value = value;
|
|
374
396
|
} else {
|
|
@@ -46,6 +46,8 @@ const demoIdMap = Object.keys(filesMeta).reduce((total, current) => {
|
|
|
46
46
|
return total;
|
|
47
47
|
}, {});
|
|
48
48
|
|
|
49
|
+
type DemoGetter = () => Promise<{ demos: Record<string, IDemoData> }>;
|
|
50
|
+
|
|
49
51
|
const demosCache = new Map<string, Promise<IDemoData | undefined>>();
|
|
50
52
|
|
|
51
53
|
/**
|
|
@@ -68,19 +70,31 @@ function expandDemoContext(context?: IDemoData['context']) {
|
|
|
68
70
|
/**
|
|
69
71
|
* use demo data by id
|
|
70
72
|
*/
|
|
71
|
-
export function useDemo(
|
|
72
|
-
|
|
73
|
+
export function useDemo(
|
|
74
|
+
id: string,
|
|
75
|
+
loader?: DemoGetter,
|
|
76
|
+
version?: string,
|
|
77
|
+
): IDemoData | undefined {
|
|
78
|
+
const cacheKey = version ? `${id}:${version}` : id;
|
|
79
|
+
const getter = loader ?? demoIdMap[id];
|
|
80
|
+
|
|
81
|
+
if (!demosCache.get(cacheKey)) {
|
|
82
|
+
if (!getter) return undefined;
|
|
83
|
+
|
|
73
84
|
demosCache.set(
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
cacheKey,
|
|
86
|
+
getter().then(({ demos }) => {
|
|
76
87
|
// expand context for omit ext
|
|
77
88
|
expandDemoContext(demos[id].context);
|
|
78
89
|
return demos[id];
|
|
79
90
|
}),
|
|
80
91
|
);
|
|
92
|
+
|
|
93
|
+
// Reuse local demo data for consumers that still call useDemo(id), such as useLiveDemo.
|
|
94
|
+
demosCache.set(id, demosCache.get(cacheKey)!);
|
|
81
95
|
}
|
|
82
96
|
|
|
83
|
-
return use(demosCache.get(
|
|
97
|
+
return use(demosCache.get(cacheKey)!);
|
|
84
98
|
}
|
|
85
99
|
|
|
86
100
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{{#metaFiles}}
|
|
2
|
-
{{#
|
|
2
|
+
{{#loadDemoIndex}}
|
|
3
3
|
import { frontmatter as fm{{{index}}}, toc as t{{{index}}}, demoIndex as dmi{{{index}}} } from '{{{file}}}?type=frontmatter';
|
|
4
|
-
{{/
|
|
5
|
-
{{^
|
|
4
|
+
{{/loadDemoIndex}}
|
|
5
|
+
{{^loadDemoIndex}}
|
|
6
6
|
import { frontmatter as fm{{{index}}}, toc as t{{{index}}} } from '{{{file}}}?type=frontmatter';
|
|
7
|
-
{{/
|
|
7
|
+
{{/loadDemoIndex}}
|
|
8
8
|
{{/metaFiles}}
|
|
9
9
|
|
|
10
10
|
export const filesMeta = {
|
|
@@ -12,9 +12,9 @@ export const filesMeta = {
|
|
|
12
12
|
'{{{id}}}': {
|
|
13
13
|
frontmatter: fm{{{index}}},
|
|
14
14
|
toc: t{{{index}}},
|
|
15
|
-
{{#
|
|
15
|
+
{{#loadDemoIndex}}
|
|
16
16
|
demoIndex: dmi{{{index}}},
|
|
17
|
-
{{/
|
|
17
|
+
{{/loadDemoIndex}}
|
|
18
18
|
{{#tabs}}
|
|
19
19
|
tabs: {{{tabs}}},
|
|
20
20
|
{{/tabs}}
|