@@ -19,37 +19,54 @@ function LiveProvider({
1919 element : undefined ,
2020 } ) ;
2121
22- function transpile ( newCode ) {
23- // Transpilation arguments
24- const input = {
25- code : transformCode ? transformCode ( newCode ) : newCode ,
26- scope,
22+ function transpileAsync ( newCode ) {
23+ const errorCallback = ( error ) => {
24+ setState ( { error : error . toString ( ) , element : undefined } ) ;
2725 } ;
2826
29- const errorCallback = ( error ) =>
30- setState ( { error : error . toString ( ) , element : undefined } ) ;
27+ // - transformCode may be synchronous or asynchronous.
28+ // - transformCode may throw an exception or return a rejected promise, e.g.
29+ // if newCode is invalid and cannot be transformed.
30+ // - Not using async-await to since it requires targeting ES 2017 or
31+ // importing regenerator-runtime... in the next major version of
32+ // react-live, should target ES 2017+
33+ try {
34+ const transformResult = transformCode ? transformCode ( newCode ) : newCode ;
3135
32- const renderElement = ( element ) => setState ( { error : undefined , element } ) ;
36+ return Promise . resolve ( transformResult )
37+ . then ( ( transformedCode ) => {
38+ const renderElement = ( element ) =>
39+ setState ( { error : undefined , element } ) ;
3340
34- try {
35- if ( noInline ) {
36- setState ( { error : undefined , element : null } ) ; // Reset output for async (no inline) evaluation
37- renderElementAsync ( input , renderElement , errorCallback ) ;
38- } else {
39- renderElement ( generateElement ( input , errorCallback ) ) ;
40- }
41- } catch ( error ) {
42- errorCallback ( error ) ;
41+ // Transpilation arguments
42+ const input = {
43+ code : transformedCode ,
44+ scope,
45+ } ;
46+
47+ if ( noInline ) {
48+ setState ( { error : undefined , element : null } ) ; // Reset output for async (no inline) evaluation
49+ renderElementAsync ( input , renderElement , errorCallback ) ;
50+ } else {
51+ renderElement ( generateElement ( input , errorCallback ) ) ;
52+ }
53+ } )
54+ . catch ( errorCallback ) ;
55+ } catch ( e ) {
56+ errorCallback ( e ) ;
57+ return Promise . resolve ( ) ;
4358 }
4459 }
4560
61+ const onError = ( error ) => setState ( { error : error . toString ( ) } ) ;
62+
4663 useEffect ( ( ) => {
47- transpile ( code ) ;
64+ transpileAsync ( code ) . catch ( onError ) ;
4865 } , [ code , scope , noInline , transformCode ] ) ;
4966
50- const onChange = ( newCode ) => transpile ( newCode ) ;
51-
52- const onError = ( error ) => setState ( { error : error . toString ( ) } ) ;
67+ const onChange = ( newCode ) => {
68+ transpileAsync ( newCode ) . catch ( onError ) ;
69+ } ;
5370
5471 return (
5572 < LiveContext . Provider
@@ -76,7 +93,7 @@ LiveProvider.propTypes = {
7693 noInline : PropTypes . bool ,
7794 scope : PropTypes . object ,
7895 theme : PropTypes . object ,
79- transformCode : PropTypes . node ,
96+ transformCode : PropTypes . func ,
8097} ;
8198
8299LiveProvider . defaultProps = {
0 commit comments