HlsJSDecorator.svelte
1 <script lang="ts" context="module"> 2 // This store is used to keep track of in-flight requests, ensuring that we don't attempt 3 // to load the same src (which is stored in the Map key) multiple times. 4 const inFlightRequests = new Map<string, Promise<void>>(); 5 </script> 6 7 <script lang="ts"> 8 import { onMount } from 'svelte'; 9 import { generateHLSJSURL } from '~/config/hlsjs'; 10 import { generateRTCJSURL } from '~/config/rtcjs'; 11 12 export let version: string | undefined = undefined; 13 14 let hlsjsSourceURL = generateHLSJSURL(version).toString(); 15 let rtcjsSourceURL = generateRTCJSURL(version).toString(); 16 17 function loadScript(src: string): Promise<void> { 18 // If we have an in-flight request for this `src`, return it. 19 const inFlightRequest = inFlightRequests.get(src); 20 if (inFlightRequest) { 21 return inFlightRequest; 22 } 23 24 const promise = new Promise<void>(function (resolve, reject) { 25 const scriptElement = document.createElement('script'); 26 scriptElement.src = src; 27 scriptElement.onload = () => resolve(); 28 scriptElement.onerror = () => { 29 // If a script fails to load due to a network blip, we remove it from the store, 30 // so that the next attempt in an `onMount` will try to load the `src` again. 31 inFlightRequests.delete(src); 32 reject(); 33 }; 34 35 document.head.appendChild(scriptElement); 36 }); 37 38 // Add the given `src` to the store so we can keep track of in-flight requests. 39 inFlightRequests.set(src, promise); 40 41 return promise; 42 } 43 44 let loading: Promise<[void, void]> | undefined; 45 46 onMount(() => { 47 loading = Promise.all([ 48 window.Hls ?? loadScript(hlsjsSourceURL), 49 window.rtc ?? loadScript(rtcjsSourceURL), 50 ]); 51 }); 52 </script> 53 54 {#if loading} 55 {#await loading} 56 <slot name="loading-component" /> 57 {:then} 58 <slot HLS={window.Hls} RTC={window.rtc} /> 59 {:catch} 60 <div> 61 <p> 62 Failed to load HLS.js {version} from 63 <a href={hlsjsSourceURL}>{hlsjsSourceURL}</a> 64 </p> 65 </div> 66 {/await} 67 {/if}