expo-blob 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +2 -0
- package/CHANGELOG.md +15 -0
- package/README.md +148 -0
- package/android/build.gradle +15 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/blob/Blob.kt +185 -0
- package/android/src/main/java/expo/modules/blob/BlobModule.kt +50 -0
- package/build/ExpoBlob.d.ts +12 -0
- package/build/ExpoBlob.d.ts.map +1 -0
- package/build/ExpoBlob.js +90 -0
- package/build/ExpoBlob.js.map +1 -0
- package/build/ExpoBlob.types.d.ts +65 -0
- package/build/ExpoBlob.types.d.ts.map +1 -0
- package/build/ExpoBlob.types.js +2 -0
- package/build/ExpoBlob.types.js.map +1 -0
- package/build/ExpoBlob.web.d.ts +5 -0
- package/build/ExpoBlob.web.d.ts.map +1 -0
- package/build/ExpoBlob.web.js +2 -0
- package/build/ExpoBlob.web.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2 -0
- package/build/index.js.map +1 -0
- package/build/utils.d.ts +48 -0
- package/build/utils.d.ts.map +1 -0
- package/build/utils.js +88 -0
- package/build/utils.js.map +1 -0
- package/expo-module.config.json +15 -0
- package/ios/Blob.swift +108 -0
- package/ios/BlobPart.swift +29 -0
- package/ios/BlobUtils.swift +39 -0
- package/ios/ExpoBlob.podspec +34 -0
- package/ios/ExpoBlob.swift +44 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.module +87 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.pom +35 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/0.1.0/expo.modules.blob-0.1.0.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/maven-metadata.xml +13 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/maven-metadata.xml.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/maven-metadata.xml.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/maven-metadata.xml.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.blob/maven-metadata.xml.sha512 +1 -0
- package/package.json +36 -1
- package/src/ExpoBlob.ts +114 -0
- package/src/ExpoBlob.types.ts +75 -0
- package/src/ExpoBlob.web.ts +1 -0
- package/src/index.ts +2 -0
- package/src/utils.ts +94 -0
- package/tsconfig.json +9 -0
package/.eslintrc.js
ADDED
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# ExpoBlob
|
|
2
|
+
|
|
3
|
+
A Expo package that provides a Blob implementation for handling binary data, similar to the web Blob API.
|
|
4
|
+
|
|
5
|
+
# Installation in managed Expo projects
|
|
6
|
+
|
|
7
|
+
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/blob/).
|
|
8
|
+
|
|
9
|
+
# Installation in bare React Native projects
|
|
10
|
+
|
|
11
|
+
For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
|
|
12
|
+
|
|
13
|
+
### Add the package to your npm dependencies
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx expo install expo-blob
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Configure for Android
|
|
20
|
+
|
|
21
|
+
No additional set up necessary.
|
|
22
|
+
|
|
23
|
+
### Configure for iOS
|
|
24
|
+
|
|
25
|
+
Run `npx pod-install` after installing the npm package.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Basic Blob Creation
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { ExpoBlob as Blob } from 'expo-blob';
|
|
33
|
+
|
|
34
|
+
// Create an empty blob
|
|
35
|
+
const emptyBlob = new Blob();
|
|
36
|
+
|
|
37
|
+
// Create a blob from text
|
|
38
|
+
const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });
|
|
39
|
+
|
|
40
|
+
// Create a blob from binary data
|
|
41
|
+
const binaryBlob = new Blob([new Uint8Array([1, 2, 3, 4])], {
|
|
42
|
+
type: 'application/octet-stream',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Create a blob from mixed content
|
|
46
|
+
const mixedBlob = new Blob(
|
|
47
|
+
[
|
|
48
|
+
'Text content',
|
|
49
|
+
new Uint8Array([65, 66, 67]), // ABC in ASCII
|
|
50
|
+
'More text',
|
|
51
|
+
],
|
|
52
|
+
{ type: 'text/plain' }
|
|
53
|
+
);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Blob Properties
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
|
|
60
|
+
|
|
61
|
+
console.log(blob.size); // 13 (bytes)
|
|
62
|
+
console.log(blob.type); // "text/plain"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Reading Blob Content
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
|
|
69
|
+
|
|
70
|
+
// Read as text
|
|
71
|
+
const text = await blob.text();
|
|
72
|
+
console.log(text); // "Hello, World!"
|
|
73
|
+
|
|
74
|
+
// Read as bytes
|
|
75
|
+
const bytes = await blob.bytes();
|
|
76
|
+
console.log(bytes); // Uint8Array(13) [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]
|
|
77
|
+
|
|
78
|
+
// Read as ArrayBuffer
|
|
79
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
80
|
+
console.log(arrayBuffer); // ArrayBuffer(13)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Slicing Blobs
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
|
|
87
|
+
|
|
88
|
+
// Slice from position 0 to 5
|
|
89
|
+
const slice1 = blob.slice(0, 5);
|
|
90
|
+
console.log(await slice1.text()); // "Hello"
|
|
91
|
+
|
|
92
|
+
// Slice from position 7 to end
|
|
93
|
+
const slice2 = blob.slice(7);
|
|
94
|
+
console.log(await slice2.text()); // "World!"
|
|
95
|
+
|
|
96
|
+
// Slice with custom type
|
|
97
|
+
const slice3 = blob.slice(0, 5, 'text/html');
|
|
98
|
+
console.log(slice3.type); // "text/html"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Streaming
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
const blob = new Blob(['Large content...'], { type: 'text/plain' });
|
|
105
|
+
|
|
106
|
+
// Create a readable stream
|
|
107
|
+
const stream = blob.stream();
|
|
108
|
+
const reader = stream.getReader();
|
|
109
|
+
|
|
110
|
+
// Read chunks
|
|
111
|
+
while (true) {
|
|
112
|
+
const { done, value } = await reader.read();
|
|
113
|
+
if (done) break;
|
|
114
|
+
console.log('Chunk:', value);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## API Reference
|
|
119
|
+
|
|
120
|
+
### Constructor
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
new Blob(blobParts?: BlobPart[], options?: BlobPropertyBag)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Parameters:**
|
|
127
|
+
|
|
128
|
+
- `blobParts` (optional): Array of data to include in the blob
|
|
129
|
+
- `options` (optional): Configuration object with:
|
|
130
|
+
- `type`: MIME type string
|
|
131
|
+
- `endings`: Line ending normalization ('transparent' or 'native')
|
|
132
|
+
|
|
133
|
+
### Properties
|
|
134
|
+
|
|
135
|
+
- `size`: The size of the blob in bytes (read-only)
|
|
136
|
+
- `type`: The MIME type of the blob (read-only)
|
|
137
|
+
|
|
138
|
+
### Methods
|
|
139
|
+
|
|
140
|
+
- `slice(start?, end?, contentType?)`: Returns a new Blob containing a subset of the data
|
|
141
|
+
- `text()`: Returns a Promise that resolves with the blob's content as a string
|
|
142
|
+
- `bytes()`: Returns a Promise that resolves with the blob's content as a Uint8Array
|
|
143
|
+
- `arrayBuffer()`: Returns a Promise that resolves with the blob's content as an ArrayBuffer
|
|
144
|
+
- `stream()`: Returns a ReadableStream for streaming the blob's content
|
|
145
|
+
|
|
146
|
+
# Contributing
|
|
147
|
+
|
|
148
|
+
Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
package expo.modules.blob
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.records.Field
|
|
4
|
+
import expo.modules.kotlin.records.Record
|
|
5
|
+
import expo.modules.kotlin.sharedobjects.SharedObject
|
|
6
|
+
import expo.modules.kotlin.typedarray.TypedArray
|
|
7
|
+
import expo.modules.kotlin.types.EitherOfThree
|
|
8
|
+
import expo.modules.kotlin.types.Enumerable
|
|
9
|
+
import java.io.ByteArrayOutputStream
|
|
10
|
+
import kotlin.math.max
|
|
11
|
+
import kotlin.math.min
|
|
12
|
+
|
|
13
|
+
internal const val DEFAULT_TYPE = ""
|
|
14
|
+
|
|
15
|
+
internal class Blob(val blobParts: List<InternalBlobPart> = listOf(), rawType: String = DEFAULT_TYPE) : SharedObject() {
|
|
16
|
+
val size: Int by lazy {
|
|
17
|
+
blobParts.sumOf { it.size() }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
val type = if (validType(rawType)) {
|
|
21
|
+
rawType.lowercase()
|
|
22
|
+
} else {
|
|
23
|
+
DEFAULT_TYPE
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override fun getAdditionalMemoryPressure(): Int {
|
|
27
|
+
return size
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fun bytesToStream(byteStream: ByteArrayOutputStream) {
|
|
31
|
+
for (blobPart in blobParts) {
|
|
32
|
+
blobPart.bytesToStream(byteStream)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fun bytes(): ByteArray {
|
|
37
|
+
val byteStream = ByteArrayOutputStream(size)
|
|
38
|
+
bytesToStream(byteStream)
|
|
39
|
+
return byteStream.toByteArray()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private fun InternalBlobPart.offsetSlice(start: Int, end: Int, offset: Int): InternalBlobPart {
|
|
43
|
+
val startIndex: Int = max(start - offset, 0)
|
|
44
|
+
val endIndex: Int = min(end - offset, size())
|
|
45
|
+
if (startIndex == 0 && endIndex == size()) {
|
|
46
|
+
return this
|
|
47
|
+
}
|
|
48
|
+
return when (this) {
|
|
49
|
+
is InternalBlobPart.StringWrapper -> InternalBlobPart.BufferWrapper(cachedBytes.slice(startIndex..<endIndex).toByteArray())
|
|
50
|
+
is InternalBlobPart.BlobWrapper -> InternalBlobPart.BlobWrapper(blob.slice(startIndex, endIndex, ""))
|
|
51
|
+
is InternalBlobPart.BufferWrapper -> InternalBlobPart.BufferWrapper(buffer.slice(startIndex..<endIndex).toByteArray())
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
fun slice(start: Int, end: Int, contentType: String): Blob {
|
|
56
|
+
if (start <= 0 && end >= size) {
|
|
57
|
+
return Blob(blobParts, contentType)
|
|
58
|
+
}
|
|
59
|
+
if (start >= end) {
|
|
60
|
+
return Blob(listOf(), contentType)
|
|
61
|
+
}
|
|
62
|
+
var i = 0
|
|
63
|
+
val bps = mutableListOf<InternalBlobPart>()
|
|
64
|
+
for (blobPart in blobParts) {
|
|
65
|
+
if (i + blobPart.size() <= start) {
|
|
66
|
+
i += blobPart.size()
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
if (i >= end) {
|
|
70
|
+
break
|
|
71
|
+
}
|
|
72
|
+
bps.add(blobPart.offsetSlice(start, end, i))
|
|
73
|
+
i += blobPart.size()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return Blob(bps, contentType)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private fun validType(type: String): Boolean {
|
|
81
|
+
for (char in type) {
|
|
82
|
+
if (char.code < 0x20 || char.code > 0x7E) {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
internal typealias BlobPart = EitherOfThree<String, Blob, TypedArray>
|
|
90
|
+
|
|
91
|
+
private fun TypedArray.bytes(): ByteArray {
|
|
92
|
+
val byteArray = ByteArray(this.byteLength)
|
|
93
|
+
|
|
94
|
+
for (i in 0..<this.byteLength) {
|
|
95
|
+
byteArray[i] = this.readByte(i)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return byteArray
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private fun String.toNativeNewlines(): String {
|
|
102
|
+
val result = StringBuilder(length)
|
|
103
|
+
var prevCR = false
|
|
104
|
+
for (char in this) {
|
|
105
|
+
if (char == '\r') {
|
|
106
|
+
result.append('\n')
|
|
107
|
+
prevCR = true
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
if (!prevCR || char != '\n') {
|
|
111
|
+
result.append(char)
|
|
112
|
+
}
|
|
113
|
+
prevCR = false
|
|
114
|
+
}
|
|
115
|
+
return result.toString()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
internal fun List<BlobPart>.internal(nativeNewlines: Boolean): List<InternalBlobPart> {
|
|
119
|
+
return this.map { blobPart: BlobPart ->
|
|
120
|
+
if (blobPart.`is`(String::class)) {
|
|
121
|
+
blobPart.get(String::class).let {
|
|
122
|
+
val str = if (nativeNewlines) {
|
|
123
|
+
it.toNativeNewlines()
|
|
124
|
+
} else {
|
|
125
|
+
it
|
|
126
|
+
}
|
|
127
|
+
InternalBlobPart.StringWrapper(str)
|
|
128
|
+
}
|
|
129
|
+
} else if (blobPart.`is`(Blob::class)) {
|
|
130
|
+
blobPart.get(Blob::class).let {
|
|
131
|
+
InternalBlobPart.BlobWrapper(it)
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
blobPart.get(TypedArray::class).let {
|
|
135
|
+
InternalBlobPart.BufferWrapper(it.bytes())
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
internal fun makeBlob(blobParts: List<BlobPart>?, options: BlobOptionsBag?): Blob {
|
|
142
|
+
val safeBlobParts = blobParts ?: listOf()
|
|
143
|
+
val safeOptions = options ?: BlobOptionsBag()
|
|
144
|
+
return Blob(safeBlobParts.internal(safeOptions.endings == EndingType.NATIVE), safeOptions.type)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
internal sealed class InternalBlobPart {
|
|
148
|
+
class StringWrapper(string: String) : InternalBlobPart() {
|
|
149
|
+
val cachedBytes: ByteArray by lazy {
|
|
150
|
+
string.toByteArray()
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
data class BlobWrapper(val blob: Blob) : InternalBlobPart()
|
|
155
|
+
data class BufferWrapper(val buffer: ByteArray) : InternalBlobPart()
|
|
156
|
+
|
|
157
|
+
fun size(): Int {
|
|
158
|
+
return when (this) {
|
|
159
|
+
is StringWrapper -> cachedBytes.size
|
|
160
|
+
is BlobWrapper -> blob.size
|
|
161
|
+
is BufferWrapper -> buffer.size
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
fun bytesToStream(byteStream: ByteArrayOutputStream) {
|
|
166
|
+
when (this) {
|
|
167
|
+
is StringWrapper -> byteStream.write(cachedBytes)
|
|
168
|
+
is BlobWrapper -> blob.bytesToStream(byteStream)
|
|
169
|
+
is BufferWrapper -> byteStream.write(buffer)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
internal enum class EndingType(val str: String) : Enumerable {
|
|
175
|
+
TRANSPARENT("transparent"),
|
|
176
|
+
NATIVE("native")
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
internal class BlobOptionsBag : Record {
|
|
180
|
+
@Field
|
|
181
|
+
val type: String = DEFAULT_TYPE
|
|
182
|
+
|
|
183
|
+
@Field
|
|
184
|
+
val endings: EndingType = EndingType.TRANSPARENT
|
|
185
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
package expo.modules.blob
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.modules.Module
|
|
4
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
+
import kotlin.math.max
|
|
6
|
+
import kotlin.math.min
|
|
7
|
+
|
|
8
|
+
class BlobModule : Module() {
|
|
9
|
+
override fun definition() = ModuleDefinition {
|
|
10
|
+
Name("ExpoBlob")
|
|
11
|
+
|
|
12
|
+
Class(Blob::class) {
|
|
13
|
+
Constructor { blobParts: List<BlobPart>?, options: BlobOptionsBag? ->
|
|
14
|
+
makeBlob(blobParts, options)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Property("size") { blob: Blob ->
|
|
18
|
+
blob.size
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Property("type") { blob: Blob ->
|
|
22
|
+
blob.type
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Function("slice") { blob: Blob, start: Int?, end: Int?, contentType: String? ->
|
|
26
|
+
var sliceStart: Int = start ?: 0
|
|
27
|
+
var sliceEnd: Int = end ?: blob.size
|
|
28
|
+
if (sliceStart < 0) {
|
|
29
|
+
sliceStart = max(blob.size + sliceStart, 0)
|
|
30
|
+
} else {
|
|
31
|
+
sliceStart = min(sliceStart, blob.size)
|
|
32
|
+
}
|
|
33
|
+
if (sliceEnd < 0) {
|
|
34
|
+
sliceEnd = max(blob.size + sliceEnd, 0)
|
|
35
|
+
} else {
|
|
36
|
+
sliceEnd = min(sliceEnd, blob.size)
|
|
37
|
+
}
|
|
38
|
+
blob.slice(sliceStart, sliceEnd, contentType ?: "")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
AsyncFunction("bytes") { blob: Blob ->
|
|
42
|
+
blob.bytes()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
AsyncFunction("text") { blob: Blob ->
|
|
46
|
+
blob.bytes().decodeToString()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BlobPart, ExpoBlobModule } from './ExpoBlob.types';
|
|
2
|
+
declare const NativeBlobModule: ExpoBlobModule;
|
|
3
|
+
export declare class Blob extends NativeBlobModule.Blob {
|
|
4
|
+
constructor(blobParts?: BlobPart[] | Iterable<BlobPart>, options?: BlobPropertyBag);
|
|
5
|
+
slice(start?: number, end?: number, contentType?: string): Blob;
|
|
6
|
+
stream(): ReadableStream;
|
|
7
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
8
|
+
toString(): string;
|
|
9
|
+
static get length(): number;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=ExpoBlob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoBlob.d.ts","sourceRoot":"","sources":["../src/ExpoBlob.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAkB5D,QAAA,MAAM,gBAAgB,gBAAkD,CAAC;AAEzE,qBAAa,IAAK,SAAQ,gBAAgB,CAAC,IAAI;gBACjC,SAAS,CAAC,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe;IAmBlF,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAO/D,MAAM,IAAI,cAAc;IAgDlB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAQzC,QAAQ,IAAI,MAAM;IAKlB,MAAM,KAAK,MAAM,WAEhB;CACF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { requireNativeModule } from 'expo';
|
|
2
|
+
import { DEFAULT_CHUNK_SIZE, isTypedArray, normalizedContentType, preprocessOptions, } from './utils';
|
|
3
|
+
const inputMapping = (blobPart) => {
|
|
4
|
+
if (blobPart instanceof ArrayBuffer) {
|
|
5
|
+
return new Uint8Array(blobPart);
|
|
6
|
+
}
|
|
7
|
+
if (blobPart instanceof Blob || isTypedArray(blobPart)) {
|
|
8
|
+
return blobPart;
|
|
9
|
+
}
|
|
10
|
+
return String(blobPart);
|
|
11
|
+
};
|
|
12
|
+
const NativeBlobModule = requireNativeModule('ExpoBlob');
|
|
13
|
+
export class Blob extends NativeBlobModule.Blob {
|
|
14
|
+
constructor(blobParts, options) {
|
|
15
|
+
if (!new.target) {
|
|
16
|
+
throw new TypeError("Blob constructor requires 'new' operator");
|
|
17
|
+
}
|
|
18
|
+
const processedBlobParts = [];
|
|
19
|
+
if (blobParts === undefined) {
|
|
20
|
+
super([], preprocessOptions(options));
|
|
21
|
+
}
|
|
22
|
+
else if (blobParts === null || typeof blobParts !== 'object') {
|
|
23
|
+
throw TypeError('Blob constructor requires blobParts to be a non-null object or undefined');
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
for (const blobPart of blobParts) {
|
|
27
|
+
processedBlobParts.push(inputMapping(blobPart));
|
|
28
|
+
}
|
|
29
|
+
super(processedBlobParts, preprocessOptions(options));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
slice(start, end, contentType) {
|
|
33
|
+
const normalizedType = normalizedContentType(contentType);
|
|
34
|
+
const slicedBlob = super.slice(start, end, normalizedType);
|
|
35
|
+
Object.setPrototypeOf(slicedBlob, Blob.prototype);
|
|
36
|
+
return slicedBlob;
|
|
37
|
+
}
|
|
38
|
+
stream() {
|
|
39
|
+
let getBlobBytes = this.bytes.bind(this);
|
|
40
|
+
let offset = 0;
|
|
41
|
+
let cachedBytes = null;
|
|
42
|
+
return new ReadableStream({
|
|
43
|
+
type: 'bytes',
|
|
44
|
+
async pull(controller) {
|
|
45
|
+
if (!cachedBytes) {
|
|
46
|
+
if (!getBlobBytes) {
|
|
47
|
+
throw new Error('Cannot read from a closed stream');
|
|
48
|
+
}
|
|
49
|
+
cachedBytes = await getBlobBytes();
|
|
50
|
+
getBlobBytes = null;
|
|
51
|
+
}
|
|
52
|
+
if (offset >= cachedBytes.length) {
|
|
53
|
+
controller.close();
|
|
54
|
+
cachedBytes = null;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (controller.byobRequest?.view) {
|
|
58
|
+
const view = new Uint8Array(controller.byobRequest.view.buffer, controller.byobRequest.view.byteOffset, controller.byobRequest.view.byteLength);
|
|
59
|
+
const end = Math.min(offset + view.byteLength, cachedBytes.length);
|
|
60
|
+
const chunk = cachedBytes.subarray(offset, end);
|
|
61
|
+
view.set(chunk, 0);
|
|
62
|
+
controller.byobRequest.respond(chunk.length);
|
|
63
|
+
offset = end;
|
|
64
|
+
if (offset >= cachedBytes.length) {
|
|
65
|
+
controller.close();
|
|
66
|
+
cachedBytes = null;
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const chunkSize = DEFAULT_CHUNK_SIZE;
|
|
71
|
+
const end = Math.min(offset + chunkSize, cachedBytes.length);
|
|
72
|
+
controller.enqueue(cachedBytes.subarray(offset, end));
|
|
73
|
+
offset = end;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async arrayBuffer() {
|
|
78
|
+
return super.bytes().then((bytes) =>
|
|
79
|
+
// The Blob spec requires we always return a new ArrayBuffer even when its bounds match the TypedArray's
|
|
80
|
+
bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
|
|
81
|
+
}
|
|
82
|
+
toString() {
|
|
83
|
+
return '[object Blob]';
|
|
84
|
+
}
|
|
85
|
+
// Changed the length property to match that of the default js implementation
|
|
86
|
+
static get length() {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=ExpoBlob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoBlob.js","sourceRoot":"","sources":["../src/ExpoBlob.ts"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeModule } from 'expo';\n\nimport { BlobPart, ExpoBlobModule } from './ExpoBlob.types';\nimport {\n DEFAULT_CHUNK_SIZE,\n isTypedArray,\n normalizedContentType,\n preprocessOptions,\n} from './utils';\n\nconst inputMapping = (blobPart: BlobPart) => {\n if (blobPart instanceof ArrayBuffer) {\n return new Uint8Array(blobPart);\n }\n if (blobPart instanceof Blob || isTypedArray(blobPart)) {\n return blobPart;\n }\n return String(blobPart);\n};\n\nconst NativeBlobModule = requireNativeModule<ExpoBlobModule>('ExpoBlob');\n\nexport class Blob extends NativeBlobModule.Blob {\n constructor(blobParts?: BlobPart[] | Iterable<BlobPart>, options?: BlobPropertyBag) {\n if (!new.target) {\n throw new TypeError(\"Blob constructor requires 'new' operator\");\n }\n\n const processedBlobParts: BlobPart[] = [];\n\n if (blobParts === undefined) {\n super([], preprocessOptions(options));\n } else if (blobParts === null || typeof blobParts !== 'object') {\n throw TypeError('Blob constructor requires blobParts to be a non-null object or undefined');\n } else {\n for (const blobPart of blobParts) {\n processedBlobParts.push(inputMapping(blobPart));\n }\n super(processedBlobParts, preprocessOptions(options));\n }\n }\n\n slice(start?: number, end?: number, contentType?: string): Blob {\n const normalizedType = normalizedContentType(contentType);\n const slicedBlob = super.slice(start, end, normalizedType);\n Object.setPrototypeOf(slicedBlob, Blob.prototype);\n return slicedBlob as Blob;\n }\n\n stream(): ReadableStream {\n let getBlobBytes: (() => Promise<Uint8Array>) | null = this.bytes.bind(this);\n let offset = 0;\n let cachedBytes: Uint8Array | null = null;\n\n return new ReadableStream({\n type: 'bytes',\n async pull(controller: ReadableByteStreamController) {\n if (!cachedBytes) {\n if (!getBlobBytes) {\n throw new Error('Cannot read from a closed stream');\n }\n cachedBytes = await getBlobBytes();\n getBlobBytes = null;\n }\n\n if (offset >= cachedBytes.length) {\n controller.close();\n cachedBytes = null;\n return;\n }\n\n if (controller.byobRequest?.view) {\n const view: Uint8Array = new Uint8Array(\n controller.byobRequest.view.buffer,\n controller.byobRequest.view.byteOffset,\n controller.byobRequest.view.byteLength\n );\n const end = Math.min(offset + view.byteLength, cachedBytes.length);\n const chunk = cachedBytes.subarray(offset, end);\n view.set(chunk, 0);\n controller.byobRequest.respond(chunk.length);\n offset = end;\n if (offset >= cachedBytes.length) {\n controller.close();\n cachedBytes = null;\n }\n return;\n }\n\n const chunkSize = DEFAULT_CHUNK_SIZE;\n const end = Math.min(offset + chunkSize, cachedBytes.length);\n controller.enqueue(cachedBytes.subarray(offset, end) as ArrayBufferView<ArrayBuffer>);\n offset = end;\n },\n });\n }\n\n async arrayBuffer(): Promise<ArrayBuffer> {\n return super.bytes().then(\n (bytes: Uint8Array) =>\n // The Blob spec requires we always return a new ArrayBuffer even when its bounds match the TypedArray's\n bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer\n );\n }\n\n toString(): string {\n return '[object Blob]';\n }\n\n // Changed the length property to match that of the default js implementation\n static get length() {\n return 0;\n }\n}\n"]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { NativeModule, SharedObject } from 'expo';
|
|
2
|
+
export declare class Blob {
|
|
3
|
+
/**
|
|
4
|
+
* The size of the `Blob` in bytes.
|
|
5
|
+
*/
|
|
6
|
+
readonly size: number;
|
|
7
|
+
/**
|
|
8
|
+
* The MIME type of the `Blob`, or the empty string if the type cannot be determined.
|
|
9
|
+
*/
|
|
10
|
+
readonly type: string;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new `Blob` object from the given parts and options.
|
|
13
|
+
* @param blobParts An array of `BlobPart` to include in the `Blob`.
|
|
14
|
+
* @param options An optional `BlobPropertyBag` dictionary.
|
|
15
|
+
*/
|
|
16
|
+
constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);
|
|
17
|
+
/**
|
|
18
|
+
* @param start The starting byte index (inclusive) represented as a signed 32 bit integer (up to 2^31 - 1).
|
|
19
|
+
* @param end The ending byte index (exclusive) represented as a signed 32 bit integer (up to 2^31 - 1).
|
|
20
|
+
* @param contentType The MIME type of the new `Blob`. If not provided, defaults to an empty string.
|
|
21
|
+
* @returns A new `Blob` object containing the data in the specified range of bytes of the source `Blob`.
|
|
22
|
+
*/
|
|
23
|
+
slice(start?: number, end?: number, contentType?: string): Blob;
|
|
24
|
+
/**
|
|
25
|
+
* @returns Promise resolving to the `Blob`'s binary data as a `Uint8Array`.
|
|
26
|
+
*/
|
|
27
|
+
bytes(): Promise<Uint8Array>;
|
|
28
|
+
/**
|
|
29
|
+
* @returns Promise that resolves with the entire contents of the `Blob` as a UTF-8 string.
|
|
30
|
+
*/
|
|
31
|
+
text(): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* > **Note**: The current implementation loads the entire `Blob` into memory before streaming.
|
|
34
|
+
* @returns A `ReadableStream` of the `Blob`'s data.
|
|
35
|
+
*/
|
|
36
|
+
stream(): ReadableStream;
|
|
37
|
+
/**
|
|
38
|
+
* @returns Promise resolving to the `Blob`'s binary data as an `ArrayBuffer`.
|
|
39
|
+
*/
|
|
40
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @hidden
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
export declare class NativeBlob extends SharedObject {
|
|
47
|
+
readonly size: number;
|
|
48
|
+
readonly type: string;
|
|
49
|
+
constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);
|
|
50
|
+
slice(start?: number, end?: number, contentType?: string): Blob;
|
|
51
|
+
bytes(): Promise<Uint8Array>;
|
|
52
|
+
text(): Promise<string>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* @hidden
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
export declare class ExpoBlobModule extends NativeModule {
|
|
59
|
+
Blob: typeof NativeBlob;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Represents a part of a `Blob`. Can be a `string`, `ArrayBuffer`, `ArrayBufferView`, or another `Blob`.
|
|
63
|
+
*/
|
|
64
|
+
export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob;
|
|
65
|
+
//# sourceMappingURL=ExpoBlob.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoBlob.types.d.ts","sourceRoot":"","sources":["../src/ExpoBlob.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAElD,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;gBACS,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe;IAE7D;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAE/D;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC;IAE5B;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IACvB;;;OAGG;IACH,MAAM,IAAI,cAAc;IAExB;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,YAAY;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe;IAE7D,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAC/D,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC;IAC5B,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,YAAY;IACtD,IAAI,EAAE,OAAO,UAAU,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,eAAe,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoBlob.types.js","sourceRoot":"","sources":["../src/ExpoBlob.types.ts"],"names":[],"mappings":"","sourcesContent":["import { NativeModule, SharedObject } from 'expo';\n\nexport declare class Blob {\n /**\n * The size of the `Blob` in bytes.\n */\n readonly size: number;\n /**\n * The MIME type of the `Blob`, or the empty string if the type cannot be determined.\n */\n readonly type: string;\n\n /**\n * Creates a new `Blob` object from the given parts and options.\n * @param blobParts An array of `BlobPart` to include in the `Blob`.\n * @param options An optional `BlobPropertyBag` dictionary.\n */\n constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);\n\n /**\n * @param start The starting byte index (inclusive) represented as a signed 32 bit integer (up to 2^31 - 1).\n * @param end The ending byte index (exclusive) represented as a signed 32 bit integer (up to 2^31 - 1).\n * @param contentType The MIME type of the new `Blob`. If not provided, defaults to an empty string.\n * @returns A new `Blob` object containing the data in the specified range of bytes of the source `Blob`.\n */\n slice(start?: number, end?: number, contentType?: string): Blob;\n\n /**\n * @returns Promise resolving to the `Blob`'s binary data as a `Uint8Array`.\n */\n bytes(): Promise<Uint8Array>;\n\n /**\n * @returns Promise that resolves with the entire contents of the `Blob` as a UTF-8 string.\n */\n text(): Promise<string>;\n /**\n * > **Note**: The current implementation loads the entire `Blob` into memory before streaming.\n * @returns A `ReadableStream` of the `Blob`'s data.\n */\n stream(): ReadableStream;\n\n /**\n * @returns Promise resolving to the `Blob`'s binary data as an `ArrayBuffer`.\n */\n arrayBuffer(): Promise<ArrayBuffer>;\n}\n\n/**\n * @hidden\n * @private\n */\nexport declare class NativeBlob extends SharedObject {\n readonly size: number;\n readonly type: string;\n\n constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);\n\n slice(start?: number, end?: number, contentType?: string): Blob;\n bytes(): Promise<Uint8Array>;\n text(): Promise<string>;\n}\n\n/**\n * @hidden\n * @private\n */\nexport declare class ExpoBlobModule extends NativeModule {\n Blob: typeof NativeBlob;\n}\n\n/**\n * Represents a part of a `Blob`. Can be a `string`, `ArrayBuffer`, `ArrayBufferView`, or another `Blob`.\n */\nexport type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoBlob.web.d.ts","sourceRoot":"","sources":["../src/ExpoBlob.web.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;CAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoBlob.web.js","sourceRoot":"","sources":["../src/ExpoBlob.web.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC","sourcesContent":["export const ExpoBlob = Blob;\n"]}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC","sourcesContent":["export * from './ExpoBlob';\nexport type { BlobPart } from './ExpoBlob.types';\n"]}
|