{"version":3,"file":"TranscoderWorker.mjs","sources":["../src/TranscoderWorker.ts"],"sourcesContent":["import { TranscoderWorkerWrapper } from './TranscoderWorkerWrapper';\n\nimport type { BASIS_FORMATS } from './Basis';\nimport type { ITranscodeResponse } from './TranscoderWorkerWrapper';\n\n/**\n * Worker class for transcoding *.basis files in background threads.\n *\n * To enable asynchronous transcoding, you need to provide the URL to the basis_universal transcoding\n * library.\n * @memberof PIXI.BasisParser\n */\nexport class TranscoderWorker\n{\n    // IMPLEMENTATION NOTE: TranscoderWorker tracks transcoding requests with a requestID; the worker can be issued\n    // multiple requests (once it is initialized) and the response contains the requestID of the triggering request. Based on\n    // the response, the transcodeAsync promise is fulfilled or rejected.\n\n    // TODO: Publish our own @pixi/basis package & set default URL to jsdelivr/cdnjs\n    /** URL for the script containing the basis_universal library. */\n    static bindingURL: string;\n    static jsSource: string;\n    static wasmSource: ArrayBuffer;\n\n    private static _onTranscoderInitializedResolve: () => void;\n\n    /** a promise that when reslved means the transcoder is ready to be used */\n    public static onTranscoderInitialized = new Promise<void>((resolve) =>\n    {\n        TranscoderWorker._onTranscoderInitializedResolve = resolve;\n    });\n\n    isInit: boolean;\n    load: number;\n    requests: { [id: number]: {\n        resolve: (data: ITranscodeResponse) => void,\n        reject: () => void\n    } } = {};\n\n    private static _workerURL: string;\n    private static _tempID = 0;\n\n    /** Generated URL for the transcoder worker script. */\n    static get workerURL(): string\n    {\n        if (!TranscoderWorker._workerURL)\n        {\n            let workerSource = TranscoderWorkerWrapper.toString();\n\n            const beginIndex = workerSource.indexOf('{');\n            const endIndex = workerSource.lastIndexOf('}');\n\n            workerSource = workerSource.slice(beginIndex + 1, endIndex);\n\n            if (TranscoderWorker.jsSource)\n            {\n                workerSource = `${TranscoderWorker.jsSource}\\n${workerSource}`;\n            }\n\n            TranscoderWorker._workerURL = URL.createObjectURL(new Blob([workerSource]));\n        }\n\n        return TranscoderWorker._workerURL;\n    }\n\n    protected worker: Worker;\n    protected initPromise: Promise<void>;\n    protected onInit: () => void;\n\n    constructor()\n    {\n        this.isInit = false;\n        this.load = 0;\n        this.initPromise = new Promise((resolve) => { this.onInit = resolve; });\n\n        if (!TranscoderWorker.wasmSource)\n        {\n            console.warn('resources.BasisResource.TranscoderWorker has not been given the transcoder WASM binary!');\n        }\n\n        this.worker = new Worker(TranscoderWorker.workerURL);\n        this.worker.onmessage = this.onMessage;\n        this.worker.postMessage({\n            type: 'init',\n            jsSource: TranscoderWorker.jsSource,\n            wasmSource: TranscoderWorker.wasmSource\n        });\n    }\n\n    /** @returns a promise that is resolved when the web-worker is initialized */\n    initAsync(): Promise<void>\n    {\n        return this.initPromise;\n    }\n\n    /**\n     * Creates a promise that will resolve when the transcoding of a *.basis file is complete.\n     * @param basisData - *.basis file contents\n     * @param rgbaFormat - transcoding format for RGBA files\n     * @param rgbFormat - transcoding format for RGB files\n     * @returns a promise that is resolved with the transcoding response of the web-worker\n     */\n    async transcodeAsync(\n        basisData: Uint8Array,\n        rgbaFormat: BASIS_FORMATS,\n        rgbFormat: BASIS_FORMATS\n    ): Promise<ITranscodeResponse>\n    {\n        ++this.load;\n\n        const requestID = TranscoderWorker._tempID++;\n        const requestPromise = new Promise((resolve: (data: ITranscodeResponse) => void, reject: () => void) =>\n        {\n            this.requests[requestID] = {\n                resolve,\n                reject\n            };\n        });\n\n        this.worker.postMessage({\n            requestID,\n            basisData,\n            rgbaFormat,\n            rgbFormat,\n            type: 'transcode'\n        });\n\n        return requestPromise;\n    }\n\n    /**\n     * Handles responses from the web-worker\n     * @param e - a message event containing the transcoded response\n     */\n    protected onMessage = (e: MessageEvent): void =>\n    {\n        const data = e.data as ITranscodeResponse;\n\n        if (data.type === 'init')\n        {\n            if (!data.success)\n            {\n                throw new Error('BasisResource.TranscoderWorker failed to initialize.');\n            }\n\n            this.isInit = true;\n            this.onInit();\n        }\n        else if (data.type === 'transcode')\n        {\n            --this.load;\n\n            const requestID = data.requestID;\n\n            if (data.success)\n            {\n                this.requests[requestID].resolve(data);\n            }\n            else\n            {\n                this.requests[requestID].reject();\n            }\n\n            delete this.requests[requestID];\n        }\n    };\n\n    /**\n     * Loads the transcoder source code\n     * @param jsURL - URL to the javascript basis transcoder\n     * @param wasmURL - URL to the wasm basis transcoder\n     * @returns A promise that resolves when both the js and wasm transcoders have been loaded.\n     */\n    static loadTranscoder(jsURL: string, wasmURL: string): Promise<[void, void]>\n    {\n        const jsPromise = fetch(jsURL)\n            .then((res: Response) => res.text())\n            .then((text: string) => { TranscoderWorker.jsSource = text; });\n        const wasmPromise = fetch(wasmURL)\n            .then((res: Response) => res.arrayBuffer())\n            .then((arrayBuffer: ArrayBuffer) => { TranscoderWorker.wasmSource = arrayBuffer; });\n\n        return Promise.all([jsPromise, wasmPromise]).then((data) =>\n\n        {\n            this._onTranscoderInitializedResolve();\n\n            return data;\n        });\n    }\n\n    /**\n     * Set the transcoder source code directly\n     * @param jsSource - source for the javascript basis transcoder\n     * @param wasmSource - source for the wasm basis transcoder\n     */\n    static setTranscoder(jsSource: string, wasmSource: ArrayBuffer): void\n    {\n        TranscoderWorker.jsSource = jsSource;\n        TranscoderWorker.wasmSource = wasmSource;\n    }\n}\n"],"names":["_TranscoderWorker"],"mappings":"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"}