11import useThemeContext from "@theme/hooks/useThemeContext" ;
22import clsx from "clsx" ;
3- import React , { useCallback , useContext , useEffect , useRef , useState } from "react" ;
3+ import React , { useCallback , useContext , useEffect , useRef , useState , useMemo } from "react" ;
44import JSONTree from "react-json-tree" ;
55import MonacoEditor from "react-monaco-editor" ;
66import { version as tstlVersion } from "typescript-to-lua/package.json" ;
@@ -27,29 +27,33 @@ async function executeLua(code: string) {
2727 } ) ;
2828}
2929
30- const EditorContext = React . createContext < EditorContext > ( null ! ) ;
31- interface EditorContext {
32- updateModel ( model : monaco . editor . ITextModel ) : void ;
33- code : string ;
30+ interface EditorState {
31+ source : string ;
32+ lua : string ;
33+ sourceMap : string ;
3434 ast : object ;
3535 results : LuaMessage [ ] ;
3636}
3737
38+ const EditorContext = React . createContext < EditorContext > ( null ! ) ;
39+ interface EditorContext extends EditorState {
40+ updateModel ( model : monaco . editor . ITextModel ) : void ;
41+ }
42+
3843function EditorContextProvider ( { children } : { children : React . ReactNode } ) {
39- const [ code , setCode ] = useState ( "" ) ;
40- const [ ast , setAst ] = useState < object > ( { } ) ;
41- const [ results , setResults ] = useState < LuaMessage [ ] > ( [ ] ) ;
44+ const [ state , setState ] = useState < EditorState > ( { source : "" , lua : "" , ast : { } , sourceMap : "" , results : [ ] } ) ;
4245 const updateModel = useCallback < EditorContext [ "updateModel" ] > ( async model => {
4346 const getWorker = await monaco . languages . typescript . getTypeScriptWorker ( ) ;
4447 const client = ( await getWorker ( model . uri ) ) as CustomTypeScriptWorker ;
48+ const { lua, ast, sourceMap } = await client . getTranspileOutput ( model . uri . toString ( ) ) ;
49+
50+ const source = model . getValue ( ) ;
51+ const results = await executeLua ( lua ) ;
4552
46- const { code, ast } = await client . getTranspileOutput ( model . uri . toString ( ) ) ;
47- setCode ( code ) ;
48- setAst ( ast ) ;
49- setResults ( await executeLua ( code ) ) ;
53+ setState ( { source, lua, ast, sourceMap, results } ) ;
5054 } , [ ] ) ;
5155
52- return < EditorContext . Provider value = { { code , ast , results , updateModel } } > { children } </ EditorContext . Provider > ;
56+ return < EditorContext . Provider value = { { updateModel , ... state } } > { children } </ EditorContext . Provider > ;
5357}
5458
5559const commonMonacoOptions : monaco . editor . IEditorConstructionOptions = {
@@ -67,7 +71,6 @@ function InputPane() {
6771 updateModel ( ref . current ! . editor ! . getModel ( ) ! ) ;
6872 } , [ ] ) ;
6973
70- // TODO: Debounce
7174 const onChange = useCallback (
7275 debounce ( ( newValue : string ) => {
7376 updateCodeHistory ( newValue ) ;
@@ -133,9 +136,16 @@ function LuaAST({ ast }: { ast: object }) {
133136
134137function OutputPane ( ) {
135138 const theme = useMonacoTheme ( ) ;
136- const { code , ast, results } = useContext ( EditorContext ) ;
139+ const { source , lua , sourceMap , ast, results } = useContext ( EditorContext ) ;
137140 const [ isAstView , setAstView ] = useState ( false ) ;
138141 const toggleAstView = useCallback ( ( ) => setAstView ( x => ! x ) , [ ] ) ;
142+ const sourceMapUrl = useMemo ( ( ) => {
143+ const inputs = [ lua , sourceMap , source ]
144+ // Replace non-ASCII characters, because btoa not supports them
145+ . map ( s => btoa ( s . replace ( / [ ^ \x00 - \x7F ] / g, "?" ) ) )
146+ . join ( "," ) ;
147+ return `https://sokra.github.io/source-map-visualization#base64,${ inputs } ` ;
148+ } , [ lua , sourceMap , source ] ) ;
139149
140150 return (
141151 < div className = { styles . contentPane } >
@@ -144,7 +154,7 @@ function OutputPane() {
144154 < MonacoEditor
145155 theme = { theme }
146156 language = "lua"
147- value = { code }
157+ value = { lua }
148158 options = { {
149159 ...commonMonacoOptions ,
150160 scrollBeyondLastLine : false ,
@@ -157,16 +167,17 @@ function OutputPane() {
157167 < LuaAST ast = { ast } />
158168 </ div >
159169
160- < button
161- className = { clsx (
162- "button button--outline button--primary" ,
163- styles . outputToggleButton ,
164- ! isAstView && "button--active" ,
165- ) }
166- onClick = { toggleAstView }
167- >
168- { isAstView ? "Lua AST" : "TEXT" }
169- </ button >
170+ < div className = { styles . outputControls } >
171+ < button
172+ className = { clsx ( "button button--outline button--primary" , ! isAstView && "button--active" ) }
173+ onClick = { toggleAstView }
174+ >
175+ { isAstView ? "Lua AST" : "TEXT" }
176+ </ button >
177+ < a className = "button button--success" href = { sourceMapUrl } target = "_blank" >
178+ Source Map
179+ </ a >
180+ </ div >
170181 </ div >
171182
172183 < div className = { styles . editorOutput } >
0 commit comments