{"version":3,"file":"Loader.mjs","sources":["../../src/loader/Loader.ts"],"sourcesContent":["import { utils } from 'pixijs/core';\nimport { convertToList, isSingleItem } from '../utils';\n\nimport type { LoaderParser } from './parsers/LoaderParser';\nimport type { LoadAsset, PromiseAndParser } from './types';\n\n/**\n * The Loader is responsible for loading all assets, such as images, spritesheets, audio files, etc.\n * It does not do anything clever with URLs - it just loads stuff!\n * Behind the scenes all things are cached using promises. This means it's impossible to load an asset more than once.\n * Through the use of LoaderParsers, the loader can understand how to load any kind of file!\n *\n * It is not intended that this class is created by developers - its part of the Asset class\n * This is the second major system of PixiJS' main Assets class\n * @memberof PIXI\n * @class AssetLoader\n */\nexport class Loader\n{\n    private _parsers: LoaderParser[] = [];\n\n    /** Cache loading promises that ae currently active */\n    public promiseCache: Record<string, PromiseAndParser> = {};\n\n    /** function used for testing */\n    public reset(): void\n    {\n        this.promiseCache = {};\n    }\n\n    /**\n     * Used internally to generate a promise for the asset to be loaded.\n     * @param url - The URL to be loaded\n     * @param data - any custom additional information relevant to the asset being loaded\n     * @returns - a promise that will resolve to an Asset for example a Texture of a JSON object\n     */\n    private _getLoadPromiseAndParser(url: string, data?: LoadAsset): PromiseAndParser\n    {\n        const result: PromiseAndParser = {\n            promise: null,\n            parser: null\n        };\n\n        result.promise = (async () =>\n        {\n            let asset = null;\n\n            for (let i = 0; i < this.parsers.length; i++)\n            {\n                const parser = this.parsers[i];\n\n                if (parser.load && parser.test?.(url, data, this))\n                {\n                    asset = await parser.load(url, data, this);\n                    result.parser = parser;\n\n                    break;\n                }\n            }\n\n            if (!result.parser)\n            {\n                // #if _DEBUG\n                // eslint-disable-next-line max-len\n                console.warn(`[Assets] ${url} could not be loaded as we don't know how to parse it, ensure the correct parser has being added`);\n                // #endif\n\n                return null;\n            }\n\n            for (let i = 0; i < this.parsers.length; i++)\n            {\n                const parser = this.parsers[i];\n\n                if (parser.parse)\n                {\n                    if (parser.parse && await parser.testParse?.(asset, data, this))\n                    {\n                        // transform the asset..\n                        asset = await parser.parse(asset, data, this) || asset;\n\n                        result.parser = parser;\n                    }\n                }\n            }\n\n            return asset;\n        })();\n\n        return result;\n    }\n\n    /**\n     * Loads one or more assets using the parsers added to the Loader.\n     * @example\n     * // Single asset:\n     * const asset = await Loader.load('cool.png');\n     * console.log(asset);\n     *\n     * // Multiple assets:\n     * const assets = await Loader.load(['cool.png', 'cooler.png']);\n     * console.log(assets);\n     * @param assetsToLoadIn - urls that you want to load, or a single one!\n     * @param onProgress - For multiple asset loading only, an optional function that is called\n     * when progress on asset loading is made. The function is passed a single parameter, `progress`,\n     * which represents the percentage (0.0 - 1.0) of the assets loaded. Do not use this function\n     * to detect when assets are complete and available, instead use the Promise returned by this function.\n     */\n    public async load<T = any>(\n        assetsToLoadIn: string | LoadAsset,\n        onProgress?: (progress: number) => void,\n    ): Promise<T>;\n    public async load<T = any>(\n        assetsToLoadIn: string[] | LoadAsset[],\n        onProgress?: (progress: number) => void,\n    ): Promise<Record<string, T>>;\n    public async load<T = any>(\n        assetsToLoadIn: string | string[] | LoadAsset | LoadAsset[],\n        onProgress?: (progress: number) => void,\n    ): Promise<T | Record<string, T>>\n    {\n        let count = 0;\n\n        const assets: Record<string, Promise<any>> = {};\n\n        const singleAsset = isSingleItem(assetsToLoadIn);\n\n        const assetsToLoad = convertToList<LoadAsset>(assetsToLoadIn, (item) => ({\n            src: item,\n        }));\n\n        const total = assetsToLoad.length;\n\n        const promises: Promise<void>[] = assetsToLoad.map(async (asset: LoadAsset) =>\n        {\n            const url = utils.path.toAbsolute(asset.src);\n\n            if (!assets[asset.src])\n            {\n                try\n                {\n                    if (!this.promiseCache[url])\n                    {\n                        this.promiseCache[url] = this._getLoadPromiseAndParser(url, asset);\n                    }\n\n                    assets[asset.src] = await this.promiseCache[url].promise;\n\n                    // Only progress if nothing goes wrong\n                    if (onProgress) onProgress(++count / total);\n                }\n                catch (e)\n                {\n                    // Delete eventually registered file and promises from internal cache\n                    // so they can be eligible for another loading attempt\n                    delete this.promiseCache[url];\n                    delete assets[asset.src];\n\n                    // Stop further execution\n                    throw new Error(`[Loader.load] Failed to load ${url}.\\n${e}`);\n                }\n            }\n        });\n\n        await Promise.all(promises);\n\n        return singleAsset ? assets[assetsToLoad[0].src] : assets;\n    }\n\n    /**\n     * Unloads one or more assets. Any unloaded assets will be destroyed, freeing up memory for your app.\n     * The parser that created the asset, will be the one that unloads it.\n     * @example\n     * // Single asset:\n     * const asset = await Loader.load('cool.png');\n     *\n     * await Loader.unload('cool.png');\n     *\n     * console.log(asset.destroyed); // true\n     * @param assetsToUnloadIn - urls that you want to unload, or a single one!\n     */\n    public async unload(\n        assetsToUnloadIn: string | string[] | LoadAsset | LoadAsset[],\n    ): Promise<void>\n    {\n        const assetsToUnload = convertToList<LoadAsset>(assetsToUnloadIn, (item) => ({\n            src: item,\n        }));\n\n        const promises: Promise<void>[] = assetsToUnload.map(async (asset: LoadAsset) =>\n        {\n            const url = utils.path.toAbsolute(asset.src);\n\n            const loadPromise = this.promiseCache[url];\n\n            if (loadPromise)\n            {\n                const loadedAsset = await loadPromise.promise;\n\n                loadPromise.parser?.unload?.(loadedAsset, asset, this);\n\n                delete this.promiseCache[url];\n            }\n        });\n\n        await Promise.all(promises);\n    }\n\n    /** All loader parsers registered */\n    public get parsers(): LoaderParser[]\n    {\n        return this._parsers;\n    }\n}\n"],"names":[],"mappings":"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"}