From a9a29842cdc0dc177e008780158be8f617759ec7 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 10:00:20 +0200 Subject: [PATCH 01/10] fix: added back files --- src/components/Monaco.tsx | 65 +++++++++++++ src/components/RunnableCode.tsx | 158 ++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 src/components/Monaco.tsx create mode 100644 src/components/RunnableCode.tsx diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx new file mode 100644 index 00000000..cecf7a8c --- /dev/null +++ b/src/components/Monaco.tsx @@ -0,0 +1,65 @@ +import React, { Suspense, lazy } from "react"; +import useThemeContext from "@theme/hooks/useThemeContext"; +import { libs } from "./monaco-types"; + +const MonacoEditor = lazy(() => import("react-monaco-editor")); + +function Monaco(props) { + let monacoRef; + const { isDarkTheme } = useThemeContext(); + + function onEditorWillMount(monaco) { + monacoRef = monaco; + const vsDarkTheme = { + base: "vs-dark", + inherit: true, + rules: [{ background: "121212" }], + colors: { + "editor.background": "#121212", + }, + }; + + monaco.editor.defineTheme("vs-dark", vsDarkTheme); + + monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ + target: monaco.languages.typescript.ScriptTarget.ES2017, + allowNonTsExtensions: true, + moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs, + module: monaco.languages.typescript.ModuleKind.ESNext, + typeRoots: ["node_modules/@types"], + }); + + libs.forEach((lib) => { + const MONACO_LIB_PREFIX = "file:///node_modules/"; + const path = `${MONACO_LIB_PREFIX}${lib.name}`; + monaco.languages.typescript.typescriptDefaults.addExtraLib(lib.dts, path); + }); + + if (props.editorWillMount) { + props.editorWillMount(monaco); + } + } + + function onEditorDidMount(editor) { + editor.setModel( + monacoRef.editor.createModel( + props.value, + "typescript", + monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`) + ) + ); + } + + return ( + Loading}> + + + ); +} + +export default Monaco; diff --git a/src/components/RunnableCode.tsx b/src/components/RunnableCode.tsx new file mode 100644 index 00000000..258904b3 --- /dev/null +++ b/src/components/RunnableCode.tsx @@ -0,0 +1,158 @@ +import { DAppClient } from "@airgap/beacon-sdk"; + +import React, { useState } from "react"; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import BrowserWindow from "./BrowserWindow/BrowserWindow"; +import Monaco from "./Monaco"; +import LoadingAnimation from "./LoadingAnimation"; +import { copyShareUrl, runBeaconCode } from "../utils"; +import { ExecutionState } from "../ExecutionState"; + +const Child = ({ code }) => { + const [runnableCode, setRunnableCode] = useState( + code.props.children.props.children + ); + const [executionState, setExecutionState] = useState(ExecutionState.INIT); + const [output, setOutput] = useState(""); + const [readonly, setReadonly] = useState(true); + + const execute = async () => { + if (executionState === ExecutionState.STARTED) { + return; + } + await clear(); + setExecutionState(ExecutionState.STARTED); + await runBeaconCode(runnableCode, setOutput); + setExecutionState(ExecutionState.ENDED); + }; + const reset = async () => { + clear(); + const dAppClient = new DAppClient({ name: "Cleanup" }); + await dAppClient.destroy(); + }; + const clear = async () => { + setOutput(""); + setExecutionState(ExecutionState.INIT); + }; + const toggleReadonly = async () => { + setReadonly(!readonly); + }; + const handleShareUrl = async () => { + copyShareUrl(runnableCode); + }; + + const numberOfLines = 1 + runnableCode.split("\n").length; + const editorLayout = { + width: 800, + height: 18 * numberOfLines, + }; + + const setInput = (input: string) => { + setRunnableCode(input); + }; + + return ( + <> + {readonly ? ( + code + ) : ( + + )} + + + + + + + + {executionState !== ExecutionState.INIT ? ( + <> +

Output

+
+              
+                {executionState === ExecutionState.STARTED ? (
+                  <>
+                    
+                  
+                ) : (
+                  ""
+                )}
+                {output || executionState === ExecutionState.ENDED
+                  ? output
+                  : "Waiting for output..."}
+              
+            
+ + ) : ( + "" + )} +
+ + ); +}; + +export const RunnableCode = ({ children, color, beacon, taquito }) => { + return ( + + + + + + + + + ); +}; From 1121f0636a472c8aa4773ff835d94006d7b2da58 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 10:10:18 +0200 Subject: [PATCH 02/10] fix: added browseronly --- src/components/Monaco.tsx | 4 +- src/components/RunnableCode.tsx | 47 ++++++++------ src/utils.ts | 111 +++++++++++++++++++++++++++++++- 3 files changed, 138 insertions(+), 24 deletions(-) diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx index cecf7a8c..ef53bfd7 100644 --- a/src/components/Monaco.tsx +++ b/src/components/Monaco.tsx @@ -45,8 +45,8 @@ function Monaco(props) { monacoRef.editor.createModel( props.value, "typescript", - monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`) - ) + monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`), + ), ); } diff --git a/src/components/RunnableCode.tsx b/src/components/RunnableCode.tsx index 258904b3..3f8b8c53 100644 --- a/src/components/RunnableCode.tsx +++ b/src/components/RunnableCode.tsx @@ -1,17 +1,20 @@ -import { DAppClient } from "@airgap/beacon-sdk"; - import React, { useState } from "react"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; import BrowserWindow from "./BrowserWindow/BrowserWindow"; -import Monaco from "./Monaco"; import LoadingAnimation from "./LoadingAnimation"; -import { copyShareUrl, runBeaconCode } from "../utils"; import { ExecutionState } from "../ExecutionState"; +import BrowserOnly from "@docusaurus/BrowserOnly"; const Child = ({ code }) => { + const { DAppClient } = require("../node_modules/beacon-sdk/dist/cjs"); + + const Monaco = require("./Monaco"); + + const { copyShareUrl, runBeaconCode } = require("../utils"); + const [runnableCode, setRunnableCode] = useState( - code.props.children.props.children + code.props.children.props.children, ); const [executionState, setExecutionState] = useState(ExecutionState.INIT); const [output, setOutput] = useState(""); @@ -139,20 +142,24 @@ const Child = ({ code }) => { export const RunnableCode = ({ children, color, beacon, taquito }) => { return ( - - - - - - - - + }> + {() => ( + + + + + + + + + )} + ); }; diff --git a/src/utils.ts b/src/utils.ts index 4c19eb20..31dddf31 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,113 @@ -import { DAppClient } from "./node_modules/beacon-sdk/dist/cjs"; +import * as beacon from "./node_modules/beacon-sdk/dist/cjs"; +import * as ts from "typescript"; + +import * as taquito from "@taquito/taquito"; +import * as taquitoWallet from "@taquito/beacon-wallet"; + +function replaceAll(string: string, search: string, replace: string) { + return string.split(search).join(replace); +} + +const removeImports = (code: string) => { + const lines = code.split("\n"); + let include = true; + + return lines + .map((l) => { + if (l.trim().startsWith("import")) { + include = false; + } + + const out = include ? l : undefined; + + if (l.indexOf("@airgap/beacon-sdk") >= 0 || l.indexOf("@taquito") >= 0) { + include = true; + } + + return out; + }) + .filter((l) => !!l) + .join("\n"); +}; + +export const runBeaconCode = ( + rawCode: string, + setOutput: (str: string) => void, +) => { + let code = rawCode; + + let output = ""; + const appendOutput = (str: string) => { + output += "\n" + str; + setOutput(output.trim()); + }; + + const myLog = (...args: any[]) => { + console.log("CODE_RUNNER:", ...args); + appendOutput( + args + .map((arg) => + typeof arg === "object" ? JSON.stringify(arg, null, 2) : arg, + ) + .join(" "), + ); + }; + + code = replaceAll(code, "console.log(", "progress("); + code = removeImports(code); + code = ts.transpile(`({ + run: async (beacon: any, taquito: any, taquitoWallet: any, progress: any): string => { + Object.keys(beacon).forEach(key => { + window[key] = beacon[key] + }) + Object.keys(taquito).forEach(key => { + window[key] = taquito[key] + }) + Object.keys(taquitoWallet).forEach(key => { + window[key] = taquitoWallet[key] + }) + return (async () => { + ${code}; + if (typeof result !== 'undefined') { + return result + } + })() + })`); + let runnable: any; + // console.log("TRANSPILED code", code); + return new Promise((resolve) => { + try { + runnable = eval(code); + runnable + .run(beacon, taquito, taquitoWallet, myLog) + .then((result: string) => { + if (result) { + appendOutput("Returned:\n" + JSON.stringify(result, null, 2)); + } + resolve(result); + }) + .catch((err: any) => { + console.warn(err); + appendOutput(JSON.stringify(err, null, 2)); + resolve(err); + }); + } catch (e) { + appendOutput(e); + console.error(e); + resolve(e); + } + }); +}; + +export const copyShareUrl = (input: string) => { + const url = `https://${window.location.host}/playground?code=${btoa(input)}`; + + navigator.clipboard + .writeText(url) + .catch((err) => console.error("Failed to copy to url!", err)); +}; export const reset = async () => { - const dAppClient = new DAppClient({ name: "Cleanup" }); + const dAppClient = new beacon.DAppClient({ name: "Cleanup" }); await dAppClient.destroy(); }; From 085b3b2cf4b6ab8b9c8f0e1bcc3bd6a1c1072a4d Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 10:31:14 +0200 Subject: [PATCH 03/10] fix: added back playground --- src/components/Monaco.tsx | 6 +- src/pages/playground.tsx | 167 ++++++++++++++++++++++++++++++++++++ src/pages/styles.module.css | 115 +++++++++++++++++++++++++ 3 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 src/pages/playground.tsx create mode 100644 src/pages/styles.module.css diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx index ef53bfd7..a548f27d 100644 --- a/src/components/Monaco.tsx +++ b/src/components/Monaco.tsx @@ -1,12 +1,12 @@ import React, { Suspense, lazy } from "react"; -import useThemeContext from "@theme/hooks/useThemeContext"; +import { useColorMode } from "@docusaurus/theme-common"; import { libs } from "./monaco-types"; const MonacoEditor = lazy(() => import("react-monaco-editor")); function Monaco(props) { let monacoRef; - const { isDarkTheme } = useThemeContext(); + const { colorMode } = useColorMode(); function onEditorWillMount(monaco) { monacoRef = monaco; @@ -56,7 +56,7 @@ function Monaco(props) { {...props} editorWillMount={onEditorWillMount} editorDidMount={onEditorDidMount} - theme={isDarkTheme ? "vs-dark" : "vs-light"} + theme={colorMode === "dark" ? "vs-dark" : "vs-light"} /> ); diff --git a/src/pages/playground.tsx b/src/pages/playground.tsx new file mode 100644 index 00000000..aedc535d --- /dev/null +++ b/src/pages/playground.tsx @@ -0,0 +1,167 @@ +import React, { useState } from "react"; +import classnames from "classnames"; +import Layout from "@theme/Layout"; +import useWindowSize from "@site/src/hooks/useWindowSize"; +import styles from "./styles.module.css"; +import { ExecutionState } from "../ExecutionState"; + +import BrowserOnly from "@docusaurus/BrowserOnly"; + +const defaultCode = `import { DAppClient } from "@airgap/beacon-sdk"; + +const dAppClient = new DAppClient({ name: 'Beacon Docs' }) + +const activeAccount = await dAppClient.getActiveAccount() +if (activeAccount) { + // User already has account connected, everything is ready + // You can now do an operation request, sign request, or send another permission request to switch wallet + console.log('Already connected:', activeAccount.address) + return activeAccount +} else { + const permissions = await dAppClient.requestPermissions() + console.log('New connection:', permissions.address) + return permissions +}`; + +function Playground() { + if (typeof window === "undefined") { + return null; + } + + const urlParams = new URLSearchParams(window.location.search); + const initialCode = urlParams.has("code") + ? atob(urlParams.get("code")) + : defaultCode; + + const [input, setInput] = useState(initialCode); + const [output, setOutput] = useState(""); + const [executionState, setExecutionState] = useState(ExecutionState.INIT); + + const windowSize = useWindowSize(); + + const inputChanged = (str) => { + setInput(str); + }; + + const headerLayout = { + height: 100, + }; + + const editorWidthRatio = 3 / 5; + const editorLayout = { + xs: { + width: windowSize.width, + height: 200, + }, + lg: { + width: editorWidthRatio * windowSize.width, + height: windowSize.height - headerLayout.height, + }, + }; + + const outputLayout = { + xs: { + width: windowSize.width, + height: windowSize.height - headerLayout.height - editorLayout.xs.height, + }, + lg: { + width: (1 - editorWidthRatio - 0.05) * windowSize.width, + height: windowSize.height, + }, + }; + + return ( + }> + {() => { + const { DAppClient } = require("@airgap/beacon-sdk"); + const { Monaco } = require("@site/src/components/Monaco"); + const { copyShareUrl, runBeaconCode } = require("../utils"); + + const execute = async () => { + if (executionState === ExecutionState.STARTED) { + return; + } + await clear(); + setExecutionState(ExecutionState.STARTED); + await runBeaconCode(input, setOutput); + setExecutionState(ExecutionState.ENDED); + }; + const clear = async () => { + setOutput(""); + setExecutionState(ExecutionState.INIT); + }; + + const handleClickShare = () => { + copyShareUrl(input); + }; + + const reset = async () => { + clear(); + const dAppClient = new DAppClient({ name: "Cleanup" }); + await dAppClient.destroy(); + }; + + return ( + +
+ + + + +
+ +
+ 600 + ? editorLayout.lg + : editorLayout.xs)} + language="typescript" + value={input} + onChange={inputChanged} + options={{ minimap: { enabled: false }, wordWrap: "on" }} + /> + 600 + ? outputLayout.lg + : outputLayout.xs)} + language="bash" + value={output} + options={{ + readOnly: true, + minimap: { enabled: false }, + wordWrap: "on", + }} + /> +
+
+ ); + }} +
+ ); +} + +export default Playground; diff --git a/src/pages/styles.module.css b/src/pages/styles.module.css new file mode 100644 index 00000000..d76a889b --- /dev/null +++ b/src/pages/styles.module.css @@ -0,0 +1,115 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +li, +p { + max-width: 70ch; +} + +body > div { + overflow: hidden; +} + +.runbox { + margin: 10px; +} + +.headerContainer { + display: flex; + flex-wrap: wrap; + margin-left: 10px; + padding: 10px; +} + +.argsInputContainer { + display: flex; + height: 30px; + margin-right: 10px; +} + +.argsInputField { + color: var(--ifm-navbar-search-input-color); + background-color: var(--ifm-navbar-search-input-background-color); + border: 1px solid var(--ifm-color-emphasis-500); + border-radius: 4px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + width: 300px; + padding: 10px; + outline: none; +} + +html[data-theme="dark"] .argsInputField { + border: 1px solid var(--ifm-color-emphasis-100); +} + +.argsIconContainer { + padding-top: 4px; + margin-left: 0; + background-color: var(--ifm-navbar-search-input-background-color); + border: 1px solid var(--ifm-color-emphasis-500); + border-left: none; + border-radius: 4px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + color: var(--ifm-color-primary); + min-width: 50px; + text-align: center; +} + +html[data-theme="dark"] .argsIconContainer { + border: 1px solid var(--ifm-color-emphasis-100); +} + +.argsIconContainer:hover { + cursor: pointer; + background-color: var(--ifm-color-primary); + color: white; +} + +.helperButton { + margin-right: 10px; + height: 30px; + padding-top: 4px; + background-color: var(--ifm-navbar-search-input-background-color); + border: 1px solid var(--ifm-color-emphasis-500); + border-radius: 4px; + color: var(--ifm-color-primary); + text-align: center; + font-size: var(--ifm-font-size-base); + padding: 0px 12px; +} + +.helperButton:hover { + cursor: pointer; + background-color: var(--ifm-color-primary); + color: white; +} + +html[data-theme="dark"] .helperButton { + border: 1px solid var(--ifm-color-emphasis-100); +} + +.row { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +.spinner { + animation: rotate 1.5s linear infinite; +} + +@keyframes rotate { + 100% { + transform: rotate(360deg); + } +} + +@media screen and (max-width: 600px) { + .argsInputField { + width: 100%; + } +} From f955d94d8e9f8e72ff9cd951e96e4c91dea42831 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 13:40:45 +0200 Subject: [PATCH 04/10] fix: monaco-editor --- .gitignore | 1 + .yarnrc.yml | 1 + docusaurus.config.js | 6 +-- package-lock.json | 75 +++++++++++++++++++++++---------- package.json | 4 +- src/components/Monaco.tsx | 18 ++++---- src/components/RunnableCode.tsx | 2 +- src/pages/playground.tsx | 2 +- 8 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 .yarnrc.yml diff --git a/.gitignore b/.gitignore index 0165c169..92d2e414 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ # Generated files .docusaurus .cache-loader +.yarn # Misc .DS_Store diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..8b757b29 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules \ No newline at end of file diff --git a/docusaurus.config.js b/docusaurus.config.js index a3cc071a..8c7af8db 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -90,11 +90,7 @@ const config = { docId: "wallet/getting-started/web/getting-started", label: "Wallets", }, - { - href: "https://stackblitz.com/edit/vitejs-vite-71wsul?file=src%2Fmain.ts&terminal=dev", - label: "Playground", - position: "right", - }, + { to: "playground/", label: "Playground", position: "right" }, { href: "https://debug.walletbeacon.io", label: "Debug Wallet", diff --git a/package-lock.json b/package-lock.json index da7fcfa2..695a5a76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,14 +14,14 @@ "@docusaurus/preset-classic": "2.4.3", "@docusaurus/theme-live-codeblock": "^2.4.3", "@mdx-js/react": "^1.6.22", + "@monaco-editor/react": "^4.6.0", "@taquito/beacon-wallet": "^17.3.1", "@taquito/taquito": "^17.3.1", "clsx": "^1.2.1", "mermaid": "^10.4.0", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-monaco-editor": "^0.54.0" + "react-dom": "^17.0.2" }, "devDependencies": { "@docusaurus/module-type-aliases": "2.4.3", @@ -3164,6 +3164,30 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", + "dependencies": { + "@monaco-editor/loader": "^1.4.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -13147,19 +13171,6 @@ "webpack": ">=4.41.1 || 5.x" } }, - "node_modules/react-monaco-editor": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.54.0.tgz", - "integrity": "sha512-9JwO69851mfpuhYLHlKbae7omQWJ/2ICE2lbL0VHyNyZR8rCOH7440u+zAtDgiOMpLwmYdY1sEZCdRefywX6GQ==", - "dependencies": { - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "@types/react": ">=16 <= 18", - "monaco-editor": "^0.39.0", - "react": ">=16 <= 18" - } - }, "node_modules/react-router": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", @@ -14475,6 +14486,11 @@ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, "node_modules/state-toggle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", @@ -18765,6 +18781,22 @@ "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==" }, + "@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", + "requires": { + "state-local": "^1.0.6" + } + }, + "@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", + "requires": { + "@monaco-editor/loader": "^1.4.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -26198,14 +26230,6 @@ "@babel/runtime": "^7.10.3" } }, - "react-monaco-editor": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.54.0.tgz", - "integrity": "sha512-9JwO69851mfpuhYLHlKbae7omQWJ/2ICE2lbL0VHyNyZR8rCOH7440u+zAtDgiOMpLwmYdY1sEZCdRefywX6GQ==", - "requires": { - "prop-types": "^15.8.1" - } - }, "react-router": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", @@ -27224,6 +27248,11 @@ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" }, + "state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, "state-toggle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", diff --git a/package.json b/package.json index 23e79ea0..53fdfbfd 100644 --- a/package.json +++ b/package.json @@ -28,14 +28,14 @@ "@docusaurus/preset-classic": "2.4.3", "@docusaurus/theme-live-codeblock": "^2.4.3", "@mdx-js/react": "^1.6.22", + "@monaco-editor/react": "^4.6.0", "@taquito/beacon-wallet": "^17.3.1", "@taquito/taquito": "^17.3.1", "clsx": "^1.2.1", "mermaid": "^10.4.0", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-monaco-editor": "^0.54.0" + "react-dom": "^17.0.2" }, "devDependencies": { "@docusaurus/module-type-aliases": "2.4.3", diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx index a548f27d..c20b38d9 100644 --- a/src/components/Monaco.tsx +++ b/src/components/Monaco.tsx @@ -2,7 +2,7 @@ import React, { Suspense, lazy } from "react"; import { useColorMode } from "@docusaurus/theme-common"; import { libs } from "./monaco-types"; -const MonacoEditor = lazy(() => import("react-monaco-editor")); +import Editor from "@monaco-editor/react"; function Monaco(props) { let monacoRef; @@ -45,18 +45,20 @@ function Monaco(props) { monacoRef.editor.createModel( props.value, "typescript", - monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`), - ), + monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`) + ) ); } return ( Loading}> - ); diff --git a/src/components/RunnableCode.tsx b/src/components/RunnableCode.tsx index 3f8b8c53..eb3ff731 100644 --- a/src/components/RunnableCode.tsx +++ b/src/components/RunnableCode.tsx @@ -9,7 +9,7 @@ import BrowserOnly from "@docusaurus/BrowserOnly"; const Child = ({ code }) => { const { DAppClient } = require("../node_modules/beacon-sdk/dist/cjs"); - const Monaco = require("./Monaco"); + const Monaco = require("./Monaco").default; const { copyShareUrl, runBeaconCode } = require("../utils"); diff --git a/src/pages/playground.tsx b/src/pages/playground.tsx index aedc535d..eb63ef32 100644 --- a/src/pages/playground.tsx +++ b/src/pages/playground.tsx @@ -74,7 +74,7 @@ function Playground() { }> {() => { const { DAppClient } = require("@airgap/beacon-sdk"); - const { Monaco } = require("@site/src/components/Monaco"); + const Monaco = require("@site/src/components/Monaco").default; const { copyShareUrl, runBeaconCode } = require("../utils"); const execute = async () => { From 16a07c8e8d58948ed1554a738aabf7dd7b03d3d1 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 14:21:00 +0200 Subject: [PATCH 05/10] fix: typings --- scripts/generate-monaco-types.js | 2 +- src/components/Monaco.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/generate-monaco-types.js b/scripts/generate-monaco-types.js index ec3e8a5b..ae2d74c5 100644 --- a/scripts/generate-monaco-types.js +++ b/scripts/generate-monaco-types.js @@ -2,7 +2,7 @@ const fs = require("fs"); const getFilesRecursively = require("./get-files-in-folder"); const files = getFilesRecursively( - "./node_modules/@airgap/beacon-sdk/dist/cjs/" + "./node_modules/@airgap/" ).filter((file) => file.endsWith(".d.ts")); files.push( ...getFilesRecursively("./node_modules/@taquito/").filter((file) => diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx index c20b38d9..b65a3e14 100644 --- a/src/components/Monaco.tsx +++ b/src/components/Monaco.tsx @@ -45,8 +45,8 @@ function Monaco(props) { monacoRef.editor.createModel( props.value, "typescript", - monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`) - ) + monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`), + ), ); } From 5bf08a5b0b09c544acaa1ca5b0f9c23c0ae65262 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 14:32:56 +0200 Subject: [PATCH 06/10] fix: view --- package.json | 3 ++- src/components/Monaco.tsx | 9 ++++----- src/pages/playground.tsx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 53fdfbfd..7ce9db51 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,10 @@ "prettier": "npx prettier --write './sidebars.js' 'docusaurus.config.js' && npm run pretty-source", "pretty-source": "npx prettier --ignore-unknown --write 'src/**/*'", "pretty-docs": "npx prettier --ignore-unknown --write 'docs/**/*'", + "generate-monaco-types": "node scripts/generate-monaco-types.js", "remove-folders": "rm -rf build-docs && rm -rf docs", "clear-folders": "npm run remove-folders && mkdir build-docs && mkdir docs", - "embed-code": "npm run prettier && tsc --module es2015 --target es2015 --moduleResolution node --esModuleInterop true src/examples/*.ts && node scripts/copy-examples.js && npm run clear-folders && cp -r src/docs/* build-docs/ && rm -r docs && mv build-docs docs && npm run pretty-docs" + "embed-code": "npm run generate-monaco-types && npm run prettier && tsc --module es2015 --target es2015 --moduleResolution node --esModuleInterop true src/examples/*.ts && node scripts/copy-examples.js && npm run clear-folders && cp -r src/docs/* build-docs/ && rm -r docs && mv build-docs docs && npm run pretty-docs" }, "dependencies": { "@airgap/beacon-sdk": "4.0.10", diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx index b65a3e14..173abdad 100644 --- a/src/components/Monaco.tsx +++ b/src/components/Monaco.tsx @@ -44,18 +44,17 @@ function Monaco(props) { editor.setModel( monacoRef.editor.createModel( props.value, - "typescript", - monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`), - ), + props.language, + monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`) + ) ); } return ( Loading}> 600 ? outputLayout.lg : outputLayout.xs)} - language="bash" + language="shell" value={output} options={{ readOnly: true, From d362ca350fbc833c8458a1c02fec12df62d68c03 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 14:41:10 +0200 Subject: [PATCH 07/10] fix: disabled live editing --- src/theme/Playground/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/theme/Playground/index.js b/src/theme/Playground/index.js index aad11c72..722c7a91 100644 --- a/src/theme/Playground/index.js +++ b/src/theme/Playground/index.js @@ -110,6 +110,7 @@ export default function Playground({ children, transformCode, ...props }) { noInline={noInline} transformCode={transformCode ?? ((code) => `${code};`)} theme={prismTheme} + disabled={true} {...props} > {playgroundPosition === "top" ? ( From 957104d2562c68e6ce7485878900d9086fba4f40 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 15:12:11 +0200 Subject: [PATCH 08/10] feat: added error boundary --- src/components/Monaco.tsx | 4 ++-- src/theme/Playground/index.js | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/Monaco.tsx b/src/components/Monaco.tsx index 173abdad..622fec4c 100644 --- a/src/components/Monaco.tsx +++ b/src/components/Monaco.tsx @@ -45,8 +45,8 @@ function Monaco(props) { monacoRef.editor.createModel( props.value, props.language, - monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`) - ) + monacoRef.Uri.parse(`file:///main-${Math.random()}.ts`), + ), ); } diff --git a/src/theme/Playground/index.js b/src/theme/Playground/index.js index 722c7a91..db0bfe70 100644 --- a/src/theme/Playground/index.js +++ b/src/theme/Playground/index.js @@ -9,6 +9,7 @@ import { usePrismTheme } from "@docusaurus/theme-common"; import styles from "./styles.module.css"; import BrowserWindow from "@site/src/components/BrowserWindow/BrowserWindow"; +import ErrorBoundary from "@docusaurus/ErrorBoundary"; function getCodeBody(code) { const lines = code.split("\n"); @@ -102,7 +103,14 @@ export default function Playground({ children, transformCode, ...props }) { }; return ( - <> + ( +
+

This editor crashed because of error: {error.message}.

+ +
+ )} + >
{/* @ts-expect-error: type incompatibility with refs */} - + ); } From a4f66070465db4fc843ec4350ceefc930d0bde53 Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 15:21:35 +0200 Subject: [PATCH 09/10] fix: add error boundary to monaco --- src/pages/playground.tsx | 54 +++++++++++++++++++++-------------- src/theme/Playground/index.js | 13 ++------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/pages/playground.tsx b/src/pages/playground.tsx index 886e702a..06dd0a5a 100644 --- a/src/pages/playground.tsx +++ b/src/pages/playground.tsx @@ -6,6 +6,7 @@ import styles from "./styles.module.css"; import { ExecutionState } from "../ExecutionState"; import BrowserOnly from "@docusaurus/BrowserOnly"; +import ErrorBoundary from "@docusaurus/ErrorBoundary"; const defaultCode = `import { DAppClient } from "@airgap/beacon-sdk"; @@ -135,27 +136,38 @@ function Playground() {
- 600 - ? editorLayout.lg - : editorLayout.xs)} - language="typescript" - value={input} - onChange={inputChanged} - options={{ minimap: { enabled: false }, wordWrap: "on" }} - /> - 600 - ? outputLayout.lg - : outputLayout.xs)} - language="shell" - value={output} - options={{ - readOnly: true, - minimap: { enabled: false }, - wordWrap: "on", - }} - /> + ( +
+

+ This editor crashed because of error: {error.message}. +

+ +
+ )} + > + 600 + ? editorLayout.lg + : editorLayout.xs)} + language="typescript" + value={input} + onChange={inputChanged} + options={{ minimap: { enabled: false }, wordWrap: "on" }} + /> + 600 + ? outputLayout.lg + : outputLayout.xs)} + language="shell" + value={output} + options={{ + readOnly: true, + minimap: { enabled: false }, + wordWrap: "on", + }} + /> +
); diff --git a/src/theme/Playground/index.js b/src/theme/Playground/index.js index db0bfe70..aad11c72 100644 --- a/src/theme/Playground/index.js +++ b/src/theme/Playground/index.js @@ -9,7 +9,6 @@ import { usePrismTheme } from "@docusaurus/theme-common"; import styles from "./styles.module.css"; import BrowserWindow from "@site/src/components/BrowserWindow/BrowserWindow"; -import ErrorBoundary from "@docusaurus/ErrorBoundary"; function getCodeBody(code) { const lines = code.split("\n"); @@ -103,14 +102,7 @@ export default function Playground({ children, transformCode, ...props }) { }; return ( - ( -
-

This editor crashed because of error: {error.message}.

- -
- )} - > + <>
{/* @ts-expect-error: type incompatibility with refs */} `${code};`)} theme={prismTheme} - disabled={true} {...props} > {playgroundPosition === "top" ? ( @@ -171,6 +162,6 @@ export default function Playground({ children, transformCode, ...props }) { ); }} - + ); } From ce2d03f1c87fd94e32875cacfb64763bb3a633af Mon Sep 17 00:00:00 2001 From: Isacco Date: Thu, 12 Oct 2023 15:26:54 +0200 Subject: [PATCH 10/10] fix: disabled editing in code blocks --- src/theme/Playground/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/theme/Playground/index.js b/src/theme/Playground/index.js index aad11c72..722c7a91 100644 --- a/src/theme/Playground/index.js +++ b/src/theme/Playground/index.js @@ -110,6 +110,7 @@ export default function Playground({ children, transformCode, ...props }) { noInline={noInline} transformCode={transformCode ?? ((code) => `${code};`)} theme={prismTheme} + disabled={true} {...props} > {playgroundPosition === "top" ? (