UNPKG

static-assets-loader

Version:
77 lines (67 loc) 2.57 kB
import loadjs from "loadjs" import BadUrlPrefixCache from './bad-url' export interface ModuleAssets { /** assets name,For caching */ name: string /** multiple load urls for easy switch failure */ loadUrls: string[] /** do something else before getting it */ ready?: () => void status: 'ready' | 'loading' | 'success' | 'fail' } export interface LoadModuleItem { // currently loaded url url?: string // module assets moduleAssets: ModuleAssets } const badUrlPrefixCache = BadUrlPrefixCache.getInstance({ strategy: 'localStorage', }) export const resloveCanUseUrl = (moduleAssets: ModuleAssets): string => { const allUrls = (moduleAssets || {}).loadUrls || [] return badUrlPrefixCache.getCanUseUrl(allUrls) } export const isModuleAssets = (item: Record<string, any>): item is ModuleAssets => { return 'name' in item && 'loadUrls' in item } /** * * @param needLoadItems * @returns */ export const moduleRetryLoad = (needLoadItems: LoadModuleItem[]) => { return new Promise((resolve, reject) => { const startLoad = (urls: string[]) => loadjs(urls, { returnPromise: true }).then(() => { // Remove bad urls after success urls.forEach(url => badUrlPrefixCache.delete(url)) resolve('success') }).catch((failUrls: string[]) => { // add bad urls after failure urls.forEach(url => badUrlPrefixCache.add(url)) const retryUrls: string[] = [] for (let i = 0, len = failUrls.length; i < len; i++) { const failUrl = failUrls[i] // find module that fail to load and check for alternative urls const failItem = needLoadItems.find(item => item.url === failUrl) if (!failItem || !failItem.moduleAssets) { return } const newUrl = resloveCanUseUrl(failItem.moduleAssets) // there is no url that can be replaced, and an error is reported directly if (!newUrl) { failItem.moduleAssets.status = 'fail' reject(new Error(`Cannot load assets ${failItem.moduleAssets.name} ${newUrl}`)) return } retryUrls.push(newUrl) } // retry until successful or all urls fail startLoad(retryUrls) }) const urlsToLoad: string[] = needLoadItems.map(x => x.url) as string[] startLoad(urlsToLoad) }) }