@@ -26,8 +26,6 @@ const global = getGlobal() as Window & { BrowserFS: any };
2626const browserFs = global . BrowserFS . BFSRequire ( 'fs' ) ;
2727const SERVICE_URL = 'https://ata-fetcher.cloud/api/v5/typings' ;
2828
29- let lastMTime = new Date ( 0 ) ;
30-
3129declare global {
3230 interface Window {
3331 BrowserFS : any ;
@@ -50,14 +48,25 @@ class SandboxFsSync {
5048 '@types/jest' : 'latest' ,
5149 } ;
5250
51+ private workerIds : string [ ] = [ ] ;
52+
5353 private isDisposed = false ;
54- private currentSyncId = 0 ;
5554 private typesInfo : Promise < any > ;
5655 constructor ( options : SandboxFsSyncOptions ) {
5756 this . options = options ;
5857 self . addEventListener ( 'message' , this . onWorkerMessage ) ;
5958 }
6059
60+ public sync ( cb : ( ) => void ) {
61+ this . send ( 'reset' , { } ) ;
62+ this . syncDependencyTypings ( ) ;
63+ setTimeout ( ( ) => {
64+ if ( ! this . isDisposed ) {
65+ cb ( ) ;
66+ }
67+ } , WAIT_INITIAL_TYPINGS_MS ) ;
68+ }
69+
6170 public getTypes ( ) {
6271 return Object . keys ( this . types ) . reduce (
6372 ( aggr , key ) => Object . assign ( aggr , this . types [ key ] ) ,
@@ -94,8 +103,6 @@ class SandboxFsSync {
94103 }
95104 } ) ;
96105
97- this . syncSandbox ( sandboxFs ) ;
98-
99106 return sandboxFs ;
100107 }
101108
@@ -106,7 +113,7 @@ class SandboxFsSync {
106113 this . send ( 'write-file' , copy ) ;
107114
108115 if ( module . title === 'package.json' ) {
109- this . syncDependencyTypings ( this . currentSyncId + 1 ) ;
116+ this . syncDependencyTypings ( ) ;
110117 }
111118 }
112119
@@ -139,43 +146,32 @@ class SandboxFsSync {
139146 this . send ( 'mkdir' , copy ) ;
140147 }
141148
142- public async syncTypings ( cb : ( ) => void ) {
143- try {
144- await this . syncDependencyTypings ( this . currentSyncId + 1 ) ;
145- } catch ( error ) {
146- // Do nothing
147- }
148-
149- setTimeout ( ( ) => {
150- if ( ! this . isDisposed ) {
151- cb ( ) ;
152- }
153- } , WAIT_INITIAL_TYPINGS_MS ) ;
154- }
155-
156149 private onWorkerMessage = evt => {
157- if ( evt . data . $type === 'sync-types' ) {
158- // We pass the current syncId as we want to latch on
159- // to the existing sync
160- this . syncDependencyTypings ( this . currentSyncId ) ;
150+ if ( evt . data . $fs_id && ! this . workerIds . includes ( evt . data . $fs_id ) ) {
151+ this . workerIds . push ( evt . data . $fs_id ) ;
161152 }
162153
163154 if ( evt . data . $type === 'sync-sandbox' ) {
164- this . syncSandbox ( this . options . getSandboxFs ( ) ) ;
155+ this . syncSandbox ( this . options . getSandboxFs ( ) , evt . data . $fs_id ) ;
156+ }
157+
158+ if ( evt . data . $type === 'sync-types' ) {
159+ this . send ( 'types-sync' , this . getTypes ( ) , evt . data . $fs_id ) ;
165160 }
166161 } ;
167162
168163 // We sync the FS whenever we create a new one, which happens in different
169164 // scenarios. If a worker is requesting a sync we grab the existing FS from
170165 // the state
171- private syncSandbox ( sandboxFs ) {
172- this . send ( 'sandbox-fs' , json ( sandboxFs ) ) ;
166+ private syncSandbox ( sandboxFs , id ? ) {
167+ this . send ( 'sandbox-fs' , json ( sandboxFs ) , id ) ;
173168 }
174169
175- private send ( type : string , data : any ) {
170+ private send ( type : string , data : any , id ?: string ) {
176171 global . postMessage (
177172 {
178173 $broadcast : true ,
174+ $fs_ids : typeof id === 'undefined' ? this . workerIds : [ id ] ,
179175 $type : type ,
180176 $data : data ,
181177 } ,
@@ -186,15 +182,8 @@ class SandboxFsSync {
186182 // We pass in either existing or new syncId. This allows us to evaluate
187183 // if we are just going to pass existing types or start up a new round
188184 // to fetch types
189- private async syncDependencyTypings ( syncId : number ) {
190- if ( syncId === this . currentSyncId ) {
191- this . sendTypes ( ) ;
192- return ;
193- }
194-
185+ private async syncDependencyTypings ( fsId ?) {
195186 try {
196- this . currentSyncId = syncId ;
197-
198187 this . typesInfo = await this . getTypesInfo ( ) ;
199188 const syncDetails = await this . getDependencyTypingsSyncDetails ( ) ;
200189
@@ -205,7 +194,7 @@ class SandboxFsSync {
205194 this . deps = newDeps ;
206195
207196 added . forEach ( dep => {
208- this . fetchDependencyTyping ( syncId , dep , syncDetails . autoInstall ) ;
197+ this . fetchDependencyTyping ( dep , syncDetails . autoInstall ) ;
209198 } ) ;
210199
211200 if ( removed . length ) {
@@ -221,7 +210,7 @@ class SandboxFsSync {
221210 delete this . types [ removedDep . name ] ;
222211 } ) ;
223212
224- this . send ( 'types-remove' , removedTypings ) ;
213+ this . send ( 'types-remove' , removedTypings , fsId ) ;
225214 }
226215 }
227216 } catch ( error ) {
@@ -272,42 +261,34 @@ class SandboxFsSync {
272261 return ;
273262 }
274263
275- if ( stat . mtime . toString ( ) !== lastMTime . toString ( ) ) {
276- lastMTime = stat . mtime ;
277-
278- browserFs . readFile (
279- '/sandbox/package.json' ,
280- async ( packageJsonReadError , rv ) => {
281- if ( packageJsonReadError ) {
282- reject ( packageJsonReadError ) ;
283- return ;
284- }
264+ browserFs . readFile (
265+ '/sandbox/package.json' ,
266+ async ( packageJsonReadError , rv ) => {
267+ if ( packageJsonReadError ) {
268+ reject ( packageJsonReadError ) ;
269+ return ;
270+ }
285271
286- browserFs . stat (
287- '/sandbox/tsconfig.json' ,
288- ( tsConfigError , result ) => {
289- // If tsconfig exists we want to sync the typesp
290- try {
291- const packageJson = JSON . parse ( rv . toString ( ) ) ;
292- resolve ( {
293- dependencies : {
294- ...packageJson . dependencies ,
295- ...packageJson . devDependencies ,
296- } ,
297- autoInstall : Boolean ( tsConfigError ) || ! result ,
298- } ) ;
299- } catch ( error ) {
300- reject (
301- new Error ( 'TYPINGS: Could not parse package.json' )
302- ) ;
303- }
272+ browserFs . stat (
273+ '/sandbox/tsconfig.json' ,
274+ ( tsConfigError , result ) => {
275+ // If tsconfig exists we want to sync the typesp
276+ try {
277+ const packageJson = JSON . parse ( rv . toString ( ) ) ;
278+ resolve ( {
279+ dependencies : {
280+ ...packageJson . dependencies ,
281+ ...packageJson . devDependencies ,
282+ } ,
283+ autoInstall : Boolean ( tsConfigError ) || ! result ,
284+ } ) ;
285+ } catch ( error ) {
286+ reject ( new Error ( 'TYPINGS: Could not parse package.json' ) ) ;
304287 }
305- ) ;
306- }
307- ) ;
308- } else {
309- resolve ( null ) ;
310- }
288+ }
289+ ) ;
290+ }
291+ ) ;
311292 } ) ;
312293 } catch ( e ) {
313294 resolve ( null ) ;
@@ -316,14 +297,6 @@ class SandboxFsSync {
316297 } ) ;
317298 }
318299
319- private sendTypes ( ) {
320- this . send ( 'types-sync' , this . getTypes ( ) ) ;
321- }
322-
323- private sendPackageTypes ( types : { [ path : string ] : any } ) {
324- this . send ( 'package-types-sync' , types ) ;
325- }
326-
327300 /**
328301 * Gets all entries of dependencies -> @types/ version
329302 */
@@ -339,23 +312,22 @@ class SandboxFsSync {
339312 return this . typesInfo ;
340313 }
341314
315+ // We send new packages to all registered workers
342316 private setAndSendPackageTypes (
343317 name : string ,
344- types : { [ name : string ] : string } ,
345- syncId : number
318+ types : { [ name : string ] : string }
346319 ) {
347- if ( ! this . isDisposed && this . currentSyncId === syncId ) {
320+ if ( ! this . isDisposed ) {
348321 if ( ! this . types [ name ] ) {
349322 this . types [ name ] = { } ;
350323 }
351324
352325 Object . assign ( this . types [ name ] , types ) ;
353- this . sendPackageTypes ( types ) ;
326+ this . send ( 'package-types-sync' , types ) ;
354327 }
355328 }
356329
357330 private async fetchDependencyTyping (
358- syncId : number ,
359331 dep : { name : string ; version : string } ,
360332 autoInstallTypes : boolean
361333 ) {
@@ -368,13 +340,9 @@ class SandboxFsSync {
368340 ) {
369341 const name = `@types/${ dep . name } ` ;
370342 fetchPackageJSON ( name , dep . version ) . then ( ( { version } ) => {
371- this . setAndSendPackageTypes (
372- dep . name ,
373- {
374- [ name ] : version ,
375- } ,
376- syncId
377- ) ;
343+ this . setAndSendPackageTypes ( dep . name , {
344+ [ name ] : version ,
345+ } ) ;
378346 } ) ;
379347 }
380348
@@ -389,7 +357,7 @@ class SandboxFsSync {
389357
390358 const { files } = await fetchRequest . json ( ) ;
391359
392- this . setAndSendPackageTypes ( dep . name , files , syncId ) ;
360+ this . setAndSendPackageTypes ( dep . name , files ) ;
393361 } catch ( e ) {
394362 if ( process . env . NODE_ENV === 'development' ) {
395363 console . warn ( 'Trouble fetching types for ' + dep . name ) ;
0 commit comments