import { Injectable } from '@angular/core' ; function load ( url ) { return new Promise ( ( resolve , reject ) => { const script = document . createElement ( 'script' ) ; script . src = url ; script . onload = ( ) => resolve ( ) ; script . onerror = ( ) => reject ( { error : `Bundle ${ url } could not be loaded` , } ) ; document . body . appendChild ( script ) ; } ) ; } /**
 * The loading state of a bundle.
 *
 * UNKNOWN -> It has not been tried to load this bundle.
 * LOADING -> The loading of this bundle is currently happening.
 * LOADED -> The bundle has been successfully loaded.
 * FAILED -> The loading of the bundle failed.
 */ type LoadingState = 'UNKNOWN' | 'LOADING' | 'LOADED' | 'FAILED' ; /**
 * This service loads bundles and keeps track of which bundles have been already loaded.
 * This way, it prevents errors that would occur if a bundle is loaded a second time.
 */ @ Injectable ( { providedIn : 'root' } ) export class BundleRegistryService { private loadingStates : Record < string , LoadingState > = { } ; param bundleUrl async loadBundle ( bundleUrl ) { if ( [ 'LOADING' , 'LOADED' ] . includes ( this . getLoadingState ( bundleUrl ) ) ) { return true ; } this . loadingStates [ bundleUrl ] = 'LOADING' ; const isSuccess = await load ( bundleUrl ) . then ( ( ) => true ) . catch ( ( ) => false ) ; this . loadingStates [ bundleUrl ] = isSuccess ? 'LOADED' : 'FAILED' ; return isSuccess ; } param bundleUrl getLoadingState ( bundleUrl ) { return this . loadingStates [ bundleUrl ] || 'UNKNOWN' ; } param bundleUrl isBundleLoaded ( bundleUrl ) { return this . getLoadingState ( bundleUrl ) === 'LOADED' ; } }