@rspress/plugin-playground 0.0.0-next-20230925114748
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/cli/cjs/index.js +3052 -0
- package/dist/cli/cjs/index.js.map +1 -0
- package/dist/cli/esm/index.d.ts +19 -0
- package/dist/cli/esm/index.js +3178 -0
- package/dist/cli/esm/index.js.map +1 -0
- package/dist/web/cjs/index.js +338 -0
- package/dist/web/cjs/index.js.map +1 -0
- package/dist/web/esm/index.d.ts +36 -0
- package/dist/web/esm/index.js +321 -0
- package/dist/web/esm/index.js.map +1 -0
- package/package.json +90 -0
- package/static/global-components/Playground.tsx +51 -0
- package/static/global-styles/web.css +51 -0
- package/static/modern-app-env.d.ts +6 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
// src/web/index.ts
|
|
2
|
+
import { default as default2, loader as loader2, EditorProps } from "@monaco-editor/react";
|
|
3
|
+
|
|
4
|
+
// src/web/editor.tsx
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
import MonacoEditor, { loader } from "@monaco-editor/react";
|
|
7
|
+
|
|
8
|
+
// src/web/constant.ts
|
|
9
|
+
var DEFAULT_BABEL_URL = "https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.20/babel.min.js";
|
|
10
|
+
var DEFAULT_MONACO_URL = "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.43.0/min/vs";
|
|
11
|
+
|
|
12
|
+
// src/web/editor.tsx
|
|
13
|
+
function initLoader() {
|
|
14
|
+
let loaderConfig = {
|
|
15
|
+
paths: {
|
|
16
|
+
vs: DEFAULT_MONACO_URL
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
try {
|
|
20
|
+
const keys = Object.keys(__PLAYGROUND_MONACO_LOADER__);
|
|
21
|
+
if (keys.length > 0) {
|
|
22
|
+
loaderConfig = __PLAYGROUND_MONACO_LOADER__;
|
|
23
|
+
}
|
|
24
|
+
} catch (e) {
|
|
25
|
+
}
|
|
26
|
+
loader.config(loaderConfig);
|
|
27
|
+
}
|
|
28
|
+
initLoader();
|
|
29
|
+
function getMonacoOptions() {
|
|
30
|
+
try {
|
|
31
|
+
return __PLAYGROUND_MONACO_OPTIONS__;
|
|
32
|
+
} catch (e) {
|
|
33
|
+
}
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
function Editor(props) {
|
|
37
|
+
const { options, className = "", ...rest } = props || {};
|
|
38
|
+
return /* @__PURE__ */ _jsx("div", {
|
|
39
|
+
className: `rspress-playground-editor ${className}`,
|
|
40
|
+
children: /* @__PURE__ */ _jsx(MonacoEditor, {
|
|
41
|
+
...rest,
|
|
42
|
+
theme: "light",
|
|
43
|
+
options: {
|
|
44
|
+
minimap: {
|
|
45
|
+
enabled: true,
|
|
46
|
+
autohide: true
|
|
47
|
+
},
|
|
48
|
+
fontSize: 14,
|
|
49
|
+
lineNumbersMinChars: 7,
|
|
50
|
+
scrollBeyondLastLine: false,
|
|
51
|
+
automaticLayout: true,
|
|
52
|
+
wordBasedSuggestions: true,
|
|
53
|
+
quickSuggestions: true,
|
|
54
|
+
scrollbar: {
|
|
55
|
+
verticalScrollbarSize: 8,
|
|
56
|
+
horizontalScrollbarSize: 8
|
|
57
|
+
},
|
|
58
|
+
scrollPredominantAxis: false,
|
|
59
|
+
...getMonacoOptions(),
|
|
60
|
+
...options
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/web/runner.tsx
|
|
67
|
+
import { jsx as _jsx2 } from "react/jsx-runtime";
|
|
68
|
+
import React, { Component } from "react";
|
|
69
|
+
|
|
70
|
+
// src/web/ast.ts
|
|
71
|
+
function createVariableDeclaration(id, init) {
|
|
72
|
+
return {
|
|
73
|
+
type: "VariableDeclaration",
|
|
74
|
+
declarations: [
|
|
75
|
+
{
|
|
76
|
+
type: "VariableDeclarator",
|
|
77
|
+
id: typeof id === "string" ? {
|
|
78
|
+
type: "Identifier",
|
|
79
|
+
name: id
|
|
80
|
+
} : id,
|
|
81
|
+
init
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
kind: "const"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function createObjectPattern(names) {
|
|
88
|
+
return {
|
|
89
|
+
type: "ObjectPattern",
|
|
90
|
+
properties: names.map((name) => ({
|
|
91
|
+
type: "ObjectProperty",
|
|
92
|
+
key: {
|
|
93
|
+
type: "Identifier",
|
|
94
|
+
name
|
|
95
|
+
},
|
|
96
|
+
computed: false,
|
|
97
|
+
method: false,
|
|
98
|
+
shorthand: true,
|
|
99
|
+
value: {
|
|
100
|
+
type: "Identifier",
|
|
101
|
+
name
|
|
102
|
+
}
|
|
103
|
+
}))
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function createGetImport(name, getDefault) {
|
|
107
|
+
return {
|
|
108
|
+
type: "CallExpression",
|
|
109
|
+
callee: {
|
|
110
|
+
type: "Identifier",
|
|
111
|
+
name: "__get_import"
|
|
112
|
+
},
|
|
113
|
+
arguments: [
|
|
114
|
+
{
|
|
115
|
+
type: "StringLiteral",
|
|
116
|
+
value: name
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
type: "BooleanLiteral",
|
|
120
|
+
value: Boolean(getDefault)
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/web/utils.ts
|
|
127
|
+
var loadingMap = /* @__PURE__ */ new Map();
|
|
128
|
+
function loadScript(url) {
|
|
129
|
+
const exists = loadingMap.get(url);
|
|
130
|
+
if (exists) {
|
|
131
|
+
return exists;
|
|
132
|
+
}
|
|
133
|
+
const n = new Promise((resolve) => {
|
|
134
|
+
const e = document.createElement("script");
|
|
135
|
+
e.src = url;
|
|
136
|
+
e.onload = () => resolve();
|
|
137
|
+
document.body.appendChild(e);
|
|
138
|
+
});
|
|
139
|
+
loadingMap.set(url, n);
|
|
140
|
+
return n;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/web/babel.ts
|
|
144
|
+
async function getBabel() {
|
|
145
|
+
if (!window.Babel) {
|
|
146
|
+
let babelUrl = DEFAULT_BABEL_URL;
|
|
147
|
+
try {
|
|
148
|
+
const u = __PLAYGROUND_BABEL_URL__;
|
|
149
|
+
if (u) {
|
|
150
|
+
babelUrl = u;
|
|
151
|
+
}
|
|
152
|
+
} catch (e) {
|
|
153
|
+
}
|
|
154
|
+
await loadScript(babelUrl);
|
|
155
|
+
}
|
|
156
|
+
return window.Babel;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/web/runner.tsx
|
|
160
|
+
function _define_property(obj, key, value) {
|
|
161
|
+
if (key in obj) {
|
|
162
|
+
Object.defineProperty(obj, key, {
|
|
163
|
+
value,
|
|
164
|
+
enumerable: true,
|
|
165
|
+
configurable: true,
|
|
166
|
+
writable: true
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
obj[key] = value;
|
|
170
|
+
}
|
|
171
|
+
return obj;
|
|
172
|
+
}
|
|
173
|
+
var Runner = class extends Component {
|
|
174
|
+
static getDerivedStateFromError(error) {
|
|
175
|
+
return {
|
|
176
|
+
error,
|
|
177
|
+
comp: null
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
waitCompile(targetCode) {
|
|
181
|
+
if (this.timer) {
|
|
182
|
+
clearTimeout(this.timer);
|
|
183
|
+
}
|
|
184
|
+
this.timer = setTimeout(() => {
|
|
185
|
+
this.timer = null;
|
|
186
|
+
this.doCompile(targetCode);
|
|
187
|
+
}, 600);
|
|
188
|
+
}
|
|
189
|
+
async doCompile(targetCode) {
|
|
190
|
+
const { language, getImport } = this.props;
|
|
191
|
+
const babel = await getBabel();
|
|
192
|
+
try {
|
|
193
|
+
const presets = [
|
|
194
|
+
[
|
|
195
|
+
babel.availablePresets.react
|
|
196
|
+
],
|
|
197
|
+
[
|
|
198
|
+
babel.availablePresets.env,
|
|
199
|
+
{
|
|
200
|
+
modules: "commonjs"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
];
|
|
204
|
+
if (language === "tsx" || language === "ts") {
|
|
205
|
+
presets.unshift([
|
|
206
|
+
babel.availablePresets.typescript,
|
|
207
|
+
{
|
|
208
|
+
allExtensions: true,
|
|
209
|
+
isTSX: language === "tsx"
|
|
210
|
+
}
|
|
211
|
+
]);
|
|
212
|
+
}
|
|
213
|
+
const result = babel.transform(targetCode, {
|
|
214
|
+
sourceType: "module",
|
|
215
|
+
presets,
|
|
216
|
+
plugins: [
|
|
217
|
+
{
|
|
218
|
+
visitor: {
|
|
219
|
+
ImportDeclaration(path) {
|
|
220
|
+
const pkg = path.node.source.value;
|
|
221
|
+
const code = [];
|
|
222
|
+
for (const specifier of path.node.specifiers) {
|
|
223
|
+
if (specifier.type === "ImportDefaultSpecifier") {
|
|
224
|
+
code.push(createVariableDeclaration(specifier.local.name, createGetImport(pkg, true)));
|
|
225
|
+
}
|
|
226
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
227
|
+
code.push(createVariableDeclaration(specifier.local.name, createGetImport(pkg)));
|
|
228
|
+
}
|
|
229
|
+
if (specifier.type === "ImportSpecifier") {
|
|
230
|
+
code.push(createVariableDeclaration(createObjectPattern([
|
|
231
|
+
specifier.local.name
|
|
232
|
+
]), createGetImport(pkg)));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
path.replaceWithMultiple(code);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
});
|
|
241
|
+
if (targetCode !== this.props.code || !result || !result.code) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const runExports = {};
|
|
245
|
+
const func = new Function("__get_import", "exports", result.code);
|
|
246
|
+
func(getImport, runExports);
|
|
247
|
+
if (runExports.default) {
|
|
248
|
+
this.setState({
|
|
249
|
+
error: void 0,
|
|
250
|
+
comp: /* @__PURE__ */ React.createElement(runExports.default)
|
|
251
|
+
});
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
this.setState({
|
|
255
|
+
error: new Error("No default export"),
|
|
256
|
+
comp: null
|
|
257
|
+
});
|
|
258
|
+
} catch (e) {
|
|
259
|
+
if (targetCode !== this.props.code) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
console.error(e);
|
|
263
|
+
this.setState({
|
|
264
|
+
error: e,
|
|
265
|
+
comp: null
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
componentDidCatch(error, errorInfo) {
|
|
270
|
+
console.error(error);
|
|
271
|
+
console.error(errorInfo);
|
|
272
|
+
}
|
|
273
|
+
componentDidMount() {
|
|
274
|
+
this.doCompile(this.props.code);
|
|
275
|
+
}
|
|
276
|
+
componentDidUpdate(prevProps) {
|
|
277
|
+
if (prevProps.code !== this.props.code) {
|
|
278
|
+
this.waitCompile(this.props.code);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
render() {
|
|
282
|
+
const { className = "", code, language, getImport, ...rest } = this.props;
|
|
283
|
+
const { error, comp } = this.state;
|
|
284
|
+
if (error) {
|
|
285
|
+
return /* @__PURE__ */ _jsx2("div", {
|
|
286
|
+
className: `rspress-playground-runner ${className}`,
|
|
287
|
+
...rest,
|
|
288
|
+
children: /* @__PURE__ */ _jsx2("span", {
|
|
289
|
+
style: {
|
|
290
|
+
color: "red"
|
|
291
|
+
},
|
|
292
|
+
children: error.message
|
|
293
|
+
})
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return /* @__PURE__ */ _jsx2("div", {
|
|
297
|
+
className: `rspress-playground-runner ${className}`,
|
|
298
|
+
...rest,
|
|
299
|
+
children: comp
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
constructor(props) {
|
|
303
|
+
super(props);
|
|
304
|
+
_define_property(this, "timer", void 0);
|
|
305
|
+
this.state = {
|
|
306
|
+
error: void 0,
|
|
307
|
+
comp: null
|
|
308
|
+
};
|
|
309
|
+
this.doCompile = this.doCompile.bind(this);
|
|
310
|
+
this.waitCompile = this.waitCompile.bind(this);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
export {
|
|
314
|
+
Editor,
|
|
315
|
+
default2 as MonacoEditor,
|
|
316
|
+
loader2 as MonacoEditorLoader,
|
|
317
|
+
EditorProps as MonacoEditorProps,
|
|
318
|
+
Runner
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":"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","names":["MonacoEditor","default","MonacoEditorLoader","loader","MonacoEditorProps","DEFAULT_BABEL_URL","DEFAULT_MONACO_URL","initLoader","loaderConfig","paths","vs","keys","Object","__PLAYGROUND_MONACO_LOADER__","length","e","config","getMonacoOptions","__PLAYGROUND_MONACO_OPTIONS__","Editor","props","options","className","rest","div","theme","minimap","enabled","autohide","fontSize","lineNumbersMinChars","scrollBeyondLastLine","automaticLayout","wordBasedSuggestions","quickSuggestions","scrollbar","verticalScrollbarSize","horizontalScrollbarSize","scrollPredominantAxis","React","Component","createVariableDeclaration","id","init","type","declarations","name","kind","createObjectPattern","names","properties","map","key","computed","method","shorthand","value","createGetImport","getDefault","callee","arguments","Boolean","loadingMap","Map","loadScript","url","exists","get","n","Promise","resolve","document","createElement","src","onload","body","appendChild","set","getBabel","window","Babel","babelUrl","u","__PLAYGROUND_BABEL_URL__","Runner","getDerivedStateFromError","error","comp","waitCompile","targetCode","timer","clearTimeout","setTimeout","doCompile","language","getImport","babel","presets","availablePresets","react","env","modules","unshift","typescript","allExtensions","isTSX","result","transform","sourceType","plugins","visitor","ImportDeclaration","path","pkg","node","source","code","specifier","specifiers","push","local","replaceWithMultiple","runExports","func","Function","setState","undefined","Error","console","componentDidCatch","errorInfo","componentDidMount","componentDidUpdate","prevProps","render","state","span","style","color","message","constructor","bind"],"sources":["../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/index.ts","../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/editor.tsx","../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/constant.ts","../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/runner.tsx","../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/ast.ts","../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/utils.ts","../../../src/web/home/runner/work/rspress/rspress/packages/plugin-playground/src/web/babel.ts"],"sourcesContent":["export {\n default as MonacoEditor,\n loader as MonacoEditorLoader,\n EditorProps as MonacoEditorProps,\n} from '@monaco-editor/react';\nexport { Editor } from './editor';\nexport { Runner } from './runner';\n","import React from 'react';\nimport MonacoEditor, {\n loader,\n EditorProps as MonacoEditorProps,\n} from '@monaco-editor/react';\nimport { DEFAULT_MONACO_URL } from './constant';\n\n// inject by builder in cli/index.ts\n// see: https://modernjs.dev/builder/api/config-source.html#sourcedefine\ndeclare global {\n const __PLAYGROUND_MONACO_LOADER__: any;\n const __PLAYGROUND_MONACO_OPTIONS__: any;\n}\n\nfunction initLoader() {\n let loaderConfig = {\n paths: {\n vs: DEFAULT_MONACO_URL,\n },\n };\n\n try {\n const keys = Object.keys(__PLAYGROUND_MONACO_LOADER__);\n\n if (keys.length > 0) {\n loaderConfig = __PLAYGROUND_MONACO_LOADER__;\n }\n } catch (e) {\n // ignore\n }\n\n loader.config(loaderConfig);\n}\ninitLoader();\n\nfunction getMonacoOptions() {\n try {\n return __PLAYGROUND_MONACO_OPTIONS__;\n } catch (e) {\n // ignore\n }\n return {};\n}\n\nexport type EditorProps = Partial<MonacoEditorProps>;\n\nexport function Editor(props: EditorProps) {\n const { options, className = '', ...rest } = props || {};\n\n return (\n <div className={`rspress-playground-editor ${className}`}>\n <MonacoEditor\n {...rest}\n theme=\"light\"\n options={{\n minimap: {\n enabled: true,\n autohide: true,\n },\n fontSize: 14,\n lineNumbersMinChars: 7,\n scrollBeyondLastLine: false,\n automaticLayout: true,\n wordBasedSuggestions: true,\n quickSuggestions: true,\n scrollbar: {\n verticalScrollbarSize: 8,\n horizontalScrollbarSize: 8,\n },\n scrollPredominantAxis: false,\n ...getMonacoOptions(),\n ...options,\n }}\n />\n </div>\n );\n}\n","export const DEFAULT_BABEL_URL =\n 'https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.20/babel.min.js';\n\nexport const DEFAULT_MONACO_URL =\n 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.43.0/min/vs';\n","import type { Node } from '@babel/types';\nimport React, { Component, HTMLAttributes } from 'react';\nimport {\n createGetImport,\n createObjectPattern,\n createVariableDeclaration,\n} from './ast';\nimport { getBabel } from './babel';\n\ninterface RunnerProps extends HTMLAttributes<HTMLDivElement> {\n code: string;\n language: string;\n getImport: (name: string, getDefault?: boolean) => void;\n}\n\ninterface RunnerState {\n error?: Error;\n comp: any;\n}\n\nclass Runner extends Component<RunnerProps, RunnerState> {\n static getDerivedStateFromError(error: Error) {\n return {\n error,\n comp: null,\n };\n }\n\n timer: any;\n\n constructor(props: RunnerProps) {\n super(props);\n\n this.state = {\n error: undefined,\n comp: null,\n };\n\n this.doCompile = this.doCompile.bind(this);\n this.waitCompile = this.waitCompile.bind(this);\n }\n\n waitCompile(targetCode: string) {\n if (this.timer) {\n clearTimeout(this.timer);\n }\n this.timer = setTimeout(() => {\n this.timer = null;\n this.doCompile(targetCode);\n }, 600);\n }\n\n async doCompile(targetCode: string) {\n const { language, getImport } = this.props;\n const babel = await getBabel();\n try {\n const presets = [\n [babel.availablePresets.react],\n [babel.availablePresets.env, { modules: 'commonjs' }],\n ];\n if (language === 'tsx' || language === 'ts') {\n presets.unshift([\n babel.availablePresets.typescript,\n {\n allExtensions: true,\n isTSX: language === 'tsx',\n },\n ]);\n }\n const result = babel.transform(targetCode, {\n sourceType: 'module',\n presets,\n plugins: [\n {\n visitor: {\n ImportDeclaration(path) {\n const pkg = path.node.source.value;\n const code: Node[] = [];\n for (const specifier of path.node.specifiers) {\n // import X from 'xxx'\n if (specifier.type === 'ImportDefaultSpecifier') {\n // const ${specifier.local.name} = __get_import()\n code.push(\n createVariableDeclaration(\n specifier.local.name,\n createGetImport(pkg, true),\n ),\n );\n }\n // import * as X from 'xxx'\n if (specifier.type === 'ImportNamespaceSpecifier') {\n // const ${specifier.local.name} = __get_import()\n code.push(\n createVariableDeclaration(\n specifier.local.name,\n createGetImport(pkg),\n ),\n );\n }\n // import { a, b, c } from 'xxx'\n if (specifier.type === 'ImportSpecifier') {\n // const {${specifier.local.name}} = __get_import()\n code.push(\n createVariableDeclaration(\n createObjectPattern([specifier.local.name]),\n createGetImport(pkg),\n ),\n );\n }\n }\n path.replaceWithMultiple(code);\n },\n },\n },\n ],\n });\n\n // Code has been updated\n if (targetCode !== this.props.code || !result || !result.code) {\n return;\n }\n\n const runExports: any = {};\n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n const func = new Function('__get_import', 'exports', result.code);\n func(getImport, runExports);\n\n if (runExports.default) {\n this.setState({\n error: undefined,\n comp: React.createElement(runExports.default),\n });\n return;\n }\n\n this.setState({\n error: new Error('No default export'),\n comp: null,\n });\n } catch (e) {\n // Code has been updated\n if (targetCode !== this.props.code) {\n return;\n }\n console.error(e);\n this.setState({\n error: e as Error,\n comp: null,\n });\n }\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n console.error(error);\n console.error(errorInfo);\n }\n\n componentDidMount() {\n this.doCompile(this.props.code);\n }\n\n componentDidUpdate(prevProps: RunnerProps) {\n if (prevProps.code !== this.props.code) {\n this.waitCompile(this.props.code);\n }\n }\n\n render() {\n const { className = '', code, language, getImport, ...rest } = this.props;\n const { error, comp } = this.state;\n\n if (error) {\n return (\n <div className={`rspress-playground-runner ${className}`} {...rest}>\n <span style={{ color: 'red' }}>{error.message}</span>\n </div>\n );\n }\n\n return (\n <div className={`rspress-playground-runner ${className}`} {...rest}>\n {comp}\n </div>\n );\n }\n}\n\nexport { Runner };\n","import type {\n CallExpression,\n Expression,\n ObjectPattern,\n VariableDeclaration,\n} from '@babel/types';\n\nexport function createVariableDeclaration(\n id: string | ObjectPattern,\n init: Expression,\n): VariableDeclaration {\n return {\n type: 'VariableDeclaration',\n declarations: [\n {\n type: 'VariableDeclarator',\n id:\n typeof id === 'string'\n ? {\n type: 'Identifier',\n name: id,\n }\n : id,\n init,\n },\n ],\n kind: 'const',\n };\n}\n\nexport function createObjectPattern(names: string[]): ObjectPattern {\n return {\n type: 'ObjectPattern',\n properties: names.map(name => ({\n type: 'ObjectProperty',\n key: {\n type: 'Identifier',\n name,\n },\n computed: false,\n method: false,\n shorthand: true,\n value: {\n type: 'Identifier',\n name,\n },\n })),\n };\n}\n\nexport function createGetImport(\n name: string,\n getDefault?: boolean,\n): CallExpression {\n return {\n type: 'CallExpression',\n callee: {\n type: 'Identifier',\n name: '__get_import',\n },\n arguments: [\n {\n type: 'StringLiteral',\n value: name,\n },\n {\n type: 'BooleanLiteral',\n value: Boolean(getDefault),\n },\n ],\n };\n}\n","const loadingMap = new Map<string, Promise<void>>();\n\nexport function loadScript(url: string): Promise<void> {\n const exists = loadingMap.get(url);\n if (exists) {\n return exists;\n }\n const n: Promise<void> = new Promise(resolve => {\n const e = document.createElement('script');\n e.src = url;\n e.onload = () => resolve();\n document.body.appendChild(e);\n });\n loadingMap.set(url, n);\n return n;\n}\n\nexport function normalizeUrl(u: string) {\n return u.replace(/\\/\\//g, '/');\n}\n","import type babel from '@babel/standalone';\nimport { DEFAULT_BABEL_URL } from './constant';\nimport { loadScript } from './utils';\n\ndeclare global {\n // inject by builder in cli/index.ts\n // see: https://modernjs.dev/builder/api/config-source.html#sourcedefine\n const __PLAYGROUND_BABEL_URL__: any;\n interface Window {\n Babel: typeof babel;\n }\n}\n\nasync function getBabel() {\n if (!window.Babel) {\n let babelUrl = DEFAULT_BABEL_URL;\n try {\n const u = __PLAYGROUND_BABEL_URL__;\n if (u) {\n babelUrl = u;\n }\n } catch (e) {\n // ignore\n }\n await loadScript(babelUrl);\n }\n return window.Babel;\n}\n\nexport { getBabel };\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rspress/plugin-playground",
|
|
3
|
+
"version": "0.0.0-next-20230925114748",
|
|
4
|
+
"description": "A plugin for rspress to preview the code block in markdown/mdx file.",
|
|
5
|
+
"bugs": "https://github.com/web-infra-dev/rspress/issues",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/web-infra-dev/rspress",
|
|
9
|
+
"directory": "packages/plugin-preview"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"types": "./dist/cli/esm/index.d.ts",
|
|
13
|
+
"main": "./dist/cli/cjs/index.js",
|
|
14
|
+
"module": "./dist/cli/esm/index.js",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/cli/esm/index.d.ts",
|
|
18
|
+
"import": "./dist/cli/esm/index.js",
|
|
19
|
+
"default": "./dist/cli/cjs/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./web": {
|
|
22
|
+
"types": "./dist/web/esm/index.d.ts",
|
|
23
|
+
"import": "./dist/web/esm/index.js",
|
|
24
|
+
"default": "./dist/web/cjs/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=14.17.6"
|
|
29
|
+
},
|
|
30
|
+
"eslintIgnore": [
|
|
31
|
+
"node_modules/",
|
|
32
|
+
"dist/"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@mdx-js/mdx": "2.2.1",
|
|
36
|
+
"@modern-js/utils": "2.35.1",
|
|
37
|
+
"@monaco-editor/react": "~4.4.6",
|
|
38
|
+
"@oxidation-compiler/napi": "^0.1.0",
|
|
39
|
+
"remark-gfm": "3.0.1",
|
|
40
|
+
"@rspress/shared": "0.0.0-next-20230925114748"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@babel/types": "^7.22.17",
|
|
44
|
+
"@types/babel__core": "^7.20.1",
|
|
45
|
+
"@types/babel__standalone": "^7.1.4",
|
|
46
|
+
"@types/babel__traverse": "^7.20.1",
|
|
47
|
+
"@types/mdast": "^3.0.10",
|
|
48
|
+
"@types/node": "^18.11.17",
|
|
49
|
+
"@types/react": "^18",
|
|
50
|
+
"@types/react-dom": "^18",
|
|
51
|
+
"mdast-util-mdxjs-esm": "^1.3.0",
|
|
52
|
+
"prettier": "^2.6.2",
|
|
53
|
+
"react": "^18",
|
|
54
|
+
"react-dom": "^18",
|
|
55
|
+
"react-router-dom": "^6.8.1",
|
|
56
|
+
"rspack-plugin-virtual-module": "0.1.11",
|
|
57
|
+
"typescript": "^5",
|
|
58
|
+
"unified": "^10.1.2",
|
|
59
|
+
"unist-util-visit": "^4.1.1"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@rspress/core": "0.0.0-next-20230925114748",
|
|
63
|
+
"react": ">=17",
|
|
64
|
+
"react-router-dom": "^6.8.1"
|
|
65
|
+
},
|
|
66
|
+
"files": [
|
|
67
|
+
"dist",
|
|
68
|
+
"static"
|
|
69
|
+
],
|
|
70
|
+
"publishConfig": {
|
|
71
|
+
"access": "public",
|
|
72
|
+
"provenance": true,
|
|
73
|
+
"registry": "https://registry.npmjs.org/"
|
|
74
|
+
},
|
|
75
|
+
"scripts": {
|
|
76
|
+
"dev": "modern build -w",
|
|
77
|
+
"build": "modern build",
|
|
78
|
+
"reset": "rimraf ./**/node_modules",
|
|
79
|
+
"lint": "modern lint",
|
|
80
|
+
"change": "modern change",
|
|
81
|
+
"bump": "modern bump",
|
|
82
|
+
"pre": "modern pre",
|
|
83
|
+
"change-status": "modern change-status",
|
|
84
|
+
"gen-release-note": "modern gen-release-note",
|
|
85
|
+
"release": "modern release",
|
|
86
|
+
"new": "modern new",
|
|
87
|
+
"test": "vitest run --passWithNoTests",
|
|
88
|
+
"upgrade": "modern upgrade"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { HTMLAttributes, useCallback, useState } from 'react';
|
|
2
|
+
import getImport from '_rspress_playground_imports';
|
|
3
|
+
import { Editor, Runner } from '../../dist/web/esm';
|
|
4
|
+
|
|
5
|
+
interface PlaygroundProps extends HTMLAttributes<HTMLDivElement> {
|
|
6
|
+
code: string;
|
|
7
|
+
language: string;
|
|
8
|
+
direction?: 'horizontal' | 'vertical';
|
|
9
|
+
editorPosition?: 'left' | 'right';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function Playground(props: PlaygroundProps) {
|
|
13
|
+
const {
|
|
14
|
+
code: codeProp,
|
|
15
|
+
language,
|
|
16
|
+
className = '',
|
|
17
|
+
direction = 'horizontal',
|
|
18
|
+
editorPosition,
|
|
19
|
+
...rest
|
|
20
|
+
} = props;
|
|
21
|
+
|
|
22
|
+
const [code, setCode] = useState(codeProp);
|
|
23
|
+
|
|
24
|
+
const handleCodeChange = useCallback((e?: string) => {
|
|
25
|
+
setCode(e || '');
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
const useReverseLayout =
|
|
29
|
+
direction === 'horizontal' && editorPosition === 'left';
|
|
30
|
+
|
|
31
|
+
const monacoLanguage =
|
|
32
|
+
language === 'tsx' || language === 'ts' ? 'typescript' : 'javascript';
|
|
33
|
+
|
|
34
|
+
const classNames = [
|
|
35
|
+
'rspress-playground',
|
|
36
|
+
`rspress-playground-${direction}`,
|
|
37
|
+
`rspress-playground-reverse-${useReverseLayout ? 'y' : 'n'}`,
|
|
38
|
+
className,
|
|
39
|
+
].join(' ');
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div className={classNames} {...rest}>
|
|
43
|
+
<Runner language={language} code={code} getImport={getImport} />
|
|
44
|
+
<Editor
|
|
45
|
+
value={code}
|
|
46
|
+
onChange={handleCodeChange}
|
|
47
|
+
language={monacoLanguage}
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.rspress-playground {
|
|
2
|
+
display: flex;
|
|
3
|
+
border: 1px solid rgba(28, 31, 35, 0.08);
|
|
4
|
+
border-radius: 3px;
|
|
5
|
+
margin-top: 20px;
|
|
6
|
+
margin-bottom: 20px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.rspress-playground-horizontal {
|
|
10
|
+
flex-direction: row;
|
|
11
|
+
height: 400px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.rspress-playground-horizontal.rspress-playground-reverse-y {
|
|
15
|
+
flex-direction: row-reverse;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.rspress-playground-vertical {
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.rspress-playground > .rspress-playground-runner {
|
|
23
|
+
padding: 20px;
|
|
24
|
+
overflow: auto;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.rspress-playground-horizontal > .rspress-playground-runner {
|
|
28
|
+
width: 40%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.rspress-playground-horizontal > .rspress-playground-editor {
|
|
32
|
+
width: 60%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.rspress-playground-horizontal.rspress-playground-reverse-y
|
|
36
|
+
> .rspress-playground-editor {
|
|
37
|
+
border-right: 1px solid rgba(28, 31, 35, 0.08);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rspress-playground-horizontal.rspress-playground-reverse-n
|
|
41
|
+
> .rspress-playground-editor {
|
|
42
|
+
border-left: 1px solid rgba(28, 31, 35, 0.08);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.rspress-playground-vertical > .rspress-playground-editor {
|
|
46
|
+
height: 300px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.rspress-playground-vertical > .rspress-playground-editor {
|
|
50
|
+
border-top: 1px solid rgba(28, 31, 35, 0.08);
|
|
51
|
+
}
|