@@ -20,38 +20,55 @@ function LiveProvider({
2020 element : undefined
2121 } ) ;
2222
23- function transpile ( newCode ) {
24- // Transpilation arguments
25- const input = {
26- code : transformCode ? transformCode ( newCode ) : newCode ,
27- scope,
28- transpileOptions
23+ function transpileAsync ( newCode ) {
24+ const errorCallback = error => {
25+ setState ( { error : error . toString ( ) , element : undefined } ) ;
2926 } ;
3027
31- const errorCallback = error =>
32- setState ( { error : error . toString ( ) , element : undefined } ) ;
28+ // - transformCode may be synchronous or asynchronous.
29+ // - transformCode may throw an exception or return a rejected promise, e.g.
30+ // if newCode is invalid and cannot be transformed.
31+ // - Not using async-await to since it requires targeting ES 2017 or
32+ // importing regenerator-runtime... in the next major version of
33+ // react-live, should target ES 2017+
34+ try {
35+ const transformResult = transformCode ? transformCode ( newCode ) : newCode ;
3336
34- const renderElement = element => setState ( { error : undefined , element } ) ;
37+ return Promise . resolve ( transformResult )
38+ . then ( transformedCode => {
39+ const renderElement = element =>
40+ setState ( { error : undefined , element } ) ;
3541
36- try {
37- if ( noInline ) {
38- setState ( { error : undefined , element : null } ) ; // Reset output for async (no inline) evaluation
39- renderElementAsync ( input , renderElement , errorCallback ) ;
40- } else {
41- renderElement ( generateElement ( input , errorCallback ) ) ;
42- }
43- } catch ( error ) {
44- errorCallback ( error ) ;
42+ // Transpilation arguments
43+ const input = {
44+ code : transformedCode ,
45+ scope,
46+ transpileOptions
47+ } ;
48+
49+ if ( noInline ) {
50+ setState ( { error : undefined , element : null } ) ; // Reset output for async (no inline) evaluation
51+ renderElementAsync ( input , renderElement , errorCallback ) ;
52+ } else {
53+ renderElement ( generateElement ( input , errorCallback ) ) ;
54+ }
55+ } )
56+ . catch ( errorCallback ) ;
57+ } catch ( e ) {
58+ errorCallback ( e ) ;
59+ return Promise . resolve ( ) ;
4560 }
4661 }
4762
63+ const onError = error => setState ( { error : error . toString ( ) } ) ;
64+
4865 useEffect ( ( ) => {
49- transpile ( code ) ;
66+ transpileAsync ( code ) . catch ( onError ) ;
5067 } , [ code , scope , noInline , transformCode , transpileOptions ] ) ;
5168
52- const onChange = newCode => transpile ( newCode ) ;
53-
54- const onError = error => setState ( { error : error . toString ( ) } ) ;
69+ const onChange = newCode => {
70+ transpileAsync ( newCode ) . catch ( onError ) ;
71+ } ;
5572
5673 return (
5774 < LiveContext . Provider
@@ -78,7 +95,7 @@ LiveProvider.propTypes = {
7895 noInline : PropTypes . bool ,
7996 scope : PropTypes . object ,
8097 theme : PropTypes . object ,
81- transformCode : PropTypes . node ,
98+ transformCode : PropTypes . func ,
8299 transpileOptions : PropTypes . object
83100} ;
84101
0 commit comments