···270 * On web, converts blob URLs to data URIs immediately to prevent revocation issues.
271 */
272async function copyToCache(from: string): Promise<string> {
273- // Handle web blob URLs - convert to data URI immediately before they can be revoked
274- if (IS_WEB && from.startsWith('blob:')) {
275- try {
276- const response = await fetch(from)
277- const blob = await response.blob()
278- return await blobToDataUri(blob)
279- } catch (e) {
280- // If fetch fails, the blob URL was likely already revoked
281- // Return as-is and let downstream code handle the error
282- return from
283- }
284- }
285-286 // Data URIs don't need any conversion
287 if (from.startsWith('data:')) {
288 return from
289 }
290291- const cacheDir = IS_WEB && getImageCacheDirectory()
00000000000000292293- // On web (non-blob URLs) or if already in cache dir, no need to copy
0294 if (!cacheDir || from.startsWith(cacheDir)) {
295 return from
296 }
···298 const to = joinPath(cacheDir, nanoid(36))
299 await makeDirectoryAsync(cacheDir, {intermediates: true})
300301- // Normalize the source path for expo-file-system
302 let normalizedFrom = from
303 if (!from.startsWith('file://') && from.startsWith('/')) {
304 normalizedFrom = `file://${from}`
···270 * On web, converts blob URLs to data URIs immediately to prevent revocation issues.
271 */
272async function copyToCache(from: string): Promise<string> {
0000000000000273 // Data URIs don't need any conversion
274 if (from.startsWith('data:')) {
275 return from
276 }
277278+ if (IS_WEB) {
279+ // Web: convert blob URLs to data URIs before they can be revoked
280+ if (from.startsWith('blob:')) {
281+ try {
282+ const response = await fetch(from)
283+ const blob = await response.blob()
284+ return await blobToDataUri(blob)
285+ } catch (e) {
286+ // Blob URL was likely revoked, return as-is for downstream error handling
287+ return from
288+ }
289+ }
290+ // Other URLs on web don't need conversion
291+ return from
292+ }
293294+ // Native: copy to cache directory to survive OS temp file cleanup
295+ const cacheDir = getImageCacheDirectory()
296 if (!cacheDir || from.startsWith(cacheDir)) {
297 return from
298 }
···300 const to = joinPath(cacheDir, nanoid(36))
301 await makeDirectoryAsync(cacheDir, {intermediates: true})
3020303 let normalizedFrom = from
304 if (!from.startsWith('file://') && from.startsWith('/')) {
305 normalizedFrom = `file://${from}`