1212
1313const invariant = require ( 'fbjs/lib/invariant' ) ;
1414const memoize = require ( 'async/memoize' ) ;
15+ const nullthrows = require ( 'fbjs/lib/nullthrows' ) ;
1516const queue = require ( 'async/queue' ) ;
1617const seq = require ( 'async/seq' ) ;
1718
18- import type { GraphFn , LoadFn , ResolveFn , File , Module } from './types.flow' ;
19+ import type {
20+ Callback ,
21+ File ,
22+ GraphFn ,
23+ LoadFn ,
24+ Module ,
25+ ResolveFn ,
26+ } from './types.flow' ;
27+
28+ type Async$Queue < T , C > = {
29+ buffer : number ,
30+ concurrency : number ,
31+ drain : ( ) => mixed ,
32+ empty : ( ) => mixed ,
33+ error : ( Error , T ) => mixed ,
34+ idle ( ) : boolean ,
35+ kill ( ) : void ,
36+ length ( ) : number ,
37+ pause ( ) : void ,
38+ paused : boolean ,
39+ push ( T | Array < T > , void | C ) : void ,
40+ resume ( ) : void ,
41+ running ( ) : number ,
42+ saturated : ( ) => mixed ,
43+ started : boolean ,
44+ unsaturated : ( ) => mixed ,
45+ unshift ( T , void | C ) : void ,
46+ workersList ( ) : Array < T > ,
47+ } ;
48+
49+ type LoadQueue =
50+ Async$Queue < { id : string , parent : string } , Callback < File , Array < string >>> ;
1951
2052const createParentModule =
21- ( ) => ( { file : { path : '' , ast : { } } , dependencies : [ ] } ) ;
53+ ( ) => ( { file : { code : '' , isPolyfill : false , path : '' } , dependencies : [ ] } ) ;
2254
2355const noop = ( ) => { } ;
56+ const NO_OPTIONS = { } ;
2457
2558exports . create = function create ( resolve : ResolveFn , load : LoadFn ) : GraphFn {
26- function Graph ( entryPoints , platform , options = { } , callback = noop ) {
27- const { cwd = '' , log = ( console : any ) , optimize = false , skip} = options ;
59+ function Graph ( entryPoints , platform , options , callback = noop ) {
60+ const {
61+ cwd = '' ,
62+ log = ( console : any ) ,
63+ optimize = false ,
64+ skip,
65+ } = options || NO_OPTIONS ;
2866
2967 if ( typeof platform !== 'string' ) {
3068 log . error ( '`Graph`, called without a platform' ) ;
@@ -35,58 +73,76 @@ exports.create = function create(resolve: ResolveFn, load: LoadFn): GraphFn {
3573 const modules : Map < string | null , Module > = new Map ( ) ;
3674 modules . set ( null , createParentModule ( ) ) ;
3775
38- const loadQueue = queue ( seq (
39- ( { id, parent} , cb ) => resolve ( id , parent , platform , options , cb ) ,
76+ const loadQueue : LoadQueue = queue ( seq (
77+ ( { id, parent} , cb ) => resolve ( id , parent , platform , options || NO_OPTIONS , cb ) ,
4078 memoize ( ( file , cb ) => load ( file , { log, optimize} , cb ) ) ,
4179 ) , Number . MAX_SAFE_INTEGER ) ;
4280
43- const cleanup = ( ) => ( loadQueue . drain = noop ) ;
4481 loadQueue . drain = ( ) => {
45- cleanup ( ) ;
82+ loadQueue . kill ( ) ;
4683 callback ( null , collect ( null , modules ) ) ;
4784 } ;
48-
49- function loadModule ( id : string , parent : string | null , parentDependencyIndex ) {
50- function onFileLoaded (
51- error : ?Error ,
52- file : File ,
53- dependencyIDs : Array < string > ,
54- ) {
55- if ( error ) {
56- cleanup ( ) ;
57- callback ( error ) ;
58- return ;
59- }
60-
61- const parentModule = modules . get ( parent ) ;
62- invariant ( parentModule , 'Invalid parent module: ' + String ( parent ) ) ;
63- parentModule . dependencies [ parentDependencyIndex ] = { id, path : file . path } ;
64-
65- if ( ( ! skip || ! skip . has ( file . path ) ) && ! modules . has ( file . path ) ) {
66- const dependencies = Array ( dependencyIDs . length ) ;
67- modules . set ( file . path , { file, dependencies} ) ;
68- dependencyIDs . forEach (
69- ( dependencyID , j ) => loadModule ( dependencyID , file . path , j ) ) ;
70- }
71- }
72- loadQueue . push ( { id, parent : parent != null ? parent : cwd } , onFileLoaded ) ;
73- }
85+ loadQueue . error = error => {
86+ loadQueue . error = noop ;
87+ loadQueue . kill ( ) ;
88+ callback ( error ) ;
89+ } ;
7490
7591 let i = 0 ;
7692 for ( const entryPoint of entryPoints ) {
77- loadModule ( entryPoint , null , i ++ ) ;
93+ loadModule ( entryPoint , null , i ++ , loadQueue , modules , skip , cwd , callback ) ;
7894 }
7995
80- if ( loadQueue . idle ( ) ) {
96+ if ( i === 0 ) {
8197 log . error ( '`Graph` called without any entry points' ) ;
82- cleanup ( ) ;
98+ loadQueue . kill ( ) ;
8399 callback ( Error ( 'At least one entry point has to be passed.' ) ) ;
84100 }
85101 }
86102
87103 return Graph ;
88104} ;
89105
106+ function loadModule (
107+ id : string ,
108+ parent : string | null ,
109+ parentDependencyIndex : number ,
110+ loadQueue : LoadQueue ,
111+ modules : Map < string | null , Module > ,
112+ skip ?: Set < string > ,
113+ cwd : string ,
114+ ) {
115+ function onFileLoaded (
116+ error ?: ?Error ,
117+ file ?: File ,
118+ dependencyIDs ?: Array < string > ,
119+ ) {
120+ if ( error ) {
121+ return ;
122+ }
123+
124+ const { path} = nullthrows ( file ) ;
125+ dependencyIDs = nullthrows ( dependencyIDs ) ;
126+
127+ const parentModule = modules . get ( parent ) ;
128+ invariant ( parentModule , 'Invalid parent module: ' + String ( parent ) ) ;
129+ parentModule . dependencies [ parentDependencyIndex ] = { id, path} ;
130+
131+ if ( ( ! skip || ! skip . has ( path ) ) && ! modules . has ( path ) ) {
132+ const dependencies = Array ( dependencyIDs . length ) ;
133+ modules . set ( path , { dependencies, file : nullthrows ( file ) } ) ;
134+ for ( let i = 0 ; i < dependencyIDs . length ; ++ i ) {
135+ loadModule ( dependencyIDs [ i ] , path , i , loadQueue , modules , skip , cwd ) ;
136+ }
137+ }
138+ }
139+
140+ loadQueue . push (
141+ { id, parent : parent != null ? parent : cwd } ,
142+ onFileLoaded ,
143+ ) ;
144+ }
145+
90146function collect (
91147 path ,
92148 modules ,
@@ -100,8 +156,11 @@ function collect(
100156 serialized . push ( module ) ;
101157 seen . add ( path ) ;
102158 }
103- module . dependencies . forEach (
104- dependency => collect ( dependency . path , modules , serialized , seen ) ) ;
159+
160+ const { dependencies } = module ;
161+ for ( var i = 0 ; i < dependencies . length ; i ++ ) {
162+ collect ( dependencies [ i ] . path , modules , serialized , seen ) ;
163+ }
105164
106165 return serialized ;
107166}
0 commit comments