react-native-nitro-unzip 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -1,13 +1,16 @@
1
1
  # react-native-nitro-unzip
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/react-native-nitro-unzip)](https://www.npmjs.com/package/react-native-nitro-unzip)
4
+ [![npm downloads](https://img.shields.io/npm/dm/react-native-nitro-unzip)](https://www.npmjs.com/package/react-native-nitro-unzip)
4
5
  [![license](https://img.shields.io/npm/l/react-native-nitro-unzip)](https://github.com/isaacrowntree/react-native-nitro-unzip/blob/main/LICENSE)
5
6
  [![CI](https://github.com/isaacrowntree/react-native-nitro-unzip/actions/workflows/lint-typescript.yml/badge.svg)](https://github.com/isaacrowntree/react-native-nitro-unzip/actions/workflows/lint-typescript.yml)
7
+ ![Platform - iOS](https://img.shields.io/badge/platform-iOS-blue)
8
+ ![Platform - Android](https://img.shields.io/badge/platform-Android-green)
6
9
 
7
10
  High-performance ZIP operations for React Native, powered by [Nitro Modules](https://nitro.margelo.com/).
8
11
 
9
- - **iOS**: SSZipArchive (C-based libz) — ~500 files/sec
10
- - **Android**: Optimized ZipInputStream with 64KB buffers — ~474 files/sec
12
+ - **iOS**: [SSZipArchive](https://github.com/ZipArchive/ZipArchive) (C-based libz) — ~500 files/sec
13
+ - **Android**: Optimized ZipInputStream + [zip4j](https://github.com/srikanth-lingala/zip4j) for encryption — ~474 files/sec
11
14
  - **Zero bridge overhead** — progress callbacks via JSI, no serialization
12
15
  - **Object instances** — each task is an observable, cancellable `UnzipTask` or `ZipTask`
13
16
  - **Concurrent operations** supported out of the box
@@ -15,6 +18,18 @@ High-performance ZIP operations for React Native, powered by [Nitro Modules](htt
15
18
  - **Zip creation** — compress files and directories with optional password protection
16
19
  - **Background tasks** — iOS background task management for continued extraction
17
20
 
21
+ ### vs react-native-zip-archive
22
+
23
+ | | react-native-nitro-unzip | react-native-zip-archive |
24
+ |---|---|---|
25
+ | Architecture | JSI (Nitro Modules) | Bridge |
26
+ | Progress callbacks | Via JSI, no serialization | Via bridge events |
27
+ | Cancellation | Synchronous | Not supported |
28
+ | Concurrent ops | Yes | Limited |
29
+ | Password support | AES-256 (zip & unzip) | Unzip only |
30
+ | Zip creation | Yes | Yes |
31
+ | New Architecture | Required | Optional |
32
+
18
33
  ## Installation
19
34
 
20
35
  ```bash
@@ -49,14 +49,11 @@ class HybridUnzipTask(
49
49
  }
50
50
 
51
51
  override fun await(): Promise<UnzipResult> {
52
- return Promise.async { resolve, reject ->
52
+ return Promise.async {
53
53
  try {
54
- val result = if (password != null) extractWithPassword() else extract()
55
- resolve(result)
54
+ if (password != null) extractWithPassword() else extract()
56
55
  } catch (e: CancellationException) {
57
- reject(Exception("Extraction cancelled"))
58
- } catch (e: Exception) {
59
- reject(e)
56
+ throw Exception("Extraction cancelled")
60
57
  }
61
58
  }
62
59
  }
@@ -46,14 +46,11 @@ class HybridZipTask(
46
46
  }
47
47
 
48
48
  override fun await(): Promise<ZipResult> {
49
- return Promise.async { resolve, reject ->
49
+ return Promise.async {
50
50
  try {
51
- val result = compress()
52
- resolve(result)
51
+ compress()
53
52
  } catch (e: CancellationException) {
54
- reject(Exception("Zip creation cancelled"))
55
- } catch (e: Exception) {
56
- reject(e)
53
+ throw Exception("Zip creation cancelled")
57
54
  }
58
55
  }
59
56
  }
@@ -30,10 +30,6 @@ class HybridUnzipTask: HybridUnzipTaskSpec {
30
30
  private var backgroundTaskId: UIBackgroundTaskIdentifier = .invalid
31
31
  private let lock = NSLock()
32
32
  private let progressThrottle: TimeInterval = 1.0
33
-
34
- // Promise resolution — held until extraction completes or fails
35
- private var resolvePromise: ((UnzipResult) -> Void)?
36
- private var rejectPromise: ((Error) -> Void)?
37
33
  private var hasStarted = false
38
34
 
39
35
  init(zipPath: String, destinationPath: String, password: String? = nil) {
@@ -59,45 +55,38 @@ class HybridUnzipTask: HybridUnzipTaskSpec {
59
55
  }
60
56
 
61
57
  func await() throws -> Promise<UnzipResult> {
62
- return Promise.async { [self] resolve, reject in
63
- self.lock.lock()
64
- self.resolvePromise = resolve
65
- self.rejectPromise = reject
58
+ lock.lock()
59
+ guard !hasStarted else {
60
+ lock.unlock()
61
+ return Promise.rejected(withError: NSError(
62
+ domain: "NitroUnzip",
63
+ code: 4,
64
+ userInfo: [NSLocalizedDescriptionKey: "Task already started"]
65
+ ))
66
+ }
67
+ hasStarted = true
68
+ lock.unlock()
66
69
 
67
- guard !self.hasStarted else {
68
- self.lock.unlock()
69
- return
70
+ return Promise.async {
71
+ try await withCheckedThrowingContinuation { continuation in
72
+ self.beginBackgroundTask()
73
+
74
+ DispatchQueue.global(qos: .userInitiated).async {
75
+ do {
76
+ let result = try self.extract()
77
+ self.endBackgroundTask()
78
+ continuation.resume(returning: result)
79
+ } catch {
80
+ self.endBackgroundTask()
81
+ continuation.resume(throwing: error)
82
+ }
83
+ }
70
84
  }
71
- self.hasStarted = true
72
- self.lock.unlock()
73
-
74
- self.startExtraction()
75
85
  }
76
86
  }
77
87
 
78
88
  // MARK: - Extraction
79
89
 
80
- private func startExtraction() {
81
- beginBackgroundTask()
82
-
83
- DispatchQueue.global(qos: .userInitiated).async { [self] in
84
- do {
85
- let result = try self.extract()
86
- self.endBackgroundTask()
87
- self.lock.lock()
88
- let resolve = self.resolvePromise
89
- self.lock.unlock()
90
- resolve?(result)
91
- } catch {
92
- self.endBackgroundTask()
93
- self.lock.lock()
94
- let reject = self.rejectPromise
95
- self.lock.unlock()
96
- reject?(error)
97
- }
98
- }
99
- }
100
-
101
90
  private func extract() throws -> UnzipResult {
102
91
  let startTime = Date()
103
92
  let fileManager = FileManager.default
@@ -199,7 +188,7 @@ class HybridUnzipTask: HybridUnzipTaskSpec {
199
188
  let finalCount = extractedFiles
200
189
  let averageSpeed = duration > 0 ? Double(finalCount) / (duration / 1000) : 0
201
190
 
202
- // Calculate total bytes from extracted files
191
+ // Calculate total bytes from zip file size
203
192
  let totalBytes: Double
204
193
  if let attrs = try? fileManager.attributesOfItem(atPath: cleanZip),
205
194
  let fileSize = attrs[.size] as? UInt64 {
@@ -24,9 +24,6 @@ class HybridZipTask: HybridZipTaskSpec {
24
24
  private var backgroundTaskId: UIBackgroundTaskIdentifier = .invalid
25
25
  private let lock = NSLock()
26
26
  private let progressThrottle: TimeInterval = 1.0
27
-
28
- private var resolvePromise: ((ZipResult) -> Void)?
29
- private var rejectPromise: ((Error) -> Void)?
30
27
  private var hasStarted = false
31
28
 
32
29
  init(sourcePath: String, destinationZipPath: String, password: String? = nil) {
@@ -52,45 +49,38 @@ class HybridZipTask: HybridZipTaskSpec {
52
49
  }
53
50
 
54
51
  func await() throws -> Promise<ZipResult> {
55
- return Promise.async { [self] resolve, reject in
56
- self.lock.lock()
57
- self.resolvePromise = resolve
58
- self.rejectPromise = reject
59
-
60
- guard !self.hasStarted else {
61
- self.lock.unlock()
62
- return
63
- }
64
- self.hasStarted = true
65
- self.lock.unlock()
66
-
67
- self.startCompression()
52
+ lock.lock()
53
+ guard !hasStarted else {
54
+ lock.unlock()
55
+ return Promise.rejected(withError: NSError(
56
+ domain: "NitroUnzip",
57
+ code: 4,
58
+ userInfo: [NSLocalizedDescriptionKey: "Task already started"]
59
+ ))
68
60
  }
69
- }
70
-
71
- // MARK: - Compression
61
+ hasStarted = true
62
+ lock.unlock()
72
63
 
73
- private func startCompression() {
74
- beginBackgroundTask()
75
-
76
- DispatchQueue.global(qos: .userInitiated).async { [self] in
77
- do {
78
- let result = try self.compress()
79
- self.endBackgroundTask()
80
- self.lock.lock()
81
- let resolve = self.resolvePromise
82
- self.lock.unlock()
83
- resolve?(result)
84
- } catch {
85
- self.endBackgroundTask()
86
- self.lock.lock()
87
- let reject = self.rejectPromise
88
- self.lock.unlock()
89
- reject?(error)
64
+ return Promise.async {
65
+ try await withCheckedThrowingContinuation { continuation in
66
+ self.beginBackgroundTask()
67
+
68
+ DispatchQueue.global(qos: .userInitiated).async {
69
+ do {
70
+ let result = try self.compress()
71
+ self.endBackgroundTask()
72
+ continuation.resume(returning: result)
73
+ } catch {
74
+ self.endBackgroundTask()
75
+ continuation.resume(throwing: error)
76
+ }
77
+ }
90
78
  }
91
79
  }
92
80
  }
93
81
 
82
+ // MARK: - Compression
83
+
94
84
  private func compress() throws -> ZipResult {
95
85
  let startTime = Date()
96
86
  let fileManager = FileManager.default
package/nitro.json CHANGED
@@ -12,14 +12,6 @@
12
12
  "Unzip": {
13
13
  "swift": "HybridUnzip",
14
14
  "kotlin": "HybridUnzip"
15
- },
16
- "UnzipTask": {
17
- "swift": "HybridUnzipTask",
18
- "kotlin": "HybridUnzipTask"
19
- },
20
- "ZipTask": {
21
- "swift": "HybridZipTask",
22
- "kotlin": "HybridZipTask"
23
15
  }
24
16
  },
25
17
  "ignorePaths": ["node_modules", "lib", "example"]
@@ -50,22 +50,6 @@ void registerAllNatives() {
50
50
  return instance->cthis()->shared();
51
51
  }
52
52
  );
53
- HybridObjectRegistry::registerHybridObjectConstructor(
54
- "UnzipTask",
55
- []() -> std::shared_ptr<HybridObject> {
56
- static DefaultConstructableObject<JHybridUnzipTaskSpec::javaobject> object("com/margelo/nitro/unzip/HybridUnzipTask");
57
- auto instance = object.create();
58
- return instance->cthis()->shared();
59
- }
60
- );
61
- HybridObjectRegistry::registerHybridObjectConstructor(
62
- "ZipTask",
63
- []() -> std::shared_ptr<HybridObject> {
64
- static DefaultConstructableObject<JHybridZipTaskSpec::javaobject> object("com/margelo/nitro/unzip/HybridZipTask");
65
- auto instance = object.create();
66
- return instance->cthis()->shared();
67
- }
68
- );
69
53
  }
70
54
 
71
55
  } // namespace margelo::nitro::unzip
@@ -11,8 +11,6 @@
11
11
  #import <type_traits>
12
12
 
13
13
  #include "HybridUnzipSpecSwift.hpp"
14
- #include "HybridUnzipTaskSpecSwift.hpp"
15
- #include "HybridZipTaskSpecSwift.hpp"
16
14
 
17
15
  @interface NitroUnzipAutolinking : NSObject
18
16
  @end
@@ -30,20 +28,6 @@
30
28
  return hybridObject;
31
29
  }
32
30
  );
33
- HybridObjectRegistry::registerHybridObjectConstructor(
34
- "UnzipTask",
35
- []() -> std::shared_ptr<HybridObject> {
36
- std::shared_ptr<HybridUnzipTaskSpec> hybridObject = NitroUnzip::NitroUnzipAutolinking::createUnzipTask();
37
- return hybridObject;
38
- }
39
- );
40
- HybridObjectRegistry::registerHybridObjectConstructor(
41
- "ZipTask",
42
- []() -> std::shared_ptr<HybridObject> {
43
- std::shared_ptr<HybridZipTaskSpec> hybridObject = NitroUnzip::NitroUnzipAutolinking::createZipTask();
44
- return hybridObject;
45
- }
46
- );
47
31
  }
48
32
 
49
33
  @end
@@ -23,28 +23,4 @@ public final class NitroUnzipAutolinking {
23
23
  public static func isUnzipRecyclable() -> Bool {
24
24
  return HybridUnzip.self is any RecyclableView.Type
25
25
  }
26
-
27
- public static func createUnzipTask() -> bridge.std__shared_ptr_HybridUnzipTaskSpec_ {
28
- let hybridObject = HybridUnzipTask()
29
- return { () -> bridge.std__shared_ptr_HybridUnzipTaskSpec_ in
30
- let __cxxWrapped = hybridObject.getCxxWrapper()
31
- return __cxxWrapped.getCxxPart()
32
- }()
33
- }
34
-
35
- public static func isUnzipTaskRecyclable() -> Bool {
36
- return HybridUnzipTask.self is any RecyclableView.Type
37
- }
38
-
39
- public static func createZipTask() -> bridge.std__shared_ptr_HybridZipTaskSpec_ {
40
- let hybridObject = HybridZipTask()
41
- return { () -> bridge.std__shared_ptr_HybridZipTaskSpec_ in
42
- let __cxxWrapped = hybridObject.getCxxWrapper()
43
- return __cxxWrapped.getCxxPart()
44
- }()
45
- }
46
-
47
- public static func isZipTaskRecyclable() -> Bool {
48
- return HybridZipTask.self is any RecyclableView.Type
49
- }
50
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-unzip",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "High-performance ZIP extraction for React Native, powered by Nitro Modules",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",