react-native-buffered-blob 1.0.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/android/AGENTS.md +74 -0
- package/android/build.gradle +34 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/bufferedblob/BufferedBlobModule.kt +274 -0
- package/android/src/main/java/com/bufferedblob/BufferedBlobPackage.kt +32 -0
- package/android/src/main/java/com/bufferedblob/HandleRegistry.kt +84 -0
- package/android/src/main/java/com/bufferedblob/StreamingBridge.kt +211 -0
- package/cpp/AGENTS.md +71 -0
- package/cpp/AndroidPlatformBridge.cpp +437 -0
- package/cpp/AndroidPlatformBridge.h +79 -0
- package/cpp/BufferedBlobStreamingHostObject.cpp +344 -0
- package/cpp/BufferedBlobStreamingHostObject.h +118 -0
- package/cpp/CMakeLists.txt +49 -0
- package/cpp/jni_onload.cpp +32 -0
- package/ios/AGENTS.md +76 -0
- package/ios/BufferedBlobModule.h +44 -0
- package/ios/BufferedBlobModule.m +433 -0
- package/ios/BufferedBlobModule.mm +192 -0
- package/ios/BufferedBlobStreamingBridge.h +21 -0
- package/ios/BufferedBlobStreamingBridge.mm +442 -0
- package/ios/HandleRegistry.h +29 -0
- package/ios/HandleRegistry.m +67 -0
- package/ios/HandleTypes.h +83 -0
- package/ios/HandleTypes.m +333 -0
- package/lib/module/AGENTS.md +70 -0
- package/lib/module/NativeBufferedBlob.js +5 -0
- package/lib/module/NativeBufferedBlob.js.map +1 -0
- package/lib/module/api/AGENTS.md +62 -0
- package/lib/module/api/download.js +40 -0
- package/lib/module/api/download.js.map +1 -0
- package/lib/module/api/fileOps.js +70 -0
- package/lib/module/api/fileOps.js.map +1 -0
- package/lib/module/api/hash.js +13 -0
- package/lib/module/api/hash.js.map +1 -0
- package/lib/module/api/readFile.js +23 -0
- package/lib/module/api/readFile.js.map +1 -0
- package/lib/module/api/writeFile.js +18 -0
- package/lib/module/api/writeFile.js.map +1 -0
- package/lib/module/errors.js +45 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/index.js +25 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/module.js +19 -0
- package/lib/module/module.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/paths.js +32 -0
- package/lib/module/paths.js.map +1 -0
- package/lib/module/types.js +15 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/wrappers.js +107 -0
- package/lib/module/wrappers.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeBufferedBlob.d.ts +37 -0
- package/lib/typescript/src/NativeBufferedBlob.d.ts.map +1 -0
- package/lib/typescript/src/api/download.d.ts +13 -0
- package/lib/typescript/src/api/download.d.ts.map +1 -0
- package/lib/typescript/src/api/fileOps.d.ts +9 -0
- package/lib/typescript/src/api/fileOps.d.ts.map +1 -0
- package/lib/typescript/src/api/hash.d.ts +3 -0
- package/lib/typescript/src/api/hash.d.ts.map +1 -0
- package/lib/typescript/src/api/readFile.d.ts +3 -0
- package/lib/typescript/src/api/readFile.d.ts.map +1 -0
- package/lib/typescript/src/api/writeFile.d.ts +3 -0
- package/lib/typescript/src/api/writeFile.d.ts.map +1 -0
- package/lib/typescript/src/errors.d.ts +25 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +11 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/module.d.ts +23 -0
- package/lib/typescript/src/module.d.ts.map +1 -0
- package/lib/typescript/src/paths.d.ts +11 -0
- package/lib/typescript/src/paths.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +37 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/wrappers.d.ts +14 -0
- package/lib/typescript/src/wrappers.d.ts.map +1 -0
- package/package.json +114 -0
- package/react-native-buffered-blob.podspec +37 -0
- package/react-native.config.js +10 -0
- package/src/AGENTS.md +70 -0
- package/src/NativeBufferedBlob.ts +54 -0
- package/src/api/AGENTS.md +62 -0
- package/src/api/download.ts +46 -0
- package/src/api/fileOps.ts +83 -0
- package/src/api/hash.ts +14 -0
- package/src/api/readFile.ts +37 -0
- package/src/api/writeFile.ts +24 -0
- package/src/errors.ts +50 -0
- package/src/index.ts +28 -0
- package/src/module.ts +48 -0
- package/src/paths.ts +35 -0
- package/src/types.ts +42 -0
- package/src/wrappers.ts +123 -0
package/src/paths.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { NativeModule } from './module';
|
|
2
|
+
|
|
3
|
+
const constants = NativeModule.getConstants();
|
|
4
|
+
|
|
5
|
+
export const Dirs = Object.freeze({
|
|
6
|
+
document: constants.documentDir,
|
|
7
|
+
cache: constants.cacheDir,
|
|
8
|
+
temp: constants.tempDir,
|
|
9
|
+
download: constants.downloadDir,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export function join(...parts: string[]): string {
|
|
13
|
+
const result = parts.filter(Boolean).join('/').replace(/\/+/g, '/');
|
|
14
|
+
return result.length > 1 ? result.replace(/\/$/, '') : result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function dirname(path: string): string {
|
|
18
|
+
const idx = path.lastIndexOf('/');
|
|
19
|
+
return idx === -1 ? '.' : path.substring(0, idx);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function basename(path: string, ext?: string): string {
|
|
23
|
+
const idx = path.lastIndexOf('/');
|
|
24
|
+
const name = idx === -1 ? path : path.substring(idx + 1);
|
|
25
|
+
if (ext && name.endsWith(ext)) {
|
|
26
|
+
return name.substring(0, name.length - ext.length);
|
|
27
|
+
}
|
|
28
|
+
return name;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function extname(path: string): string {
|
|
32
|
+
const name = basename(path);
|
|
33
|
+
const idx = name.lastIndexOf('.');
|
|
34
|
+
return idx <= 0 ? '' : name.substring(idx);
|
|
35
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// NOTE: Enums changed from numeric (Nitro) to string (Turbo Module compatibility)
|
|
2
|
+
export enum HashAlgorithm {
|
|
3
|
+
SHA256 = 'sha256',
|
|
4
|
+
MD5 = 'md5',
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export enum FileType {
|
|
8
|
+
FILE = 'file',
|
|
9
|
+
DIRECTORY = 'directory',
|
|
10
|
+
UNKNOWN = 'unknown',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface FileInfo {
|
|
14
|
+
path: string;
|
|
15
|
+
name: string;
|
|
16
|
+
size: number;
|
|
17
|
+
type: FileType;
|
|
18
|
+
lastModified: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DownloadProgress {
|
|
22
|
+
bytesDownloaded: number;
|
|
23
|
+
totalBytes: number;
|
|
24
|
+
progress: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface BlobReader extends Disposable {
|
|
28
|
+
readonly handleId: number;
|
|
29
|
+
readonly fileSize: number;
|
|
30
|
+
readonly bytesRead: number;
|
|
31
|
+
readonly isEOF: boolean;
|
|
32
|
+
readNextChunk(): Promise<ArrayBuffer | null>;
|
|
33
|
+
close(): void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface BlobWriter extends Disposable {
|
|
37
|
+
readonly handleId: number;
|
|
38
|
+
readonly bytesWritten: number;
|
|
39
|
+
write(data: ArrayBuffer): Promise<number>;
|
|
40
|
+
flush(): Promise<void>;
|
|
41
|
+
close(): void;
|
|
42
|
+
}
|
package/src/wrappers.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { StreamingProxy } from './module';
|
|
2
|
+
import type { BlobReader, BlobWriter } from './types';
|
|
3
|
+
import { BlobError, ErrorCode } from './errors';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Wraps a native reader handle with explicit getter delegation.
|
|
7
|
+
* IMPORTANT: Does NOT use spread operator on HostObject (getters would be lost).
|
|
8
|
+
* Instead, proxies each property access through getReaderInfo().
|
|
9
|
+
*/
|
|
10
|
+
export function wrapReader(
|
|
11
|
+
handleId: number,
|
|
12
|
+
streaming: StreamingProxy
|
|
13
|
+
): BlobReader {
|
|
14
|
+
let closed = false;
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
get handleId() {
|
|
18
|
+
return handleId;
|
|
19
|
+
},
|
|
20
|
+
get fileSize() {
|
|
21
|
+
return streaming.getReaderInfo(handleId).fileSize;
|
|
22
|
+
},
|
|
23
|
+
get bytesRead() {
|
|
24
|
+
return streaming.getReaderInfo(handleId).bytesRead;
|
|
25
|
+
},
|
|
26
|
+
get isEOF() {
|
|
27
|
+
return streaming.getReaderInfo(handleId).isEOF;
|
|
28
|
+
},
|
|
29
|
+
readNextChunk() {
|
|
30
|
+
if (closed) {
|
|
31
|
+
throw new BlobError(
|
|
32
|
+
ErrorCode.READER_CLOSED,
|
|
33
|
+
'Reader is already closed'
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return streaming.readNextChunk(handleId);
|
|
37
|
+
},
|
|
38
|
+
close() {
|
|
39
|
+
if (!closed) {
|
|
40
|
+
closed = true;
|
|
41
|
+
streaming.close(handleId);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
[Symbol.dispose]() {
|
|
45
|
+
if (!closed) {
|
|
46
|
+
closed = true;
|
|
47
|
+
streaming.close(handleId);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Wraps a native writer handle with explicit getter delegation.
|
|
55
|
+
* IMPORTANT: Does NOT use spread operator on HostObject (getters would be lost).
|
|
56
|
+
*/
|
|
57
|
+
export function wrapWriter(
|
|
58
|
+
handleId: number,
|
|
59
|
+
streaming: StreamingProxy
|
|
60
|
+
): BlobWriter {
|
|
61
|
+
let closed = false;
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
get handleId() {
|
|
65
|
+
return handleId;
|
|
66
|
+
},
|
|
67
|
+
get bytesWritten() {
|
|
68
|
+
return streaming.getWriterInfo(handleId).bytesWritten;
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* Write data to the file.
|
|
72
|
+
*
|
|
73
|
+
* **Backpressure warning:** Each call queues data to the native write
|
|
74
|
+
* pipeline. You MUST await each write() call before issuing the next
|
|
75
|
+
* one. Failing to await writes can cause unbounded memory growth as
|
|
76
|
+
* ArrayBuffer copies accumulate in the native queue.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* // Correct - sequential writes with await
|
|
81
|
+
* for (const chunk of chunks) {
|
|
82
|
+
* await writer.write(chunk);
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* // WRONG - parallel writes without backpressure
|
|
86
|
+
* chunks.forEach(chunk => writer.write(chunk)); // Do NOT do this
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @param data - The ArrayBuffer to write
|
|
90
|
+
* @returns Promise resolving to the number of bytes written
|
|
91
|
+
*/
|
|
92
|
+
write(data: ArrayBuffer) {
|
|
93
|
+
if (closed) {
|
|
94
|
+
throw new BlobError(
|
|
95
|
+
ErrorCode.WRITER_CLOSED,
|
|
96
|
+
'Writer is already closed'
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return streaming.write(handleId, data);
|
|
100
|
+
},
|
|
101
|
+
flush() {
|
|
102
|
+
if (closed) {
|
|
103
|
+
throw new BlobError(
|
|
104
|
+
ErrorCode.WRITER_CLOSED,
|
|
105
|
+
'Writer is already closed'
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
return streaming.flush(handleId);
|
|
109
|
+
},
|
|
110
|
+
close() {
|
|
111
|
+
if (!closed) {
|
|
112
|
+
closed = true;
|
|
113
|
+
streaming.close(handleId);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
[Symbol.dispose]() {
|
|
117
|
+
if (!closed) {
|
|
118
|
+
closed = true;
|
|
119
|
+
streaming.close(handleId);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|