11import resolve from 'browser-resolve' ;
2+ import { getGlobal } from '@codesandbox/common/lib/utils/global' ;
23import getRequireStatements from './simple-get-require-statements' ;
34
4- const path = self . BrowserFS . BFSRequire ( 'path' ) ;
5+ const global = getGlobal ( ) ;
6+ const path = global . BrowserFS . BFSRequire ( 'path' ) ;
57
6- function mkDirByPathSync ( targetDir , { isRelativeToScript = false } = { } ) {
7- const fs = self . BrowserFS . BFSRequire ( 'fs' ) ;
8+ function mkDirByPathSync (
9+ targetDir : string ,
10+ { isRelativeToScript = false } = { }
11+ ) {
12+ const fs = global . BrowserFS . BFSRequire ( 'fs' ) ;
813
914 const { sep } = path ;
1015 const initDir = path . isAbsolute ( targetDir ) ? sep : '' ;
@@ -36,54 +41,77 @@ function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
3641 } , initDir ) ;
3742}
3843
44+ interface IResolveResponse {
45+ found : boolean ;
46+ type : 'resolve-async-transpiled-module-response' ;
47+ id : number ;
48+ path : string ;
49+ code : string ;
50+ }
51+
52+ const downloadCache = new Map < string , Promise < IResolveResponse > > ( ) ;
53+ let lastSentId = 0 ;
54+
3955export const resolveAsyncModule = (
4056 modulePath : string ,
41- { ignoredExtensions } ?: { ignoredExtensions ?: Array < string > }
42- ) =>
43- new Promise ( ( r , reject ) => {
44- const sendId = Math . floor ( Math . random ( ) * 10000 ) ;
45- self . postMessage ( {
46- type : 'resolve-async-transpiled-module' ,
47- path : modulePath ,
48- id : sendId ,
49- options : { isAbsolute : true , ignoredExtensions } ,
50- } ) ;
51-
52- const resolveFunc = message => {
53- const { type, id, found } = message . data ;
54-
55- if (
56- type === 'resolve-async-transpiled-module-response' &&
57- id === sendId
58- ) {
59- if ( found ) {
60- r ( message . data ) ;
61- } else {
62- reject ( new Error ( "Could not find path: '" + modulePath + "'." ) ) ;
57+ { ignoredExtensions } : { ignoredExtensions ?: Array < string > }
58+ ) : Promise < IResolveResponse > => {
59+ if ( downloadCache . get ( modulePath ) ) {
60+ return downloadCache . get ( modulePath ) ;
61+ }
62+
63+ downloadCache . set (
64+ modulePath ,
65+ new Promise ( ( r , reject ) => {
66+ const sendId = lastSentId ++ ;
67+
68+ global . postMessage ( {
69+ type : 'resolve-async-transpiled-module' ,
70+ path : modulePath ,
71+ id : sendId ,
72+ options : { isAbsolute : true , ignoredExtensions } ,
73+ } ) ;
74+
75+ const resolveFunc = ( message : { data : IResolveResponse } ) => {
76+ const { type, id, found } = message . data ;
77+
78+ if (
79+ type === 'resolve-async-transpiled-module-response' &&
80+ id === sendId
81+ ) {
82+ if ( found ) {
83+ r ( message . data ) ;
84+ } else {
85+ reject ( new Error ( "Could not find path: '" + modulePath + "'." ) ) ;
86+ }
87+ global . removeEventListener ( 'message' , resolveFunc ) ;
6388 }
64- self . removeEventListener ( 'message' , resolveFunc ) ;
65- }
66- } ;
89+ } ;
6790
68- self . addEventListener ( 'message' , resolveFunc ) ;
69- } ) ;
91+ global . addEventListener ( 'message' , resolveFunc ) ;
92+ } )
93+ ) ;
7094
71- const downloads = { } ;
72- export async function downloadPath ( absolutePath ) {
95+ return downloadCache . get ( modulePath ) ;
96+ } ;
97+
98+ export async function downloadPath (
99+ absolutePath : string
100+ ) : Promise < { code : string ; path : string } > {
73101 const r = await resolveAsyncModule ( absolutePath , { } ) ;
74102
75103 if ( ! r . found ) {
76104 throw new Error ( `${ absolutePath } not found.` ) ;
77105 }
78106
79- self . postMessage ( {
107+ global . postMessage ( {
80108 type : 'add-transpilation-dependency' ,
81109 path : r . path ,
82110 } ) ;
83111
84- const fs = self . BrowserFS . BFSRequire ( 'fs' ) ;
112+ const fs = global . BrowserFS . BFSRequire ( 'fs' ) ;
85113
86- let existingFile ;
114+ let existingFile : string ;
87115
88116 try {
89117 existingFile = fs . readFileSync ( r . path ) ;
@@ -108,27 +136,23 @@ export async function downloadPath(absolutePath) {
108136 /* ignore */
109137 }
110138
111- return Promise . resolve ( {
139+ return {
112140 code : existingFile ,
113141 path : r . path ,
114- } ) ;
142+ } ;
115143 }
116144
117145 mkDirByPathSync ( path . dirname ( r . path ) ) ;
118-
119146 fs . writeFileSync ( r . path , r . code ) ;
120147
121148 const requires = getRequireStatements ( r . code ) ;
122149
150+ // Download all other needed files
123151 await Promise . all (
124- requires . map ( foundR => {
152+ requires . map ( async foundR => {
125153 if ( foundR . type === 'direct' ) {
126154 if ( foundR . path === 'babel-plugin-macros' ) {
127- return '' ;
128- }
129-
130- if ( downloads [ foundR . path ] ) {
131- return downloads [ foundR . path ] ;
155+ return ;
132156 }
133157
134158 try {
@@ -137,35 +161,23 @@ export async function downloadPath(absolutePath) {
137161 extensions : [ '.js' , '.json' ] ,
138162 moduleDirectory : [ 'node_modules' ] ,
139163 } ) ;
140- return '' ;
141164 } catch ( e ) {
142- // eslint-disable-next-line no-use-before-define
143- downloads [ foundR . path ] = downloadFromError ( e )
144- . then ( ( ) => {
145- delete downloads [ foundR . path ] ;
146- } )
147- . catch ( ( ) => {
148- delete downloads [ foundR . path ] ;
149- } ) ;
150- return downloads [ foundR . path ] ;
165+ await downloadFromError ( e ) ;
151166 }
152167 }
153- return Promise . resolve ( ) ;
154168 } )
155169 ) ;
156170
157171 return r ;
158172}
159173
160- export async function downloadFromError ( e ) {
174+ export function downloadFromError ( e : Error ) {
161175 if ( e . message . indexOf ( 'Cannot find module' ) > - 1 ) {
162- return new Promise ( res => {
163- const dep = e . message . match ( / C a n n o t f i n d m o d u l e ' ( .* ?) ' / ) [ 1 ] ;
164- const from = e . message . match ( / f r o m ' ( .* ?) ' / ) [ 1 ] ;
165- const absolutePath = dep . startsWith ( '.' ) ? path . join ( from , dep ) : dep ;
176+ const dep = e . message . match ( / C a n n o t f i n d m o d u l e ' ( .* ?) ' / ) [ 1 ] ;
177+ const from = e . message . match ( / f r o m ' ( .* ?) ' / ) [ 1 ] ;
178+ const absolutePath = dep . startsWith ( '.' ) ? path . join ( from , dep ) : dep ;
166179
167- res ( downloadPath ( absolutePath ) ) ;
168- } ) ;
180+ return downloadPath ( absolutePath ) ;
169181 }
170182
171183 return Promise . resolve ( ) ;
0 commit comments