1+ 'use strict' ;
2+
3+ Object . defineProperty ( exports , "__esModule" , {
4+ value : true
5+ } ) ;
6+
7+ var _createClass = function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ( ) ;
8+
9+ var _typeof = typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ? function ( obj ) { return typeof obj ; } : function ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ;
10+
11+ var _react = require ( 'react' ) ;
12+
13+ var _react2 = _interopRequireDefault ( _react ) ;
14+
15+ function _interopRequireDefault ( obj ) { return obj && obj . __esModule ? obj : { default : obj } ; }
16+
17+ function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
18+
19+ function _possibleConstructorReturn ( self , call ) { if ( ! self ) { throw new ReferenceError ( "this hasn't been initialised - super() hasn't been called" ) ; } return call && ( typeof call === "object" || typeof call === "function" ) ? call : self ; }
20+
21+ function _inherits ( subClass , superClass ) { if ( typeof superClass !== "function" && superClass !== null ) { throw new TypeError ( "Super expression must either be null or a function, not " + typeof superClass ) ; } subClass . prototype = Object . create ( superClass && superClass . prototype , { constructor : { value : subClass , enumerable : false , writable : true , configurable : true } } ) ; if ( superClass ) Object . setPrototypeOf ? Object . setPrototypeOf ( subClass , superClass ) : subClass . __proto__ = superClass ; }
22+
23+ var validSSRModes = [ 'render' , 'defer' , 'boundary' ] ;
24+
25+ function asyncComponent ( args ) {
26+ var name = args . name ,
27+ resolve = args . resolve ,
28+ _args$autoResolveES = args . autoResolveES2015Default ,
29+ autoResolveES2015Default = _args$autoResolveES === undefined ? true : _args$autoResolveES ,
30+ _args$serverMode = args . serverMode ,
31+ serverMode = _args$serverMode === undefined ? 'render' : _args$serverMode ,
32+ LoadingComponent = args . LoadingComponent ,
33+ ErrorComponent = args . ErrorComponent ;
34+
35+
36+ if ( validSSRModes . indexOf ( serverMode ) === - 1 ) {
37+ throw new Error ( 'Invalid serverMode provided to asyncComponent' ) ;
38+ }
39+
40+ var env = typeof window === 'undefined' ? 'node' : 'browser' ;
41+
42+ var sharedState = {
43+ // A unique id we will assign to our async component which is especially
44+ // useful when rehydrating server side rendered async components.
45+ id : null ,
46+ // This will be use to hold the resolved module allowing sharing across
47+ // instances.
48+ // NOTE: When using React Hot Loader this reference will become null.
49+ module : null ,
50+ // If an error occurred during a resolution it will be stored here.
51+ error : null ,
52+ // Allows us to share the resolver promise across instances.
53+ resolver : null
54+ } ;
55+
56+ // Takes the given module and if it has a ".default" the ".default" will
57+ // be returned. i.e. handy when you could be dealing with es6 imports.
58+ var es6Resolve = function es6Resolve ( x ) {
59+ return autoResolveES2015Default && x != null && ( typeof x === 'function' || ( typeof x === 'undefined' ? 'undefined' : _typeof ( x ) ) === 'object' ) && x . default ? x . default : x ;
60+ } ;
61+
62+ var getResolver = function getResolver ( ) {
63+ if ( sharedState . resolver == null ) {
64+ try {
65+ // Wrap whatever the user returns in Promise.resolve to ensure a Promise
66+ // is always returned.
67+ var resolver = resolve ( ) ;
68+ sharedState . resolver = Promise . resolve ( resolver ) ;
69+ } catch ( err ) {
70+ sharedState . resolver = Promise . reject ( err ) ;
71+ }
72+ }
73+ return sharedState . resolver ;
74+ } ;
75+
76+ var AsyncComponent = function ( _React$Component ) {
77+ _inherits ( AsyncComponent , _React$Component ) ;
78+
79+ function AsyncComponent ( props , context ) {
80+ _classCallCheck ( this , AsyncComponent ) ;
81+
82+ // We have to set the id in the constructor because a RHL seems
83+ // to recycle the module and therefore the id closure will be null.
84+ // We can't put it in componentWillMount as RHL hot swaps the new code
85+ // so the mount call will not happen (but the ctor does).
86+ var _this = _possibleConstructorReturn ( this , ( AsyncComponent . __proto__ || Object . getPrototypeOf ( AsyncComponent ) ) . call ( this , props , context ) ) ;
87+
88+ if ( _this . context . asyncComponents && ! sharedState . id ) {
89+ sharedState . id = _this . context . asyncComponents . getNextId ( ) ;
90+ }
91+ return _this ;
92+ }
93+
94+ _createClass ( AsyncComponent , [ {
95+ key : 'getChildContext' ,
96+ value : function getChildContext ( ) {
97+ if ( ! this . context . asyncComponents ) {
98+ return undefined ;
99+ }
100+
101+ return {
102+ asyncComponentsAncestor : {
103+ isBoundary : serverMode === 'boundary'
104+ }
105+ } ;
106+ }
107+ } , {
108+ key : 'componentWillMount' ,
109+ value : function componentWillMount ( ) {
110+ this . setState ( { module : sharedState . module } ) ;
111+ if ( sharedState . error ) {
112+ this . registerErrorState ( sharedState . error ) ;
113+ }
114+ }
115+ } , {
116+ key : 'componentDidMount' ,
117+ value : function componentDidMount ( ) {
118+ if ( ! this . state . module ) {
119+ this . resolveModule ( ) ;
120+ }
121+ }
122+
123+ // @see react-async-bootstrapper
124+
125+ } , {
126+ key : 'asyncBootstrap' ,
127+ value : function asyncBootstrap ( ) {
128+ var _this2 = this ;
129+
130+ var _context = this . context ,
131+ asyncComponents = _context . asyncComponents ,
132+ asyncComponentsAncestor = _context . asyncComponentsAncestor ;
133+ var shouldRehydrate = asyncComponents . shouldRehydrate ;
134+
135+
136+ var doResolve = function doResolve ( ) {
137+ return _this2 . resolveModule ( ) . then ( function ( module ) {
138+ return module !== undefined ;
139+ } ) ;
140+ } ;
141+
142+ if ( typeof window !== 'undefined' ) {
143+ // BROWSER BASED LOGIC
144+ return shouldRehydrate ( sharedState . id ) ? doResolve ( ) : false ;
145+ }
146+
147+ // SERVER BASED LOGIC
148+ var isChildOfBoundary = asyncComponentsAncestor && asyncComponentsAncestor . isBoundary ;
149+ return serverMode === 'defer' || isChildOfBoundary ? false : doResolve ( ) ;
150+ }
151+ } , {
152+ key : 'resolveModule' ,
153+ value : function resolveModule ( ) {
154+ var _this3 = this ;
155+
156+ this . resolving = true ;
157+
158+ return getResolver ( ) . then ( function ( module ) {
159+ if ( _this3 . unmounted ) {
160+ return undefined ;
161+ }
162+ if ( _this3 . context . asyncComponents ) {
163+ _this3 . context . asyncComponents . resolved ( sharedState . id ) ;
164+ }
165+ sharedState . module = module ;
166+ if ( env === 'browser' ) {
167+ _this3 . setState ( { module : module } ) ;
168+ }
169+ _this3 . resolving = false ;
170+ return module ;
171+ } ) . catch ( function ( error ) {
172+ if ( _this3 . unmounted ) {
173+ return undefined ;
174+ }
175+ if ( env === 'node' || ! ErrorComponent ) {
176+ // We will at least log the error so that user isn't completely
177+ // unaware of an error occurring.
178+ // eslint-disable-next-line no-console
179+ // console.warn('Failed to resolve asyncComponent')
180+ // eslint-disable-next-line no-console
181+ // console.warn(error)
182+ }
183+ sharedState . error = error ;
184+ _this3 . registerErrorState ( error ) ;
185+ _this3 . resolving = false ;
186+ return undefined ;
187+ } ) ;
188+ }
189+ } , {
190+ key : 'componentWillUnmount' ,
191+ value : function componentWillUnmount ( ) {
192+ this . unmounted = true ;
193+ }
194+ } , {
195+ key : 'registerErrorState' ,
196+ value : function registerErrorState ( error ) {
197+ var _this4 = this ;
198+
199+ if ( env === 'browser' ) {
200+ setTimeout ( function ( ) {
201+ if ( ! _this4 . unmounted ) {
202+ _this4 . setState ( { error : error } ) ;
203+ }
204+ } , 16 ) ;
205+ }
206+ }
207+ } , {
208+ key : 'render' ,
209+ value : function render ( ) {
210+ var _state = this . state ,
211+ module = _state . module ,
212+ error = _state . error ;
213+
214+ // This is as workaround for React Hot Loader support. When using
215+ // RHL the local component reference will be killed by any change
216+ // to the component, this will be our signal to know that we need to
217+ // re-resolve it.
218+
219+ if ( sharedState . module == null && ! this . resolving && typeof window !== 'undefined' ) {
220+ this . resolveModule ( ) ;
221+ }
222+
223+ if ( error ) {
224+ return ErrorComponent ? _react2 . default . createElement ( ErrorComponent , { error : error } ) : null ;
225+ }
226+
227+ var Component = es6Resolve ( module ) ;
228+ // eslint-disable-next-line no-nested-ternary
229+ return Component ? _react2 . default . createElement ( Component , this . props ) : LoadingComponent ? _react2 . default . createElement ( LoadingComponent , this . props ) : null ;
230+ }
231+ } ] ) ;
232+
233+ return AsyncComponent ;
234+ } ( _react2 . default . Component ) ;
235+
236+ AsyncComponent . childContextTypes = {
237+ asyncComponentsAncestor : _react2 . default . PropTypes . shape ( {
238+ isBoundary : _react2 . default . PropTypes . bool
239+ } )
240+ } ;
241+
242+ AsyncComponent . contextTypes = {
243+ asyncComponentsAncestor : _react2 . default . PropTypes . shape ( {
244+ isBoundary : _react2 . default . PropTypes . bool
245+ } ) ,
246+ asyncComponents : _react2 . default . PropTypes . shape ( {
247+ getNextId : _react2 . default . PropTypes . func . isRequired ,
248+ resolved : _react2 . default . PropTypes . func . isRequired ,
249+ shouldRehydrate : _react2 . default . PropTypes . func . isRequired
250+ } )
251+ } ;
252+
253+ AsyncComponent . displayName = name || 'AsyncComponent' ;
254+
255+ return AsyncComponent ;
256+ }
257+
258+ exports . default = asyncComponent ;
0 commit comments