From 120bae96b8360cbface6e1bde84afb8915657915 Mon Sep 17 00:00:00 2001 From: Cody Bennett <23324155+CodyJasonBennett@users.noreply.github.com> Date: Thu, 31 Aug 2023 20:10:48 -0500 Subject: [PATCH] fix: unpack modules in Android Release Mode --- packages/fiber/src/native/polyfills.ts | 84 ++++++++++++++------------ 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/packages/fiber/src/native/polyfills.ts b/packages/fiber/src/native/polyfills.ts index 7d53b4401c..8047a5fe54 100644 --- a/packages/fiber/src/native/polyfills.ts +++ b/packages/fiber/src/native/polyfills.ts @@ -78,43 +78,52 @@ if (Platform.OS !== 'web') { * Generates an asset based on input type. */ async function getAsset(input: string | number): Promise { - switch (typeof input) { - case 'string': - if (input.startsWith('data:')) { - const [header, data] = input.split(',') - const [, type] = header.split('/') - - const localUri = fs.cacheDirectory + uuidv4() + `.${type}` - await fs.writeAsStringAsync(localUri, data, { encoding: fs.EncodingType.Base64 }) - - return { localUri } as Asset - } else if (input.startsWith('blob:')) { - const blob = await new Promise((res, rej) => { - const xhr = new XMLHttpRequest() - xhr.open('GET', input) - xhr.responseType = 'blob' - xhr.onload = () => res(xhr.response) - xhr.onerror = rej - xhr.send() - }) - - const data = await new Promise((res, rej) => { - const reader = new FileReader() - reader.onload = () => res(reader.result as string) - reader.onerror = rej - reader.readAsText(blob) - }) - - const localUri = `data:${blob.type};base64,${data}` - - return getAsset(localUri) - } - return Asset.fromURI(input).downloadAsync() - case 'number': - return Asset.fromModule(input).downloadAsync() - default: - throw new Error('R3F: Invalid asset! Must be a URI or module.') + if (typeof input === 'string') { + // Unpack Blobs from react-native BlobManager + if (input.startsWith('blob:')) { + const blob = await new Promise((res, rej) => { + const xhr = new XMLHttpRequest() + xhr.open('GET', input as string) + xhr.responseType = 'blob' + xhr.onload = () => res(xhr.response) + xhr.onerror = rej + xhr.send() + }) + + const data = await new Promise((res, rej) => { + const reader = new FileReader() + reader.onload = () => res(reader.result as string) + reader.onerror = rej + reader.readAsText(blob) + }) + + input = `data:${blob.type};base64,${data}` + } + + // Create safe URI for JSI + if (input.startsWith('data:')) { + const [header, data] = input.split(',') + const [, type] = header.split('/') + + const localUri = fs.cacheDirectory + uuidv4() + `.${type}` + await fs.writeAsStringAsync(localUri, data, { encoding: fs.EncodingType.Base64 }) + + return { localUri } as Asset + } } + + // Download bundler module or external URL + const asset = Asset.fromModule(input) + + // Unpack assets in Android Release Mode + if (!asset.uri.includes(':')) { + const localUri = `${fs.cacheDirectory}ExponentAsset-${asset.hash}.${asset.type}` + await fs.copyAsync({ from: asset.uri, to: localUri }) + return { localUri } as Asset + } + + // Otherwise, resolve from registry + return asset.downloadAsync() } // Don't pre-process urls, let expo-asset generate an absolute URL @@ -141,9 +150,10 @@ if (Platform.OS !== 'web') { height: asset.height, } texture.flipY = true - // texture.unpackAlignment = 1 + texture.unpackAlignment = 1 texture.needsUpdate = true + // Force non-DOM upload for EXGL fast paths // @ts-ignore texture.isDataTexture = true