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.
Files changed (93) hide show
  1. package/android/AGENTS.md +74 -0
  2. package/android/build.gradle +34 -0
  3. package/android/src/main/AndroidManifest.xml +4 -0
  4. package/android/src/main/java/com/bufferedblob/BufferedBlobModule.kt +274 -0
  5. package/android/src/main/java/com/bufferedblob/BufferedBlobPackage.kt +32 -0
  6. package/android/src/main/java/com/bufferedblob/HandleRegistry.kt +84 -0
  7. package/android/src/main/java/com/bufferedblob/StreamingBridge.kt +211 -0
  8. package/cpp/AGENTS.md +71 -0
  9. package/cpp/AndroidPlatformBridge.cpp +437 -0
  10. package/cpp/AndroidPlatformBridge.h +79 -0
  11. package/cpp/BufferedBlobStreamingHostObject.cpp +344 -0
  12. package/cpp/BufferedBlobStreamingHostObject.h +118 -0
  13. package/cpp/CMakeLists.txt +49 -0
  14. package/cpp/jni_onload.cpp +32 -0
  15. package/ios/AGENTS.md +76 -0
  16. package/ios/BufferedBlobModule.h +44 -0
  17. package/ios/BufferedBlobModule.m +433 -0
  18. package/ios/BufferedBlobModule.mm +192 -0
  19. package/ios/BufferedBlobStreamingBridge.h +21 -0
  20. package/ios/BufferedBlobStreamingBridge.mm +442 -0
  21. package/ios/HandleRegistry.h +29 -0
  22. package/ios/HandleRegistry.m +67 -0
  23. package/ios/HandleTypes.h +83 -0
  24. package/ios/HandleTypes.m +333 -0
  25. package/lib/module/AGENTS.md +70 -0
  26. package/lib/module/NativeBufferedBlob.js +5 -0
  27. package/lib/module/NativeBufferedBlob.js.map +1 -0
  28. package/lib/module/api/AGENTS.md +62 -0
  29. package/lib/module/api/download.js +40 -0
  30. package/lib/module/api/download.js.map +1 -0
  31. package/lib/module/api/fileOps.js +70 -0
  32. package/lib/module/api/fileOps.js.map +1 -0
  33. package/lib/module/api/hash.js +13 -0
  34. package/lib/module/api/hash.js.map +1 -0
  35. package/lib/module/api/readFile.js +23 -0
  36. package/lib/module/api/readFile.js.map +1 -0
  37. package/lib/module/api/writeFile.js +18 -0
  38. package/lib/module/api/writeFile.js.map +1 -0
  39. package/lib/module/errors.js +45 -0
  40. package/lib/module/errors.js.map +1 -0
  41. package/lib/module/index.js +25 -0
  42. package/lib/module/index.js.map +1 -0
  43. package/lib/module/module.js +19 -0
  44. package/lib/module/module.js.map +1 -0
  45. package/lib/module/package.json +1 -0
  46. package/lib/module/paths.js +32 -0
  47. package/lib/module/paths.js.map +1 -0
  48. package/lib/module/types.js +15 -0
  49. package/lib/module/types.js.map +1 -0
  50. package/lib/module/wrappers.js +107 -0
  51. package/lib/module/wrappers.js.map +1 -0
  52. package/lib/typescript/package.json +1 -0
  53. package/lib/typescript/src/NativeBufferedBlob.d.ts +37 -0
  54. package/lib/typescript/src/NativeBufferedBlob.d.ts.map +1 -0
  55. package/lib/typescript/src/api/download.d.ts +13 -0
  56. package/lib/typescript/src/api/download.d.ts.map +1 -0
  57. package/lib/typescript/src/api/fileOps.d.ts +9 -0
  58. package/lib/typescript/src/api/fileOps.d.ts.map +1 -0
  59. package/lib/typescript/src/api/hash.d.ts +3 -0
  60. package/lib/typescript/src/api/hash.d.ts.map +1 -0
  61. package/lib/typescript/src/api/readFile.d.ts +3 -0
  62. package/lib/typescript/src/api/readFile.d.ts.map +1 -0
  63. package/lib/typescript/src/api/writeFile.d.ts +3 -0
  64. package/lib/typescript/src/api/writeFile.d.ts.map +1 -0
  65. package/lib/typescript/src/errors.d.ts +25 -0
  66. package/lib/typescript/src/errors.d.ts.map +1 -0
  67. package/lib/typescript/src/index.d.ts +11 -0
  68. package/lib/typescript/src/index.d.ts.map +1 -0
  69. package/lib/typescript/src/module.d.ts +23 -0
  70. package/lib/typescript/src/module.d.ts.map +1 -0
  71. package/lib/typescript/src/paths.d.ts +11 -0
  72. package/lib/typescript/src/paths.d.ts.map +1 -0
  73. package/lib/typescript/src/types.d.ts +37 -0
  74. package/lib/typescript/src/types.d.ts.map +1 -0
  75. package/lib/typescript/src/wrappers.d.ts +14 -0
  76. package/lib/typescript/src/wrappers.d.ts.map +1 -0
  77. package/package.json +114 -0
  78. package/react-native-buffered-blob.podspec +37 -0
  79. package/react-native.config.js +10 -0
  80. package/src/AGENTS.md +70 -0
  81. package/src/NativeBufferedBlob.ts +54 -0
  82. package/src/api/AGENTS.md +62 -0
  83. package/src/api/download.ts +46 -0
  84. package/src/api/fileOps.ts +83 -0
  85. package/src/api/hash.ts +14 -0
  86. package/src/api/readFile.ts +37 -0
  87. package/src/api/writeFile.ts +24 -0
  88. package/src/errors.ts +50 -0
  89. package/src/index.ts +28 -0
  90. package/src/module.ts +48 -0
  91. package/src/paths.ts +35 -0
  92. package/src/types.ts +42 -0
  93. 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
+ }
@@ -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
+ }