@@ -25,6 +25,8 @@ import {
2525 logger ,
2626 setBuildAdapter ,
2727 setLogLevel ,
28+ RebuildQueue ,
29+ AbortedError ,
2830} from '@softarc/native-federation/build' ;
2931import {
3032 createAngularBuildAdapter ,
@@ -373,8 +375,9 @@ export async function* runBuilder(
373375 indexHtmlTransformer : transformIndexHtml ( nfOptions ) ,
374376 } ) ;
375377
378+ const rebuildQueue = new RebuildQueue ( ) ;
379+
376380 try {
377- // builderRun.output.subscribe(async (output) => {
378381 for await ( const output of builderRun ) {
379382 lastResult = output ;
380383
@@ -399,8 +402,31 @@ export async function* runBuilder(
399402 // }
400403
401404 if ( ! first && ( nfOptions . dev || watch ) ) {
402- setTimeout ( async ( ) => {
403- try {
405+ rebuildQueue
406+ . enqueue ( async ( signal : AbortSignal ) => {
407+ if ( signal ?. aborted ) {
408+ throw new AbortedError ( 'Build canceled before starting' ) ;
409+ }
410+
411+ await new Promise ( ( resolve , reject ) => {
412+ const timeout = setTimeout (
413+ resolve ,
414+ Math . max ( 10 , nfOptions . rebuildDelay ) ,
415+ ) ;
416+
417+ if ( signal ) {
418+ const abortHandler = ( ) => {
419+ clearTimeout ( timeout ) ;
420+ reject ( new AbortedError ( '[builder] During delay.' ) ) ;
421+ } ;
422+ signal . addEventListener ( 'abort' , abortHandler , { once : true } ) ;
423+ }
424+ } ) ;
425+
426+ if ( signal ?. aborted ) {
427+ throw new AbortedError ( '[builder] Before federation build.' ) ;
428+ }
429+
404430 const start = process . hrtime ( ) ;
405431 federationResult = await buildForFederation (
406432 config ,
@@ -409,9 +435,14 @@ export async function* runBuilder(
409435 {
410436 skipMappingsAndExposed : false ,
411437 skipShared : true ,
438+ signal,
412439 } ,
413440 ) ;
414441
442+ if ( signal ?. aborted ) {
443+ throw new AbortedError ( '[builder] After federation build.' ) ;
444+ }
445+
415446 if ( hasLocales && localeFilter ) {
416447 translateFederationArtefacts (
417448 i18n ,
@@ -421,27 +452,40 @@ export async function* runBuilder(
421452 ) ;
422453 }
423454
455+ if ( signal ?. aborted ) {
456+ throw new AbortedError (
457+ '[builder] After federation translations.' ,
458+ ) ;
459+ }
460+
424461 logger . info ( 'Done!' ) ;
425462
426- // Notifies about build completion
427463 if ( isLocalDevelopment ) {
428464 federationBuildNotifier . broadcastBuildCompletion ( ) ;
429465 }
430- logger . measure ( start , 'To rebuild nf.' ) ;
431- } catch ( error ) {
432- logger . error ( 'Federation rebuild failed!' ) ;
433-
434- // Notifies about build failure
435- if ( isLocalDevelopment ) {
436- federationBuildNotifier . broadcastBuildError ( error ) ;
466+ logger . measure ( start , 'To rebuild the federation artifacts.' ) ;
467+ } )
468+ . catch ( ( error ) => {
469+ if ( error instanceof AbortedError ) {
470+ logger . verbose (
471+ 'Rebuild was canceled. Cancellation point: ' + error ?. message ,
472+ ) ;
473+ federationBuildNotifier . broadcastBuildCancellation ( ) ;
474+ } else {
475+ logger . error ( 'Federation rebuild failed!' ) ;
476+ if ( options . verbose ) console . error ( error ) ;
477+ if ( isLocalDevelopment ) {
478+ federationBuildNotifier . broadcastBuildError ( error ) ;
479+ }
437480 }
438- }
439- } , nfOptions . rebuildDelay ) ;
481+ } ) ;
440482 }
441483
442484 first = false ;
443485 }
444486 } finally {
487+ rebuildQueue . dispose ( ) ;
488+
445489 if ( isLocalDevelopment ) {
446490 federationBuildNotifier . stopEventServer ( ) ;
447491 }
0 commit comments