react-native-nitro-image-pipeline 0.3.5 → 1.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.
Files changed (35) hide show
  1. package/README.md +66 -6
  2. package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipeline.kt +24 -6
  3. package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/BlurTransformation.kt +50 -24
  4. package/ios/GaussianBlur.swift +135 -0
  5. package/ios/GaussianBlurProcessor.swift +41 -0
  6. package/ios/HybridNitroImagePipeline.swift +15 -20
  7. package/ios/RoundedCornersProcessor.swift +118 -0
  8. package/lib/commonjs/index.js +18 -2
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/module/index.js +18 -2
  11. package/lib/module/index.js.map +1 -1
  12. package/lib/typescript/src/index.d.ts +13 -3
  13. package/lib/typescript/src/index.d.ts.map +1 -1
  14. package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts +32 -1
  15. package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts.map +1 -1
  16. package/nitrogen/generated/android/NitroImagePipeline+autolinking.cmake +1 -0
  17. package/nitrogen/generated/android/c++/JCornerRadii.hpp +69 -0
  18. package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.cpp +6 -0
  19. package/nitrogen/generated/android/c++/JOptions.hpp +9 -5
  20. package/nitrogen/generated/android/c++/JVariant_Double_CornerRadii.cpp +26 -0
  21. package/nitrogen/generated/android/c++/JVariant_Double_CornerRadii.hpp +70 -0
  22. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/CornerRadii.kt +66 -0
  23. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/Options.kt +2 -2
  24. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/Variant_Double_CornerRadii.kt +62 -0
  25. package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.hpp +48 -0
  26. package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Umbrella.hpp +4 -0
  27. package/nitrogen/generated/ios/c++/HybridNitroImagePipelineSpecSwift.hpp +4 -0
  28. package/nitrogen/generated/ios/swift/CornerRadii.swift +96 -0
  29. package/nitrogen/generated/ios/swift/Options.swift +27 -8
  30. package/nitrogen/generated/ios/swift/Variant_Double_CornerRadii.swift +30 -0
  31. package/nitrogen/generated/shared/c++/CornerRadii.hpp +95 -0
  32. package/nitrogen/generated/shared/c++/Options.hpp +9 -5
  33. package/package.json +21 -13
  34. package/src/index.ts +38 -4
  35. package/src/specs/nitro-image-toolkit.nitro.ts +38 -3
@@ -18,6 +18,8 @@ namespace margelo::nitro::image { class HybridImageSpec; }
18
18
  namespace margelo::nitro::nitroimagepipeline { struct Options; }
19
19
  // Forward declaration of `CacheOption` to properly resolve imports.
20
20
  namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
21
+ // Forward declaration of `CornerRadii` to properly resolve imports.
22
+ namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
21
23
 
22
24
  #include <memory>
23
25
  #include <NitroImage/HybridImageSpec.hpp>
@@ -26,6 +28,8 @@ namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
26
28
  #include "Options.hpp"
27
29
  #include <optional>
28
30
  #include "CacheOption.hpp"
31
+ #include "CornerRadii.hpp"
32
+ #include <variant>
29
33
  #include <vector>
30
34
 
31
35
  #include "NitroImagePipeline-Swift-Cxx-Umbrella.hpp"
@@ -0,0 +1,96 @@
1
+ ///
2
+ /// CornerRadii.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import NitroModules
9
+
10
+ /**
11
+ * Represents an instance of `CornerRadii`, backed by a C++ struct.
12
+ */
13
+ public typealias CornerRadii = margelo.nitro.nitroimagepipeline.CornerRadii
14
+
15
+ public extension CornerRadii {
16
+ private typealias bridge = margelo.nitro.nitroimagepipeline.bridge.swift
17
+
18
+ /**
19
+ * Create a new instance of `CornerRadii`.
20
+ */
21
+ init(topLeft: Double?, topRight: Double?, bottomLeft: Double?, bottomRight: Double?) {
22
+ self.init({ () -> bridge.std__optional_double_ in
23
+ if let __unwrappedValue = topLeft {
24
+ return bridge.create_std__optional_double_(__unwrappedValue)
25
+ } else {
26
+ return .init()
27
+ }
28
+ }(), { () -> bridge.std__optional_double_ in
29
+ if let __unwrappedValue = topRight {
30
+ return bridge.create_std__optional_double_(__unwrappedValue)
31
+ } else {
32
+ return .init()
33
+ }
34
+ }(), { () -> bridge.std__optional_double_ in
35
+ if let __unwrappedValue = bottomLeft {
36
+ return bridge.create_std__optional_double_(__unwrappedValue)
37
+ } else {
38
+ return .init()
39
+ }
40
+ }(), { () -> bridge.std__optional_double_ in
41
+ if let __unwrappedValue = bottomRight {
42
+ return bridge.create_std__optional_double_(__unwrappedValue)
43
+ } else {
44
+ return .init()
45
+ }
46
+ }())
47
+ }
48
+
49
+ @inline(__always)
50
+ var topLeft: Double? {
51
+ return { () -> Double? in
52
+ if bridge.has_value_std__optional_double_(self.__topLeft) {
53
+ let __unwrapped = bridge.get_std__optional_double_(self.__topLeft)
54
+ return __unwrapped
55
+ } else {
56
+ return nil
57
+ }
58
+ }()
59
+ }
60
+
61
+ @inline(__always)
62
+ var topRight: Double? {
63
+ return { () -> Double? in
64
+ if bridge.has_value_std__optional_double_(self.__topRight) {
65
+ let __unwrapped = bridge.get_std__optional_double_(self.__topRight)
66
+ return __unwrapped
67
+ } else {
68
+ return nil
69
+ }
70
+ }()
71
+ }
72
+
73
+ @inline(__always)
74
+ var bottomLeft: Double? {
75
+ return { () -> Double? in
76
+ if bridge.has_value_std__optional_double_(self.__bottomLeft) {
77
+ let __unwrapped = bridge.get_std__optional_double_(self.__bottomLeft)
78
+ return __unwrapped
79
+ } else {
80
+ return nil
81
+ }
82
+ }()
83
+ }
84
+
85
+ @inline(__always)
86
+ var bottomRight: Double? {
87
+ return { () -> Double? in
88
+ if bridge.has_value_std__optional_double_(self.__bottomRight) {
89
+ let __unwrapped = bridge.get_std__optional_double_(self.__bottomRight)
90
+ return __unwrapped
91
+ } else {
92
+ return nil
93
+ }
94
+ }()
95
+ }
96
+ }
@@ -18,7 +18,7 @@ public extension Options {
18
18
  /**
19
19
  * Create a new instance of `Options`.
20
20
  */
21
- init(blur: Double?, cache: CacheOption?, cornerRadius: Double?) {
21
+ init(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?) {
22
22
  self.init({ () -> bridge.std__optional_double_ in
23
23
  if let __unwrappedValue = blur {
24
24
  return bridge.create_std__optional_double_(__unwrappedValue)
@@ -31,9 +31,16 @@ public extension Options {
31
31
  } else {
32
32
  return .init()
33
33
  }
34
- }(), { () -> bridge.std__optional_double_ in
34
+ }(), { () -> bridge.std__optional_std__variant_double__CornerRadii__ in
35
35
  if let __unwrappedValue = cornerRadius {
36
- return bridge.create_std__optional_double_(__unwrappedValue)
36
+ return bridge.create_std__optional_std__variant_double__CornerRadii__({ () -> bridge.std__variant_double__CornerRadii_ in
37
+ switch __unwrappedValue {
38
+ case .first(let __value):
39
+ return bridge.create_std__variant_double__CornerRadii_(__value)
40
+ case .second(let __value):
41
+ return bridge.create_std__variant_double__CornerRadii_(__value)
42
+ }
43
+ }().variant)
37
44
  } else {
38
45
  return .init()
39
46
  }
@@ -58,11 +65,23 @@ public extension Options {
58
65
  }
59
66
 
60
67
  @inline(__always)
61
- var cornerRadius: Double? {
62
- return { () -> Double? in
63
- if bridge.has_value_std__optional_double_(self.__cornerRadius) {
64
- let __unwrapped = bridge.get_std__optional_double_(self.__cornerRadius)
65
- return __unwrapped
68
+ var cornerRadius: Variant_Double_CornerRadii? {
69
+ return { () -> Variant_Double_CornerRadii? in
70
+ if bridge.has_value_std__optional_std__variant_double__CornerRadii__(self.__cornerRadius) {
71
+ let __unwrapped = bridge.get_std__optional_std__variant_double__CornerRadii__(self.__cornerRadius)
72
+ return { () -> Variant_Double_CornerRadii in
73
+ let __variant = bridge.std__variant_double__CornerRadii_(__unwrapped)
74
+ switch __variant.index() {
75
+ case 0:
76
+ let __actual = __variant.get_0()
77
+ return .first(__actual)
78
+ case 1:
79
+ let __actual = __variant.get_1()
80
+ return .second(__actual)
81
+ default:
82
+ fatalError("Variant can never have index \(__variant.index())!")
83
+ }
84
+ }()
66
85
  } else {
67
86
  return nil
68
87
  }
@@ -0,0 +1,30 @@
1
+ ///
2
+ /// Variant_Double_CornerRadii.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+
9
+
10
+ /**
11
+ * An Swift enum with associated values representing a Variant/Union type.
12
+ * JS type: `number | struct`
13
+ */
14
+ @frozen
15
+ public indirect enum Variant_Double_CornerRadii {
16
+ case first(Double)
17
+ case second(CornerRadii)
18
+ }
19
+
20
+ public extension Variant_Double_CornerRadii {
21
+ func asType<T>(_ type: T.Type = T.self) -> T? {
22
+ switch self {
23
+ case .first(let value): return value as? T
24
+ case .second(let value): return value as? T
25
+ }
26
+ }
27
+ func isType<T>(_ type: T.Type = T.self) -> Bool {
28
+ return self.asType(type) != nil
29
+ }
30
+ }
@@ -0,0 +1,95 @@
1
+ ///
2
+ /// CornerRadii.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
26
+ #include <NitroModules/PropNameIDCache.hpp>
27
+ #else
28
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
29
+ #endif
30
+
31
+
32
+
33
+ #include <optional>
34
+
35
+ namespace margelo::nitro::nitroimagepipeline {
36
+
37
+ /**
38
+ * A struct which can be represented as a JavaScript object (CornerRadii).
39
+ */
40
+ struct CornerRadii final {
41
+ public:
42
+ std::optional<double> topLeft SWIFT_PRIVATE;
43
+ std::optional<double> topRight SWIFT_PRIVATE;
44
+ std::optional<double> bottomLeft SWIFT_PRIVATE;
45
+ std::optional<double> bottomRight SWIFT_PRIVATE;
46
+
47
+ public:
48
+ CornerRadii() = default;
49
+ explicit CornerRadii(std::optional<double> topLeft, std::optional<double> topRight, std::optional<double> bottomLeft, std::optional<double> bottomRight): topLeft(topLeft), topRight(topRight), bottomLeft(bottomLeft), bottomRight(bottomRight) {}
50
+
51
+ public:
52
+ friend bool operator==(const CornerRadii& lhs, const CornerRadii& rhs) = default;
53
+ };
54
+
55
+ } // namespace margelo::nitro::nitroimagepipeline
56
+
57
+ namespace margelo::nitro {
58
+
59
+ // C++ CornerRadii <> JS CornerRadii (object)
60
+ template <>
61
+ struct JSIConverter<margelo::nitro::nitroimagepipeline::CornerRadii> final {
62
+ static inline margelo::nitro::nitroimagepipeline::CornerRadii fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
63
+ jsi::Object obj = arg.asObject(runtime);
64
+ return margelo::nitro::nitroimagepipeline::CornerRadii(
65
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topLeft"))),
66
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topRight"))),
67
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomLeft"))),
68
+ JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomRight")))
69
+ );
70
+ }
71
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::CornerRadii& arg) {
72
+ jsi::Object obj(runtime);
73
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "topLeft"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.topLeft));
74
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "topRight"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.topRight));
75
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "bottomLeft"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.bottomLeft));
76
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "bottomRight"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.bottomRight));
77
+ return obj;
78
+ }
79
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
80
+ if (!value.isObject()) {
81
+ return false;
82
+ }
83
+ jsi::Object obj = value.getObject(runtime);
84
+ if (!nitro::isPlainObject(runtime, obj)) {
85
+ return false;
86
+ }
87
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topLeft")))) return false;
88
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topRight")))) return false;
89
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomLeft")))) return false;
90
+ if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomRight")))) return false;
91
+ return true;
92
+ }
93
+ };
94
+
95
+ } // namespace margelo::nitro
@@ -30,9 +30,13 @@
30
30
 
31
31
  // Forward declaration of `CacheOption` to properly resolve imports.
32
32
  namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
33
+ // Forward declaration of `CornerRadii` to properly resolve imports.
34
+ namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
33
35
 
34
36
  #include <optional>
35
37
  #include "CacheOption.hpp"
38
+ #include "CornerRadii.hpp"
39
+ #include <variant>
36
40
 
37
41
  namespace margelo::nitro::nitroimagepipeline {
38
42
 
@@ -43,11 +47,11 @@ namespace margelo::nitro::nitroimagepipeline {
43
47
  public:
44
48
  std::optional<double> blur SWIFT_PRIVATE;
45
49
  std::optional<CacheOption> cache SWIFT_PRIVATE;
46
- std::optional<double> cornerRadius SWIFT_PRIVATE;
50
+ std::optional<std::variant<double, CornerRadii>> cornerRadius SWIFT_PRIVATE;
47
51
 
48
52
  public:
49
53
  Options() = default;
50
- explicit Options(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<double> cornerRadius): blur(blur), cache(cache), cornerRadius(cornerRadius) {}
54
+ explicit Options(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<std::variant<double, CornerRadii>> cornerRadius): blur(blur), cache(cache), cornerRadius(cornerRadius) {}
51
55
 
52
56
  public:
53
57
  friend bool operator==(const Options& lhs, const Options& rhs) = default;
@@ -65,14 +69,14 @@ namespace margelo::nitro {
65
69
  return margelo::nitro::nitroimagepipeline::Options(
66
70
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur"))),
67
71
  JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache"))),
68
- JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))
72
+ JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))
69
73
  );
70
74
  }
71
75
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::Options& arg) {
72
76
  jsi::Object obj(runtime);
73
77
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "blur"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.blur));
74
78
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "cache"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::toJSI(runtime, arg.cache));
75
- obj.setProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.cornerRadius));
79
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"), JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::toJSI(runtime, arg.cornerRadius));
76
80
  return obj;
77
81
  }
78
82
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -85,7 +89,7 @@ namespace margelo::nitro {
85
89
  }
86
90
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur")))) return false;
87
91
  if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache")))) return false;
88
- if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))) return false;
92
+ if (!JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))) return false;
89
93
  return true;
90
94
  }
91
95
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-image-pipeline",
3
- "version": "0.3.5",
3
+ "version": "1.1.0",
4
4
  "description": "High-performance image loading, caching, and processing for React Native, built with Nitro Modules",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
@@ -9,12 +9,15 @@
9
9
  "source": "src/index",
10
10
  "scripts": {
11
11
  "typecheck": "tsc --noEmit",
12
- "lint": "biome check .",
13
- "format": "biome format --write .",
12
+ "lint": "oxlint && oxfmt --check",
13
+ "lint:fix": "oxlint --fix && oxfmt",
14
+ "format": "oxfmt",
14
15
  "clean": "git clean -dfX",
16
+ "prepare": "lefthook install || true",
15
17
  "release": "semantic-release",
16
18
  "build": "bun run typecheck && bob build",
17
- "codegen": "nitrogen --logLevel=\"debug\" && bun run build"
19
+ "codegen": "nitrogen --logLevel=\"debug\" && bun run build",
20
+ "verify:blur": "swiftc -O -o \"${TMPDIR:-/tmp}/nitro-verify-blur\" scripts/verify-blur.swift ios/GaussianBlur.swift && \"${TMPDIR:-/tmp}/nitro-verify-blur\""
18
21
  },
19
22
  "keywords": [
20
23
  "react-native",
@@ -59,26 +62,28 @@
59
62
  "registry": "https://registry.npmjs.org/"
60
63
  },
61
64
  "devDependencies": {
62
- "@biomejs/biome": "^2.5.6",
63
65
  "@semantic-release/changelog": "^7.0.0",
64
66
  "@semantic-release/git": "^11.0.1",
65
- "@types/bun": "^1.3.14",
67
+ "@types/bun": "^1.4.0",
66
68
  "@types/jest": "^30.0.0",
67
69
  "@types/react": "19.2.18",
68
- "conventional-changelog-conventionalcommits": "^10.2.1",
69
- "nitrogen": "0.36.5",
70
+ "conventional-changelog-conventionalcommits": "^9.1.0",
71
+ "lefthook": "^2.1.10",
72
+ "nitrogen": "0.37.0",
73
+ "oxfmt": "^0.65.0",
74
+ "oxlint": "^1.80.0",
70
75
  "react": "19.2.3",
71
76
  "react-native": "0.84.1",
72
77
  "react-native-builder-bob": "^0.43.0",
73
- "react-native-nitro-modules": "0.36.5",
74
- "semantic-release": "^25.0.8",
75
- "typescript": "^5.8.3"
78
+ "react-native-nitro-modules": "0.37.0",
79
+ "semantic-release": "^25.0.9",
80
+ "typescript": "^7.0.2"
76
81
  },
77
82
  "peerDependencies": {
78
83
  "react": "*",
79
84
  "react-native": "*",
80
85
  "react-native-nitro-modules": "*",
81
- "react-native-nitro-image": "*"
86
+ "react-native-nitro-image": "0.15.1"
82
87
  },
83
88
  "overrides": {
84
89
  "lodash-es": "4.17.21"
@@ -96,5 +101,8 @@
96
101
  }
97
102
  ]
98
103
  ]
99
- }
104
+ },
105
+ "trustedDependencies": [
106
+ "lefthook"
107
+ ]
100
108
  }
package/src/index.ts CHANGED
@@ -4,11 +4,12 @@ import { NitroModules } from 'react-native-nitro-modules';
4
4
 
5
5
  import type {
6
6
  CacheOption,
7
+ CornerRadii,
7
8
  NitroImagePipeline as NitroImagePipelineSpec,
8
9
  Options,
9
10
  } from './specs/nitro-image-toolkit.nitro';
10
11
 
11
- export type { CacheOption, Options };
12
+ export type { CacheOption, CornerRadii, Options };
12
13
 
13
14
  export const NitroImagePipeline =
14
15
  NitroModules.createHybridObject<NitroImagePipelineSpec>('NitroImagePipeline');
@@ -45,8 +46,18 @@ export function useImage({
45
46
  cache,
46
47
  }: {
47
48
  url: string;
49
+ /**
50
+ * Gaussian blur strength, as the standard deviation (sigma) of the blur in
51
+ * source-image pixels. Matches across iOS and Android; roughly half of
52
+ * React Native's `blurRadius`.
53
+ */
48
54
  blur?: number;
49
- cornerRadius?: number;
55
+ /**
56
+ * Corner radius in points, baked into the loaded bitmap. Pass a single
57
+ * number for uniform rounding, or per-corner radii (inline object literals
58
+ * are fine — the hook compares the radii by value, not identity).
59
+ */
60
+ cornerRadius?: number | CornerRadii;
50
61
  cache?: CacheOption;
51
62
  }): Result {
52
63
  const [image, setImage] = useState<Result>({
@@ -55,6 +66,17 @@ export function useImage({
55
66
  });
56
67
  const loadedUrlRef = useRef(url);
57
68
 
69
+ // Split the option into primitives so an inline `{ topLeft: 24, ... }`
70
+ // literal (new identity every render) doesn't re-trigger the effect.
71
+ const isUniformRadius = typeof cornerRadius === 'number';
72
+ const uniformRadius = isUniformRadius ? cornerRadius : 0;
73
+ const {
74
+ topLeft = 0,
75
+ topRight = 0,
76
+ bottomLeft = 0,
77
+ bottomRight = 0,
78
+ } = isUniformRadius ? {} : cornerRadius;
79
+
58
80
  useEffect(() => {
59
81
  let cancelled = false;
60
82
  // Only reset to the loading state when the URL changes; for same-URL
@@ -69,7 +91,9 @@ export function useImage({
69
91
  try {
70
92
  const result = await NitroImagePipeline.loadImage(url, {
71
93
  blur,
72
- cornerRadius,
94
+ cornerRadius: isUniformRadius
95
+ ? uniformRadius
96
+ : { topLeft, topRight, bottomLeft, bottomRight },
73
97
  cache,
74
98
  });
75
99
 
@@ -87,7 +111,17 @@ export function useImage({
87
111
  return () => {
88
112
  cancelled = true;
89
113
  };
90
- }, [url, blur, cornerRadius, cache]);
114
+ }, [
115
+ url,
116
+ blur,
117
+ isUniformRadius,
118
+ uniformRadius,
119
+ topLeft,
120
+ topRight,
121
+ bottomLeft,
122
+ bottomRight,
123
+ cache,
124
+ ]);
91
125
 
92
126
  return image;
93
127
  }
@@ -2,17 +2,52 @@ import type { Image } from 'react-native-nitro-image';
2
2
  import type { HybridObject } from 'react-native-nitro-modules';
3
3
 
4
4
  export type CacheOption = 'memory' | 'disk' | 'none';
5
+
6
+ /**
7
+ * Independent corner radii in points. Omitted corners stay square.
8
+ */
9
+ export interface CornerRadii {
10
+ topLeft?: number;
11
+ topRight?: number;
12
+ bottomLeft?: number;
13
+ bottomRight?: number;
14
+ }
15
+
5
16
  export type Options = {
17
+ /**
18
+ * Gaussian blur strength, given as the standard deviation (sigma) of the
19
+ * blur in **source-image pixels**. The same value on the same source image
20
+ * produces the same result on iOS and Android.
21
+ *
22
+ * React Native's `<Image blurRadius={n} />` is roughly `blur: n / 2`.
23
+ *
24
+ * @default 0 (no blur)
25
+ */
6
26
  blur?: number;
7
27
  cache?: CacheOption;
8
- cornerRadius?: number;
28
+ /**
29
+ * Corner radius in points, baked into the loaded bitmap. Pass a single
30
+ * number to round all four corners uniformly, or a {@linkcode CornerRadii}
31
+ * object to round each corner independently (e.g. a "ticket" shape with
32
+ * larger bottom corners).
33
+ *
34
+ * @default 0 (square corners)
35
+ */
36
+ cornerRadius?: number | CornerRadii;
9
37
  };
10
38
 
11
- export interface NitroImagePipeline
12
- extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
39
+ export interface NitroImagePipeline extends HybridObject<{
40
+ ios: 'swift';
41
+ android: 'kotlin';
42
+ }> {
13
43
  loadImage(url: string, options?: Options): Promise<Image>;
14
44
  preLoadImage(url: string): Promise<void>;
15
45
  preLoadImages(urls: string[]): Promise<void>;
46
+ /**
47
+ * Blurs an already-loaded image. `radius` is the standard deviation (sigma)
48
+ * of the Gaussian in **source-image pixels**, the same unit as
49
+ * {@linkcode Options.blur}.
50
+ */
16
51
  gaussianBlur(image: Image, radius: number): Promise<Image>;
17
52
  // Future: brightness, saturation, tint, etc.
18
53