@rspress/plugin-preview 1.11.2 → 1.12.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.js CHANGED
@@ -5,9 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
- };
11
8
  var __export = (target, all) => {
12
9
  for (var name in all)
13
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,7 +27,51 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
27
  ));
31
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
29
 
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ pluginPreview: () => pluginPreview
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+ var import_path4 = require("path");
37
+ var import_node_net = __toESM(require("net"));
38
+ var import_core = require("@rsbuild/core");
39
+ var import_plugin_solid = require("@rsbuild/plugin-solid");
40
+ var import_plugin_babel = require("@rsbuild/plugin-babel");
41
+ var import_plugin_react = require("@rsbuild/plugin-react");
42
+ var import_lodash = require("lodash");
43
+
44
+ // src/remarkPlugin.ts
45
+ var import_path2 = require("path");
46
+
33
47
  // ../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/lib/index.js
48
+ var convert = (
49
+ /**
50
+ * @type {(
51
+ * (<Kind extends Node>(test: PredicateTest<Kind>) => AssertPredicate<Kind>) &
52
+ * ((test?: Test) => AssertAnything)
53
+ * )}
54
+ */
55
+ /**
56
+ * @param {Test} [test]
57
+ * @returns {AssertAnything}
58
+ */
59
+ function(test) {
60
+ if (test === void 0 || test === null) {
61
+ return ok;
62
+ }
63
+ if (typeof test === "string") {
64
+ return typeFactory(test);
65
+ }
66
+ if (typeof test === "object") {
67
+ return Array.isArray(test) ? anyFactory(test) : propsFactory(test);
68
+ }
69
+ if (typeof test === "function") {
70
+ return castFactory(test);
71
+ }
72
+ throw new Error("Expected function, string, or object as test");
73
+ }
74
+ );
34
75
  function anyFactory(tests) {
35
76
  const checks = [];
36
77
  let index = -1;
@@ -76,57 +117,81 @@ function castFactory(check) {
76
117
  function ok() {
77
118
  return true;
78
119
  }
79
- var convert;
80
- var init_lib = __esm({
81
- "../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/lib/index.js"() {
82
- "use strict";
83
- convert = /**
84
- * @type {(
85
- * (<Kind extends Node>(test: PredicateTest<Kind>) => AssertPredicate<Kind>) &
86
- * ((test?: Test) => AssertAnything)
87
- * )}
88
- */
89
- /**
90
- * @param {Test} [test]
91
- * @returns {AssertAnything}
92
- */
93
- function(test) {
94
- if (test === void 0 || test === null) {
95
- return ok;
96
- }
97
- if (typeof test === "string") {
98
- return typeFactory(test);
99
- }
100
- if (typeof test === "object") {
101
- return Array.isArray(test) ? anyFactory(test) : propsFactory(test);
102
- }
103
- if (typeof test === "function") {
104
- return castFactory(test);
105
- }
106
- throw new Error("Expected function, string, or object as test");
107
- };
108
- }
109
- });
110
-
111
- // ../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/index.js
112
- var init_unist_util_is = __esm({
113
- "../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/index.js"() {
114
- "use strict";
115
- init_lib();
116
- }
117
- });
118
120
 
119
121
  // ../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/color.js
120
122
  function color(d) {
121
123
  return "\x1B[33m" + d + "\x1B[39m";
122
124
  }
123
- var init_color = __esm({
124
- "../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/color.js"() {
125
- "use strict";
126
- }
127
- });
128
125
 
129
126
  // ../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/index.js
127
+ var CONTINUE = true;
128
+ var EXIT = false;
129
+ var SKIP = "skip";
130
+ var visitParents = (
131
+ /**
132
+ * @type {(
133
+ * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean | null | undefined) => void) &
134
+ * (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean | null | undefined) => void)
135
+ * )}
136
+ */
137
+ /**
138
+ * @param {Node} tree
139
+ * @param {Test} test
140
+ * @param {Visitor<Node>} visitor
141
+ * @param {boolean | null | undefined} [reverse]
142
+ * @returns {void}
143
+ */
144
+ function(tree, test, visitor, reverse) {
145
+ if (typeof test === "function" && typeof visitor !== "function") {
146
+ reverse = visitor;
147
+ visitor = test;
148
+ test = null;
149
+ }
150
+ const is2 = convert(test);
151
+ const step = reverse ? -1 : 1;
152
+ factory(tree, void 0, [])();
153
+ function factory(node, index, parents) {
154
+ const value = node && typeof node === "object" ? node : {};
155
+ if (typeof value.type === "string") {
156
+ const name = (
157
+ // `hast`
158
+ typeof value.tagName === "string" ? value.tagName : (
159
+ // `xast`
160
+ typeof value.name === "string" ? value.name : void 0
161
+ )
162
+ );
163
+ Object.defineProperty(visit2, "name", {
164
+ value: "node (" + color(node.type + (name ? "<" + name + ">" : "")) + ")"
165
+ });
166
+ }
167
+ return visit2;
168
+ function visit2() {
169
+ let result = [];
170
+ let subresult;
171
+ let offset;
172
+ let grandparents;
173
+ if (!test || is2(node, index, parents[parents.length - 1] || null)) {
174
+ result = toResult(visitor(node, parents));
175
+ if (result[0] === EXIT) {
176
+ return result;
177
+ }
178
+ }
179
+ if (node.children && result[0] !== SKIP) {
180
+ offset = (reverse ? node.children.length : -1) + step;
181
+ grandparents = parents.concat(node);
182
+ while (offset > -1 && offset < node.children.length) {
183
+ subresult = factory(node.children[offset], offset, grandparents)();
184
+ if (subresult[0] === EXIT) {
185
+ return subresult;
186
+ }
187
+ offset = typeof subresult[1] === "number" ? subresult[1] : offset + step;
188
+ }
189
+ }
190
+ return result;
191
+ }
192
+ }
193
+ }
194
+ );
130
195
  function toResult(value) {
131
196
  if (Array.isArray(value)) {
132
197
  return value;
@@ -136,154 +201,42 @@ function toResult(value) {
136
201
  }
137
202
  return [value];
138
203
  }
139
- var CONTINUE, EXIT, SKIP, visitParents;
140
- var init_lib2 = __esm({
141
- "../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/index.js"() {
142
- "use strict";
143
- init_unist_util_is();
144
- init_color();
145
- CONTINUE = true;
146
- EXIT = false;
147
- SKIP = "skip";
148
- visitParents = /**
149
- * @type {(
150
- * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean | null | undefined) => void) &
151
- * (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean | null | undefined) => void)
152
- * )}
153
- */
154
- /**
155
- * @param {Node} tree
156
- * @param {Test} test
157
- * @param {Visitor<Node>} visitor
158
- * @param {boolean | null | undefined} [reverse]
159
- * @returns {void}
160
- */
161
- function(tree, test, visitor, reverse) {
162
- if (typeof test === "function" && typeof visitor !== "function") {
163
- reverse = visitor;
164
- visitor = test;
165
- test = null;
166
- }
167
- const is2 = convert(test);
168
- const step = reverse ? -1 : 1;
169
- factory(tree, void 0, [])();
170
- function factory(node, index, parents) {
171
- const value = node && typeof node === "object" ? node : {};
172
- if (typeof value.type === "string") {
173
- const name = (
174
- // `hast`
175
- typeof value.tagName === "string" ? value.tagName : (
176
- // `xast`
177
- typeof value.name === "string" ? value.name : void 0
178
- )
179
- );
180
- Object.defineProperty(visit2, "name", {
181
- value: "node (" + color(node.type + (name ? "<" + name + ">" : "")) + ")"
182
- });
183
- }
184
- return visit2;
185
- function visit2() {
186
- let result = [];
187
- let subresult;
188
- let offset;
189
- let grandparents;
190
- if (!test || is2(node, index, parents[parents.length - 1] || null)) {
191
- result = toResult(visitor(node, parents));
192
- if (result[0] === EXIT) {
193
- return result;
194
- }
195
- }
196
- if (node.children && result[0] !== SKIP) {
197
- offset = (reverse ? node.children.length : -1) + step;
198
- grandparents = parents.concat(node);
199
- while (offset > -1 && offset < node.children.length) {
200
- subresult = factory(node.children[offset], offset, grandparents)();
201
- if (subresult[0] === EXIT) {
202
- return subresult;
203
- }
204
- offset = typeof subresult[1] === "number" ? subresult[1] : offset + step;
205
- }
206
- }
207
- return result;
208
- }
209
- }
210
- };
211
- }
212
- });
213
-
214
- // ../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/index.js
215
- var init_unist_util_visit_parents = __esm({
216
- "../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/index.js"() {
217
- "use strict";
218
- init_lib2();
219
- }
220
- });
221
204
 
222
205
  // ../../node_modules/.pnpm/unist-util-visit@4.1.1/node_modules/unist-util-visit/index.js
223
- var unist_util_visit_exports = {};
224
- __export(unist_util_visit_exports, {
225
- CONTINUE: () => CONTINUE,
226
- EXIT: () => EXIT,
227
- SKIP: () => SKIP,
228
- visit: () => visit
229
- });
230
- var visit;
231
- var init_unist_util_visit = __esm({
232
- "../../node_modules/.pnpm/unist-util-visit@4.1.1/node_modules/unist-util-visit/index.js"() {
233
- "use strict";
234
- init_unist_util_visit_parents();
235
- init_unist_util_visit_parents();
236
- visit = /**
237
- * @type {(
238
- * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
239
- * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)
240
- * )}
241
- */
242
- /**
243
- * @param {Node} tree
244
- * @param {Test} test
245
- * @param {import('./complex-types.js').Visitor} visitor
246
- * @param {boolean} [reverse]
247
- */
248
- function(tree, test, visitor, reverse) {
249
- if (typeof test === "function" && typeof visitor !== "function") {
250
- reverse = visitor;
251
- visitor = test;
252
- test = null;
253
- }
254
- visitParents(tree, test, overload, reverse);
255
- function overload(node, parents) {
256
- const parent = parents[parents.length - 1];
257
- return visitor(
258
- node,
259
- parent ? parent.children.indexOf(node) : null,
260
- parent
261
- );
262
- }
263
- };
206
+ var visit = (
207
+ /**
208
+ * @type {(
209
+ * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
210
+ * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)
211
+ * )}
212
+ */
213
+ /**
214
+ * @param {Node} tree
215
+ * @param {Test} test
216
+ * @param {import('./complex-types.js').Visitor} visitor
217
+ * @param {boolean} [reverse]
218
+ */
219
+ function(tree, test, visitor, reverse) {
220
+ if (typeof test === "function" && typeof visitor !== "function") {
221
+ reverse = visitor;
222
+ visitor = test;
223
+ test = null;
224
+ }
225
+ visitParents(tree, test, overload, reverse);
226
+ function overload(node, parents) {
227
+ const parent = parents[parents.length - 1];
228
+ return visitor(
229
+ node,
230
+ parent ? parent.children.indexOf(node) : null,
231
+ parent
232
+ );
233
+ }
264
234
  }
265
- });
235
+ );
266
236
 
267
- // src/index.ts
268
- var src_exports = {};
269
- __export(src_exports, {
270
- demoMeta: () => demoMeta,
271
- demoRoutes: () => demoRoutes,
272
- normalizeId: () => normalizeId,
273
- pluginPreview: () => pluginPreview,
274
- routeMeta: () => routeMeta
275
- });
276
- module.exports = __toCommonJS(src_exports);
277
- var import_path3 = require("path");
278
- var import_rspack_plugin_virtual_module = require("rspack-plugin-virtual-module");
237
+ // src/remarkPlugin.ts
279
238
  var import_shared2 = require("@rspress/shared");
280
- var import_lodash = require("lodash");
281
-
282
- // src/codeToDemo.ts
283
- var import_path2 = require("path");
284
- init_unist_util_visit();
285
239
  var import_fs_extra = __toESM(require("@rspress/shared/fs-extra"));
286
- var import_shared = require("@rspress/shared");
287
240
 
288
241
  // src/utils.ts
289
242
  var toValidVarName = (str) => {
@@ -296,63 +249,73 @@ var toValidVarName = (str) => {
296
249
  var generateId = (pageName, index) => {
297
250
  return `_${toValidVarName(pageName)}_${index}`;
298
251
  };
299
- var normalizeId = (routePath) => {
300
- const result = routePath.replace(/\.(.*)?$/, "");
301
- return toValidVarName(result);
302
- };
303
252
  var injectDemoBlockImport = (str, path2) => {
304
253
  return `
305
- import DemoBlock from '${path2}';
254
+ import DemoBlock from ${JSON.stringify(path2)};
306
255
  ${str}
307
256
  `;
308
257
  };
309
258
 
310
259
  // src/constant.ts
311
260
  var import_path = __toESM(require("path"));
261
+ var import_shared = require("@rspress/shared");
312
262
  var staticPath = import_path.default.join(__dirname, "..", "static");
313
- var demoComponentPath = import_path.default.join(
314
- __dirname,
315
- "..",
316
- "dist",
317
- "virtual-demo.js"
318
- );
319
263
  var demoBlockComponentPath = import_path.default.join(
320
264
  staticPath,
321
265
  "global-components",
322
266
  "DemoBlock.tsx"
323
267
  );
324
-
325
- // src/codeToDemo.ts
326
- var json = JSON.parse(
327
- import_fs_extra.default.readFileSync((0, import_path2.resolve)(process.cwd(), "./package.json"), "utf8")
268
+ var virtualDir = import_path.default.join(
269
+ process.cwd(),
270
+ "node_modules",
271
+ import_shared.RSPRESS_TEMP_DIR,
272
+ "virtual-demo"
328
273
  );
329
- var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, defaultRenderMode }) => {
274
+
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
+ // src/remarkPlugin.ts
283
+ var remarkCodeToDemo = ({
284
+ getRouteMeta,
285
+ previewMode,
286
+ defaultRenderMode,
287
+ position
288
+ }) => {
330
289
  const routeMeta2 = getRouteMeta();
290
+ import_fs_extra.default.ensureDirSync(virtualDir);
331
291
  return (tree, vfile) => {
332
- const demos = [];
292
+ const demoMdx = [];
333
293
  const route = routeMeta2.find(
334
- (meta) => (0, import_shared.normalizePosixPath)(meta.absolutePath) === (0, import_shared.normalizePosixPath)(vfile.path || vfile.history[0])
294
+ (meta2) => (0, import_shared2.normalizePosixPath)(meta2.absolutePath) === (0, import_shared2.normalizePosixPath)(vfile.path || vfile.history[0])
335
295
  );
336
296
  if (!route) {
337
297
  return;
338
298
  }
339
299
  const { pageName } = route;
300
+ demos[pageName] = [];
301
+ let title = pageName;
340
302
  let index = 1;
341
303
  let externalDemoIndex = 0;
342
304
  function constructDemoNode(demoId, demoPath, currentNode, isMobileMode, externalDemoIndex2) {
343
- const demoRoute = `/~demo/${demoId}`;
344
305
  if (isMobileMode) {
345
- demoRoutes.push({
346
- path: demoRoute
306
+ demos[pageName].push({
307
+ title,
308
+ id: demoId,
309
+ path: (0, import_path2.isAbsolute)(demoPath) ? demoPath : (0, import_path2.join)(vfile.dirname || (0, import_path2.dirname)(vfile.path), demoPath)
347
310
  });
348
311
  } else {
349
- demos.push(getASTNodeImport(`Demo${demoId}`, demoPath));
312
+ demoMdx.push(getASTNodeImport(`Demo${demoId}`, demoPath));
350
313
  }
351
314
  const tempVar = `externalDemoContent${externalDemoIndex2}`;
352
315
  if (externalDemoIndex2 !== void 0) {
353
- demos.push(getASTNodeImport(tempVar, `!!${demoPath}?raw`));
316
+ demoMdx.push(getASTNodeImport(tempVar, `!!${demoPath}?raw`));
354
317
  }
355
- if (isMobileMode && iframePosition === "fixed") {
318
+ if (isMobileMode && position === "fixed") {
356
319
  externalDemoIndex2 !== void 0 && Object.assign(currentNode, getExternalDemoContent(tempVar));
357
320
  } else {
358
321
  Object.assign(currentNode, {
@@ -366,18 +329,8 @@ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, defaultRenderM
366
329
  },
367
330
  {
368
331
  type: "mdxJsxAttribute",
369
- name: "url",
370
- value: demoRoute
371
- },
372
- {
373
- type: "mdxJsxAttribute",
374
- name: "content",
375
- value: currentNode.value
376
- },
377
- {
378
- type: "mdxJsxAttribute",
379
- name: "packageName",
380
- value: json.name
332
+ name: "demoId",
333
+ value: demoId
381
334
  }
382
335
  ],
383
336
  children: [
@@ -396,16 +349,29 @@ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, defaultRenderM
396
349
  });
397
350
  }
398
351
  }
352
+ visit(tree, "heading", (node) => {
353
+ if (node.depth === 1) {
354
+ if (node.children) {
355
+ title = node.children[0]?.value || title;
356
+ }
357
+ }
358
+ });
399
359
  visit(tree, "mdxJsxFlowElement", (node) => {
400
360
  if (node.name === "code") {
401
361
  const src = node.attributes.find(
402
362
  (attr) => attr.name === "src"
403
363
  )?.value;
364
+ if (!src) {
365
+ return;
366
+ }
367
+ const currtentMode = node.attributes.find(
368
+ (attr) => attr.name === "previewMode"
369
+ )?.value ?? previewMode;
404
370
  let isMobileMode = node.attributes.find(
405
371
  (attr) => attr.name === "isMobile"
406
372
  )?.value;
407
373
  if (isMobileMode === void 0) {
408
- isMobileMode = isMobile;
374
+ isMobileMode = currtentMode === "iframe";
409
375
  } else if (isMobileMode === null) {
410
376
  isMobileMode = true;
411
377
  } else if (typeof isMobileMode === "object") {
@@ -413,9 +379,6 @@ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, defaultRenderM
413
379
  } else {
414
380
  isMobileMode = isMobileMode !== "false";
415
381
  }
416
- if (!src) {
417
- return;
418
- }
419
382
  const id = generateId(pageName, index++);
420
383
  constructDemoNode(id, src, node, isMobileMode, externalDemoIndex++);
421
384
  }
@@ -426,42 +389,27 @@ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, defaultRenderM
426
389
  }
427
390
  if (node.lang === "jsx" || node.lang === "tsx") {
428
391
  const value = injectDemoBlockImport(node.value, demoBlockComponentPath);
429
- const hasPureMeta = node?.meta?.includes("pure");
430
- const hasPreviewMeta = node?.meta?.includes("preview");
431
- let noTransform;
432
- switch (defaultRenderMode) {
433
- case "pure":
434
- noTransform = !hasPreviewMeta;
435
- break;
436
- case "preview":
437
- noTransform = hasPureMeta;
438
- break;
439
- default:
440
- break;
441
- }
442
- if (noTransform) {
392
+ if (node?.meta?.includes("pure") || !node?.meta?.includes("preview") && defaultRenderMode === "pure") {
443
393
  return;
444
394
  }
445
- const isMobileMode = node?.meta?.includes("mobile") || !node?.meta?.includes("web") && isMobile;
446
- const demoDir = (0, import_path2.join)(
447
- process.cwd(),
448
- "node_modules",
449
- import_shared.RSPRESS_TEMP_DIR,
450
- `virtual-demo`
451
- );
395
+ const isMobileMode = node?.meta?.includes("mobile") || node?.meta?.includes("iframe") || !node?.meta?.includes("web") && !node?.meta?.includes("internal") && previewMode === "iframe";
452
396
  const id = generateId(pageName, index++);
453
- const virtualModulePath = (0, import_path2.join)(demoDir, `${id}.tsx`);
454
- import_fs_extra.default.ensureDirSync((0, import_path2.join)(demoDir));
397
+ const virtualModulePath = (0, import_path2.join)(virtualDir, `${id}.tsx`);
398
+ constructDemoNode(id, virtualModulePath, node, isMobileMode);
455
399
  if (import_fs_extra.default.existsSync(virtualModulePath)) {
456
400
  const content = import_fs_extra.default.readFileSync(virtualModulePath, "utf-8");
457
- if (content !== value) {
458
- import_fs_extra.default.writeFileSync(virtualModulePath, value);
401
+ if (content === value) {
402
+ return;
459
403
  }
460
404
  }
461
- constructDemoNode(id, virtualModulePath, node, isMobileMode);
405
+ import_fs_extra.default.writeFileSync(virtualModulePath, value);
462
406
  }
463
407
  });
464
- tree.children.unshift(...demos);
408
+ tree.children.unshift(...demoMdx);
409
+ const meta = `
410
+ export const demos = ${JSON.stringify(demos)}
411
+ `;
412
+ demoRuntimeModule.writeModule("virtual-meta", meta);
465
413
  };
466
414
  };
467
415
  var getASTNodeImport = (name, from) => ({
@@ -541,17 +489,105 @@ var getExternalDemoContent = (tempVar) => ({
541
489
  ]
542
490
  });
543
491
 
492
+ // src/generate-entry.ts
493
+ var import_path3 = require("path");
494
+ var import_fs = require("fs");
495
+ function generateEntry(demos2, framework, position) {
496
+ const sourceEntry = {};
497
+ const entryCssPath = (0, import_path3.join)(staticPath, "global-styles", "entry.css");
498
+ if (position === "follow") {
499
+ Object.values(demos2).forEach((routes) => {
500
+ routes.forEach((route) => {
501
+ const { id, path: demoPath } = route;
502
+ const entry = (0, import_path3.join)(virtualDir, `${id}.entry.tsx`);
503
+ const solidEntry = `
504
+ import { render } from 'solid-js/web';
505
+ import ${JSON.stringify(entryCssPath)};
506
+ import Demo from ${JSON.stringify(demoPath)};
507
+ render(() => <Demo />, document.getElementById('root'));
508
+ `;
509
+ const reactEntry = `
510
+ import { render } from 'react-dom';
511
+ import ${JSON.stringify(entryCssPath)};
512
+ import Demo from ${JSON.stringify(demoPath)};
513
+ render(<Demo />, document.getElementById('root'));
514
+ `;
515
+ const entryContent = framework === "react" ? reactEntry : solidEntry;
516
+ (0, import_fs.writeFileSync)(entry, entryContent);
517
+ sourceEntry[id] = entry;
518
+ });
519
+ });
520
+ } else {
521
+ Object.entries(demos2).forEach(([key, routes]) => {
522
+ if (routes.length === 0) {
523
+ return;
524
+ }
525
+ const reactContent = `
526
+ import { render } from 'react-dom';
527
+ import ${JSON.stringify(entryCssPath)};
528
+ ${routes.map((demo, index) => {
529
+ return `import Demo_${index} from ${JSON.stringify(demo.path)}`;
530
+ }).join("\n")}
531
+ function App() {
532
+ return (
533
+ <div className="preview-container">
534
+ <div className="preview-nav">{"${routes[0].title}"}</div>
535
+ ${routes.map((demo, index) => {
536
+ return `<Demo_${index} />`;
537
+ }).join("\n")}
538
+ </div>
539
+ )
540
+ }
541
+ render(<App /> , document.getElementById('root'));
542
+ `;
543
+ const solidContent = `
544
+ import { render } from 'solid-js/web';
545
+ import ${JSON.stringify(entryCssPath)};
546
+ ${routes.map((demo, index) => {
547
+ return `import Demo_${index} from ${JSON.stringify(demo.path)}`;
548
+ }).join("\n")}
549
+ function App() {
550
+ return (
551
+ <div class="preview-container">
552
+ <div class="preview-nav">{"${routes[0].title}"}</div>
553
+ ${routes.map((_, index) => {
554
+ return `<Demo_${index} />`;
555
+ }).join("\n")}
556
+ </div>
557
+ )
558
+ }
559
+ render(() => <App /> , document.getElementById('root'));
560
+ `;
561
+ const renderContent = framework === "solid" ? solidContent : reactContent;
562
+ const id = `_${toValidVarName(key)}`;
563
+ const entry = (0, import_path3.join)(virtualDir, `${id}.entry.tsx`);
564
+ (0, import_fs.writeFileSync)(entry, renderContent);
565
+ sourceEntry[id] = entry;
566
+ });
567
+ }
568
+ return sourceEntry;
569
+ }
570
+
544
571
  // src/index.ts
545
572
  var routeMeta;
546
- var demoRoutes = [];
547
- var demoMeta = {};
548
573
  function pluginPreview(options) {
549
- const isMobile = options?.isMobile ?? false;
550
- const iframePosition = options?.iframePosition ?? "follow";
551
- const defaultRenderMode = options?.defaultRenderMode ?? "preview";
552
- const demoRuntimeModule = new import_rspack_plugin_virtual_module.RspackVirtualModulePlugin({});
553
- const globalUIComponents = iframePosition === "fixed" ? [(0, import_path3.join)(staticPath, "global-components", "Device.tsx")] : [];
574
+ const {
575
+ isMobile = false,
576
+ iframeOptions = {},
577
+ iframePosition = "follow",
578
+ defaultRenderMode = "preview"
579
+ } = options ?? {};
580
+ const previewMode = options?.previewMode ?? isMobile ? "iframe" : "internal";
581
+ const {
582
+ devPort = 7890,
583
+ framework = "react",
584
+ position = iframePosition
585
+ } = iframeOptions;
586
+ const globalUIComponents = iframePosition === "fixed" ? [(0, import_path4.join)(staticPath, "global-components", "Device.tsx")] : [];
554
587
  const getRouteMeta = () => routeMeta;
588
+ let lastDemos;
589
+ let devServer;
590
+ const port = devPort;
555
591
  return {
556
592
  name: "@rspress/plugin-preview",
557
593
  config(config) {
@@ -559,192 +595,141 @@ function pluginPreview(options) {
559
595
  config.markdown.mdxRs = false;
560
596
  return config;
561
597
  },
562
- extendPageData(pageData) {
563
- pageData.demoMeta = Object.values(demoMeta).flat();
564
- },
565
- addPages(_config, _isProd) {
566
- return [
567
- {
568
- routePath: "/~demo/:id",
569
- content: `---
570
- pageType: "blank"
571
- ---
572
-
573
- import Demo from ${JSON.stringify(demoComponentPath)}
574
-
575
- <Demo iframePosition="${iframePosition}"/>
576
- `
577
- }
578
- ];
579
- },
580
- async routeGenerated(routes) {
598
+ routeGenerated(routes) {
581
599
  routeMeta = routes;
582
- const files = routes.map((route) => route.absolutePath);
583
- await Promise.all(
584
- files.map(async (filepath, _index) => {
585
- const isMdxFile = /\.mdx?$/.test(filepath);
586
- if (!isMdxFile) {
587
- return;
588
- }
589
- const { createProcessor } = await import("@mdx-js/mdx");
590
- const { visit: visit2 } = await Promise.resolve().then(() => (init_unist_util_visit(), unist_util_visit_exports));
591
- const { default: fs2 } = await import("@rspress/shared/fs-extra");
592
- const { default: remarkGFM } = await import("remark-gfm");
593
- let title = (0, import_path3.parse)(filepath).name;
594
- try {
595
- const processor = createProcessor({
596
- format: (0, import_path3.extname)(filepath).slice(1),
597
- remarkPlugins: [remarkGFM]
600
+ },
601
+ async beforeBuild(_, isProd) {
602
+ if (!isProd) {
603
+ try {
604
+ await new Promise((resolve, reject) => {
605
+ const server = import_node_net.default.createServer();
606
+ server.unref();
607
+ server.on("error", reject);
608
+ server.listen({ port, host: "0.0.0.0" }, () => {
609
+ server.close(resolve);
598
610
  });
599
- const source = await fs2.readFile(filepath, "utf-8");
600
- const ast = processor.parse(source);
601
- let index = 1;
602
- const { pageName } = routeMeta.find(
603
- (meta) => (0, import_shared2.normalizePosixPath)(meta.absolutePath) === (0, import_shared2.normalizePosixPath)(filepath)
611
+ });
612
+ } catch (e) {
613
+ if (e.code !== "EADDRINUSE") {
614
+ throw e;
615
+ } else {
616
+ throw new Error(
617
+ `Port "${port}" is occupied, please choose another one.`
604
618
  );
605
- const registerDemo = (demoId, demoPath, isMobileMode) => {
606
- if (isMobileMode) {
607
- demoMeta[filepath] = demoMeta[filepath] ?? [];
608
- const isExist = demoMeta[filepath].find(
609
- (item) => item.id === demoId
610
- );
611
- if (!isExist) {
612
- demoMeta[filepath].push({
613
- id: demoId,
614
- title,
615
- virtualModulePath: demoPath
616
- });
617
- }
618
- }
619
- };
620
- visit2(ast, "heading", (node) => {
621
- if (node.depth === 1) {
622
- if (node.children) {
623
- title = node.children[0].value;
624
- }
625
- }
626
- });
627
- visit2(ast, "mdxJsxFlowElement", (node) => {
628
- if (node.name === "code") {
629
- const src = node.attributes.find(
630
- (attr) => attr.name === "src"
631
- )?.value;
632
- const isMobileMode = node.attributes.find(
633
- (attr) => attr.name === "isMobile"
634
- )?.value ?? isMobile;
635
- if (!src) {
636
- return;
637
- }
638
- const id = generateId(pageName, index++);
639
- registerDemo(id, src, isMobileMode);
640
- }
641
- });
642
- visit2(ast, "code", (node) => {
643
- if (node.lang === "jsx" || node.lang === "tsx") {
644
- const { value, meta } = node;
645
- const hasPureMeta = meta?.includes("pure");
646
- const hasPreviewMeta = meta?.includes("preview");
647
- let noTransform;
648
- switch (defaultRenderMode) {
649
- case "pure":
650
- noTransform = !hasPreviewMeta;
651
- break;
652
- case "preview":
653
- noTransform = hasPureMeta;
654
- break;
655
- default:
656
- break;
657
- }
658
- if (noTransform) {
659
- return;
660
- }
661
- const isMobileMode = node?.meta?.includes("mobile") || !node?.meta?.includes("web") && isMobile;
662
- const { pageName: pageName2 } = routeMeta.find(
663
- (meta2) => (0, import_shared2.normalizePosixPath)(meta2.absolutePath) === (0, import_shared2.normalizePosixPath)(filepath)
664
- );
665
- const id = generateId(pageName2, index++);
666
- const demoDir = (0, import_path3.join)(
667
- process.cwd(),
668
- "node_modules",
669
- import_shared2.RSPRESS_TEMP_DIR,
670
- `virtual-demo`
671
- );
672
- const virtualModulePath = (0, import_path3.join)(demoDir, `${id}.tsx`);
673
- registerDemo(id, virtualModulePath, isMobileMode);
674
- fs2.ensureDirSync((0, import_path3.join)(demoDir));
675
- fs2.writeFileSync(
676
- virtualModulePath,
677
- injectDemoBlockImport(value, demoBlockComponentPath)
678
- );
619
+ }
620
+ }
621
+ }
622
+ },
623
+ async afterBuild(config, isProd) {
624
+ if ((0, import_lodash.isEqual)(demos, lastDemos)) {
625
+ return;
626
+ }
627
+ lastDemos = (0, import_lodash.cloneDeep)(demos);
628
+ await devServer?.server?.close();
629
+ const sourceEntry = generateEntry(demos, framework, position);
630
+ const outDir = (0, import_path4.join)(config.outDir ?? "doc_build", "~demo");
631
+ if (Object.keys(sourceEntry).length === 0) {
632
+ return;
633
+ }
634
+ const rsbuildInstance = await (0, import_core.createRsbuild)({
635
+ rsbuildConfig: {
636
+ dev: {
637
+ progressBar: false
638
+ },
639
+ server: {
640
+ port: devPort,
641
+ printUrls: () => void 0,
642
+ strictPort: true
643
+ },
644
+ performance: {
645
+ printFileSize: false
646
+ },
647
+ source: {
648
+ entry: sourceEntry
649
+ },
650
+ output: {
651
+ distPath: {
652
+ root: outDir
653
+ }
654
+ },
655
+ tools: {
656
+ rspack: {
657
+ output: {
658
+ publicPath: "/~demo"
679
659
  }
680
- });
681
- } catch (e) {
682
- console.error(e);
683
- throw e;
660
+ }
684
661
  }
685
- })
686
- );
687
- const virtualMeta = `
688
- ${files.map((filepath, index) => {
689
- return `import Route${index} from '${filepath}?meta';`;
690
- }).join("\n")}
691
- export const demos = [${files.map((_, index) => `Route${index}`).flat().join(",")}];
692
- `;
693
- demoRuntimeModule.writeModule("virtual-meta", virtualMeta);
662
+ }
663
+ });
664
+ if (framework === "solid") {
665
+ rsbuildInstance.addPlugins([
666
+ (0, import_plugin_babel.pluginBabel)({
667
+ include: /\.(?:jsx|tsx)$/
668
+ }),
669
+ (0, import_plugin_solid.pluginSolid)()
670
+ ]);
671
+ }
672
+ if (framework === "react") {
673
+ rsbuildInstance.addPlugins([(0, import_plugin_react.pluginReact)()]);
674
+ }
675
+ if (isProd) {
676
+ rsbuildInstance.build();
677
+ } else {
678
+ devServer = await rsbuildInstance.startDevServer();
679
+ }
694
680
  },
695
681
  builderConfig: {
696
682
  source: {
697
- include: [(0, import_path3.join)(__dirname, "..")]
683
+ include: [(0, import_path4.join)(__dirname, "..")]
698
684
  },
699
685
  tools: {
700
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
701
- // @ts-ignore
702
686
  rspack: {
703
687
  plugins: [demoRuntimeModule]
704
688
  },
705
689
  bundlerChain(chain) {
706
- chain.module.rule("Raw").resourceQuery(/raw/).type("asset/source").end().rule("MDX").oneOf("MDXMeta").before("MDXCompile").resourceQuery(/meta/).use("mdx-meta-loader").loader((0, import_path3.join)(__dirname, "../mdx-meta-loader.cjs")).end();
690
+ chain.module.rule("Raw").resourceQuery(/raw/).type("asset/source").end();
707
691
  chain.resolve.extensions.prepend(".md").prepend(".mdx");
708
692
  }
693
+ },
694
+ plugins: [
695
+ {
696
+ name: "close-demo-server",
697
+ setup: (api) => {
698
+ api.onCloseDevServer(async () => {
699
+ await devServer?.server?.close();
700
+ });
701
+ }
702
+ }
703
+ ]
704
+ },
705
+ extendPageData(pageData, isProd) {
706
+ if (!isProd) {
707
+ pageData.devPort = port;
709
708
  }
710
709
  },
711
710
  markdown: {
712
711
  remarkPlugins: [
713
712
  [
714
713
  remarkCodeToDemo,
715
- { isMobile, getRouteMeta, iframePosition, defaultRenderMode }
714
+ {
715
+ getRouteMeta,
716
+ position,
717
+ previewMode,
718
+ defaultRenderMode
719
+ }
716
720
  ]
717
721
  ],
718
722
  globalComponents: [
719
- (0, import_path3.join)(staticPath, "global-components", "Container.tsx")
723
+ (0, import_path4.join)(staticPath, "global-components", "Container.tsx")
720
724
  ]
721
725
  },
722
726
  globalUIComponents,
723
- globalStyles: (0, import_path3.join)(
724
- staticPath,
725
- "global-styles",
726
- `${isMobile ? "mobile" : "web"}.css`
727
- ),
728
- addSSGRoutes() {
729
- if (iframePosition === "fixed") {
730
- const normalizeRoutes = demoRoutes.map(({ path: item }) => {
731
- const fragments = item.split("/").filter(Boolean);
732
- const demoId = fragments.pop()?.replace(/_(\d+)$/, "");
733
- return { path: `/${fragments.join("/")}/${demoId}` };
734
- });
735
- return (0, import_lodash.uniqBy)(normalizeRoutes, "path");
736
- }
737
- return demoRoutes;
738
- }
727
+ globalStyles: (0, import_path4.join)(staticPath, "global-styles", `${previewMode}.css`)
739
728
  };
740
729
  }
741
730
  // Annotate the CommonJS export names for ESM import in node:
742
731
  0 && (module.exports = {
743
- demoMeta,
744
- demoRoutes,
745
- normalizeId,
746
- pluginPreview,
747
- routeMeta
732
+ pluginPreview
748
733
  });
749
734
 
750
735
  //# sourceMappingURL=index.js.map