Skip to content

Commit

Permalink
fix(native): amend BlobManager over globals (#3030)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett authored Oct 2, 2023
1 parent 320a5df commit c56e346
Showing 1 changed file with 51 additions and 21 deletions.
72 changes: 51 additions & 21 deletions packages/fiber/src/native/polyfills.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,10 @@
import * as THREE from 'three'
import { Image } from 'react-native'
import { Image, Platform, NativeModules } from 'react-native'
import { Asset } from 'expo-asset'
import * as fs from 'expo-file-system'
import { fromByteArray } from 'base64-js'

export function polyfills() {
// Patch Blob for ArrayBuffer if unsupported
try {
new Blob([new ArrayBuffer(4) as any])
} catch (_) {
global.Blob = class extends Blob {
constructor(parts?: any[], options?: any) {
super(
parts?.map((part) => {
if (part instanceof ArrayBuffer || ArrayBuffer.isView(part)) {
part = fromByteArray(new Uint8Array(part as ArrayBuffer))
}

return part
}),
options,
)
}
}
}

function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0,
Expand All @@ -33,6 +13,56 @@ export function polyfills() {
})
}

// Patch Blob for ArrayBuffer if unsupported
if (Platform.OS !== 'web') {
try {
new Blob([new ArrayBuffer(4) as any])
} catch (_) {
const BlobManager = require('react-native/Libraries/Blob/BlobManager.js')

BlobManager.createFromParts = function createFromParts(parts: Array<Blob | BlobPart | string>, options: any) {
const blobId = uuidv4()

const items = parts.map((part) => {
if (part instanceof ArrayBuffer || ArrayBuffer.isView(part)) {
const data = fromByteArray(new Uint8Array(part as ArrayBuffer))
return {
data,
type: 'string',
}
} else if (part instanceof Blob) {
return {
data: (part as any).data,
type: 'blob',
}
} else {
return {
data: String(part),
type: 'string',
}
}
})
const size = items.reduce((acc, curr) => {
if (curr.type === 'string') {
return acc + global.unescape(encodeURI(curr.data)).length
} else {
return acc + curr.data.size
}
}, 0)

NativeModules.BlobModule.createFromParts(items, blobId)

return BlobManager.createFromOptions({
blobId,
offset: 0,
size,
type: options ? options.type : '',
lastModified: options ? options.lastModified : Date.now(),
})
}
}
}

async function getAsset(input: string | number): Promise<string> {
if (typeof input === 'string') {
// Don't process storage or data uris
Expand Down

0 comments on commit c56e346

Please sign in to comment.