| 214 | } |
| 215 | |
| 216 | export function createFileLoader(): FileLoader { |
| 217 | const caches = { |
| 218 | 'data-url': new LimitedCacheStorage(), |
| 219 | 'text': new LimitedCacheStorage(), |
| 220 | }; |
| 221 | |
| 222 | const loaders = { |
| 223 | 'data-url': loadAsDataURL, |
| 224 | 'text': loadAsText, |
| 225 | }; |
| 226 | |
| 227 | const limiters = { |
| 228 | 'data-url': createLimiter(), |
| 229 | 'text': createLimiter(), |
| 230 | }; |
| 231 | |
| 232 | async function get({url, responseType, mimeType, origin}: FetchRequestParameters): Promise<FileLoaderResponse> { |
| 233 | const cache = caches[responseType]; |
| 234 | const load = loaders[responseType]; |
| 235 | const limiter = limiters[responseType]; |
| 236 | if (cache.has(url)) { |
| 237 | const data = cache.get(url)!; |
| 238 | return {data}; |
| 239 | } |
| 240 | |
| 241 | if (limiter.loading(url)) { |
| 242 | return limiter.wait(url); |
| 243 | } |
| 244 | |
| 245 | try { |
| 246 | const data = await load(url, mimeType, origin); |
| 247 | cache.set(url, data); |
| 248 | limiter.loaded(url, data); |
| 249 | return {data}; |
| 250 | } catch (error: any) { |
| 251 | limiter.failed(url, error); |
| 252 | return {error}; |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | return {get}; |
| 257 | } |