@shopify/react-native-skia 2.9.1 → 2.10.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 (220) hide show
  1. package/android/CMakeLists.txt +1 -5
  2. package/cpp/api/JsiNativeBuffer.h +15 -10
  3. package/cpp/api/JsiSkAnimatedImage.h +21 -19
  4. package/cpp/api/JsiSkAnimatedImageFactory.h +13 -14
  5. package/cpp/api/JsiSkApi.h +246 -92
  6. package/cpp/api/JsiSkCanvas.h +76 -58
  7. package/cpp/api/JsiSkColor.h +7 -5
  8. package/cpp/api/JsiSkColorFilter.h +15 -8
  9. package/cpp/api/JsiSkColorFilterFactory.h +45 -45
  10. package/cpp/api/JsiSkContourMeasure.h +24 -21
  11. package/cpp/api/JsiSkContourMeasureIter.h +18 -21
  12. package/cpp/api/JsiSkData.h +13 -7
  13. package/cpp/api/JsiSkDataFactory.h +22 -21
  14. package/cpp/api/JsiSkFont.h +56 -44
  15. package/cpp/api/JsiSkFontMgr.h +22 -13
  16. package/cpp/api/JsiSkFontMgrFactory.h +12 -10
  17. package/cpp/api/JsiSkFontStyle.h +14 -12
  18. package/cpp/api/JsiSkImage.h +45 -34
  19. package/cpp/api/JsiSkImageFactory.h +47 -52
  20. package/cpp/api/JsiSkImageFilter.h +21 -11
  21. package/cpp/api/JsiSkImageFilterFactory.h +96 -96
  22. package/cpp/api/JsiSkImageInfo.h +22 -19
  23. package/cpp/api/JsiSkMaskFilter.h +21 -11
  24. package/cpp/api/JsiSkMaskFilterFactory.h +16 -13
  25. package/cpp/api/JsiSkMatrix.h +31 -31
  26. package/cpp/api/JsiSkNativeObjects.h +419 -0
  27. package/cpp/api/JsiSkPaint.h +59 -39
  28. package/cpp/api/JsiSkParagraph.h +39 -32
  29. package/cpp/api/JsiSkParagraphBuilder.h +24 -21
  30. package/cpp/api/JsiSkParagraphBuilderFactory.h +13 -12
  31. package/cpp/api/JsiSkPath.h +95 -70
  32. package/cpp/api/JsiSkPathBuilder.h +83 -67
  33. package/cpp/api/JsiSkPathBuilderFactory.h +16 -17
  34. package/cpp/api/JsiSkPathEffect.h +21 -11
  35. package/cpp/api/JsiSkPathEffectFactory.h +33 -32
  36. package/cpp/api/JsiSkPathFactory.h +79 -103
  37. package/cpp/api/JsiSkPicture.h +24 -13
  38. package/cpp/api/JsiSkPictureFactory.h +21 -26
  39. package/cpp/api/JsiSkPictureRecorder.h +21 -22
  40. package/cpp/api/JsiSkPoint.h +19 -22
  41. package/cpp/api/JsiSkRRect.h +22 -29
  42. package/cpp/api/JsiSkRSXform.h +26 -30
  43. package/cpp/api/JsiSkRect.h +28 -30
  44. package/cpp/api/JsiSkRuntimeEffect.h +39 -30
  45. package/cpp/api/JsiSkRuntimeEffectFactory.h +12 -12
  46. package/cpp/api/JsiSkRuntimeShaderBuilder.h +25 -18
  47. package/cpp/api/JsiSkSVG.h +13 -13
  48. package/cpp/api/JsiSkSVGFactory.h +17 -20
  49. package/cpp/api/JsiSkShader.h +15 -8
  50. package/cpp/api/JsiSkShaderFactory.h +41 -48
  51. package/cpp/api/JsiSkSkottie.h +49 -39
  52. package/cpp/api/JsiSkSurface.h +24 -24
  53. package/cpp/api/JsiSkSurfaceFactory.h +15 -16
  54. package/cpp/api/JsiSkTextBlob.h +15 -8
  55. package/cpp/api/JsiSkTextBlobFactory.h +25 -28
  56. package/cpp/api/JsiSkTypeface.h +19 -12
  57. package/cpp/api/JsiSkTypefaceFactory.h +12 -12
  58. package/cpp/api/JsiSkTypefaceFontProvider.h +30 -25
  59. package/cpp/api/JsiSkTypefaceFontProviderFactory.h +14 -12
  60. package/cpp/api/JsiSkVertices.h +21 -18
  61. package/cpp/api/JsiSkiaContext.h +17 -17
  62. package/cpp/api/JsiSkottieFactory.h +16 -17
  63. package/cpp/api/JsiVideo.h +27 -25
  64. package/cpp/api/recorder/Convertor.h +31 -61
  65. package/cpp/api/recorder/DataTypes.h +8 -16
  66. package/cpp/api/recorder/JsiRecorder.h +83 -55
  67. package/cpp/api/recorder/RNRecorder.h +1 -1
  68. package/cpp/jsi/BoxedNativeObject.h +146 -0
  69. package/cpp/{jsi2 → jsi}/EnumMapper.h +4 -1
  70. package/cpp/{jsi2 → jsi}/NativeObject.h +120 -146
  71. package/cpp/jsi/RuntimeAwareCache.cpp +1 -1
  72. package/cpp/jsi/RuntimeAwareCache.h +26 -8
  73. package/cpp/jsi/ViewProperty.h +5 -11
  74. package/cpp/rnskia/RNSkJsiViewApi.h +20 -11
  75. package/cpp/rnskia/RNSkManager.cpp +23 -25
  76. package/cpp/rnskia/RNSkPictureView.h +1 -1
  77. package/cpp/rnwgpu/ArrayBuffer.h +5 -6
  78. package/cpp/rnwgpu/Canvas.h +4 -2
  79. package/cpp/rnwgpu/api/GPU.cpp +4 -4
  80. package/cpp/rnwgpu/api/GPU.h +1 -1
  81. package/cpp/rnwgpu/api/GPUAdapter.cpp +2 -3
  82. package/cpp/rnwgpu/api/GPUAdapter.h +4 -4
  83. package/cpp/rnwgpu/api/GPUAdapterInfo.h +1 -1
  84. package/cpp/rnwgpu/api/GPUBindGroup.h +1 -1
  85. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -1
  86. package/cpp/rnwgpu/api/GPUBuffer.h +1 -1
  87. package/cpp/rnwgpu/api/GPUCanvasContext.h +1 -1
  88. package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -1
  89. package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -1
  90. package/cpp/rnwgpu/api/GPUCompilationInfo.h +1 -1
  91. package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -1
  92. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -1
  93. package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -1
  94. package/cpp/rnwgpu/api/GPUDevice.cpp +6 -7
  95. package/cpp/rnwgpu/api/GPUDevice.h +3 -3
  96. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -1
  97. package/cpp/rnwgpu/api/GPUError.h +1 -1
  98. package/cpp/rnwgpu/api/GPUExtent3D.h +1 -1
  99. package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -1
  100. package/cpp/rnwgpu/api/GPUInternalError.h +1 -1
  101. package/cpp/rnwgpu/api/GPUOrigin2D.h +1 -1
  102. package/cpp/rnwgpu/api/GPUOrigin3D.h +1 -1
  103. package/cpp/rnwgpu/api/GPUOutOfMemoryError.h +1 -1
  104. package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -1
  105. package/cpp/rnwgpu/api/GPUQuerySet.h +1 -1
  106. package/cpp/rnwgpu/api/GPUQueue.h +1 -1
  107. package/cpp/rnwgpu/api/GPURenderBundle.h +1 -1
  108. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -1
  109. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -1
  110. package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -1
  111. package/cpp/rnwgpu/api/GPUSampler.h +1 -1
  112. package/cpp/rnwgpu/api/GPUShaderModule.cpp +1 -1
  113. package/cpp/rnwgpu/api/GPUShaderModule.h +1 -1
  114. package/cpp/rnwgpu/api/GPUSharedFence.h +1 -1
  115. package/cpp/rnwgpu/api/GPUSharedTextureMemory.h +1 -1
  116. package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -1
  117. package/cpp/rnwgpu/api/GPUTexture.h +1 -1
  118. package/cpp/rnwgpu/api/GPUTextureView.h +1 -1
  119. package/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h +1 -1
  120. package/cpp/rnwgpu/api/GPUValidationError.h +1 -1
  121. package/cpp/rnwgpu/api/ImageBitmap.h +1 -1
  122. package/cpp/rnwgpu/api/RNWebGPU.h +1 -1
  123. package/cpp/rnwgpu/api/descriptors/GPUBindGroupDescriptor.h +1 -1
  124. package/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h +1 -1
  125. package/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutDescriptor.h +1 -1
  126. package/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutEntry.h +1 -1
  127. package/cpp/rnwgpu/api/descriptors/GPUBlendComponent.h +1 -1
  128. package/cpp/rnwgpu/api/descriptors/GPUBlendState.h +1 -1
  129. package/cpp/rnwgpu/api/descriptors/GPUBufferBinding.h +1 -1
  130. package/cpp/rnwgpu/api/descriptors/GPUBufferBindingLayout.h +1 -1
  131. package/cpp/rnwgpu/api/descriptors/GPUBufferDescriptor.h +1 -1
  132. package/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h +1 -1
  133. package/cpp/rnwgpu/api/descriptors/GPUColor.h +1 -1
  134. package/cpp/rnwgpu/api/descriptors/GPUColorTargetState.h +1 -1
  135. package/cpp/rnwgpu/api/descriptors/GPUCommandBufferDescriptor.h +1 -1
  136. package/cpp/rnwgpu/api/descriptors/GPUCommandEncoderDescriptor.h +1 -1
  137. package/cpp/rnwgpu/api/descriptors/GPUComputePassDescriptor.h +1 -1
  138. package/cpp/rnwgpu/api/descriptors/GPUComputePassTimestampWrites.h +1 -1
  139. package/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h +1 -1
  140. package/cpp/rnwgpu/api/descriptors/GPUDawnTogglesDescriptor.h +1 -1
  141. package/cpp/rnwgpu/api/descriptors/GPUDepthStencilState.h +1 -1
  142. package/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h +1 -1
  143. package/cpp/rnwgpu/api/descriptors/GPUExternalTextureBindingLayout.h +1 -1
  144. package/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h +1 -1
  145. package/cpp/rnwgpu/api/descriptors/GPUFragmentState.h +1 -1
  146. package/cpp/rnwgpu/api/descriptors/GPUImageCopyBuffer.h +1 -1
  147. package/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +1 -1
  148. package/cpp/rnwgpu/api/descriptors/GPUImageCopyTexture.h +1 -1
  149. package/cpp/rnwgpu/api/descriptors/GPUImageCopyTextureTagged.h +1 -1
  150. package/cpp/rnwgpu/api/descriptors/GPUImageDataLayout.h +1 -1
  151. package/cpp/rnwgpu/api/descriptors/GPUMultisampleState.h +1 -1
  152. package/cpp/rnwgpu/api/descriptors/GPUPipelineLayoutDescriptor.h +1 -1
  153. package/cpp/rnwgpu/api/descriptors/GPUPrimitiveState.h +1 -1
  154. package/cpp/rnwgpu/api/descriptors/GPUProgrammableStage.h +1 -1
  155. package/cpp/rnwgpu/api/descriptors/GPUQuerySetDescriptor.h +1 -1
  156. package/cpp/rnwgpu/api/descriptors/GPUQueueDescriptor.h +1 -1
  157. package/cpp/rnwgpu/api/descriptors/GPURenderBundleDescriptor.h +1 -1
  158. package/cpp/rnwgpu/api/descriptors/GPURenderBundleEncoderDescriptor.h +1 -1
  159. package/cpp/rnwgpu/api/descriptors/GPURenderPassColorAttachment.h +1 -1
  160. package/cpp/rnwgpu/api/descriptors/GPURenderPassDepthStencilAttachment.h +1 -1
  161. package/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h +1 -1
  162. package/cpp/rnwgpu/api/descriptors/GPURenderPassTimestampWrites.h +1 -1
  163. package/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h +1 -1
  164. package/cpp/rnwgpu/api/descriptors/GPURequestAdapterOptions.h +1 -1
  165. package/cpp/rnwgpu/api/descriptors/GPUSamplerBindingLayout.h +1 -1
  166. package/cpp/rnwgpu/api/descriptors/GPUSamplerDescriptor.h +1 -1
  167. package/cpp/rnwgpu/api/descriptors/GPUShaderModuleCompilationHint.h +1 -1
  168. package/cpp/rnwgpu/api/descriptors/GPUShaderModuleDescriptor.h +1 -1
  169. package/cpp/rnwgpu/api/descriptors/GPUSharedFenceDescriptor.h +1 -1
  170. package/cpp/rnwgpu/api/descriptors/GPUSharedFenceState.h +1 -1
  171. package/cpp/rnwgpu/api/descriptors/GPUSharedTextureMemoryDescriptor.h +1 -1
  172. package/cpp/rnwgpu/api/descriptors/GPUStencilFaceState.h +1 -1
  173. package/cpp/rnwgpu/api/descriptors/GPUStorageTextureBindingLayout.h +1 -1
  174. package/cpp/rnwgpu/api/descriptors/GPUTextureBindingLayout.h +1 -1
  175. package/cpp/rnwgpu/api/descriptors/GPUTextureDescriptor.h +1 -1
  176. package/cpp/rnwgpu/api/descriptors/GPUTextureViewDescriptor.h +1 -1
  177. package/cpp/rnwgpu/api/descriptors/GPUUncapturedErrorEventInit.h +1 -1
  178. package/cpp/rnwgpu/api/descriptors/GPUVertexAttribute.h +1 -1
  179. package/cpp/rnwgpu/api/descriptors/GPUVertexBufferLayout.h +1 -1
  180. package/cpp/rnwgpu/api/descriptors/GPUVertexState.h +1 -1
  181. package/cpp/rnwgpu/api/descriptors/Unions.h +1 -1
  182. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +20 -21
  183. package/lib/commonjs/external/reanimated/renderHelpers.d.ts +15 -0
  184. package/lib/commonjs/external/reanimated/renderHelpers.js +30 -1
  185. package/lib/commonjs/external/reanimated/renderHelpers.js.map +1 -1
  186. package/lib/commonjs/skia/NativeSetup.js +4 -0
  187. package/lib/commonjs/skia/NativeSetup.js.map +1 -1
  188. package/lib/commonjs/skia/SkiaWorkletSerialization.d.ts +1 -0
  189. package/lib/commonjs/skia/SkiaWorkletSerialization.js +66 -0
  190. package/lib/commonjs/skia/SkiaWorkletSerialization.js.map +1 -0
  191. package/lib/commonjs/sksg/Container.native.js +20 -1
  192. package/lib/commonjs/sksg/Container.native.js.map +1 -1
  193. package/lib/module/external/reanimated/renderHelpers.d.ts +15 -0
  194. package/lib/module/external/reanimated/renderHelpers.js +29 -0
  195. package/lib/module/external/reanimated/renderHelpers.js.map +1 -1
  196. package/lib/module/skia/NativeSetup.js +4 -0
  197. package/lib/module/skia/NativeSetup.js.map +1 -1
  198. package/lib/module/skia/SkiaWorkletSerialization.d.ts +1 -0
  199. package/lib/module/skia/SkiaWorkletSerialization.js +59 -0
  200. package/lib/module/skia/SkiaWorkletSerialization.js.map +1 -0
  201. package/lib/module/sksg/Container.native.js +21 -2
  202. package/lib/module/sksg/Container.native.js.map +1 -1
  203. package/lib/typescript/lib/commonjs/external/reanimated/renderHelpers.d.ts +2 -0
  204. package/lib/typescript/lib/commonjs/skia/SkiaWorkletSerialization.d.ts +2 -0
  205. package/lib/typescript/lib/module/external/reanimated/renderHelpers.d.ts +15 -0
  206. package/lib/typescript/lib/module/skia/SkiaWorkletSerialization.d.ts +1 -0
  207. package/lib/typescript/src/external/reanimated/renderHelpers.d.ts +15 -0
  208. package/lib/typescript/src/skia/SkiaWorkletSerialization.d.ts +1 -0
  209. package/package.json +6 -2
  210. package/react-native-skia.podspec +1 -2
  211. package/src/external/reanimated/renderHelpers.ts +30 -0
  212. package/src/skia/NativeSetup.ts +5 -0
  213. package/src/skia/SkiaWorkletSerialization.ts +67 -0
  214. package/src/sksg/Container.native.ts +40 -2
  215. package/cpp/api/JsiSkHostObjects.h +0 -257
  216. package/cpp/jsi/JsiHostObject.cpp +0 -137
  217. package/cpp/jsi/JsiHostObject.h +0 -385
  218. /package/cpp/{jsi2 → jsi}/JSIConverter.h +0 -0
  219. /package/cpp/{jsi2 → jsi}/Promise.cpp +0 -0
  220. /package/cpp/{jsi2 → jsi}/Promise.h +0 -0
@@ -0,0 +1,146 @@
1
+ #pragma once
2
+
3
+ #include <functional>
4
+ #include <memory>
5
+ #include <mutex>
6
+ #include <stdexcept>
7
+ #include <string>
8
+ #include <unordered_map>
9
+ #include <utility>
10
+ #include <vector>
11
+
12
+ #include <jsi/jsi.h>
13
+
14
+ namespace RNJsi {
15
+
16
+ namespace jsi = facebook::jsi;
17
+
18
+ /**
19
+ * Registry mapping a NativeObject class brand (CLASS_NAME) to a reconstructor
20
+ * that can recreate a fully functional JS object (prototype + native state)
21
+ * on any runtime. This is what enables native objects (Skia and WebGPU) to
22
+ * travel between the React Native runtime and secondary runtimes (Reanimated
23
+ * worklets) via BoxedNativeObject.
24
+ */
25
+ class BoxedNativeObjectRegistry {
26
+ public:
27
+ using Reconstructor = std::function<jsi::Value(
28
+ jsi::Runtime &, std::shared_ptr<jsi::NativeState>)>;
29
+
30
+ static BoxedNativeObjectRegistry &getInstance() {
31
+ static BoxedNativeObjectRegistry instance;
32
+ return instance;
33
+ }
34
+
35
+ void registerClass(const std::string &brand, Reconstructor reconstructor) {
36
+ std::lock_guard<std::mutex> lock(_mutex);
37
+ // Brands are the unboxing key and must be unique process-wide; a silent
38
+ // overwrite would make one class unbox into another's reconstructor.
39
+ if (_reconstructors.count(brand) > 0) {
40
+ throw std::runtime_error("Duplicate native object brand registered: " +
41
+ brand);
42
+ }
43
+ _reconstructors[brand] = std::move(reconstructor);
44
+ }
45
+
46
+ jsi::Value reconstruct(jsi::Runtime &runtime, const std::string &brand,
47
+ std::shared_ptr<jsi::NativeState> state) {
48
+ Reconstructor reconstructor;
49
+ {
50
+ std::lock_guard<std::mutex> lock(_mutex);
51
+ auto it = _reconstructors.find(brand);
52
+ if (it == _reconstructors.end()) {
53
+ throw jsi::JSError(runtime,
54
+ "No native class registered for brand: " + brand);
55
+ }
56
+ reconstructor = it->second;
57
+ }
58
+ return reconstructor(runtime, std::move(state));
59
+ }
60
+
61
+ private:
62
+ BoxedNativeObjectRegistry() = default;
63
+ std::mutex _mutex;
64
+ std::unordered_map<std::string, Reconstructor> _reconstructors;
65
+ };
66
+
67
+ /**
68
+ * HostObject bridge used to move NativeObjects between runtimes.
69
+ *
70
+ * NativeObject-based values are plain JS objects carrying jsi::NativeState;
71
+ * worklets cannot serialize their prototype, so they are "boxed" into this
72
+ * HostObject (which worklets pass across runtimes by reference) and unboxed
73
+ * on the target runtime, where the prototype is re-installed from the class
74
+ * registry. See registerCustomSerializable in
75
+ * src/skia/SkiaWorkletSerialization.ts.
76
+ */
77
+ class BoxedNativeObject : public jsi::HostObject {
78
+ public:
79
+ BoxedNativeObject(std::shared_ptr<jsi::NativeState> state, std::string brand)
80
+ : _state(std::move(state)), _brand(std::move(brand)) {}
81
+
82
+ jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override {
83
+ auto propName = name.utf8(runtime);
84
+ if (propName == "unbox") {
85
+ auto state = _state;
86
+ auto brand = _brand;
87
+ return jsi::Function::createFromHostFunction(
88
+ runtime, jsi::PropNameID::forUtf8(runtime, "unbox"), 0,
89
+ [state, brand](jsi::Runtime &rt, const jsi::Value &,
90
+ const jsi::Value *, size_t) -> jsi::Value {
91
+ return BoxedNativeObjectRegistry::getInstance().reconstruct(
92
+ rt, brand, state);
93
+ });
94
+ }
95
+ if (propName == "__boxedNativeObject") {
96
+ return jsi::Value(true);
97
+ }
98
+ if (propName == "__brand") {
99
+ return jsi::String::createFromUtf8(runtime, _brand);
100
+ }
101
+ return jsi::Value::undefined();
102
+ }
103
+
104
+ void set(jsi::Runtime &runtime, const jsi::PropNameID &,
105
+ const jsi::Value &) override {
106
+ throw jsi::JSError(runtime, "Boxed native objects are read-only");
107
+ }
108
+
109
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override {
110
+ std::vector<jsi::PropNameID> names;
111
+ names.reserve(3);
112
+ names.push_back(jsi::PropNameID::forUtf8(rt, "unbox"));
113
+ names.push_back(jsi::PropNameID::forUtf8(rt, "__boxedNativeObject"));
114
+ names.push_back(jsi::PropNameID::forUtf8(rt, "__brand"));
115
+ return names;
116
+ }
117
+
118
+ private:
119
+ std::shared_ptr<jsi::NativeState> _state;
120
+ std::string _brand;
121
+ };
122
+
123
+ /**
124
+ * Boxes a NativeObject-backed JS value so it can be serialized by worklets
125
+ * and unboxed on another runtime.
126
+ */
127
+ inline jsi::Value boxNativeObject(jsi::Runtime &runtime,
128
+ const jsi::Value &value) {
129
+ if (!value.isObject()) {
130
+ throw jsi::JSError(runtime, "box() expects a native object");
131
+ }
132
+ auto object = value.asObject(runtime);
133
+ if (!object.hasNativeState(runtime)) {
134
+ throw jsi::JSError(runtime, "box() expects a native object");
135
+ }
136
+ auto brand = object.getProperty(runtime, "__typename__");
137
+ if (!brand.isString()) {
138
+ throw jsi::JSError(runtime, "box() expects a native object");
139
+ }
140
+ return jsi::Object::createFromHostObject(
141
+ runtime, std::make_shared<BoxedNativeObject>(
142
+ object.getNativeState(runtime),
143
+ brand.asString(runtime).utf8(runtime)));
144
+ }
145
+
146
+ } // namespace RNJsi
@@ -12,7 +12,10 @@ namespace EnumMapper {
12
12
  // outEnum)`
13
13
  // 2. `static void convertEnumToJSUnion(Enum inEnum, std::string* outUnion)`
14
14
 
15
- static std::runtime_error invalidUnion(const std::string &passedUnion) {
15
+ // inline (not static): this header is now included by every TU via
16
+ // NativeObject.h, and an unused file-scope static would trip
17
+ // -Werror=unused-function in non-Graphite builds.
18
+ inline std::runtime_error invalidUnion(const std::string &passedUnion) {
16
19
  return std::runtime_error(
17
20
  "Cannot convert JS Value to Enum: Invalid Union value passed! (\"" +
18
21
  std::string(passedUnion) + "\")");
@@ -14,6 +14,7 @@
14
14
  #include <unordered_map>
15
15
  #include <utility>
16
16
 
17
+ #include "jsi/BoxedNativeObject.h"
17
18
  #include "jsi/RuntimeAwareCache.h" // Use Skia's RuntimeAwareCache
18
19
 
19
20
  // Forward declare to avoid circular dependency
@@ -36,41 +37,6 @@ static constexpr size_t kMinMemoryPressure = 256;
36
37
  // Forward declaration
37
38
  template <typename Derived> class NativeObject;
38
39
 
39
- /**
40
- * Registry for NativeObject prototype installers.
41
- * This allows BoxedWebGPUObject::unbox() to install prototypes on any runtime
42
- * by looking up the brand name and calling the appropriate installer.
43
- */
44
- class NativeObjectRegistry {
45
- public:
46
- using InstallerFunc = std::function<void(jsi::Runtime &)>;
47
-
48
- static NativeObjectRegistry &getInstance() {
49
- static NativeObjectRegistry instance;
50
- return instance;
51
- }
52
-
53
- void registerInstaller(const std::string &brand, InstallerFunc installer) {
54
- std::lock_guard<std::mutex> lock(_mutex);
55
- _installers[brand] = std::move(installer);
56
- }
57
-
58
- bool installPrototype(jsi::Runtime &runtime, const std::string &brand) {
59
- std::lock_guard<std::mutex> lock(_mutex);
60
- auto it = _installers.find(brand);
61
- if (it != _installers.end()) {
62
- it->second(runtime);
63
- return true;
64
- }
65
- return false;
66
- }
67
-
68
- private:
69
- NativeObjectRegistry() = default;
70
- std::mutex _mutex;
71
- std::unordered_map<std::string, InstallerFunc> _installers;
72
- };
73
-
74
40
  /**
75
41
  * Per-runtime cache entry for a prototype object.
76
42
  * Uses std::optional<jsi::Object> so the prototype is stored directly
@@ -110,93 +76,6 @@ template <typename T> struct StaticRuntimeAwareCache {
110
76
  }
111
77
  };
112
78
 
113
- /**
114
- * BoxedWebGPUObject is a HostObject wrapper that holds a reference to ANY
115
- * WebGPU NativeObject. This is used for Reanimated/Worklets serialization.
116
- *
117
- * Since NativeObject uses NativeState (not HostObject), Worklets can't
118
- * serialize them directly. But Worklets CAN serialize HostObjects.
119
- *
120
- * This class stores:
121
- * - The NativeState from the original object
122
- * - The brand name for prototype reconstruction
123
- *
124
- * Usage pattern with registerCustomSerializable:
125
- * - pack(): Call WebGPU.box(obj) to create a BoxedWebGPUObject (HostObject)
126
- * - The HostObject is serialized by Worklets and transferred to UI runtime
127
- * - unpack(): Call boxed.unbox() to get back the original object with prototype
128
- *
129
- * This is similar to NitroModules.box()/unbox() pattern.
130
- */
131
- class BoxedWebGPUObject : public jsi::HostObject {
132
- public:
133
- BoxedWebGPUObject(std::shared_ptr<jsi::NativeState> nativeState,
134
- const std::string &brand)
135
- : _nativeState(std::move(nativeState)), _brand(brand) {}
136
-
137
- jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override {
138
- auto propName = name.utf8(runtime);
139
- if (propName == "unbox") {
140
- return jsi::Function::createFromHostFunction(
141
- runtime, jsi::PropNameID::forUtf8(runtime, "unbox"), 0,
142
- [this](jsi::Runtime &rt, const jsi::Value & /*thisVal*/,
143
- const jsi::Value * /*args*/, size_t /*count*/) -> jsi::Value {
144
- // Try to get the prototype from the global constructor
145
- auto ctor = rt.global().getProperty(rt, _brand.c_str());
146
- if (!ctor.isObject()) {
147
- // Constructor doesn't exist on this runtime - install it
148
- NativeObjectRegistry::getInstance().installPrototype(rt, _brand);
149
- ctor = rt.global().getProperty(rt, _brand.c_str());
150
- }
151
-
152
- // Create a new object and attach the native state
153
- jsi::Object obj(rt);
154
- obj.setNativeState(rt, _nativeState);
155
-
156
- // Set the prototype if constructor exists
157
- if (ctor.isObject()) {
158
- auto ctorObj = ctor.getObject(rt);
159
- auto proto = ctorObj.getProperty(rt, "prototype");
160
- if (proto.isObject()) {
161
- auto objectCtor = rt.global().getPropertyAsObject(rt, "Object");
162
- auto setPrototypeOf =
163
- objectCtor.getPropertyAsFunction(rt, "setPrototypeOf");
164
- setPrototypeOf.call(rt, obj, proto);
165
- }
166
- }
167
-
168
- return std::move(obj);
169
- });
170
- }
171
- if (propName == "__boxedWebGPU") {
172
- return jsi::Value(true);
173
- }
174
- if (propName == "__brand") {
175
- return jsi::String::createFromUtf8(runtime, _brand);
176
- }
177
- return jsi::Value::undefined();
178
- }
179
-
180
- void set(jsi::Runtime &runtime, const jsi::PropNameID &name,
181
- const jsi::Value &value) override {
182
- throw jsi::JSError(runtime, "BoxedWebGPUObject is read-only");
183
- }
184
-
185
- std::vector<jsi::PropNameID>
186
- getPropertyNames(jsi::Runtime &runtime) override {
187
- std::vector<jsi::PropNameID> names;
188
- names.reserve(3);
189
- names.push_back(jsi::PropNameID::forUtf8(runtime, "unbox"));
190
- names.push_back(jsi::PropNameID::forUtf8(runtime, "__boxedWebGPU"));
191
- names.push_back(jsi::PropNameID::forUtf8(runtime, "__brand"));
192
- return names;
193
- }
194
-
195
- private:
196
- std::shared_ptr<jsi::NativeState> _nativeState;
197
- std::string _brand;
198
- };
199
-
200
79
  /**
201
80
  * Base class for native objects using the NativeState pattern.
202
81
  *
@@ -237,6 +116,10 @@ public:
237
116
  * Each NativeObject<Derived> type has its own static cache.
238
117
  * Uses StaticRuntimeAwareCache to properly handle runtime lifecycle
239
118
  * and hot reload (where the main runtime is destroyed and recreated).
119
+ *
120
+ * Callers must hold getPrototypeCacheMutex(): the cache is reached
121
+ * concurrently from the main JS thread (create()) and from worklet
122
+ * runtime threads (BoxedNativeObject::unbox() -> installPrototype()).
240
123
  */
241
124
  static RNJsi::RuntimeAwareCache<PrototypeCacheEntry> &
242
125
  getPrototypeCache(jsi::Runtime &runtime) {
@@ -244,11 +127,22 @@ public:
244
127
  return cache.get(runtime);
245
128
  }
246
129
 
130
+ /**
131
+ * Per-class mutex guarding getPrototypeCache() and prototype
132
+ * installation. Serializes the StaticRuntimeAwareCache pointer swap
133
+ * (hot reload) and the per-runtime cache lookups.
134
+ */
135
+ static std::mutex &getPrototypeCacheMutex() {
136
+ static std::mutex mutex;
137
+ return mutex;
138
+ }
139
+
247
140
  /**
248
141
  * Ensure the prototype is installed for this runtime.
249
142
  * Called automatically by create(), but can be called manually.
250
143
  */
251
144
  static void installPrototype(jsi::Runtime &runtime) {
145
+ std::lock_guard<std::mutex> lock(getPrototypeCacheMutex());
252
146
  auto &entry = getPrototypeCache(runtime).get(runtime);
253
147
  if (entry.prototype.has_value()) {
254
148
  return; // Already installed
@@ -279,6 +173,95 @@ public:
279
173
  defineProperty.call(runtime, prototype, toStringTag, descriptor);
280
174
  }
281
175
 
176
+ // Install the shared pieces every native object needs for JS type
177
+ // detection and cross-runtime transfer (worklets):
178
+ // - `__typename__` (CLASS_NAME), used by JS type guards and as the
179
+ // boxing brand
180
+ // - `__box()`, which wraps the object into a RNJsi::BoxedNativeObject
181
+ // HostObject that worklets can pass across runtimes by reference
182
+ // See registerCustomSerializable in src/skia/SkiaWorkletSerialization.ts.
183
+ prototype.setProperty(
184
+ runtime, "__typename__",
185
+ jsi::String::createFromUtf8(runtime, Derived::CLASS_NAME));
186
+
187
+ auto boxFunc = jsi::Function::createFromHostFunction(
188
+ runtime, jsi::PropNameID::forUtf8(runtime, "__box"), 0,
189
+ [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *,
190
+ size_t) -> jsi::Value {
191
+ return RNJsi::boxNativeObject(rt, thisValue);
192
+ });
193
+ prototype.setProperty(runtime, "__box", boxFunc);
194
+
195
+ // Install a generic toJSON so JSON.stringify sees the data properties.
196
+ // They live on the prototype (getters), and JSON.stringify only
197
+ // serializes *own* enumerable properties — with the legacy HostObject
198
+ // pattern all properties were reported as own, so e.g.
199
+ // JSON.stringify(rect) used to produce {x, y, width, height,
200
+ // __typename__} and now would produce {} without this.
201
+ auto toJSONFunc = jsi::Function::createFromHostFunction(
202
+ runtime, jsi::PropNameID::forUtf8(runtime, "toJSON"), 0,
203
+ [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *,
204
+ size_t) -> jsi::Value {
205
+ if (!thisValue.isObject()) {
206
+ return jsi::Value::undefined();
207
+ }
208
+ auto self = thisValue.asObject(rt);
209
+ auto objectCtor = rt.global().getPropertyAsObject(rt, "Object");
210
+ auto getPrototypeOf =
211
+ objectCtor.getPropertyAsFunction(rt, "getPrototypeOf");
212
+ auto getOwnPropertyNames =
213
+ objectCtor.getPropertyAsFunction(rt, "getOwnPropertyNames");
214
+ auto proto = getPrototypeOf.call(rt, self);
215
+ jsi::Object result(rt);
216
+ if (proto.isObject()) {
217
+ auto names =
218
+ getOwnPropertyNames.call(rt, proto).asObject(rt).asArray(rt);
219
+ auto size = names.size(rt);
220
+ for (size_t i = 0; i < size; i++) {
221
+ auto name = names.getValueAtIndex(rt, i).asString(rt).utf8(rt);
222
+ if (name == "constructor" || name == "toJSON") {
223
+ continue;
224
+ }
225
+ auto value = self.getProperty(rt, name.c_str());
226
+ // Skip methods (dispose, __box, ...) — JSON.stringify would
227
+ // drop them anyway; skipping avoids serializing them at all.
228
+ if (value.isObject() && value.asObject(rt).isFunction(rt)) {
229
+ continue;
230
+ }
231
+ result.setProperty(rt, name.c_str(), value);
232
+ }
233
+ }
234
+ return result;
235
+ });
236
+ prototype.setProperty(runtime, "toJSON", toJSONFunc);
237
+
238
+ // Register the reconstructor used by BoxedNativeObject::unbox() to
239
+ // rebuild this object (prototype + native state) on another runtime.
240
+ static std::once_flag boxingRegistered;
241
+ std::call_once(boxingRegistered, []() {
242
+ RNJsi::BoxedNativeObjectRegistry::getInstance().registerClass(
243
+ Derived::CLASS_NAME,
244
+ [](jsi::Runtime &rt,
245
+ std::shared_ptr<jsi::NativeState> state) -> jsi::Value {
246
+ auto instance = std::dynamic_pointer_cast<Derived>(state);
247
+ if (instance == nullptr) {
248
+ throw jsi::JSError(rt, "Invalid boxed native object state");
249
+ }
250
+ // Unboxing creates a *view* of the object on the target runtime.
251
+ // Keep the runtime the object was originally created on: async
252
+ // native code (e.g. GPUDevice error/lost events) delivers into
253
+ // the creation runtime, and rebinding it to a worklet runtime
254
+ // would invoke main-runtime jsi::Functions on the wrong runtime
255
+ // and thread.
256
+ auto *originalRuntime = instance->getCreationRuntime();
257
+ auto value = Derived::create(rt, instance);
258
+ if (originalRuntime != nullptr) {
259
+ instance->setCreationRuntime(originalRuntime);
260
+ }
261
+ return value;
262
+ });
263
+ });
264
+
282
265
  // Cache the prototype
283
266
  entry.prototype = std::move(prototype);
284
267
  }
@@ -289,22 +272,11 @@ public:
289
272
  *
290
273
  * The constructor throws if called directly (these objects are only
291
274
  * created internally by the native code).
292
- *
293
- * Also registers this class with NativeObjectRegistry so that
294
- * BoxedWebGPUObject::unbox() can install prototypes on secondary runtimes.
295
275
  */
296
276
  static void installConstructor(jsi::Runtime &runtime) {
297
- // Register this class's installer in the registry (only needs to happen
298
- // once)
299
- static std::once_flag registryFlag;
300
- std::call_once(registryFlag, []() {
301
- NativeObjectRegistry::getInstance().registerInstaller(
302
- Derived::CLASS_NAME,
303
- [](jsi::Runtime &rt) { Derived::installConstructor(rt); });
304
- });
305
-
306
277
  installPrototype(runtime);
307
278
 
279
+ std::lock_guard<std::mutex> lock(getPrototypeCacheMutex());
308
280
  auto &entry = getPrototypeCache(runtime).get(runtime);
309
281
  if (!entry.prototype.has_value()) {
310
282
  return;
@@ -348,13 +320,17 @@ public:
348
320
  obj.setNativeState(runtime, instance);
349
321
 
350
322
  // Set prototype
351
- auto &entry = getPrototypeCache(runtime).get(runtime);
352
- if (entry.prototype.has_value()) {
353
- // Use Object.setPrototypeOf to set the prototype
354
- auto objectCtor = runtime.global().getPropertyAsObject(runtime, "Object");
355
- auto setPrototypeOf =
356
- objectCtor.getPropertyAsFunction(runtime, "setPrototypeOf");
357
- setPrototypeOf.call(runtime, obj, *entry.prototype);
323
+ {
324
+ std::lock_guard<std::mutex> lock(getPrototypeCacheMutex());
325
+ auto &entry = getPrototypeCache(runtime).get(runtime);
326
+ if (entry.prototype.has_value()) {
327
+ // Use Object.setPrototypeOf to set the prototype
328
+ auto objectCtor =
329
+ runtime.global().getPropertyAsObject(runtime, "Object");
330
+ auto setPrototypeOf =
331
+ objectCtor.getPropertyAsFunction(runtime, "setPrototypeOf");
332
+ setPrototypeOf.call(runtime, obj, *entry.prototype);
333
+ }
358
334
  }
359
335
 
360
336
  // Set memory pressure hint for GC
@@ -438,11 +414,9 @@ protected:
438
414
  * (e.g. GPU::requestAdapter, which creates a per-runtime RuntimeContext).
439
415
  */
440
416
  template <typename ReturnType, typename... Args>
441
- static void
442
- installMethodWithRuntime(jsi::Runtime &runtime, jsi::Object &prototype,
443
- const char *name,
444
- ReturnType (Derived::*method)(jsi::Runtime &,
445
- Args...)) {
417
+ static void installMethodWithRuntime(
418
+ jsi::Runtime &runtime, jsi::Object &prototype, const char *name,
419
+ ReturnType (Derived::*method)(jsi::Runtime &, Args...)) {
446
420
  auto func = jsi::Function::createFromHostFunction(
447
421
  runtime, jsi::PropNameID::forUtf8(runtime, name), sizeof...(Args),
448
422
  [method](jsi::Runtime &rt, const jsi::Value &thisVal,
@@ -2,6 +2,6 @@
2
2
 
3
3
  namespace RNJsi {
4
4
 
5
- jsi::Runtime *BaseRuntimeAwareCache::_mainRuntime = nullptr;
5
+ std::atomic<jsi::Runtime *> BaseRuntimeAwareCache::_mainRuntime{nullptr};
6
6
 
7
7
  } // namespace RNJsi
@@ -2,7 +2,9 @@
2
2
 
3
3
  #include <jsi/jsi.h>
4
4
 
5
+ #include <atomic>
5
6
  #include <memory>
7
+ #include <mutex>
6
8
  #include <unordered_map>
7
9
  #include <utility>
8
10
 
@@ -14,17 +16,21 @@ namespace jsi = facebook::jsi;
14
16
 
15
17
  class BaseRuntimeAwareCache {
16
18
  public:
17
- static void setMainJsRuntime(jsi::Runtime *rt) { _mainRuntime = rt; }
19
+ static void setMainJsRuntime(jsi::Runtime *rt) {
20
+ // Atomic: hot reload rewrites this from the JS thread while worklet
21
+ // runtime threads read it concurrently.
22
+ _mainRuntime.store(rt, std::memory_order_release);
23
+ }
18
24
  static jsi::Runtime *getMainJsRuntime() {
19
- assert(_mainRuntime != nullptr &&
20
- "Expected main Javascript runtime to be set in the "
21
- "BaseRuntimeAwareCache class.");
25
+ auto *rt = _mainRuntime.load(std::memory_order_acquire);
26
+ assert(rt != nullptr && "Expected main Javascript runtime to be set in the "
27
+ "BaseRuntimeAwareCache class.");
22
28
 
23
- return _mainRuntime;
29
+ return rt;
24
30
  }
25
31
 
26
32
  private:
27
- static jsi::Runtime *_mainRuntime;
33
+ static std::atomic<jsi::Runtime *> _mainRuntime;
28
34
  };
29
35
 
30
36
  /**
@@ -55,7 +61,10 @@ class RuntimeAwareCache : public BaseRuntimeAwareCache,
55
61
  public:
56
62
  void onRuntimeDestroyed(jsi::Runtime *rt) override {
57
63
  if (getMainJsRuntime() != rt) {
58
- // We are removing a secondary runtime
64
+ // We are removing a secondary runtime. This is invoked by
65
+ // RuntimeLifecycleMonitor on the destroyed runtime's thread, which may
66
+ // run concurrently with get() on another runtime's thread.
67
+ std::lock_guard<std::mutex> lock(_secondaryCachesMutex);
59
68
  _secondaryRuntimeCaches.erase(rt);
60
69
  }
61
70
  }
@@ -74,6 +83,14 @@ public:
74
83
  if (getMainJsRuntime() == &rt) {
75
84
  return _primaryCache;
76
85
  } else {
86
+ // Guard the secondary map: it can be mutated concurrently by get()
87
+ // on a worklet runtime's thread and by onRuntimeDestroyed() when
88
+ // another secondary runtime is torn down. The main-runtime path above
89
+ // stays lock-free. References into the map remain valid after the
90
+ // lock is released (unordered_map never invalidates references on
91
+ // insert/erase of other keys, and this runtime's entry can only be
92
+ // erased from this runtime's own thread).
93
+ std::lock_guard<std::mutex> lock(_secondaryCachesMutex);
77
94
  if (_secondaryRuntimeCaches.count(&rt) == 0) {
78
95
  // we only add listener when the secondary runtime is used, this assumes
79
96
  // that the secondary runtime is terminated first. This lets us avoid
@@ -87,11 +104,12 @@ public:
87
104
  T cache;
88
105
  _secondaryRuntimeCaches.emplace(&rt, std::move(cache));
89
106
  }
107
+ return _secondaryRuntimeCaches.at(&rt);
90
108
  }
91
- return _secondaryRuntimeCaches.at(&rt);
92
109
  }
93
110
 
94
111
  private:
112
+ std::mutex _secondaryCachesMutex;
95
113
  std::unordered_map<void *, T> _secondaryRuntimeCaches;
96
114
  T _primaryCache;
97
115
  };
@@ -7,8 +7,8 @@
7
7
  #include <string>
8
8
  #include <variant>
9
9
 
10
- #include "api/JsiSkPicture.h"
11
10
  #include "RuntimeLifecycleMonitor.h"
11
+ #include "api/JsiSkPicture.h"
12
12
 
13
13
  namespace RNJsi {
14
14
  namespace jsi = facebook::jsi;
@@ -38,16 +38,10 @@ private:
38
38
  class ViewProperty {
39
39
  public:
40
40
  ViewProperty(jsi::Runtime &runtime, const jsi::Value &value) {
41
- if (value.isObject()) {
42
- auto object = value.asObject(runtime);
43
- if (object.isHostObject(runtime)) {
44
- auto hostObject = object.asHostObject(runtime);
45
- auto jsiPicture =
46
- std::dynamic_pointer_cast<RNSkia::JsiSkPicture>(hostObject);
47
- if (jsiPicture) {
48
- _value = jsiPicture->getObject();
49
- }
50
- }
41
+ auto jsiPicture =
42
+ RNSkia::tryGetJsiObject<RNSkia::JsiSkPicture>(runtime, value);
43
+ if (jsiPicture) {
44
+ _value = jsiPicture->getObject();
51
45
  }
52
46
  }
53
47
 
@@ -13,7 +13,8 @@
13
13
  #include "RNSkPictureView.h"
14
14
  #include "RNSkPlatformContext.h"
15
15
  #include "RNSkView.h"
16
- #include "jsi/JsiHostObject.h"
16
+ #include "api/JsiSkNativeObjects.h"
17
+ #include "jsi/JsiPromises.h"
17
18
  #include "jsi/ViewProperty.h"
18
19
  #include <jsi/jsi.h>
19
20
 
@@ -92,9 +93,10 @@ private:
92
93
  std::unordered_set<size_t> _unregistered;
93
94
  };
94
95
 
95
- class RNSkJsiViewApi : public RNJsi::JsiHostObject,
96
- public std::enable_shared_from_this<RNSkJsiViewApi> {
96
+ class RNSkJsiViewApi : public JsiSkNativeObject<RNSkJsiViewApi> {
97
97
  public:
98
+ static constexpr const char *CLASS_NAME = "ViewApi";
99
+
98
100
  /**
99
101
  Sets a custom property on a view given a view id. The property name/value
100
102
  will be stored in a map alongside the id of the view and propagated to the
@@ -199,7 +201,7 @@ public:
199
201
  "Could not create image from current surface.");
200
202
  return jsi::Value::undefined();
201
203
  }
202
- return jsi::Object::createFromHostObject(
204
+ return makeJsiObject(
203
205
  runtime, std::make_shared<JsiSkImage>(_platformContext, image));
204
206
  }
205
207
  throw jsi::JSError(runtime, "No Skia View currently available.");
@@ -245,7 +247,7 @@ public:
245
247
  promise->reject("Failed to make snapshot from view.");
246
248
  return;
247
249
  }
248
- promise->resolve(jsi::Object::createFromHostObject(
250
+ promise->resolve(makeJsiObject(
249
251
  runtime, std::make_shared<JsiSkImage>(std::move(context),
250
252
  std::move(image))));
251
253
  });
@@ -286,18 +288,25 @@ public:
286
288
  return sizeObj;
287
289
  }
288
290
 
289
- JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(RNSkJsiViewApi, setJsiProperty),
290
- JSI_EXPORT_FUNC(RNSkJsiViewApi, requestRedraw),
291
- JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshotAsync),
292
- JSI_EXPORT_FUNC(RNSkJsiViewApi, makeImageSnapshot),
293
- JSI_EXPORT_FUNC(RNSkJsiViewApi, size))
291
+ static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
292
+ installHostMethod(runtime, prototype, "setJsiProperty",
293
+ &RNSkJsiViewApi::setJsiProperty);
294
+ installHostMethod(runtime, prototype, "requestRedraw",
295
+ &RNSkJsiViewApi::requestRedraw);
296
+ installHostMethod(runtime, prototype, "makeImageSnapshotAsync",
297
+ &RNSkJsiViewApi::makeImageSnapshotAsync);
298
+ installHostMethod(runtime, prototype, "makeImageSnapshot",
299
+ &RNSkJsiViewApi::makeImageSnapshot);
300
+ installHostMethod(runtime, prototype, "size", &RNSkJsiViewApi::size);
301
+ }
294
302
 
295
303
  /**
296
304
  * Constructor
297
305
  * @param platformContext Platform context
298
306
  */
299
307
  explicit RNSkJsiViewApi(std::shared_ptr<RNSkPlatformContext> platformContext)
300
- : JsiHostObject(), _platformContext(platformContext) {}
308
+ : JsiSkNativeObject<RNSkJsiViewApi>(platformContext),
309
+ _platformContext(platformContext) {}
301
310
 
302
311
  /**
303
312
  Call to remove all draw view infos