react-native-nitro-image-pipeline 1.3.2 → 1.5.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/README.md +103 -11
- package/android/CMakeLists.txt +4 -0
- package/android/src/main/cpp/GaussianBlur.cpp +165 -0
- package/android/src/main/cpp/GaussianBlur.hpp +52 -0
- package/android/src/main/cpp/GaussianBlurJni.cpp +50 -0
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipeline.kt +153 -74
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/PipelineImageLoader.kt +177 -0
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/BlurTransformation.kt +36 -81
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/HardwareBitmapTransformation.kt +45 -0
- package/ios/GaussianBlur.swift +48 -9
- package/ios/HybridNitroImagePipeline.swift +79 -33
- package/ios/PipelineImageLoader.swift +195 -0
- package/ios/RoundedCornersProcessor.swift +5 -0
- package/lib/commonjs/NativePipelineImage.js +71 -0
- package/lib/commonjs/NativePipelineImage.js.map +1 -0
- package/lib/commonjs/index.js +14 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/usePipelineImageLoader.js +69 -0
- package/lib/commonjs/usePipelineImageLoader.js.map +1 -0
- package/lib/module/NativePipelineImage.js +67 -0
- package/lib/module/NativePipelineImage.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/usePipelineImageLoader.js +65 -0
- package/lib/module/usePipelineImageLoader.js.map +1 -0
- package/lib/typescript/src/NativePipelineImage.d.ts +66 -0
- package/lib/typescript/src/NativePipelineImage.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts +54 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts.map +1 -1
- package/lib/typescript/src/usePipelineImageLoader.d.ts +15 -0
- package/lib/typescript/src/usePipelineImageLoader.d.ts.map +1 -0
- package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.cpp +17 -0
- package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.hpp +2 -0
- package/nitrogen/generated/android/c++/JViewOptions.hpp +77 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipelineSpec.kt +9 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/ViewOptions.kt +66 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.cpp +10 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.hpp +53 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Umbrella.hpp +8 -0
- package/nitrogen/generated/ios/c++/HybridNitroImagePipelineSpecSwift.hpp +20 -0
- package/nitrogen/generated/ios/swift/HybridNitroImagePipelineSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridNitroImagePipelineSpec_cxx.swift +26 -0
- package/nitrogen/generated/ios/swift/ViewOptions.swift +101 -0
- package/nitrogen/generated/shared/c++/HybridNitroImagePipelineSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridNitroImagePipelineSpec.hpp +8 -0
- package/nitrogen/generated/shared/c++/ViewOptions.hpp +104 -0
- package/package.json +4 -3
- package/src/NativePipelineImage.tsx +103 -0
- package/src/index.ts +7 -0
- package/src/specs/nitro-image-toolkit.nitro.ts +56 -1
- package/src/usePipelineImageLoader.ts +82 -0
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
13
13
|
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
14
14
|
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
15
|
+
// Forward declaration of `HybridImageLoaderSpec` to properly resolve imports.
|
|
16
|
+
namespace margelo::nitro::image { class HybridImageLoaderSpec; }
|
|
15
17
|
// Forward declaration of `HybridImageSpec` to properly resolve imports.
|
|
16
18
|
namespace margelo::nitro::image { class HybridImageSpec; }
|
|
17
19
|
// Forward declaration of `HybridNitroImagePipelineSpec` to properly resolve imports.
|
|
@@ -20,8 +22,12 @@ namespace margelo::nitro::nitroimagepipeline { class HybridNitroImagePipelineSpe
|
|
|
20
22
|
namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
21
23
|
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
22
24
|
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
25
|
+
// Forward declaration of `ViewOptions` to properly resolve imports.
|
|
26
|
+
namespace margelo::nitro::nitroimagepipeline { struct ViewOptions; }
|
|
23
27
|
|
|
24
28
|
// Forward declarations of Swift defined types
|
|
29
|
+
// Forward declaration of `HybridImageLoaderSpec_cxx` to properly resolve imports.
|
|
30
|
+
namespace NitroImage { class HybridImageLoaderSpec_cxx; }
|
|
25
31
|
// Forward declaration of `HybridImageSpec_cxx` to properly resolve imports.
|
|
26
32
|
namespace NitroImage { class HybridImageSpec_cxx; }
|
|
27
33
|
// Forward declaration of `HybridNitroImagePipelineSpec_cxx` to properly resolve imports.
|
|
@@ -33,6 +39,8 @@ namespace NitroImagePipeline { class HybridNitroImagePipelineSpec_cxx; }
|
|
|
33
39
|
#include "HybridNitroImagePipelineSpec.hpp"
|
|
34
40
|
#include "Options.hpp"
|
|
35
41
|
#include "ResizeOptions.hpp"
|
|
42
|
+
#include "ViewOptions.hpp"
|
|
43
|
+
#include <NitroImage/HybridImageLoaderSpec.hpp>
|
|
36
44
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
37
45
|
#include <NitroModules/Promise.hpp>
|
|
38
46
|
#include <NitroModules/PromiseHolder.hpp>
|
|
@@ -223,6 +231,33 @@ namespace margelo::nitro::nitroimagepipeline::bridge::swift {
|
|
|
223
231
|
return optional.value();
|
|
224
232
|
}
|
|
225
233
|
|
|
234
|
+
// pragma MARK: std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>
|
|
235
|
+
/**
|
|
236
|
+
* Specialized version of `std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>`.
|
|
237
|
+
*/
|
|
238
|
+
using std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec_ = std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>;
|
|
239
|
+
std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec> create_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec_(void* NON_NULL swiftUnsafePointer) noexcept;
|
|
240
|
+
void* NON_NULL get_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec_(std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec_ cppType);
|
|
241
|
+
|
|
242
|
+
// pragma MARK: std::weak_ptr<margelo::nitro::image::HybridImageLoaderSpec>
|
|
243
|
+
using std__weak_ptr_margelo__nitro__image__HybridImageLoaderSpec_ = std::weak_ptr<margelo::nitro::image::HybridImageLoaderSpec>;
|
|
244
|
+
inline std__weak_ptr_margelo__nitro__image__HybridImageLoaderSpec_ weakify_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec_(const std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>& strong) noexcept { return strong; }
|
|
245
|
+
|
|
246
|
+
// pragma MARK: std::optional<ViewOptions>
|
|
247
|
+
/**
|
|
248
|
+
* Specialized version of `std::optional<ViewOptions>`.
|
|
249
|
+
*/
|
|
250
|
+
using std__optional_ViewOptions_ = std::optional<ViewOptions>;
|
|
251
|
+
inline std::optional<ViewOptions> create_std__optional_ViewOptions_(const ViewOptions& value) noexcept {
|
|
252
|
+
return std::optional<ViewOptions>(value);
|
|
253
|
+
}
|
|
254
|
+
inline bool has_value_std__optional_ViewOptions_(const std::optional<ViewOptions>& optional) noexcept {
|
|
255
|
+
return optional.has_value();
|
|
256
|
+
}
|
|
257
|
+
inline ViewOptions get_std__optional_ViewOptions_(const std::optional<ViewOptions>& optional) noexcept {
|
|
258
|
+
return optional.value();
|
|
259
|
+
}
|
|
260
|
+
|
|
226
261
|
// pragma MARK: std::shared_ptr<Promise<void>>
|
|
227
262
|
/**
|
|
228
263
|
* Specialized version of `std::shared_ptr<Promise<void>>`.
|
|
@@ -289,6 +324,15 @@ namespace margelo::nitro::nitroimagepipeline::bridge::swift {
|
|
|
289
324
|
return Result<std::shared_ptr<Promise<std::shared_ptr<margelo::nitro::image::HybridImageSpec>>>>::withError(error);
|
|
290
325
|
}
|
|
291
326
|
|
|
327
|
+
// pragma MARK: Result<std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>>
|
|
328
|
+
using Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__ = Result<std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>>;
|
|
329
|
+
inline Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__ create_Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__(const std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>& value) noexcept {
|
|
330
|
+
return Result<std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>>::withValue(value);
|
|
331
|
+
}
|
|
332
|
+
inline Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__ create_Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__(const std::exception_ptr& error) noexcept {
|
|
333
|
+
return Result<std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec>>::withError(error);
|
|
334
|
+
}
|
|
335
|
+
|
|
292
336
|
// pragma MARK: Result<std::shared_ptr<Promise<void>>>
|
|
293
337
|
using Result_std__shared_ptr_Promise_void___ = Result<std::shared_ptr<Promise<void>>>;
|
|
294
338
|
inline Result_std__shared_ptr_Promise_void___ create_Result_std__shared_ptr_Promise_void___(const std::shared_ptr<Promise<void>>& value) noexcept {
|
|
@@ -297,5 +341,14 @@ namespace margelo::nitro::nitroimagepipeline::bridge::swift {
|
|
|
297
341
|
inline Result_std__shared_ptr_Promise_void___ create_Result_std__shared_ptr_Promise_void___(const std::exception_ptr& error) noexcept {
|
|
298
342
|
return Result<std::shared_ptr<Promise<void>>>::withError(error);
|
|
299
343
|
}
|
|
344
|
+
|
|
345
|
+
// pragma MARK: Result<void>
|
|
346
|
+
using Result_void_ = Result<void>;
|
|
347
|
+
inline Result_void_ create_Result_void_() noexcept {
|
|
348
|
+
return Result<void>::withValue();
|
|
349
|
+
}
|
|
350
|
+
inline Result_void_ create_Result_void_(const std::exception_ptr& error) noexcept {
|
|
351
|
+
return Result<void>::withError(error);
|
|
352
|
+
}
|
|
300
353
|
|
|
301
354
|
} // namespace margelo::nitro::nitroimagepipeline::bridge::swift
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
13
13
|
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
14
14
|
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
15
|
+
// Forward declaration of `HybridImageLoaderSpec` to properly resolve imports.
|
|
16
|
+
namespace margelo::nitro::image { class HybridImageLoaderSpec; }
|
|
15
17
|
// Forward declaration of `HybridImageSpec` to properly resolve imports.
|
|
16
18
|
namespace margelo::nitro::image { class HybridImageSpec; }
|
|
17
19
|
// Forward declaration of `HybridNitroImagePipelineSpec` to properly resolve imports.
|
|
@@ -20,6 +22,8 @@ namespace margelo::nitro::nitroimagepipeline { class HybridNitroImagePipelineSpe
|
|
|
20
22
|
namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
21
23
|
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
22
24
|
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
25
|
+
// Forward declaration of `ViewOptions` to properly resolve imports.
|
|
26
|
+
namespace margelo::nitro::nitroimagepipeline { struct ViewOptions; }
|
|
23
27
|
|
|
24
28
|
// Include C++ defined types
|
|
25
29
|
#include "CacheOption.hpp"
|
|
@@ -27,6 +31,8 @@ namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
|
27
31
|
#include "HybridNitroImagePipelineSpec.hpp"
|
|
28
32
|
#include "Options.hpp"
|
|
29
33
|
#include "ResizeOptions.hpp"
|
|
34
|
+
#include "ViewOptions.hpp"
|
|
35
|
+
#include <NitroImage/HybridImageLoaderSpec.hpp>
|
|
30
36
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
31
37
|
#include <NitroModules/Promise.hpp>
|
|
32
38
|
#include <NitroModules/Result.hpp>
|
|
@@ -47,6 +53,8 @@ namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
|
47
53
|
#include <NitroModules/DateToChronoDate.hpp>
|
|
48
54
|
|
|
49
55
|
// Forward declarations of Swift defined types
|
|
56
|
+
// Forward declaration of `HybridImageLoaderSpec_cxx` to properly resolve imports.
|
|
57
|
+
namespace NitroImage { class HybridImageLoaderSpec_cxx; }
|
|
50
58
|
// Forward declaration of `HybridImageSpec_cxx` to properly resolve imports.
|
|
51
59
|
namespace NitroImage { class HybridImageSpec_cxx; }
|
|
52
60
|
// Forward declaration of `HybridNitroImagePipelineSpec_cxx` to properly resolve imports.
|
|
@@ -22,6 +22,10 @@ namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
|
22
22
|
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
23
23
|
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
24
24
|
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
25
|
+
// Forward declaration of `HybridImageLoaderSpec` to properly resolve imports.
|
|
26
|
+
namespace margelo::nitro::image { class HybridImageLoaderSpec; }
|
|
27
|
+
// Forward declaration of `ViewOptions` to properly resolve imports.
|
|
28
|
+
namespace margelo::nitro::nitroimagepipeline { struct ViewOptions; }
|
|
25
29
|
|
|
26
30
|
#include <memory>
|
|
27
31
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
@@ -33,6 +37,8 @@ namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
|
33
37
|
#include "CornerRadii.hpp"
|
|
34
38
|
#include <variant>
|
|
35
39
|
#include "ResizeOptions.hpp"
|
|
40
|
+
#include <NitroImage/HybridImageLoaderSpec.hpp>
|
|
41
|
+
#include "ViewOptions.hpp"
|
|
36
42
|
#include <vector>
|
|
37
43
|
|
|
38
44
|
#include "NitroImagePipeline-Swift-Cxx-Umbrella.hpp"
|
|
@@ -93,6 +99,14 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
93
99
|
auto __value = std::move(__result.value());
|
|
94
100
|
return __value;
|
|
95
101
|
}
|
|
102
|
+
inline std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec> createImageLoader(const std::string& url, const std::optional<ViewOptions>& options) override {
|
|
103
|
+
auto __result = _swiftPart.createImageLoader(url, options);
|
|
104
|
+
if (__result.hasError()) [[unlikely]] {
|
|
105
|
+
std::rethrow_exception(__result.error());
|
|
106
|
+
}
|
|
107
|
+
auto __value = std::move(__result.value());
|
|
108
|
+
return __value;
|
|
109
|
+
}
|
|
96
110
|
inline std::shared_ptr<Promise<void>> preLoadImage(const std::string& url) override {
|
|
97
111
|
auto __result = _swiftPart.preLoadImage(url);
|
|
98
112
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -117,6 +131,12 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
117
131
|
auto __value = std::move(__result.value());
|
|
118
132
|
return __value;
|
|
119
133
|
}
|
|
134
|
+
inline void setMemoryCacheLimit(double bytes) override {
|
|
135
|
+
auto __result = _swiftPart.setMemoryCacheLimit(std::forward<decltype(bytes)>(bytes));
|
|
136
|
+
if (__result.hasError()) [[unlikely]] {
|
|
137
|
+
std::rethrow_exception(__result.error());
|
|
138
|
+
}
|
|
139
|
+
}
|
|
120
140
|
inline std::shared_ptr<Promise<void>> clearCache() override {
|
|
121
141
|
auto __result = _swiftPart.clearCache();
|
|
122
142
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -15,9 +15,11 @@ public protocol HybridNitroImagePipelineSpec_protocol: HybridObject {
|
|
|
15
15
|
|
|
16
16
|
// Methods
|
|
17
17
|
func loadImage(url: String, options: Options?) throws -> Promise<(any HybridImageSpec)>
|
|
18
|
+
func createImageLoader(url: String, options: ViewOptions?) throws -> (any HybridImageLoaderSpec)
|
|
18
19
|
func preLoadImage(url: String) throws -> Promise<Void>
|
|
19
20
|
func preLoadImages(urls: [String]) throws -> Promise<Void>
|
|
20
21
|
func gaussianBlur(image: (any HybridImageSpec), radius: Double) throws -> Promise<(any HybridImageSpec)>
|
|
22
|
+
func setMemoryCacheLimit(bytes: Double) throws -> Void
|
|
21
23
|
func clearCache() throws -> Promise<Void>
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -147,6 +147,21 @@ open class HybridNitroImagePipelineSpec_cxx {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
@inline(__always)
|
|
151
|
+
public final func createImageLoader(url: std.string, options: bridge.std__optional_ViewOptions_) -> bridge.Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__ {
|
|
152
|
+
do {
|
|
153
|
+
let __result = try self.__implementation.createImageLoader(url: String(url), options: options.value)
|
|
154
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec_ in
|
|
155
|
+
let __cxxWrapped = __result.getCxxWrapper()
|
|
156
|
+
return __cxxWrapped.getCxxPart()
|
|
157
|
+
}()
|
|
158
|
+
return bridge.create_Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__(__resultCpp)
|
|
159
|
+
} catch (let __error) {
|
|
160
|
+
let __exceptionPtr = __error.toCpp()
|
|
161
|
+
return bridge.create_Result_std__shared_ptr_margelo__nitro__image__HybridImageLoaderSpec__(__exceptionPtr)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
150
165
|
@inline(__always)
|
|
151
166
|
public final func preLoadImage(url: std.string) -> bridge.Result_std__shared_ptr_Promise_void___ {
|
|
152
167
|
do {
|
|
@@ -211,6 +226,17 @@ open class HybridNitroImagePipelineSpec_cxx {
|
|
|
211
226
|
}
|
|
212
227
|
}
|
|
213
228
|
|
|
229
|
+
@inline(__always)
|
|
230
|
+
public final func setMemoryCacheLimit(bytes: Double) -> bridge.Result_void_ {
|
|
231
|
+
do {
|
|
232
|
+
try self.__implementation.setMemoryCacheLimit(bytes: bytes)
|
|
233
|
+
return bridge.create_Result_void_()
|
|
234
|
+
} catch (let __error) {
|
|
235
|
+
let __exceptionPtr = __error.toCpp()
|
|
236
|
+
return bridge.create_Result_void_(__exceptionPtr)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
214
240
|
@inline(__always)
|
|
215
241
|
public final func clearCache() -> bridge.Result_std__shared_ptr_Promise_void___ {
|
|
216
242
|
do {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ViewOptions.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 `ViewOptions`, backed by a C++ struct.
|
|
12
|
+
*/
|
|
13
|
+
public typealias ViewOptions = margelo.nitro.nitroimagepipeline.ViewOptions
|
|
14
|
+
|
|
15
|
+
public extension ViewOptions {
|
|
16
|
+
private typealias bridge = margelo.nitro.nitroimagepipeline.bridge.swift
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a new instance of `ViewOptions`.
|
|
20
|
+
*/
|
|
21
|
+
init(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?, resize: ResizeOptions?) {
|
|
22
|
+
self.init({ () -> bridge.std__optional_double_ in
|
|
23
|
+
if let __unwrappedValue = blur {
|
|
24
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
25
|
+
} else {
|
|
26
|
+
return .init()
|
|
27
|
+
}
|
|
28
|
+
}(), { () -> bridge.std__optional_CacheOption_ in
|
|
29
|
+
if let __unwrappedValue = cache {
|
|
30
|
+
return bridge.create_std__optional_CacheOption_(__unwrappedValue)
|
|
31
|
+
} else {
|
|
32
|
+
return .init()
|
|
33
|
+
}
|
|
34
|
+
}(), { () -> bridge.std__optional_std__variant_double__CornerRadii__ in
|
|
35
|
+
if let __unwrappedValue = cornerRadius {
|
|
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)
|
|
44
|
+
} else {
|
|
45
|
+
return .init()
|
|
46
|
+
}
|
|
47
|
+
}(), { () -> bridge.std__optional_ResizeOptions_ in
|
|
48
|
+
if let __unwrappedValue = resize {
|
|
49
|
+
return bridge.create_std__optional_ResizeOptions_(__unwrappedValue)
|
|
50
|
+
} else {
|
|
51
|
+
return .init()
|
|
52
|
+
}
|
|
53
|
+
}())
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@inline(__always)
|
|
57
|
+
var blur: Double? {
|
|
58
|
+
return { () -> Double? in
|
|
59
|
+
if bridge.has_value_std__optional_double_(self.__blur) {
|
|
60
|
+
let __unwrapped = bridge.get_std__optional_double_(self.__blur)
|
|
61
|
+
return __unwrapped
|
|
62
|
+
} else {
|
|
63
|
+
return nil
|
|
64
|
+
}
|
|
65
|
+
}()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@inline(__always)
|
|
69
|
+
var cache: CacheOption? {
|
|
70
|
+
return self.__cache.value
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@inline(__always)
|
|
74
|
+
var cornerRadius: Variant_Double_CornerRadii? {
|
|
75
|
+
return { () -> Variant_Double_CornerRadii? in
|
|
76
|
+
if bridge.has_value_std__optional_std__variant_double__CornerRadii__(self.__cornerRadius) {
|
|
77
|
+
let __unwrapped = bridge.get_std__optional_std__variant_double__CornerRadii__(self.__cornerRadius)
|
|
78
|
+
return { () -> Variant_Double_CornerRadii in
|
|
79
|
+
let __variant = bridge.std__variant_double__CornerRadii_(__unwrapped)
|
|
80
|
+
switch __variant.index() {
|
|
81
|
+
case 0:
|
|
82
|
+
let __actual = __variant.get_0()
|
|
83
|
+
return .first(__actual)
|
|
84
|
+
case 1:
|
|
85
|
+
let __actual = __variant.get_1()
|
|
86
|
+
return .second(__actual)
|
|
87
|
+
default:
|
|
88
|
+
fatalError("Variant can never have index \(__variant.index())!")
|
|
89
|
+
}
|
|
90
|
+
}()
|
|
91
|
+
} else {
|
|
92
|
+
return nil
|
|
93
|
+
}
|
|
94
|
+
}()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@inline(__always)
|
|
98
|
+
var resize: ResizeOptions? {
|
|
99
|
+
return self.__resize.value
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -15,9 +15,11 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
15
15
|
// load custom methods/properties
|
|
16
16
|
registerHybrids(this, [](Prototype& prototype) {
|
|
17
17
|
prototype.registerHybridMethod("loadImage", &HybridNitroImagePipelineSpec::loadImage);
|
|
18
|
+
prototype.registerHybridMethod("createImageLoader", &HybridNitroImagePipelineSpec::createImageLoader);
|
|
18
19
|
prototype.registerHybridMethod("preLoadImage", &HybridNitroImagePipelineSpec::preLoadImage);
|
|
19
20
|
prototype.registerHybridMethod("preLoadImages", &HybridNitroImagePipelineSpec::preLoadImages);
|
|
20
21
|
prototype.registerHybridMethod("gaussianBlur", &HybridNitroImagePipelineSpec::gaussianBlur);
|
|
22
|
+
prototype.registerHybridMethod("setMemoryCacheLimit", &HybridNitroImagePipelineSpec::setMemoryCacheLimit);
|
|
21
23
|
prototype.registerHybridMethod("clearCache", &HybridNitroImagePipelineSpec::clearCache);
|
|
22
24
|
});
|
|
23
25
|
}
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
namespace margelo::nitro::image { class HybridImageSpec; }
|
|
18
18
|
// Forward declaration of `Options` to properly resolve imports.
|
|
19
19
|
namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
20
|
+
// Forward declaration of `HybridImageLoaderSpec` to properly resolve imports.
|
|
21
|
+
namespace margelo::nitro::image { class HybridImageLoaderSpec; }
|
|
22
|
+
// Forward declaration of `ViewOptions` to properly resolve imports.
|
|
23
|
+
namespace margelo::nitro::nitroimagepipeline { struct ViewOptions; }
|
|
20
24
|
|
|
21
25
|
#include <memory>
|
|
22
26
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
@@ -24,6 +28,8 @@ namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
|
24
28
|
#include <string>
|
|
25
29
|
#include "Options.hpp"
|
|
26
30
|
#include <optional>
|
|
31
|
+
#include <NitroImage/HybridImageLoaderSpec.hpp>
|
|
32
|
+
#include "ViewOptions.hpp"
|
|
27
33
|
#include <vector>
|
|
28
34
|
|
|
29
35
|
namespace margelo::nitro::nitroimagepipeline {
|
|
@@ -58,9 +64,11 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
58
64
|
public:
|
|
59
65
|
// Methods
|
|
60
66
|
virtual std::shared_ptr<Promise<std::shared_ptr<margelo::nitro::image::HybridImageSpec>>> loadImage(const std::string& url, const std::optional<Options>& options) = 0;
|
|
67
|
+
virtual std::shared_ptr<margelo::nitro::image::HybridImageLoaderSpec> createImageLoader(const std::string& url, const std::optional<ViewOptions>& options) = 0;
|
|
61
68
|
virtual std::shared_ptr<Promise<void>> preLoadImage(const std::string& url) = 0;
|
|
62
69
|
virtual std::shared_ptr<Promise<void>> preLoadImages(const std::vector<std::string>& urls) = 0;
|
|
63
70
|
virtual std::shared_ptr<Promise<std::shared_ptr<margelo::nitro::image::HybridImageSpec>>> gaussianBlur(const std::shared_ptr<margelo::nitro::image::HybridImageSpec>& image, double radius) = 0;
|
|
71
|
+
virtual void setMemoryCacheLimit(double bytes) = 0;
|
|
64
72
|
virtual std::shared_ptr<Promise<void>> clearCache() = 0;
|
|
65
73
|
|
|
66
74
|
protected:
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ViewOptions.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
|
+
// Forward declaration of `CacheOption` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
33
|
+
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
34
|
+
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
35
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
36
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
37
|
+
|
|
38
|
+
#include <optional>
|
|
39
|
+
#include "CacheOption.hpp"
|
|
40
|
+
#include "CornerRadii.hpp"
|
|
41
|
+
#include <variant>
|
|
42
|
+
#include "ResizeOptions.hpp"
|
|
43
|
+
|
|
44
|
+
namespace margelo::nitro::nitroimagepipeline {
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A struct which can be represented as a JavaScript object (ViewOptions).
|
|
48
|
+
*/
|
|
49
|
+
struct ViewOptions final {
|
|
50
|
+
public:
|
|
51
|
+
std::optional<double> blur SWIFT_PRIVATE;
|
|
52
|
+
std::optional<CacheOption> cache SWIFT_PRIVATE;
|
|
53
|
+
std::optional<std::variant<double, CornerRadii>> cornerRadius SWIFT_PRIVATE;
|
|
54
|
+
std::optional<ResizeOptions> resize SWIFT_PRIVATE;
|
|
55
|
+
|
|
56
|
+
public:
|
|
57
|
+
ViewOptions() = default;
|
|
58
|
+
explicit ViewOptions(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<std::variant<double, CornerRadii>> cornerRadius, std::optional<ResizeOptions> resize): blur(blur), cache(cache), cornerRadius(cornerRadius), resize(resize) {}
|
|
59
|
+
|
|
60
|
+
public:
|
|
61
|
+
friend bool operator==(const ViewOptions& lhs, const ViewOptions& rhs) = default;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
} // namespace margelo::nitro::nitroimagepipeline
|
|
65
|
+
|
|
66
|
+
namespace margelo::nitro {
|
|
67
|
+
|
|
68
|
+
// C++ ViewOptions <> JS ViewOptions (object)
|
|
69
|
+
template <>
|
|
70
|
+
struct JSIConverter<margelo::nitro::nitroimagepipeline::ViewOptions> final {
|
|
71
|
+
static inline margelo::nitro::nitroimagepipeline::ViewOptions fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
72
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
73
|
+
return margelo::nitro::nitroimagepipeline::ViewOptions(
|
|
74
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur"))),
|
|
75
|
+
JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache"))),
|
|
76
|
+
JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"))),
|
|
77
|
+
JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "resize")))
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::ViewOptions& arg) {
|
|
81
|
+
jsi::Object obj(runtime);
|
|
82
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "blur"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.blur));
|
|
83
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cache"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::toJSI(runtime, arg.cache));
|
|
84
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"), JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::toJSI(runtime, arg.cornerRadius));
|
|
85
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "resize"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::toJSI(runtime, arg.resize));
|
|
86
|
+
return obj;
|
|
87
|
+
}
|
|
88
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
89
|
+
if (!value.isObject()) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
jsi::Object obj = value.getObject(runtime);
|
|
93
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur")))) return false;
|
|
97
|
+
if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache")))) return false;
|
|
98
|
+
if (!JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))) return false;
|
|
99
|
+
if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "resize")))) return false;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-image-pipeline",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.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",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"release": "semantic-release",
|
|
18
18
|
"build": "bun run typecheck && bob build",
|
|
19
19
|
"codegen": "nitrogen --logLevel=\"debug\" && bun run build",
|
|
20
|
-
"
|
|
20
|
+
"fixtures": "bun scripts/fixture-server.ts",
|
|
21
|
+
"verify:blur": "sh scripts/verify-blur.sh"
|
|
21
22
|
},
|
|
22
23
|
"keywords": [
|
|
23
24
|
"react-native",
|
|
@@ -83,7 +84,7 @@
|
|
|
83
84
|
"react": "*",
|
|
84
85
|
"react-native": "*",
|
|
85
86
|
"react-native-nitro-modules": "*",
|
|
86
|
-
"react-native-nitro-image": "0.15.1"
|
|
87
|
+
"react-native-nitro-image": ">=0.15.1 <0.16.0"
|
|
87
88
|
},
|
|
88
89
|
"overrides": {
|
|
89
90
|
"lodash-es": "4.17.21",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type ComponentRef, forwardRef } from 'react';
|
|
2
|
+
import type { HostComponent } from 'react-native';
|
|
3
|
+
import { NativeNitroImage } from 'react-native-nitro-image';
|
|
4
|
+
|
|
5
|
+
import { cornerRadiusForStyle } from './resizeForStyle';
|
|
6
|
+
import type {
|
|
7
|
+
CacheOption,
|
|
8
|
+
CornerRadii,
|
|
9
|
+
ResizeOptions,
|
|
10
|
+
} from './specs/nitro-image-toolkit.nitro';
|
|
11
|
+
import { usePipelineImageLoader } from './usePipelineImageLoader';
|
|
12
|
+
|
|
13
|
+
type ReactProps<T> = T extends HostComponent<infer P> ? P : never;
|
|
14
|
+
type NativeImageProps = ReactProps<typeof NativeNitroImage>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The instance `<NativePipelineImage>` exposes through its `ref` — the
|
|
18
|
+
* underlying `NativeNitroImage` host view, with the usual native-view
|
|
19
|
+
* methods (`measure`, …).
|
|
20
|
+
*/
|
|
21
|
+
export type NativePipelineImageRef = ComponentRef<typeof NativeNitroImage>;
|
|
22
|
+
|
|
23
|
+
export interface NativePipelineImageProps extends Omit<
|
|
24
|
+
NativeImageProps,
|
|
25
|
+
'image'
|
|
26
|
+
> {
|
|
27
|
+
/** URL of the image to load through the pipeline. */
|
|
28
|
+
url: string;
|
|
29
|
+
/**
|
|
30
|
+
* Gaussian blur sigma in **points** (density-independent), like
|
|
31
|
+
* `PipelineImage`. Applied natively with the screen scale.
|
|
32
|
+
* @default 0
|
|
33
|
+
*/
|
|
34
|
+
blur?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Corner radius in **points** — a single number or per-corner radii.
|
|
37
|
+
* When omitted, it's derived from `style`'s `borderRadius`-family
|
|
38
|
+
* properties instead — set this prop to override that.
|
|
39
|
+
* @default undefined (derived from `style`, or square corners if unset there)
|
|
40
|
+
*/
|
|
41
|
+
cornerRadius?: number | CornerRadii;
|
|
42
|
+
cache?: CacheOption;
|
|
43
|
+
/**
|
|
44
|
+
* Target bitmap size in **pixels**, overriding the size the native side
|
|
45
|
+
* measures from the view. Rarely needed.
|
|
46
|
+
* @default undefined (measure the view natively)
|
|
47
|
+
*/
|
|
48
|
+
resize?: ResizeOptions;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The fully native-driven variant of `PipelineImage`: after the first render
|
|
53
|
+
* there is **zero JS work per image**. The native view starts the request
|
|
54
|
+
* when it attaches to the window — at its own laid-out size, so nothing
|
|
55
|
+
* waits for an `onLayout` round trip — and cancels it (releasing the bitmap)
|
|
56
|
+
* when it detaches, which makes off-screen list cells free. Loads go through
|
|
57
|
+
* the same pipeline and caches as `useImage`/`preLoadImage`.
|
|
58
|
+
*
|
|
59
|
+
* Compared to `PipelineImage`:
|
|
60
|
+
* - No `onLoad`/`onError` callbacks — the loaded `Image` never crosses into
|
|
61
|
+
* JS. Use `PipelineImage` (or `useImage`) when you need them.
|
|
62
|
+
* - The bitmap is loaded once at the size the view first has; if the view is
|
|
63
|
+
* resized later, the bitmap scales with it instead of reloading.
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* <NativePipelineImage
|
|
67
|
+
* url="https://example.com/photo.jpg"
|
|
68
|
+
* style={{ width: 300, height: 200, borderRadius: 24 }}
|
|
69
|
+
* blur={4}
|
|
70
|
+
* />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export const NativePipelineImage = forwardRef<
|
|
74
|
+
NativePipelineImageRef,
|
|
75
|
+
NativePipelineImageProps
|
|
76
|
+
>(function NativePipelineImage(
|
|
77
|
+
{ url, blur, cornerRadius, cache, resize, style, ...viewProps },
|
|
78
|
+
ref,
|
|
79
|
+
) {
|
|
80
|
+
// Same precedence as PipelineImage: an explicit prop wins over style.
|
|
81
|
+
const effectiveCornerRadius = cornerRadius ?? cornerRadiusForStyle(style);
|
|
82
|
+
const loader = usePipelineImageLoader(url, {
|
|
83
|
+
blur,
|
|
84
|
+
cornerRadius: effectiveCornerRadius,
|
|
85
|
+
cache,
|
|
86
|
+
resize,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<NativeNitroImage
|
|
91
|
+
// Before the spread so a caller-provided recyclingKey wins.
|
|
92
|
+
recyclingKey={url}
|
|
93
|
+
{...viewProps}
|
|
94
|
+
ref={ref}
|
|
95
|
+
style={style}
|
|
96
|
+
image={loader}
|
|
97
|
+
/>
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Reanimated and DevTools read the display name; the forwardRef wrapper
|
|
102
|
+
// would otherwise report as anonymous.
|
|
103
|
+
NativePipelineImage.displayName = 'NativePipelineImage';
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export {
|
|
2
|
+
NativePipelineImage,
|
|
3
|
+
type NativePipelineImageProps,
|
|
4
|
+
type NativePipelineImageRef,
|
|
5
|
+
} from './NativePipelineImage';
|
|
1
6
|
export { NitroImagePipeline } from './NitroImagePipeline';
|
|
2
7
|
export {
|
|
3
8
|
PipelineImage,
|
|
@@ -14,5 +19,7 @@ export type {
|
|
|
14
19
|
CornerRadii,
|
|
15
20
|
Options,
|
|
16
21
|
ResizeOptions,
|
|
22
|
+
ViewOptions,
|
|
17
23
|
} from './specs/nitro-image-toolkit.nitro';
|
|
18
24
|
export { useImage } from './useImage';
|
|
25
|
+
export { usePipelineImageLoader } from './usePipelineImageLoader';
|