{"version":3,"file":"Resolver.mjs","sources":["../../src/resolver/Resolver.ts"],"sourcesContent":["import { utils } from 'pixijs/core';\nimport { convertToList } from '../utils/convertToList';\nimport { createStringVariations } from '../utils/createStringVariations';\nimport { isSingleItem } from '../utils/isSingleItem';\n\nimport type { PreferOrder, ResolveAsset, ResolverBundle, ResolverManifest, ResolveURLParser } from './types';\n\nexport interface BundleIdentifierOptions\n{\n    /** The character that is used to connect the bundleId and the assetId when generating a bundle asset id key */\n    connector?: string;\n    /**\n     * A function that generates a bundle asset id key from a bundleId and an assetId\n     * @param bundleId - the bundleId\n     * @param assetId  - the assetId\n     * @returns the bundle asset id key\n     */\n    createBundleAssetId?: (bundleId: string, assetId: string) => string;\n    /**\n     * A function that generates an assetId from a bundle asset id key. This is the reverse of generateBundleAssetId\n     * @param bundleId - the bundleId\n     * @param assetBundleId - the bundle asset id key\n     * @returns the assetId\n     */\n    extractAssetIdFromBundle?: (bundleId: string, assetBundleId: string) => string;\n}\n\n/**\n * A class that is responsible for resolving mapping asset URLs to keys.\n * At its most basic it can be used for Aliases:\n *\n * ```js\n * resolver.add('foo', 'bar');\n * resolver.resolveUrl('foo') // => 'bar'\n * ```\n *\n * It can also be used to resolve the most appropriate asset for a given URL:\n *\n * ```js\n * resolver.prefer({\n *     params: {\n *         format: 'webp',\n *         resolution: 2,\n *     }\n * });\n *\n * resolver.add('foo', ['bar@2x.webp', 'bar@2x.png', 'bar.webp', 'bar.png']);\n *\n * resolver.resolveUrl('foo') // => 'bar@2x.webp'\n * ```\n * Other features include:\n * - Ability to process a manifest file to get the correct understanding of how to resolve all assets\n * - Ability to add custom parsers for specific file types\n * - Ability to add custom prefer rules\n *\n * This class only cares about the URL, not the loading of the asset itself.\n *\n * It is not intended that this class is created by developers - its part of the Asset class\n * This is the third major system of PixiJS' main Assets class\n * @memberof PIXI\n */\nexport class Resolver\n{\n    private _defaultBundleIdentifierOptions: Required<BundleIdentifierOptions> = {\n        connector: '-',\n        createBundleAssetId: (bundleId, assetId) =>\n            `${bundleId}${this._bundleIdConnector}${assetId}`,\n        extractAssetIdFromBundle: (bundleId, assetBundleId) =>\n            assetBundleId.replace(`${bundleId}${this._bundleIdConnector}`, ''),\n    };\n\n    /** The character that is used to connect the bundleId and the assetId when generating a bundle asset id key */\n    private _bundleIdConnector = this._defaultBundleIdentifierOptions.connector;\n\n    /**\n     * A function that generates a bundle asset id key from a bundleId and an assetId\n     * @param bundleId - the bundleId\n     * @param assetId  - the assetId\n     * @returns the bundle asset id key\n     */\n    private _createBundleAssetId: (\n        bundleId: string,\n        assetId: string\n    ) => string = this._defaultBundleIdentifierOptions.createBundleAssetId;\n\n    /**\n     * A function that generates an assetId from a bundle asset id key. This is the reverse of generateBundleAssetId\n     * @param bundleId - the bundleId\n     * @param assetBundleId - the bundle asset id key\n     * @returns the assetId\n     */\n    private _extractAssetIdFromBundle: (\n        bundleId: string,\n        assetBundleId: string\n    ) => string = this._defaultBundleIdentifierOptions.extractAssetIdFromBundle;\n\n    private _assetMap: Record<string, ResolveAsset[]> = {};\n    private _preferredOrder: PreferOrder[] = [];\n    private _parsers: ResolveURLParser[] = [];\n\n    private _resolverHash: Record<string, ResolveAsset> = {};\n    private _rootPath: string;\n    private _basePath: string;\n    private _manifest: ResolverManifest;\n    private _bundles: Record<string, string[]> = {};\n    private _defaultSearchParams: string;\n\n    /**\n     * Override how the resolver deals with generating bundle ids.\n     * must be called before any bundles are added\n     * @param bundleIdentifier - the bundle identifier options\n     */\n    public setBundleIdentifier(bundleIdentifier: BundleIdentifierOptions): void\n    {\n        this._bundleIdConnector = bundleIdentifier.connector ?? this._bundleIdConnector;\n        this._createBundleAssetId = bundleIdentifier.createBundleAssetId ?? this._createBundleAssetId;\n        this._extractAssetIdFromBundle = bundleIdentifier.extractAssetIdFromBundle ?? this._extractAssetIdFromBundle;\n\n        if (this._extractAssetIdFromBundle('foo', this._createBundleAssetId('foo', 'bar')) !== 'bar')\n        {\n            throw new Error('[Resolver] GenerateBundleAssetId are not working correctly');\n        }\n    }\n\n    /**\n     * Let the resolver know which assets you prefer to use when resolving assets.\n     * Multiple prefer user defined rules can be added.\n     * @example\n     * resolver.prefer({\n     *     // first look for something with the correct format, and then then correct resolution\n     *     priority: ['format', 'resolution'],\n     *     params:{\n     *         format:'webp', // prefer webp images\n     *         resolution: 2, // prefer a resolution of 2\n     *     }\n     * })\n     * resolver.add('foo', ['bar@2x.webp', 'bar@2x.png', 'bar.webp', 'bar.png']);\n     * resolver.resolveUrl('foo') // => 'bar@2x.webp'\n     * @param preferOrders - the prefer options\n     */\n    public prefer(...preferOrders: PreferOrder[]): void\n    {\n        preferOrders.forEach((prefer) =>\n        {\n            this._preferredOrder.push(prefer);\n\n            if (!prefer.priority)\n            {\n                // generate the priority based on the order of the object\n                prefer.priority = Object.keys(prefer.params);\n            }\n        });\n\n        this._resolverHash = {};\n    }\n\n    /**\n     * Set the base path to prepend to all urls when resolving\n     * @example\n     * resolver.basePath = 'https://home.com/';\n     * resolver.add('foo', 'bar.ong');\n     * resolver.resolveUrl('foo', 'bar.png'); // => 'https://home.com/bar.png'\n     * @param basePath - the base path to use\n     */\n    public set basePath(basePath: string)\n    {\n        this._basePath = basePath;\n    }\n\n    public get basePath(): string\n    {\n        return this._basePath;\n    }\n\n    /**\n     * Set the root path for root-relative URLs. By default the `basePath`'s root is used. If no `basePath` is set, then the\n     * default value for browsers is `window.location.origin`\n     * @example\n     * // Application hosted on https://home.com/some-path/index.html\n     * resolver.basePath = 'https://home.com/some-path/';\n     * resolver.rootPath = 'https://home.com/';\n     * resolver.add('foo', '/bar.png');\n     * resolver.resolveUrl('foo', '/bar.png'); // => 'https://home.com/bar.png'\n     * @param rootPath - the root path to use\n     */\n    public set rootPath(rootPath: string)\n    {\n        this._rootPath = rootPath;\n    }\n\n    public get rootPath(): string\n    {\n        return this._rootPath;\n    }\n\n    /**\n     * All the active URL parsers that help the parser to extract information and create\n     * an asset object-based on parsing the URL itself.\n     *\n     * Can be added using the extensions API\n     * @example\n     * resolver.add('foo', [\n     *     {\n     *         resolution: 2,\n     *         format: 'png',\n     *         src: 'image@2x.png',\n     *     },\n     *     {\n     *         resolution:1,\n     *         format:'png',\n     *         src: 'image.png',\n     *     },\n     * ]);\n     *\n     * // With a url parser the information such as resolution and file format could extracted from the url itself:\n     * extensions.add({\n     *     extension: ExtensionType.ResolveParser,\n     *     test: loadTextures.test, // test if url ends in an image\n     *     parse: (value: string) =>\n     *     ({\n     *         resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? '1'),\n     *         format: value.split('.').pop(),\n     *         src: value,\n     *     }),\n     * });\n     *\n     * // Now resolution and format can be extracted from the url\n     * resolver.add('foo', [\n     *     'image@2x.png',\n     *     'image.png',\n     * ]);\n     */\n    public get parsers(): ResolveURLParser[]\n    {\n        return this._parsers;\n    }\n\n    /** Used for testing, this resets the resolver to its initial state */\n    public reset(): void\n    {\n        this.setBundleIdentifier(this._defaultBundleIdentifierOptions);\n\n        this._assetMap = {};\n        this._preferredOrder = [];\n        // Do not reset this._parsers\n\n        this._resolverHash = {};\n        this._rootPath = null;\n        this._basePath = null;\n        this._manifest = null;\n        this._bundles = {};\n        this._defaultSearchParams = null;\n    }\n\n    /**\n     * Sets the default URL search parameters for the URL resolver. The urls can be specified as a string or an object.\n     * @param searchParams - the default url parameters to append when resolving urls\n     */\n    public setDefaultSearchParams(searchParams: string | Record<string, unknown>): void\n    {\n        if (typeof searchParams === 'string')\n        {\n            this._defaultSearchParams = searchParams;\n        }\n        else\n        {\n            const queryValues = searchParams as Record<string, any>;\n\n            this._defaultSearchParams = Object.keys(queryValues)\n                .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryValues[key])}`)\n                .join('&');\n        }\n    }\n\n    /**\n     * Add a manifest to the asset resolver. This is a nice way to add all the asset information in one go.\n     * generally a manifest would be built using a tool.\n     * @param manifest - the manifest to add to the resolver\n     */\n    public addManifest(manifest: ResolverManifest): void\n    {\n        if (this._manifest)\n        {\n            // #if _DEBUG\n            console.warn('[Resolver] Manifest already exists, this will be overwritten');\n            // #endif\n        }\n\n        this._manifest = manifest;\n\n        manifest.bundles.forEach((bundle) =>\n        {\n            this.addBundle(bundle.name, bundle.assets);\n        });\n    }\n\n    /**\n     * This adds a bundle of assets in one go so that you can resolve them as a group.\n     * For example you could add a bundle for each screen in you pixi app\n     * @example\n     * resolver.addBundle('animals', {\n     *     bunny: 'bunny.png',\n     *     chicken: 'chicken.png',\n     *     thumper: 'thumper.png',\n     * });\n     *\n     * const resolvedAssets = await resolver.resolveBundle('animals');\n     * @param bundleId - The id of the bundle to add\n     * @param assets - A record of the asset or assets that will be chosen from when loading via the specified key\n     */\n    public addBundle(bundleId: string, assets: ResolverBundle['assets']): void\n    {\n        const assetNames: string[] = [];\n\n        // when storing keys against a bundle we prepend the bundleId to each asset key\n        // and pass it through as an additional alias for the asset\n        // this keeps clashing ids separate on a per-bundle basis\n        // you can also resolve a file using the bundleId-assetId syntax\n        if (Array.isArray(assets))\n        {\n            assets.forEach((asset) =>\n            {\n                if (typeof asset.name === 'string')\n                {\n                    const bundleAssetId = this._createBundleAssetId(bundleId, asset.name);\n\n                    assetNames.push(bundleAssetId);\n\n                    this.add([asset.name, bundleAssetId], asset.srcs, asset.data);\n                }\n                else\n                {\n                    const bundleIds = asset.name.map((name) => this._createBundleAssetId(bundleId, name));\n\n                    bundleIds.forEach((bundleId) =>\n                    {\n                        assetNames.push(bundleId);\n                    });\n\n                    this.add([...asset.name, ...bundleIds], asset.srcs);\n                }\n            });\n        }\n        else\n        {\n            Object.keys(assets).forEach((key) =>\n            {\n                assetNames.push(this._createBundleAssetId(bundleId, key));\n                this.add([key, this._createBundleAssetId(bundleId, key)], assets[key]);\n            });\n        }\n\n        this._bundles[bundleId] = assetNames;\n    }\n\n    /**\n     * Tells the resolver what keys are associated with witch asset.\n     * The most important thing the resolver does\n     * @example\n     * // Single key, single asset:\n     * resolver.add('foo', 'bar.png');\n     * resolver.resolveUrl('foo') // => 'bar.png'\n     *\n     * // Multiple keys, single asset:\n     * resolver.add(['foo', 'boo'], 'bar.png');\n     * resolver.resolveUrl('foo') // => 'bar.png'\n     * resolver.resolveUrl('boo') // => 'bar.png'\n     *\n     * // Multiple keys, multiple assets:\n     * resolver.add(['foo', 'boo'], ['bar.png', 'bar.webp']);\n     * resolver.resolveUrl('foo') // => 'bar.png'\n     *\n     * // Add custom data attached to the resolver\n     * Resolver.add(\n     *     'bunnyBooBooSmooth',\n     *     'bunny{png,webp}',\n     *     { scaleMode:SCALE_MODES.NEAREST }, // Base texture options\n     * );\n     *\n     * resolver.resolve('bunnyBooBooSmooth') // => { src: 'bunny.png', data: { scaleMode: SCALE_MODES.NEAREST } }\n     * @param keysIn - The keys to map, can be an array or a single key\n     * @param assetsIn - The assets to associate with the key(s)\n     * @param data - The data that will be attached to the object that resolved object.\n     */\n    public add(keysIn: string | string[], assetsIn: string | ResolveAsset | (string | ResolveAsset)[], data?: unknown): void\n    {\n        const keys: string[] = convertToList<string>(keysIn);\n\n        keys.forEach((key) =>\n        {\n            if (this.hasKey(key))\n            {\n                // #if _DEBUG\n                console.warn(`[Resolver] already has key: ${key} overwriting`);\n                // #endif\n            }\n        });\n\n        if (!Array.isArray(assetsIn))\n        {\n            if (typeof assetsIn === 'string')\n            {\n                assetsIn = createStringVariations(assetsIn);\n            }\n            else\n            {\n                assetsIn = [assetsIn];\n            }\n        }\n\n        const assetMap: ResolveAsset[] = assetsIn.map((asset): ResolveAsset =>\n        {\n            let formattedAsset = asset as ResolveAsset;\n\n            // check if is a string\n            if (typeof asset === 'string')\n            {\n                // first see if it contains any {} tags...\n\n                let parsed = false;\n\n                for (let i = 0; i < this._parsers.length; i++)\n                {\n                    const parser = this._parsers[i];\n\n                    if (parser.test(asset))\n                    {\n                        formattedAsset = parser.parse(asset);\n                        parsed = true;\n                        break;\n                    }\n                }\n\n                if (!parsed)\n                {\n                    formattedAsset = {\n                        src: asset,\n                    };\n                }\n            }\n\n            if (!formattedAsset.format)\n            {\n                formattedAsset.format = formattedAsset.src.split('.').pop();\n            }\n\n            if (!formattedAsset.alias)\n            {\n                formattedAsset.alias = keys;\n            }\n\n            if (this._basePath || this._rootPath)\n            {\n                formattedAsset.src = utils.path.toAbsolute(formattedAsset.src, this._basePath, this._rootPath);\n            }\n\n            formattedAsset.src = this._appendDefaultSearchParams(formattedAsset.src);\n\n            formattedAsset.data = formattedAsset.data ?? data;\n\n            return formattedAsset;\n        });\n\n        keys.forEach((key) =>\n        {\n            this._assetMap[key] = assetMap;\n        });\n    }\n\n    /**\n     * If the resolver has had a manifest set via setManifest, this will return the assets urls for\n     * a given bundleId or bundleIds.\n     * @example\n     * // Manifest Example\n     * const manifest = {\n     *     bundles: [\n     *         {\n     *             name: 'load-screen',\n     *             assets: [\n     *                 {\n     *                     name: 'background',\n     *                     srcs: 'sunset.png',\n     *                 },\n     *                 {\n     *                     name: 'bar',\n     *                     srcs: 'load-bar.{png,webp}',\n     *                 },\n     *             ],\n     *         },\n     *         {\n     *             name: 'game-screen',\n     *             assets: [\n     *                 {\n     *                     name: 'character',\n     *                     srcs: 'robot.png',\n     *                 },\n     *                 {\n     *                     name: 'enemy',\n     *                     srcs: 'bad-guy.png',\n     *                 },\n     *             ],\n     *         },\n     *     ]\n     * };\n     *\n     * resolver.setManifest(manifest);\n     * const resolved = resolver.resolveBundle('load-screen');\n     * @param bundleIds - The bundle ids to resolve\n     * @returns All the bundles assets or a hash of assets for each bundle specified\n     */\n    public resolveBundle(bundleIds: string | string[]):\n    Record<string, ResolveAsset> | Record<string, Record<string, ResolveAsset>>\n    {\n        const singleAsset = isSingleItem(bundleIds);\n\n        bundleIds = convertToList<string>(bundleIds);\n\n        const out: Record<string, Record<string, ResolveAsset>> = {};\n\n        bundleIds.forEach((bundleId) =>\n        {\n            const assetNames = this._bundles[bundleId];\n\n            if (assetNames)\n            {\n                const results = this.resolve(assetNames) as Record<string, ResolveAsset>;\n\n                const assets: Record<string, ResolveAsset> = {};\n\n                for (const key in results)\n                {\n                    const asset = results[key];\n\n                    assets[this._extractAssetIdFromBundle(bundleId, key)] = asset;\n                }\n\n                out[bundleId] = assets;\n            }\n        });\n\n        return singleAsset ? out[bundleIds[0]] : out;\n    }\n\n    /**\n     * Does exactly what resolve does, but returns just the URL rather than the whole asset object\n     * @param key - The key or keys to resolve\n     * @returns - The URLs associated with the key(s)\n     */\n    public resolveUrl(key: string | string[]): string | Record<string, string>\n    {\n        const result = this.resolve(key);\n\n        if (typeof key !== 'string')\n        {\n            const out: Record<string, string> = {};\n\n            for (const i in result)\n            {\n                out[i] = (result as Record<string, ResolveAsset>)[i].src;\n            }\n\n            return out;\n        }\n\n        return (result as ResolveAsset).src;\n    }\n\n    /**\n     * Resolves each key in the list to an asset object.\n     * Another key function of the resolver! After adding all the various key/asset pairs. this will run the logic\n     * of finding which asset to return based on any preferences set using the `prefer` function\n     * by default the same key passed in will be returned if nothing is matched by the resolver.\n     * @example\n     * resolver.add('boo', 'bunny.png');\n     *\n     * resolver.resolve('boo') // => { src: 'bunny.png' }\n     *\n     * // Will return the same string as no key was added for this value..\n     * resolver.resolve('another-thing.png') // => { src: 'another-thing.png' }\n     * @param keys - key or keys to resolve\n     * @returns - the resolve asset or a hash of resolve assets for each key specified\n     */\n    public resolve(keys: string | string[]): ResolveAsset | Record<string, ResolveAsset>\n    {\n        const singleAsset = isSingleItem(keys);\n\n        keys = convertToList<string>(keys);\n\n        const result: Record<string, ResolveAsset> = {};\n\n        keys.forEach((key) =>\n        {\n            if (!this._resolverHash[key])\n            {\n                if (this._assetMap[key])\n                {\n                    let assets = this._assetMap[key];\n\n                    const preferredOrder = this._getPreferredOrder(assets);\n\n                    const bestAsset = assets[0];\n\n                    preferredOrder?.priority.forEach((priorityKey) =>\n                    {\n                        preferredOrder.params[priorityKey].forEach((value: unknown) =>\n                        {\n                            const filteredAssets = assets.filter((asset) =>\n                            {\n                                if (asset[priorityKey])\n                                {\n                                    return asset[priorityKey] === value;\n                                }\n\n                                return false;\n                            });\n\n                            if (filteredAssets.length)\n                            {\n                                assets = filteredAssets;\n                            }\n                        });\n                    });\n\n                    this._resolverHash[key] = (assets[0] ?? bestAsset);\n                }\n                else\n                {\n                    let src = key;\n\n                    if (this._basePath || this._rootPath)\n                    {\n                        src = utils.path.toAbsolute(src, this._basePath, this._rootPath);\n                    }\n\n                    // make sure to append any default parameters\n                    src = this._appendDefaultSearchParams(src);\n\n                    // if the resolver fails we just pass back the key assuming its a url\n                    this._resolverHash[key] = {\n                        src,\n                    };\n                }\n            }\n\n            result[key] = this._resolverHash[key];\n        });\n\n        return singleAsset ? result[keys[0]] : result;\n    }\n\n    /**\n     * Checks if an asset with a given key exists in the resolver\n     * @param key - The key of the asset\n     */\n    public hasKey(key: string): boolean\n    {\n        return !!this._assetMap[key];\n    }\n\n    /**\n     * Checks if a bundle with the given key exists in the resolver\n     * @param key - The key of the bundle\n     */\n    public hasBundle(key: string): boolean\n    {\n        return !!this._bundles[key];\n    }\n\n    /**\n     * Internal function for figuring out what prefer criteria an asset should use.\n     * @param assets\n     */\n    private _getPreferredOrder(assets: ResolveAsset[]): PreferOrder\n    {\n        for (let i = 0; i < assets.length; i++)\n        {\n            const asset = assets[0];\n\n            const preferred = this._preferredOrder.find((preference: PreferOrder) =>\n                preference.params.format.includes(asset.format));\n\n            if (preferred)\n            {\n                return preferred;\n            }\n        }\n\n        return this._preferredOrder[0];\n    }\n\n    /**\n     * Appends the default url parameters to the url\n     * @param url - The url to append the default parameters to\n     * @returns - The url with the default parameters appended\n     */\n    private _appendDefaultSearchParams(url: string): string\n    {\n        if (!this._defaultSearchParams) return url;\n\n        const paramConnector = (/\\?/).test(url) ? '&' : '?';\n\n        return `${url}${paramConnector}${this._defaultSearchParams}`;\n    }\n}\n"],"names":[],"mappings":"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"}