@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
@@ -2,7 +2,7 @@
2
2
 
3
3
  #include <string>
4
4
 
5
- #include "jsi2/EnumMapper.h"
5
+ #include "jsi/EnumMapper.h"
6
6
  #include "rnwgpu/api/External.h"
7
7
  #include "webgpu/webgpu_cpp.h"
8
8
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  #include <ReactCommon/CallInvoker.h>
8
8
 
9
- #include "jsi2/Promise.h"
9
+ #include "jsi/Promise.h"
10
10
 
11
11
  #include "RuntimeContext.h"
12
12
 
@@ -96,11 +96,11 @@ void AsyncTaskHandle::State::schedule(Action action) {
96
96
  auto self = shared_from_this();
97
97
 
98
98
  if (!keepPumping) {
99
- // Spontaneous task (e.g. device.lost): not driven by the ProcessEvents pump.
100
- // Settle on the owning runtime's JS thread via its CallInvoker, which is
101
- // wired only for the main JS runtime. A device created on a worklet runtime
102
- // has no invoker, so its device.lost is dropped (best-effort; see the
103
- // Threading model). invokeAsync runs the closure on the main JS thread,
99
+ // Spontaneous task (e.g. device.lost): not driven by the ProcessEvents
100
+ // pump. Settle on the owning runtime's JS thread via its CallInvoker, which
101
+ // is wired only for the main JS runtime. A device created on a worklet
102
+ // runtime has no invoker, so its device.lost is dropped (best-effort; see
103
+ // the Threading model). invokeAsync runs the closure on the main JS thread,
104
104
  // where promiseRef->runtime lives for a main-runtime device.
105
105
  auto invoker = context->callInvoker();
106
106
  if (invoker) {
@@ -119,21 +119,20 @@ void AsyncTaskHandle::State::schedule(Action action) {
119
119
 
120
120
  // Pumping task (request/response op). The resolve/reject callback may fire on
121
121
  // a thread that is NOT the owning runtime's thread: with a shared
122
- // wgpu::Instance, another runtime's ProcessEvents() pump can consume this Dawn
123
- // event. Touching the Promise's runtime off-thread would corrupt Hermes. So we
124
- // deposit the actual settle (the only JSI-touching work) into the owning
125
- // context's mailbox; the context drains it on its own thread during its next
126
- // tick. The deposited closure captures only C++ state and runs no JSI until
127
- // drained, so depositing from any thread is safe.
128
- context->postSettle(
129
- [self, action = std::move(action), promiseRef]() mutable {
130
- action(promiseRef->runtime, *promiseRef);
131
- if (self->context) {
132
- self->context->onTaskSettled(/*keepPumping=*/true);
133
- }
134
- std::lock_guard<std::mutex> lock(self->mutex);
135
- self->keepAlive.reset();
136
- });
122
+ // wgpu::Instance, another runtime's ProcessEvents() pump can consume this
123
+ // Dawn event. Touching the Promise's runtime off-thread would corrupt Hermes.
124
+ // So we deposit the actual settle (the only JSI-touching work) into the
125
+ // owning context's mailbox; the context drains it on its own thread during
126
+ // its next tick. The deposited closure captures only C++ state and runs no
127
+ // JSI until drained, so depositing from any thread is safe.
128
+ context->postSettle([self, action = std::move(action), promiseRef]() mutable {
129
+ action(promiseRef->runtime, *promiseRef);
130
+ if (self->context) {
131
+ self->context->onTaskSettled(/*keepPumping=*/true);
132
+ }
133
+ std::lock_guard<std::mutex> lock(self->mutex);
134
+ self->keepAlive.reset();
135
+ });
137
136
  }
138
137
 
139
138
  AsyncTaskHandle::ResolveFunction
@@ -1 +1,16 @@
1
1
  export declare let HAS_REANIMATED_3: boolean;
2
+ /**
3
+ * True when the worklets-based Reanimated integration is available
4
+ * (Reanimated 4 with react-native-worklets providing
5
+ * registerCustomSerializable). Skia objects use the JSI NativeState pattern
6
+ * and can only be transferred to worklet runtimes through a custom
7
+ * serializer, so on native the Reanimated integration requires Reanimated 4 —
8
+ * Reanimated 3 is not supported.
9
+ */
10
+ export declare let HAS_REANIMATED_4: boolean;
11
+ /**
12
+ * Major version of the installed react-native-reanimated package, or null if
13
+ * it is not installed. Used to give actionable diagnostics when the
14
+ * integration cannot be enabled.
15
+ */
16
+ export declare let REANIMATED_VERSION_MAJOR: number | null;
@@ -3,8 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.HAS_REANIMATED_3 = void 0;
6
+ exports.REANIMATED_VERSION_MAJOR = exports.HAS_REANIMATED_4 = exports.HAS_REANIMATED_3 = void 0;
7
7
  let HAS_REANIMATED_3 = exports.HAS_REANIMATED_3 = false;
8
+
9
+ /**
10
+ * True when the worklets-based Reanimated integration is available
11
+ * (Reanimated 4 with react-native-worklets providing
12
+ * registerCustomSerializable). Skia objects use the JSI NativeState pattern
13
+ * and can only be transferred to worklet runtimes through a custom
14
+ * serializer, so on native the Reanimated integration requires Reanimated 4 —
15
+ * Reanimated 3 is not supported.
16
+ */
17
+ let HAS_REANIMATED_4 = exports.HAS_REANIMATED_4 = false;
18
+
19
+ /**
20
+ * Major version of the installed react-native-reanimated package, or null if
21
+ * it is not installed. Used to give actionable diagnostics when the
22
+ * integration cannot be enabled.
23
+ */
24
+ let REANIMATED_VERSION_MAJOR = exports.REANIMATED_VERSION_MAJOR = null;
8
25
  try {
9
26
  // This logic is convoluted but necessary
10
27
  // In most systems, `require("react-native-reanimated")` throws an error, all is well.
@@ -15,6 +32,18 @@ try {
15
32
  if (reanimatedVersion && (reanimatedVersion >= "3.0.0" || reanimatedVersion.includes("3.0.0-"))) {
16
33
  exports.HAS_REANIMATED_3 = HAS_REANIMATED_3 = true;
17
34
  }
35
+ const majorVersion = parseInt(reanimatedVersion.split(".")[0], 10);
36
+ if (!isNaN(majorVersion)) {
37
+ exports.REANIMATED_VERSION_MAJOR = REANIMATED_VERSION_MAJOR = majorVersion;
38
+ }
39
+ if (majorVersion >= 4) {
40
+ try {
41
+ const worklets = require("react-native-worklets");
42
+ exports.HAS_REANIMATED_4 = HAS_REANIMATED_4 = typeof worklets.registerCustomSerializable === "function";
43
+ } catch (e) {
44
+ // react-native-worklets not installed
45
+ }
46
+ }
18
47
  } catch (e) {
19
48
  // do nothing
20
49
  }
@@ -1 +1 @@
1
- {"version":3,"names":["HAS_REANIMATED_3","exports","reanimatedVersion","require","version","includes","e"],"sources":["renderHelpers.ts"],"sourcesContent":["export let HAS_REANIMATED_3 = false;\n\ntry {\n // This logic is convoluted but necessary\n // In most systems, `require(\"react-native-reanimated\")` throws an error, all is well.\n // In webpack, in some configuration it will return an empty object.\n // So it will not throw an error and we need to check the version to know if it's there.\n const reanimatedVersion =\n require(\"react-native-reanimated/package.json\").version;\n require(\"react-native-reanimated\");\n if (\n reanimatedVersion &&\n (reanimatedVersion >= \"3.0.0\" || reanimatedVersion.includes(\"3.0.0-\"))\n ) {\n HAS_REANIMATED_3 = true;\n }\n} catch (e) {\n // do nothing\n}\n"],"mappings":";;;;;;AAAO,IAAIA,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,KAAK;AAEnC,IAAI;EACF;EACA;EACA;EACA;EACA,MAAME,iBAAiB,GACrBC,OAAO,CAAC,sCAAsC,CAAC,CAACC,OAAO;EACzDD,OAAO,CAAC,yBAAyB,CAAC;EAClC,IACED,iBAAiB,KAChBA,iBAAiB,IAAI,OAAO,IAAIA,iBAAiB,CAACG,QAAQ,CAAC,QAAQ,CAAC,CAAC,EACtE;IACAJ,OAAA,CAAAD,gBAAA,GAAAA,gBAAgB,GAAG,IAAI;EACzB;AACF,CAAC,CAAC,OAAOM,CAAC,EAAE;EACV;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["HAS_REANIMATED_3","exports","HAS_REANIMATED_4","REANIMATED_VERSION_MAJOR","reanimatedVersion","require","version","includes","majorVersion","parseInt","split","isNaN","worklets","registerCustomSerializable","e"],"sources":["renderHelpers.ts"],"sourcesContent":["export let HAS_REANIMATED_3 = false;\n\n/**\n * True when the worklets-based Reanimated integration is available\n * (Reanimated 4 with react-native-worklets providing\n * registerCustomSerializable). Skia objects use the JSI NativeState pattern\n * and can only be transferred to worklet runtimes through a custom\n * serializer, so on native the Reanimated integration requires Reanimated 4 —\n * Reanimated 3 is not supported.\n */\nexport let HAS_REANIMATED_4 = false;\n\n/**\n * Major version of the installed react-native-reanimated package, or null if\n * it is not installed. Used to give actionable diagnostics when the\n * integration cannot be enabled.\n */\nexport let REANIMATED_VERSION_MAJOR: number | null = null;\n\ntry {\n // This logic is convoluted but necessary\n // In most systems, `require(\"react-native-reanimated\")` throws an error, all is well.\n // In webpack, in some configuration it will return an empty object.\n // So it will not throw an error and we need to check the version to know if it's there.\n const reanimatedVersion =\n require(\"react-native-reanimated/package.json\").version;\n require(\"react-native-reanimated\");\n if (\n reanimatedVersion &&\n (reanimatedVersion >= \"3.0.0\" || reanimatedVersion.includes(\"3.0.0-\"))\n ) {\n HAS_REANIMATED_3 = true;\n }\n const majorVersion = parseInt(reanimatedVersion.split(\".\")[0], 10);\n if (!isNaN(majorVersion)) {\n REANIMATED_VERSION_MAJOR = majorVersion;\n }\n if (majorVersion >= 4) {\n try {\n const worklets = require(\"react-native-worklets\");\n HAS_REANIMATED_4 =\n typeof worklets.registerCustomSerializable === \"function\";\n } catch (e) {\n // react-native-worklets not installed\n }\n }\n} catch (e) {\n // do nothing\n}\n"],"mappings":";;;;;;AAAO,IAAIA,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,KAAK;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,IAAIE,gBAAgB,GAAAD,OAAA,CAAAC,gBAAA,GAAG,KAAK;;AAEnC;AACA;AACA;AACA;AACA;AACO,IAAIC,wBAAuC,GAAAF,OAAA,CAAAE,wBAAA,GAAG,IAAI;AAEzD,IAAI;EACF;EACA;EACA;EACA;EACA,MAAMC,iBAAiB,GACrBC,OAAO,CAAC,sCAAsC,CAAC,CAACC,OAAO;EACzDD,OAAO,CAAC,yBAAyB,CAAC;EAClC,IACED,iBAAiB,KAChBA,iBAAiB,IAAI,OAAO,IAAIA,iBAAiB,CAACG,QAAQ,CAAC,QAAQ,CAAC,CAAC,EACtE;IACAN,OAAA,CAAAD,gBAAA,GAAAA,gBAAgB,GAAG,IAAI;EACzB;EACA,MAAMQ,YAAY,GAAGC,QAAQ,CAACL,iBAAiB,CAACM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;EAClE,IAAI,CAACC,KAAK,CAACH,YAAY,CAAC,EAAE;IACxBP,OAAA,CAAAE,wBAAA,GAAAA,wBAAwB,GAAGK,YAAY;EACzC;EACA,IAAIA,YAAY,IAAI,CAAC,EAAE;IACrB,IAAI;MACF,MAAMI,QAAQ,GAAGP,OAAO,CAAC,uBAAuB,CAAC;MACjDJ,OAAA,CAAAC,gBAAA,GAAAA,gBAAgB,GACd,OAAOU,QAAQ,CAACC,0BAA0B,KAAK,UAAU;IAC7D,CAAC,CAAC,OAAOC,CAAC,EAAE;MACV;IAAA;EAEJ;AACF,CAAC,CAAC,OAAOA,CAAC,EAAE;EACV;AAAA","ignoreList":[]}
@@ -2,6 +2,7 @@
2
2
 
3
3
  var _Platform = require("../Platform");
4
4
  var _NativeSkiaModule = _interopRequireDefault(require("../specs/NativeSkiaModule"));
5
+ var _SkiaWorkletSerialization = require("./SkiaWorkletSerialization");
5
6
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
6
7
  if (_Platform.Platform.OS !== "web" && global.SkiaApi == null) {
7
8
  // Initialize RN Skia
@@ -13,5 +14,8 @@ if (_Platform.Platform.OS !== "web" && global.SkiaApi == null) {
13
14
  if (result !== true) {
14
15
  throw new Error(`Native Skia Module failed to correctly install JSI Bindings! Result: ${result}`);
15
16
  }
17
+ // Skia objects use the JSI NativeState pattern and need a custom
18
+ // serializer to be transferable to worklet runtimes (Reanimated).
19
+ (0, _SkiaWorkletSerialization.registerSkiaWorkletSerialization)();
16
20
  }
17
21
  //# sourceMappingURL=NativeSetup.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_Platform","require","_NativeSkiaModule","_interopRequireDefault","e","__esModule","default","Platform","OS","global","SkiaApi","SkiaModule","NativeSkiaModule","install","Error","result"],"sources":["NativeSetup.ts"],"sourcesContent":["import { Platform } from \"../Platform\";\nimport NativeSkiaModule from \"../specs/NativeSkiaModule\";\n\nif (Platform.OS !== \"web\" && global.SkiaApi == null) {\n // Initialize RN Skia\n const SkiaModule = NativeSkiaModule;\n if (SkiaModule == null || typeof SkiaModule.install !== \"function\") {\n throw new Error(\n \"Native RNSkia Module cannot be found! Make sure you correctly \" +\n \"installed native dependencies and rebuilt your app.\"\n );\n }\n const result = SkiaModule.install();\n if (result !== true) {\n throw new Error(\n `Native Skia Module failed to correctly install JSI Bindings! Result: ${result}`\n );\n }\n}\n"],"mappings":";;AAAA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,iBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAAyD,SAAAE,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEzD,IAAIG,kBAAQ,CAACC,EAAE,KAAK,KAAK,IAAIC,MAAM,CAACC,OAAO,IAAI,IAAI,EAAE;EACnD;EACA,MAAMC,UAAU,GAAGC,yBAAgB;EACnC,IAAID,UAAU,IAAI,IAAI,IAAI,OAAOA,UAAU,CAACE,OAAO,KAAK,UAAU,EAAE;IAClE,MAAM,IAAIC,KAAK,CACb,gEAAgE,GAC9D,qDACJ,CAAC;EACH;EACA,MAAMC,MAAM,GAAGJ,UAAU,CAACE,OAAO,CAAC,CAAC;EACnC,IAAIE,MAAM,KAAK,IAAI,EAAE;IACnB,MAAM,IAAID,KAAK,CACb,wEAAwEC,MAAM,EAChF,CAAC;EACH;AACF","ignoreList":[]}
1
+ {"version":3,"names":["_Platform","require","_NativeSkiaModule","_interopRequireDefault","_SkiaWorkletSerialization","e","__esModule","default","Platform","OS","global","SkiaApi","SkiaModule","NativeSkiaModule","install","Error","result","registerSkiaWorkletSerialization"],"sources":["NativeSetup.ts"],"sourcesContent":["import { Platform } from \"../Platform\";\nimport NativeSkiaModule from \"../specs/NativeSkiaModule\";\n\nimport { registerSkiaWorkletSerialization } from \"./SkiaWorkletSerialization\";\n\nif (Platform.OS !== \"web\" && global.SkiaApi == null) {\n // Initialize RN Skia\n const SkiaModule = NativeSkiaModule;\n if (SkiaModule == null || typeof SkiaModule.install !== \"function\") {\n throw new Error(\n \"Native RNSkia Module cannot be found! Make sure you correctly \" +\n \"installed native dependencies and rebuilt your app.\"\n );\n }\n const result = SkiaModule.install();\n if (result !== true) {\n throw new Error(\n `Native Skia Module failed to correctly install JSI Bindings! Result: ${result}`\n );\n }\n // Skia objects use the JSI NativeState pattern and need a custom\n // serializer to be transferable to worklet runtimes (Reanimated).\n registerSkiaWorkletSerialization();\n}\n"],"mappings":";;AAAA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,iBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAEA,IAAAG,yBAAA,GAAAH,OAAA;AAA8E,SAAAE,uBAAAE,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE9E,IAAIG,kBAAQ,CAACC,EAAE,KAAK,KAAK,IAAIC,MAAM,CAACC,OAAO,IAAI,IAAI,EAAE;EACnD;EACA,MAAMC,UAAU,GAAGC,yBAAgB;EACnC,IAAID,UAAU,IAAI,IAAI,IAAI,OAAOA,UAAU,CAACE,OAAO,KAAK,UAAU,EAAE;IAClE,MAAM,IAAIC,KAAK,CACb,gEAAgE,GAC9D,qDACJ,CAAC;EACH;EACA,MAAMC,MAAM,GAAGJ,UAAU,CAACE,OAAO,CAAC,CAAC;EACnC,IAAIE,MAAM,KAAK,IAAI,EAAE;IACnB,MAAM,IAAID,KAAK,CACb,wEAAwEC,MAAM,EAChF,CAAC;EACH;EACA;EACA;EACA,IAAAC,0DAAgC,EAAC,CAAC;AACpC","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export declare const registerSkiaWorkletSerialization: () => void;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.registerSkiaWorkletSerialization = void 0;
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+
9
+ /**
10
+ * Skia and WebGPU API objects are implemented with the JSI NativeState
11
+ * pattern: plain JS objects with a shared prototype and native state
12
+ * attached. Worklets cannot serialize such objects by default (the prototype
13
+ * would be lost when moving them to another runtime), so we register a
14
+ * Custom Serializable that:
15
+ *
16
+ * - determine: detects native objects via the `__box` method installed on
17
+ * every Skia and WebGPU prototype (plain objects never reach the
18
+ * custom-serializable path, so this cannot misfire on user data).
19
+ * - pack: boxes the object into a HostObject wrapper that carries the native
20
+ * state and the class brand. HostObjects are transferred by reference.
21
+ * - unpack: unboxes on the target runtime, re-installing the class prototype
22
+ * there and re-attaching the same native state.
23
+ *
24
+ * See cpp/jsi/BoxedNativeObject.h for the native side.
25
+ *
26
+ * `react-native-worklets` (Reanimated 4) is required for this to work —
27
+ * without it, Skia and WebGPU objects cannot be captured in worklets or
28
+ * stored in shared values.
29
+ */
30
+
31
+ const determine = value => {
32
+ "worklet";
33
+
34
+ return typeof value.__box === "function";
35
+ };
36
+ const pack = value => {
37
+ "worklet";
38
+
39
+ return value.__box();
40
+ };
41
+ const unpack = packed => {
42
+ "worklet";
43
+
44
+ return packed.unbox();
45
+ };
46
+ const registerSkiaWorkletSerialization = () => {
47
+ try {
48
+ const worklets = require("react-native-worklets");
49
+ if (typeof worklets.registerCustomSerializable === "function") {
50
+ worklets.registerCustomSerializable({
51
+ name: "ReactNativeSkia",
52
+ determine,
53
+ pack,
54
+ unpack
55
+ });
56
+ } else {
57
+ console.error("React Native Skia requires react-native-worklets >= 0.7.0 " + "(registerCustomSerializable) to use Skia objects inside worklets. " + "Please upgrade react-native-worklets and react-native-reanimated.");
58
+ }
59
+ } catch (e) {
60
+ // react-native-worklets is not installed. This is fine for apps that do
61
+ // not use Reanimated: Skia objects simply cannot be used inside worklets
62
+ // or shared values in this configuration.
63
+ }
64
+ };
65
+ exports.registerSkiaWorkletSerialization = registerSkiaWorkletSerialization;
66
+ //# sourceMappingURL=SkiaWorkletSerialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["determine","value","__box","pack","unpack","packed","unbox","registerSkiaWorkletSerialization","worklets","require","registerCustomSerializable","name","console","error","e","exports"],"sources":["SkiaWorkletSerialization.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Skia and WebGPU API objects are implemented with the JSI NativeState\n * pattern: plain JS objects with a shared prototype and native state\n * attached. Worklets cannot serialize such objects by default (the prototype\n * would be lost when moving them to another runtime), so we register a\n * Custom Serializable that:\n *\n * - determine: detects native objects via the `__box` method installed on\n * every Skia and WebGPU prototype (plain objects never reach the\n * custom-serializable path, so this cannot misfire on user data).\n * - pack: boxes the object into a HostObject wrapper that carries the native\n * state and the class brand. HostObjects are transferred by reference.\n * - unpack: unboxes on the target runtime, re-installing the class prototype\n * there and re-attaching the same native state.\n *\n * See cpp/jsi/BoxedNativeObject.h for the native side.\n *\n * `react-native-worklets` (Reanimated 4) is required for this to work —\n * without it, Skia and WebGPU objects cannot be captured in worklets or\n * stored in shared values.\n */\n\ninterface BoxedNativeObject {\n unbox: () => object;\n __boxedNativeObject: true;\n}\n\nconst determine = (value: object): value is object => {\n \"worklet\";\n return typeof (value as any).__box === \"function\";\n};\n\nconst pack = (value: object): BoxedNativeObject => {\n \"worklet\";\n return (value as any).__box();\n};\n\nconst unpack = (packed: BoxedNativeObject): object => {\n \"worklet\";\n return packed.unbox();\n};\n\nexport const registerSkiaWorkletSerialization = () => {\n try {\n const worklets = require(\"react-native-worklets\");\n if (typeof worklets.registerCustomSerializable === \"function\") {\n worklets.registerCustomSerializable({\n name: \"ReactNativeSkia\",\n determine,\n pack,\n unpack,\n });\n } else {\n console.error(\n \"React Native Skia requires react-native-worklets >= 0.7.0 \" +\n \"(registerCustomSerializable) to use Skia objects inside worklets. \" +\n \"Please upgrade react-native-worklets and react-native-reanimated.\"\n );\n }\n } catch (e) {\n // react-native-worklets is not installed. This is fine for apps that do\n // not use Reanimated: Skia objects simply cannot be used inside worklets\n // or shared values in this configuration.\n }\n};\n"],"mappings":";;;;;;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA,MAAMA,SAAS,GAAIC,KAAa,IAAsB;EACpD,SAAS;;EACT,OAAO,OAAQA,KAAK,CAASC,KAAK,KAAK,UAAU;AACnD,CAAC;AAED,MAAMC,IAAI,GAAIF,KAAa,IAAwB;EACjD,SAAS;;EACT,OAAQA,KAAK,CAASC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAME,MAAM,GAAIC,MAAyB,IAAa;EACpD,SAAS;;EACT,OAAOA,MAAM,CAACC,KAAK,CAAC,CAAC;AACvB,CAAC;AAEM,MAAMC,gCAAgC,GAAGA,CAAA,KAAM;EACpD,IAAI;IACF,MAAMC,QAAQ,GAAGC,OAAO,CAAC,uBAAuB,CAAC;IACjD,IAAI,OAAOD,QAAQ,CAACE,0BAA0B,KAAK,UAAU,EAAE;MAC7DF,QAAQ,CAACE,0BAA0B,CAAC;QAClCC,IAAI,EAAE,iBAAiB;QACvBX,SAAS;QACTG,IAAI;QACJC;MACF,CAAC,CAAC;IACJ,CAAC,MAAM;MACLQ,OAAO,CAACC,KAAK,CACX,4DAA4D,GAC1D,oEAAoE,GACpE,mEACJ,CAAC;IACH;EACF,CAAC,CAAC,OAAOC,CAAC,EAAE;IACV;IACA;IACA;EAAA;AAEJ,CAAC;AAACC,OAAA,CAAAR,gCAAA,GAAAA,gCAAA","ignoreList":[]}
@@ -79,10 +79,29 @@ class NativeReanimatedContainer extends _StaticContainer.Container {
79
79
  }
80
80
  }
81
81
  }
82
+ let hasWarnedAboutReanimatedSupport = false;
83
+ const reanimatedSupportError = () => {
84
+ if (_renderHelpers.REANIMATED_VERSION_MAJOR !== null && _renderHelpers.REANIMATED_VERSION_MAJOR >= 4) {
85
+ return "React Native Skia requires react-native-worklets >= 0.7.0 for its " + "Reanimated integration on native platforms. Reanimated 4 is " + "installed, but react-native-worklets is missing or too old. " + "Please install or upgrade react-native-worklets.";
86
+ }
87
+ return "React Native Skia requires Reanimated 4 (react-native-worklets >= " + "0.7.0) for its Reanimated integration on native platforms. " + "Reanimated 3 is not supported anymore: Skia objects cannot be used " + "inside worklets or shared values with it. " + "Please upgrade to react-native-reanimated >= 4.0.0.";
88
+ };
82
89
  const createContainer = (Skia, nativeId) => {
83
- if (_renderHelpers.HAS_REANIMATED_3 && nativeId !== -1) {
90
+ if (_renderHelpers.HAS_REANIMATED_4 && nativeId !== -1) {
84
91
  return new NativeReanimatedContainer(Skia, nativeId);
85
92
  } else {
93
+ if (_renderHelpers.HAS_REANIMATED_3 && !_renderHelpers.HAS_REANIMATED_4) {
94
+ const message = reanimatedSupportError();
95
+ if (__DEV__) {
96
+ // Fail loudly in development — a silent fallback to static rendering
97
+ // would only be noticed as frozen animations.
98
+ throw new Error(message);
99
+ }
100
+ if (!hasWarnedAboutReanimatedSupport) {
101
+ hasWarnedAboutReanimatedSupport = true;
102
+ console.error(`${message} Falling back to static rendering (animations will not run).`);
103
+ }
104
+ }
86
105
  return new _StaticContainer.StaticContainer(Skia, nativeId);
87
106
  }
88
107
  };
@@ -1 +1 @@
1
- {"version":3,"names":["_ReanimatedProxy","_interopRequireDefault","require","_renderHelpers","_ReanimatedRecorder","_StaticContainer","_Visitor","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","SkiaViewApi","globalThis","nativeDrawOnscreen","nativeId","recorder","picture","play","setJsiProperty","NativeReanimatedContainer","Container","constructor","Skia","Picture","MakePicture","unmount","mapperId","Rea","stopMapper","redraw","unmounted","ReanimatedRecorder","visit","root","sharedValues","getSharedValues","sharedRecorder","getRecorder","runOnUI","length","startMapper","applyUpdates","createContainer","HAS_REANIMATED_3","StaticContainer","exports"],"sources":["Container.native.ts"],"sourcesContent":["import Rea from \"../external/reanimated/ReanimatedProxy\";\nimport type { Skia, SkPicture } from \"../skia/types\";\nimport { HAS_REANIMATED_3 } from \"../external/reanimated/renderHelpers\";\nimport type { JsiRecorder } from \"../skia/types/Recorder\";\n\nimport { ReanimatedRecorder } from \"./Recorder/ReanimatedRecorder\";\nimport { Container, StaticContainer } from \"./StaticContainer\";\nimport { visit } from \"./Recorder/Visitor\";\n\nimport \"../skia/NativeSetup\";\nimport \"../views/api\";\n\n// create local reference for `strictGlobal` option in Worklets\nconst { SkiaViewApi } = globalThis;\n\nconst nativeDrawOnscreen = (\n nativeId: number,\n recorder: JsiRecorder,\n picture: SkPicture\n) => {\n \"worklet\";\n\n //const start = performance.now();\n recorder.play(picture);\n //const end = performance.now();\n //console.log(\"Recording time: \", end - start);\n SkiaViewApi.setJsiProperty(nativeId, \"picture\", picture);\n};\n\nclass NativeReanimatedContainer extends Container {\n private mapperId: number | null = null;\n private picture: SkPicture;\n\n constructor(\n Skia: Skia,\n private nativeId: number\n ) {\n super(Skia);\n this.picture = Skia.Picture.MakePicture(null)!;\n }\n\n unmount() {\n super.unmount();\n if (this.mapperId !== null) {\n // The mapper closure retains the recorder and its resources (e.g.\n // images) on the UI runtime and keeps updating the picture of an\n // unmounted view — stop it or it leaks for the lifetime of the app.\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n }\n\n redraw() {\n if (this.mapperId !== null) {\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n if (this.unmounted) {\n return;\n }\n const recorder = new ReanimatedRecorder(this.Skia);\n const { nativeId, picture } = this;\n visit(recorder, this.root);\n const sharedValues = recorder.getSharedValues();\n const sharedRecorder = recorder.getRecorder();\n // Draw first frame\n Rea.runOnUI(() => {\n \"worklet\";\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n })();\n // Animate\n if (sharedValues.length > 0) {\n this.mapperId = Rea.startMapper(() => {\n \"worklet\";\n sharedRecorder.applyUpdates(sharedValues);\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n }, sharedValues);\n }\n }\n}\n\nexport const createContainer = (Skia: Skia, nativeId: number) => {\n if (HAS_REANIMATED_3 && nativeId !== -1) {\n return new NativeReanimatedContainer(Skia, nativeId);\n } else {\n return new StaticContainer(Skia, nativeId);\n }\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_ReanimatedProxy","_interopRequireDefault","require","_renderHelpers","_ReanimatedRecorder","_StaticContainer","_Visitor","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","SkiaViewApi","globalThis","nativeDrawOnscreen","nativeId","recorder","picture","play","setJsiProperty","NativeReanimatedContainer","Container","constructor","Skia","Picture","MakePicture","unmount","mapperId","Rea","stopMapper","redraw","unmounted","ReanimatedRecorder","visit","root","sharedValues","getSharedValues","sharedRecorder","getRecorder","runOnUI","length","startMapper","applyUpdates","hasWarnedAboutReanimatedSupport","reanimatedSupportError","REANIMATED_VERSION_MAJOR","createContainer","HAS_REANIMATED_4","HAS_REANIMATED_3","message","__DEV__","Error","console","error","StaticContainer","exports"],"sources":["Container.native.ts"],"sourcesContent":["import Rea from \"../external/reanimated/ReanimatedProxy\";\nimport type { Skia, SkPicture } from \"../skia/types\";\nimport {\n HAS_REANIMATED_3,\n HAS_REANIMATED_4,\n REANIMATED_VERSION_MAJOR,\n} from \"../external/reanimated/renderHelpers\";\nimport type { JsiRecorder } from \"../skia/types/Recorder\";\n\nimport { ReanimatedRecorder } from \"./Recorder/ReanimatedRecorder\";\nimport { Container, StaticContainer } from \"./StaticContainer\";\nimport { visit } from \"./Recorder/Visitor\";\n\nimport \"../skia/NativeSetup\";\nimport \"../views/api\";\n\n// create local reference for `strictGlobal` option in Worklets\nconst { SkiaViewApi } = globalThis;\n\nconst nativeDrawOnscreen = (\n nativeId: number,\n recorder: JsiRecorder,\n picture: SkPicture\n) => {\n \"worklet\";\n\n //const start = performance.now();\n recorder.play(picture);\n //const end = performance.now();\n //console.log(\"Recording time: \", end - start);\n SkiaViewApi.setJsiProperty(nativeId, \"picture\", picture);\n};\n\nclass NativeReanimatedContainer extends Container {\n private mapperId: number | null = null;\n private picture: SkPicture;\n\n constructor(\n Skia: Skia,\n private nativeId: number\n ) {\n super(Skia);\n this.picture = Skia.Picture.MakePicture(null)!;\n }\n\n unmount() {\n super.unmount();\n if (this.mapperId !== null) {\n // The mapper closure retains the recorder and its resources (e.g.\n // images) on the UI runtime and keeps updating the picture of an\n // unmounted view — stop it or it leaks for the lifetime of the app.\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n }\n\n redraw() {\n if (this.mapperId !== null) {\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n if (this.unmounted) {\n return;\n }\n const recorder = new ReanimatedRecorder(this.Skia);\n const { nativeId, picture } = this;\n visit(recorder, this.root);\n const sharedValues = recorder.getSharedValues();\n const sharedRecorder = recorder.getRecorder();\n // Draw first frame\n Rea.runOnUI(() => {\n \"worklet\";\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n })();\n // Animate\n if (sharedValues.length > 0) {\n this.mapperId = Rea.startMapper(() => {\n \"worklet\";\n sharedRecorder.applyUpdates(sharedValues);\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n }, sharedValues);\n }\n }\n}\n\nlet hasWarnedAboutReanimatedSupport = false;\n\nconst reanimatedSupportError = () => {\n if (REANIMATED_VERSION_MAJOR !== null && REANIMATED_VERSION_MAJOR >= 4) {\n return (\n \"React Native Skia requires react-native-worklets >= 0.7.0 for its \" +\n \"Reanimated integration on native platforms. Reanimated 4 is \" +\n \"installed, but react-native-worklets is missing or too old. \" +\n \"Please install or upgrade react-native-worklets.\"\n );\n }\n return (\n \"React Native Skia requires Reanimated 4 (react-native-worklets >= \" +\n \"0.7.0) for its Reanimated integration on native platforms. \" +\n \"Reanimated 3 is not supported anymore: Skia objects cannot be used \" +\n \"inside worklets or shared values with it. \" +\n \"Please upgrade to react-native-reanimated >= 4.0.0.\"\n );\n};\n\nexport const createContainer = (Skia: Skia, nativeId: number) => {\n if (HAS_REANIMATED_4 && nativeId !== -1) {\n return new NativeReanimatedContainer(Skia, nativeId);\n } else {\n if (HAS_REANIMATED_3 && !HAS_REANIMATED_4) {\n const message = reanimatedSupportError();\n if (__DEV__) {\n // Fail loudly in development — a silent fallback to static rendering\n // would only be noticed as frozen animations.\n throw new Error(message);\n }\n if (!hasWarnedAboutReanimatedSupport) {\n hasWarnedAboutReanimatedSupport = true;\n console.error(\n `${message} Falling back to static rendering (animations will not run).`\n );\n }\n }\n return new StaticContainer(Skia, nativeId);\n }\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1,16 @@
1
1
  export declare let HAS_REANIMATED_3: boolean;
2
+ /**
3
+ * True when the worklets-based Reanimated integration is available
4
+ * (Reanimated 4 with react-native-worklets providing
5
+ * registerCustomSerializable). Skia objects use the JSI NativeState pattern
6
+ * and can only be transferred to worklet runtimes through a custom
7
+ * serializer, so on native the Reanimated integration requires Reanimated 4 —
8
+ * Reanimated 3 is not supported.
9
+ */
10
+ export declare let HAS_REANIMATED_4: boolean;
11
+ /**
12
+ * Major version of the installed react-native-reanimated package, or null if
13
+ * it is not installed. Used to give actionable diagnostics when the
14
+ * integration cannot be enabled.
15
+ */
16
+ export declare let REANIMATED_VERSION_MAJOR: number | null;
@@ -1,4 +1,21 @@
1
1
  export let HAS_REANIMATED_3 = false;
2
+
3
+ /**
4
+ * True when the worklets-based Reanimated integration is available
5
+ * (Reanimated 4 with react-native-worklets providing
6
+ * registerCustomSerializable). Skia objects use the JSI NativeState pattern
7
+ * and can only be transferred to worklet runtimes through a custom
8
+ * serializer, so on native the Reanimated integration requires Reanimated 4 —
9
+ * Reanimated 3 is not supported.
10
+ */
11
+ export let HAS_REANIMATED_4 = false;
12
+
13
+ /**
14
+ * Major version of the installed react-native-reanimated package, or null if
15
+ * it is not installed. Used to give actionable diagnostics when the
16
+ * integration cannot be enabled.
17
+ */
18
+ export let REANIMATED_VERSION_MAJOR = null;
2
19
  try {
3
20
  // This logic is convoluted but necessary
4
21
  // In most systems, `require("react-native-reanimated")` throws an error, all is well.
@@ -9,6 +26,18 @@ try {
9
26
  if (reanimatedVersion && (reanimatedVersion >= "3.0.0" || reanimatedVersion.includes("3.0.0-"))) {
10
27
  HAS_REANIMATED_3 = true;
11
28
  }
29
+ const majorVersion = parseInt(reanimatedVersion.split(".")[0], 10);
30
+ if (!isNaN(majorVersion)) {
31
+ REANIMATED_VERSION_MAJOR = majorVersion;
32
+ }
33
+ if (majorVersion >= 4) {
34
+ try {
35
+ const worklets = require("react-native-worklets");
36
+ HAS_REANIMATED_4 = typeof worklets.registerCustomSerializable === "function";
37
+ } catch (e) {
38
+ // react-native-worklets not installed
39
+ }
40
+ }
12
41
  } catch (e) {
13
42
  // do nothing
14
43
  }
@@ -1 +1 @@
1
- {"version":3,"names":["HAS_REANIMATED_3","reanimatedVersion","require","version","includes","e"],"sources":["renderHelpers.ts"],"sourcesContent":["export let HAS_REANIMATED_3 = false;\n\ntry {\n // This logic is convoluted but necessary\n // In most systems, `require(\"react-native-reanimated\")` throws an error, all is well.\n // In webpack, in some configuration it will return an empty object.\n // So it will not throw an error and we need to check the version to know if it's there.\n const reanimatedVersion =\n require(\"react-native-reanimated/package.json\").version;\n require(\"react-native-reanimated\");\n if (\n reanimatedVersion &&\n (reanimatedVersion >= \"3.0.0\" || reanimatedVersion.includes(\"3.0.0-\"))\n ) {\n HAS_REANIMATED_3 = true;\n }\n} catch (e) {\n // do nothing\n}\n"],"mappings":"AAAA,OAAO,IAAIA,gBAAgB,GAAG,KAAK;AAEnC,IAAI;EACF;EACA;EACA;EACA;EACA,MAAMC,iBAAiB,GACrBC,OAAO,CAAC,sCAAsC,CAAC,CAACC,OAAO;EACzDD,OAAO,CAAC,yBAAyB,CAAC;EAClC,IACED,iBAAiB,KAChBA,iBAAiB,IAAI,OAAO,IAAIA,iBAAiB,CAACG,QAAQ,CAAC,QAAQ,CAAC,CAAC,EACtE;IACAJ,gBAAgB,GAAG,IAAI;EACzB;AACF,CAAC,CAAC,OAAOK,CAAC,EAAE;EACV;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["HAS_REANIMATED_3","HAS_REANIMATED_4","REANIMATED_VERSION_MAJOR","reanimatedVersion","require","version","includes","majorVersion","parseInt","split","isNaN","worklets","registerCustomSerializable","e"],"sources":["renderHelpers.ts"],"sourcesContent":["export let HAS_REANIMATED_3 = false;\n\n/**\n * True when the worklets-based Reanimated integration is available\n * (Reanimated 4 with react-native-worklets providing\n * registerCustomSerializable). Skia objects use the JSI NativeState pattern\n * and can only be transferred to worklet runtimes through a custom\n * serializer, so on native the Reanimated integration requires Reanimated 4 —\n * Reanimated 3 is not supported.\n */\nexport let HAS_REANIMATED_4 = false;\n\n/**\n * Major version of the installed react-native-reanimated package, or null if\n * it is not installed. Used to give actionable diagnostics when the\n * integration cannot be enabled.\n */\nexport let REANIMATED_VERSION_MAJOR: number | null = null;\n\ntry {\n // This logic is convoluted but necessary\n // In most systems, `require(\"react-native-reanimated\")` throws an error, all is well.\n // In webpack, in some configuration it will return an empty object.\n // So it will not throw an error and we need to check the version to know if it's there.\n const reanimatedVersion =\n require(\"react-native-reanimated/package.json\").version;\n require(\"react-native-reanimated\");\n if (\n reanimatedVersion &&\n (reanimatedVersion >= \"3.0.0\" || reanimatedVersion.includes(\"3.0.0-\"))\n ) {\n HAS_REANIMATED_3 = true;\n }\n const majorVersion = parseInt(reanimatedVersion.split(\".\")[0], 10);\n if (!isNaN(majorVersion)) {\n REANIMATED_VERSION_MAJOR = majorVersion;\n }\n if (majorVersion >= 4) {\n try {\n const worklets = require(\"react-native-worklets\");\n HAS_REANIMATED_4 =\n typeof worklets.registerCustomSerializable === \"function\";\n } catch (e) {\n // react-native-worklets not installed\n }\n }\n} catch (e) {\n // do nothing\n}\n"],"mappings":"AAAA,OAAO,IAAIA,gBAAgB,GAAG,KAAK;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,IAAIC,gBAAgB,GAAG,KAAK;;AAEnC;AACA;AACA;AACA;AACA;AACA,OAAO,IAAIC,wBAAuC,GAAG,IAAI;AAEzD,IAAI;EACF;EACA;EACA;EACA;EACA,MAAMC,iBAAiB,GACrBC,OAAO,CAAC,sCAAsC,CAAC,CAACC,OAAO;EACzDD,OAAO,CAAC,yBAAyB,CAAC;EAClC,IACED,iBAAiB,KAChBA,iBAAiB,IAAI,OAAO,IAAIA,iBAAiB,CAACG,QAAQ,CAAC,QAAQ,CAAC,CAAC,EACtE;IACAN,gBAAgB,GAAG,IAAI;EACzB;EACA,MAAMO,YAAY,GAAGC,QAAQ,CAACL,iBAAiB,CAACM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;EAClE,IAAI,CAACC,KAAK,CAACH,YAAY,CAAC,EAAE;IACxBL,wBAAwB,GAAGK,YAAY;EACzC;EACA,IAAIA,YAAY,IAAI,CAAC,EAAE;IACrB,IAAI;MACF,MAAMI,QAAQ,GAAGP,OAAO,CAAC,uBAAuB,CAAC;MACjDH,gBAAgB,GACd,OAAOU,QAAQ,CAACC,0BAA0B,KAAK,UAAU;IAC7D,CAAC,CAAC,OAAOC,CAAC,EAAE;MACV;IAAA;EAEJ;AACF,CAAC,CAAC,OAAOA,CAAC,EAAE;EACV;AAAA","ignoreList":[]}
@@ -1,5 +1,6 @@
1
1
  import { Platform } from "../Platform";
2
2
  import NativeSkiaModule from "../specs/NativeSkiaModule";
3
+ import { registerSkiaWorkletSerialization } from "./SkiaWorkletSerialization";
3
4
  if (Platform.OS !== "web" && global.SkiaApi == null) {
4
5
  // Initialize RN Skia
5
6
  const SkiaModule = NativeSkiaModule;
@@ -10,5 +11,8 @@ if (Platform.OS !== "web" && global.SkiaApi == null) {
10
11
  if (result !== true) {
11
12
  throw new Error(`Native Skia Module failed to correctly install JSI Bindings! Result: ${result}`);
12
13
  }
14
+ // Skia objects use the JSI NativeState pattern and need a custom
15
+ // serializer to be transferable to worklet runtimes (Reanimated).
16
+ registerSkiaWorkletSerialization();
13
17
  }
14
18
  //# sourceMappingURL=NativeSetup.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","NativeSkiaModule","OS","global","SkiaApi","SkiaModule","install","Error","result"],"sources":["NativeSetup.ts"],"sourcesContent":["import { Platform } from \"../Platform\";\nimport NativeSkiaModule from \"../specs/NativeSkiaModule\";\n\nif (Platform.OS !== \"web\" && global.SkiaApi == null) {\n // Initialize RN Skia\n const SkiaModule = NativeSkiaModule;\n if (SkiaModule == null || typeof SkiaModule.install !== \"function\") {\n throw new Error(\n \"Native RNSkia Module cannot be found! Make sure you correctly \" +\n \"installed native dependencies and rebuilt your app.\"\n );\n }\n const result = SkiaModule.install();\n if (result !== true) {\n throw new Error(\n `Native Skia Module failed to correctly install JSI Bindings! Result: ${result}`\n );\n }\n}\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,aAAa;AACtC,OAAOC,gBAAgB,MAAM,2BAA2B;AAExD,IAAID,QAAQ,CAACE,EAAE,KAAK,KAAK,IAAIC,MAAM,CAACC,OAAO,IAAI,IAAI,EAAE;EACnD;EACA,MAAMC,UAAU,GAAGJ,gBAAgB;EACnC,IAAII,UAAU,IAAI,IAAI,IAAI,OAAOA,UAAU,CAACC,OAAO,KAAK,UAAU,EAAE;IAClE,MAAM,IAAIC,KAAK,CACb,gEAAgE,GAC9D,qDACJ,CAAC;EACH;EACA,MAAMC,MAAM,GAAGH,UAAU,CAACC,OAAO,CAAC,CAAC;EACnC,IAAIE,MAAM,KAAK,IAAI,EAAE;IACnB,MAAM,IAAID,KAAK,CACb,wEAAwEC,MAAM,EAChF,CAAC;EACH;AACF","ignoreList":[]}
1
+ {"version":3,"names":["Platform","NativeSkiaModule","registerSkiaWorkletSerialization","OS","global","SkiaApi","SkiaModule","install","Error","result"],"sources":["NativeSetup.ts"],"sourcesContent":["import { Platform } from \"../Platform\";\nimport NativeSkiaModule from \"../specs/NativeSkiaModule\";\n\nimport { registerSkiaWorkletSerialization } from \"./SkiaWorkletSerialization\";\n\nif (Platform.OS !== \"web\" && global.SkiaApi == null) {\n // Initialize RN Skia\n const SkiaModule = NativeSkiaModule;\n if (SkiaModule == null || typeof SkiaModule.install !== \"function\") {\n throw new Error(\n \"Native RNSkia Module cannot be found! Make sure you correctly \" +\n \"installed native dependencies and rebuilt your app.\"\n );\n }\n const result = SkiaModule.install();\n if (result !== true) {\n throw new Error(\n `Native Skia Module failed to correctly install JSI Bindings! Result: ${result}`\n );\n }\n // Skia objects use the JSI NativeState pattern and need a custom\n // serializer to be transferable to worklet runtimes (Reanimated).\n registerSkiaWorkletSerialization();\n}\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,aAAa;AACtC,OAAOC,gBAAgB,MAAM,2BAA2B;AAExD,SAASC,gCAAgC,QAAQ,4BAA4B;AAE7E,IAAIF,QAAQ,CAACG,EAAE,KAAK,KAAK,IAAIC,MAAM,CAACC,OAAO,IAAI,IAAI,EAAE;EACnD;EACA,MAAMC,UAAU,GAAGL,gBAAgB;EACnC,IAAIK,UAAU,IAAI,IAAI,IAAI,OAAOA,UAAU,CAACC,OAAO,KAAK,UAAU,EAAE;IAClE,MAAM,IAAIC,KAAK,CACb,gEAAgE,GAC9D,qDACJ,CAAC;EACH;EACA,MAAMC,MAAM,GAAGH,UAAU,CAACC,OAAO,CAAC,CAAC;EACnC,IAAIE,MAAM,KAAK,IAAI,EAAE;IACnB,MAAM,IAAID,KAAK,CACb,wEAAwEC,MAAM,EAChF,CAAC;EACH;EACA;EACA;EACAP,gCAAgC,CAAC,CAAC;AACpC","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export declare const registerSkiaWorkletSerialization: () => void;
@@ -0,0 +1,59 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ /**
4
+ * Skia and WebGPU API objects are implemented with the JSI NativeState
5
+ * pattern: plain JS objects with a shared prototype and native state
6
+ * attached. Worklets cannot serialize such objects by default (the prototype
7
+ * would be lost when moving them to another runtime), so we register a
8
+ * Custom Serializable that:
9
+ *
10
+ * - determine: detects native objects via the `__box` method installed on
11
+ * every Skia and WebGPU prototype (plain objects never reach the
12
+ * custom-serializable path, so this cannot misfire on user data).
13
+ * - pack: boxes the object into a HostObject wrapper that carries the native
14
+ * state and the class brand. HostObjects are transferred by reference.
15
+ * - unpack: unboxes on the target runtime, re-installing the class prototype
16
+ * there and re-attaching the same native state.
17
+ *
18
+ * See cpp/jsi/BoxedNativeObject.h for the native side.
19
+ *
20
+ * `react-native-worklets` (Reanimated 4) is required for this to work —
21
+ * without it, Skia and WebGPU objects cannot be captured in worklets or
22
+ * stored in shared values.
23
+ */
24
+
25
+ const determine = value => {
26
+ "worklet";
27
+
28
+ return typeof value.__box === "function";
29
+ };
30
+ const pack = value => {
31
+ "worklet";
32
+
33
+ return value.__box();
34
+ };
35
+ const unpack = packed => {
36
+ "worklet";
37
+
38
+ return packed.unbox();
39
+ };
40
+ export const registerSkiaWorkletSerialization = () => {
41
+ try {
42
+ const worklets = require("react-native-worklets");
43
+ if (typeof worklets.registerCustomSerializable === "function") {
44
+ worklets.registerCustomSerializable({
45
+ name: "ReactNativeSkia",
46
+ determine,
47
+ pack,
48
+ unpack
49
+ });
50
+ } else {
51
+ console.error("React Native Skia requires react-native-worklets >= 0.7.0 " + "(registerCustomSerializable) to use Skia objects inside worklets. " + "Please upgrade react-native-worklets and react-native-reanimated.");
52
+ }
53
+ } catch (e) {
54
+ // react-native-worklets is not installed. This is fine for apps that do
55
+ // not use Reanimated: Skia objects simply cannot be used inside worklets
56
+ // or shared values in this configuration.
57
+ }
58
+ };
59
+ //# sourceMappingURL=SkiaWorkletSerialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["determine","value","__box","pack","unpack","packed","unbox","registerSkiaWorkletSerialization","worklets","require","registerCustomSerializable","name","console","error","e"],"sources":["SkiaWorkletSerialization.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Skia and WebGPU API objects are implemented with the JSI NativeState\n * pattern: plain JS objects with a shared prototype and native state\n * attached. Worklets cannot serialize such objects by default (the prototype\n * would be lost when moving them to another runtime), so we register a\n * Custom Serializable that:\n *\n * - determine: detects native objects via the `__box` method installed on\n * every Skia and WebGPU prototype (plain objects never reach the\n * custom-serializable path, so this cannot misfire on user data).\n * - pack: boxes the object into a HostObject wrapper that carries the native\n * state and the class brand. HostObjects are transferred by reference.\n * - unpack: unboxes on the target runtime, re-installing the class prototype\n * there and re-attaching the same native state.\n *\n * See cpp/jsi/BoxedNativeObject.h for the native side.\n *\n * `react-native-worklets` (Reanimated 4) is required for this to work —\n * without it, Skia and WebGPU objects cannot be captured in worklets or\n * stored in shared values.\n */\n\ninterface BoxedNativeObject {\n unbox: () => object;\n __boxedNativeObject: true;\n}\n\nconst determine = (value: object): value is object => {\n \"worklet\";\n return typeof (value as any).__box === \"function\";\n};\n\nconst pack = (value: object): BoxedNativeObject => {\n \"worklet\";\n return (value as any).__box();\n};\n\nconst unpack = (packed: BoxedNativeObject): object => {\n \"worklet\";\n return packed.unbox();\n};\n\nexport const registerSkiaWorkletSerialization = () => {\n try {\n const worklets = require(\"react-native-worklets\");\n if (typeof worklets.registerCustomSerializable === \"function\") {\n worklets.registerCustomSerializable({\n name: \"ReactNativeSkia\",\n determine,\n pack,\n unpack,\n });\n } else {\n console.error(\n \"React Native Skia requires react-native-worklets >= 0.7.0 \" +\n \"(registerCustomSerializable) to use Skia objects inside worklets. \" +\n \"Please upgrade react-native-worklets and react-native-reanimated.\"\n );\n }\n } catch (e) {\n // react-native-worklets is not installed. This is fine for apps that do\n // not use Reanimated: Skia objects simply cannot be used inside worklets\n // or shared values in this configuration.\n }\n};\n"],"mappings":"AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA,MAAMA,SAAS,GAAIC,KAAa,IAAsB;EACpD,SAAS;;EACT,OAAO,OAAQA,KAAK,CAASC,KAAK,KAAK,UAAU;AACnD,CAAC;AAED,MAAMC,IAAI,GAAIF,KAAa,IAAwB;EACjD,SAAS;;EACT,OAAQA,KAAK,CAASC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAME,MAAM,GAAIC,MAAyB,IAAa;EACpD,SAAS;;EACT,OAAOA,MAAM,CAACC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,OAAO,MAAMC,gCAAgC,GAAGA,CAAA,KAAM;EACpD,IAAI;IACF,MAAMC,QAAQ,GAAGC,OAAO,CAAC,uBAAuB,CAAC;IACjD,IAAI,OAAOD,QAAQ,CAACE,0BAA0B,KAAK,UAAU,EAAE;MAC7DF,QAAQ,CAACE,0BAA0B,CAAC;QAClCC,IAAI,EAAE,iBAAiB;QACvBX,SAAS;QACTG,IAAI;QACJC;MACF,CAAC,CAAC;IACJ,CAAC,MAAM;MACLQ,OAAO,CAACC,KAAK,CACX,4DAA4D,GAC1D,oEAAoE,GACpE,mEACJ,CAAC;IACH;EACF,CAAC,CAAC,OAAOC,CAAC,EAAE;IACV;IACA;IACA;EAAA;AAEJ,CAAC","ignoreList":[]}
@@ -2,7 +2,7 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
2
2
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
4
  import Rea from "../external/reanimated/ReanimatedProxy";
5
- import { HAS_REANIMATED_3 } from "../external/reanimated/renderHelpers";
5
+ import { HAS_REANIMATED_3, HAS_REANIMATED_4, REANIMATED_VERSION_MAJOR } from "../external/reanimated/renderHelpers";
6
6
  import { ReanimatedRecorder } from "./Recorder/ReanimatedRecorder";
7
7
  import { Container, StaticContainer } from "./StaticContainer";
8
8
  import { visit } from "./Recorder/Visitor";
@@ -73,10 +73,29 @@ class NativeReanimatedContainer extends Container {
73
73
  }
74
74
  }
75
75
  }
76
+ let hasWarnedAboutReanimatedSupport = false;
77
+ const reanimatedSupportError = () => {
78
+ if (REANIMATED_VERSION_MAJOR !== null && REANIMATED_VERSION_MAJOR >= 4) {
79
+ return "React Native Skia requires react-native-worklets >= 0.7.0 for its " + "Reanimated integration on native platforms. Reanimated 4 is " + "installed, but react-native-worklets is missing or too old. " + "Please install or upgrade react-native-worklets.";
80
+ }
81
+ return "React Native Skia requires Reanimated 4 (react-native-worklets >= " + "0.7.0) for its Reanimated integration on native platforms. " + "Reanimated 3 is not supported anymore: Skia objects cannot be used " + "inside worklets or shared values with it. " + "Please upgrade to react-native-reanimated >= 4.0.0.";
82
+ };
76
83
  export const createContainer = (Skia, nativeId) => {
77
- if (HAS_REANIMATED_3 && nativeId !== -1) {
84
+ if (HAS_REANIMATED_4 && nativeId !== -1) {
78
85
  return new NativeReanimatedContainer(Skia, nativeId);
79
86
  } else {
87
+ if (HAS_REANIMATED_3 && !HAS_REANIMATED_4) {
88
+ const message = reanimatedSupportError();
89
+ if (__DEV__) {
90
+ // Fail loudly in development — a silent fallback to static rendering
91
+ // would only be noticed as frozen animations.
92
+ throw new Error(message);
93
+ }
94
+ if (!hasWarnedAboutReanimatedSupport) {
95
+ hasWarnedAboutReanimatedSupport = true;
96
+ console.error(`${message} Falling back to static rendering (animations will not run).`);
97
+ }
98
+ }
80
99
  return new StaticContainer(Skia, nativeId);
81
100
  }
82
101
  };
@@ -1 +1 @@
1
- {"version":3,"names":["Rea","HAS_REANIMATED_3","ReanimatedRecorder","Container","StaticContainer","visit","SkiaViewApi","globalThis","nativeDrawOnscreen","nativeId","recorder","picture","play","setJsiProperty","NativeReanimatedContainer","constructor","Skia","_defineProperty","Picture","MakePicture","unmount","mapperId","stopMapper","redraw","unmounted","root","sharedValues","getSharedValues","sharedRecorder","getRecorder","runOnUI","length","startMapper","applyUpdates","createContainer"],"sources":["Container.native.ts"],"sourcesContent":["import Rea from \"../external/reanimated/ReanimatedProxy\";\nimport type { Skia, SkPicture } from \"../skia/types\";\nimport { HAS_REANIMATED_3 } from \"../external/reanimated/renderHelpers\";\nimport type { JsiRecorder } from \"../skia/types/Recorder\";\n\nimport { ReanimatedRecorder } from \"./Recorder/ReanimatedRecorder\";\nimport { Container, StaticContainer } from \"./StaticContainer\";\nimport { visit } from \"./Recorder/Visitor\";\n\nimport \"../skia/NativeSetup\";\nimport \"../views/api\";\n\n// create local reference for `strictGlobal` option in Worklets\nconst { SkiaViewApi } = globalThis;\n\nconst nativeDrawOnscreen = (\n nativeId: number,\n recorder: JsiRecorder,\n picture: SkPicture\n) => {\n \"worklet\";\n\n //const start = performance.now();\n recorder.play(picture);\n //const end = performance.now();\n //console.log(\"Recording time: \", end - start);\n SkiaViewApi.setJsiProperty(nativeId, \"picture\", picture);\n};\n\nclass NativeReanimatedContainer extends Container {\n private mapperId: number | null = null;\n private picture: SkPicture;\n\n constructor(\n Skia: Skia,\n private nativeId: number\n ) {\n super(Skia);\n this.picture = Skia.Picture.MakePicture(null)!;\n }\n\n unmount() {\n super.unmount();\n if (this.mapperId !== null) {\n // The mapper closure retains the recorder and its resources (e.g.\n // images) on the UI runtime and keeps updating the picture of an\n // unmounted view — stop it or it leaks for the lifetime of the app.\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n }\n\n redraw() {\n if (this.mapperId !== null) {\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n if (this.unmounted) {\n return;\n }\n const recorder = new ReanimatedRecorder(this.Skia);\n const { nativeId, picture } = this;\n visit(recorder, this.root);\n const sharedValues = recorder.getSharedValues();\n const sharedRecorder = recorder.getRecorder();\n // Draw first frame\n Rea.runOnUI(() => {\n \"worklet\";\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n })();\n // Animate\n if (sharedValues.length > 0) {\n this.mapperId = Rea.startMapper(() => {\n \"worklet\";\n sharedRecorder.applyUpdates(sharedValues);\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n }, sharedValues);\n }\n }\n}\n\nexport const createContainer = (Skia: Skia, nativeId: number) => {\n if (HAS_REANIMATED_3 && nativeId !== -1) {\n return new NativeReanimatedContainer(Skia, nativeId);\n } else {\n return new StaticContainer(Skia, nativeId);\n }\n};\n"],"mappings":";;;AAAA,OAAOA,GAAG,MAAM,wCAAwC;AAExD,SAASC,gBAAgB,QAAQ,sCAAsC;AAGvE,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,SAAS,EAAEC,eAAe,QAAQ,mBAAmB;AAC9D,SAASC,KAAK,QAAQ,oBAAoB;AAE1C,OAAO,qBAAqB;AAC5B,OAAO,cAAc;;AAErB;AACA,MAAM;EAAEC;AAAY,CAAC,GAAGC,UAAU;AAElC,MAAMC,kBAAkB,GAAGA,CACzBC,QAAgB,EAChBC,QAAqB,EACrBC,OAAkB,KACf;EACH,SAAS;;EAET;EACAD,QAAQ,CAACE,IAAI,CAACD,OAAO,CAAC;EACtB;EACA;EACAL,WAAW,CAACO,cAAc,CAACJ,QAAQ,EAAE,SAAS,EAAEE,OAAO,CAAC;AAC1D,CAAC;AAED,MAAMG,yBAAyB,SAASX,SAAS,CAAC;EAIhDY,WAAWA,CACTC,IAAU,EACFP,QAAgB,EACxB;IACA,KAAK,CAACO,IAAI,CAAC;IAAC,KAFJP,QAAgB,GAAhBA,QAAgB;IAAAQ,eAAA,mBALQ,IAAI;IAAAA,eAAA;IAQpC,IAAI,CAACN,OAAO,GAAGK,IAAI,CAACE,OAAO,CAACC,WAAW,CAAC,IAAI,CAAE;EAChD;EAEAC,OAAOA,CAAA,EAAG;IACR,KAAK,CAACA,OAAO,CAAC,CAAC;IACf,IAAI,IAAI,CAACC,QAAQ,KAAK,IAAI,EAAE;MAC1B;MACA;MACA;MACArB,GAAG,CAACsB,UAAU,CAAC,IAAI,CAACD,QAAQ,CAAC;MAC7B,IAAI,CAACA,QAAQ,GAAG,IAAI;IACtB;EACF;EAEAE,MAAMA,CAAA,EAAG;IACP,IAAI,IAAI,CAACF,QAAQ,KAAK,IAAI,EAAE;MAC1BrB,GAAG,CAACsB,UAAU,CAAC,IAAI,CAACD,QAAQ,CAAC;MAC7B,IAAI,CAACA,QAAQ,GAAG,IAAI;IACtB;IACA,IAAI,IAAI,CAACG,SAAS,EAAE;MAClB;IACF;IACA,MAAMd,QAAQ,GAAG,IAAIR,kBAAkB,CAAC,IAAI,CAACc,IAAI,CAAC;IAClD,MAAM;MAAEP,QAAQ;MAAEE;IAAQ,CAAC,GAAG,IAAI;IAClCN,KAAK,CAACK,QAAQ,EAAE,IAAI,CAACe,IAAI,CAAC;IAC1B,MAAMC,YAAY,GAAGhB,QAAQ,CAACiB,eAAe,CAAC,CAAC;IAC/C,MAAMC,cAAc,GAAGlB,QAAQ,CAACmB,WAAW,CAAC,CAAC;IAC7C;IACA7B,GAAG,CAAC8B,OAAO,CAAC,MAAM;MAChB,SAAS;;MACTtB,kBAAkB,CAACC,QAAQ,EAAEmB,cAAc,EAAEjB,OAAO,CAAC;IACvD,CAAC,CAAC,CAAC,CAAC;IACJ;IACA,IAAIe,YAAY,CAACK,MAAM,GAAG,CAAC,EAAE;MAC3B,IAAI,CAACV,QAAQ,GAAGrB,GAAG,CAACgC,WAAW,CAAC,MAAM;QACpC,SAAS;;QACTJ,cAAc,CAACK,YAAY,CAACP,YAAY,CAAC;QACzClB,kBAAkB,CAACC,QAAQ,EAAEmB,cAAc,EAAEjB,OAAO,CAAC;MACvD,CAAC,EAAEe,YAAY,CAAC;IAClB;EACF;AACF;AAEA,OAAO,MAAMQ,eAAe,GAAGA,CAAClB,IAAU,EAAEP,QAAgB,KAAK;EAC/D,IAAIR,gBAAgB,IAAIQ,QAAQ,KAAK,CAAC,CAAC,EAAE;IACvC,OAAO,IAAIK,yBAAyB,CAACE,IAAI,EAAEP,QAAQ,CAAC;EACtD,CAAC,MAAM;IACL,OAAO,IAAIL,eAAe,CAACY,IAAI,EAAEP,QAAQ,CAAC;EAC5C;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["Rea","HAS_REANIMATED_3","HAS_REANIMATED_4","REANIMATED_VERSION_MAJOR","ReanimatedRecorder","Container","StaticContainer","visit","SkiaViewApi","globalThis","nativeDrawOnscreen","nativeId","recorder","picture","play","setJsiProperty","NativeReanimatedContainer","constructor","Skia","_defineProperty","Picture","MakePicture","unmount","mapperId","stopMapper","redraw","unmounted","root","sharedValues","getSharedValues","sharedRecorder","getRecorder","runOnUI","length","startMapper","applyUpdates","hasWarnedAboutReanimatedSupport","reanimatedSupportError","createContainer","message","__DEV__","Error","console","error"],"sources":["Container.native.ts"],"sourcesContent":["import Rea from \"../external/reanimated/ReanimatedProxy\";\nimport type { Skia, SkPicture } from \"../skia/types\";\nimport {\n HAS_REANIMATED_3,\n HAS_REANIMATED_4,\n REANIMATED_VERSION_MAJOR,\n} from \"../external/reanimated/renderHelpers\";\nimport type { JsiRecorder } from \"../skia/types/Recorder\";\n\nimport { ReanimatedRecorder } from \"./Recorder/ReanimatedRecorder\";\nimport { Container, StaticContainer } from \"./StaticContainer\";\nimport { visit } from \"./Recorder/Visitor\";\n\nimport \"../skia/NativeSetup\";\nimport \"../views/api\";\n\n// create local reference for `strictGlobal` option in Worklets\nconst { SkiaViewApi } = globalThis;\n\nconst nativeDrawOnscreen = (\n nativeId: number,\n recorder: JsiRecorder,\n picture: SkPicture\n) => {\n \"worklet\";\n\n //const start = performance.now();\n recorder.play(picture);\n //const end = performance.now();\n //console.log(\"Recording time: \", end - start);\n SkiaViewApi.setJsiProperty(nativeId, \"picture\", picture);\n};\n\nclass NativeReanimatedContainer extends Container {\n private mapperId: number | null = null;\n private picture: SkPicture;\n\n constructor(\n Skia: Skia,\n private nativeId: number\n ) {\n super(Skia);\n this.picture = Skia.Picture.MakePicture(null)!;\n }\n\n unmount() {\n super.unmount();\n if (this.mapperId !== null) {\n // The mapper closure retains the recorder and its resources (e.g.\n // images) on the UI runtime and keeps updating the picture of an\n // unmounted view — stop it or it leaks for the lifetime of the app.\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n }\n\n redraw() {\n if (this.mapperId !== null) {\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n if (this.unmounted) {\n return;\n }\n const recorder = new ReanimatedRecorder(this.Skia);\n const { nativeId, picture } = this;\n visit(recorder, this.root);\n const sharedValues = recorder.getSharedValues();\n const sharedRecorder = recorder.getRecorder();\n // Draw first frame\n Rea.runOnUI(() => {\n \"worklet\";\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n })();\n // Animate\n if (sharedValues.length > 0) {\n this.mapperId = Rea.startMapper(() => {\n \"worklet\";\n sharedRecorder.applyUpdates(sharedValues);\n nativeDrawOnscreen(nativeId, sharedRecorder, picture);\n }, sharedValues);\n }\n }\n}\n\nlet hasWarnedAboutReanimatedSupport = false;\n\nconst reanimatedSupportError = () => {\n if (REANIMATED_VERSION_MAJOR !== null && REANIMATED_VERSION_MAJOR >= 4) {\n return (\n \"React Native Skia requires react-native-worklets >= 0.7.0 for its \" +\n \"Reanimated integration on native platforms. Reanimated 4 is \" +\n \"installed, but react-native-worklets is missing or too old. \" +\n \"Please install or upgrade react-native-worklets.\"\n );\n }\n return (\n \"React Native Skia requires Reanimated 4 (react-native-worklets >= \" +\n \"0.7.0) for its Reanimated integration on native platforms. \" +\n \"Reanimated 3 is not supported anymore: Skia objects cannot be used \" +\n \"inside worklets or shared values with it. \" +\n \"Please upgrade to react-native-reanimated >= 4.0.0.\"\n );\n};\n\nexport const createContainer = (Skia: Skia, nativeId: number) => {\n if (HAS_REANIMATED_4 && nativeId !== -1) {\n return new NativeReanimatedContainer(Skia, nativeId);\n } else {\n if (HAS_REANIMATED_3 && !HAS_REANIMATED_4) {\n const message = reanimatedSupportError();\n if (__DEV__) {\n // Fail loudly in development — a silent fallback to static rendering\n // would only be noticed as frozen animations.\n throw new Error(message);\n }\n if (!hasWarnedAboutReanimatedSupport) {\n hasWarnedAboutReanimatedSupport = true;\n console.error(\n `${message} Falling back to static rendering (animations will not run).`\n );\n }\n }\n return new StaticContainer(Skia, nativeId);\n }\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,2 +1,4 @@
1
1
  export const __esModule: boolean;
2
2
  export const HAS_REANIMATED_3: any;
3
+ export const HAS_REANIMATED_4: any;
4
+ export const REANIMATED_VERSION_MAJOR: any;
@@ -0,0 +1,2 @@
1
+ export const __esModule: boolean;
2
+ export function registerSkiaWorkletSerialization(): void;
@@ -1 +1,16 @@
1
1
  export let HAS_REANIMATED_3: boolean;
2
+ /**
3
+ * True when the worklets-based Reanimated integration is available
4
+ * (Reanimated 4 with react-native-worklets providing
5
+ * registerCustomSerializable). Skia objects use the JSI NativeState pattern
6
+ * and can only be transferred to worklet runtimes through a custom
7
+ * serializer, so on native the Reanimated integration requires Reanimated 4 —
8
+ * Reanimated 3 is not supported.
9
+ */
10
+ export let HAS_REANIMATED_4: boolean;
11
+ /**
12
+ * Major version of the installed react-native-reanimated package, or null if
13
+ * it is not installed. Used to give actionable diagnostics when the
14
+ * integration cannot be enabled.
15
+ */
16
+ export let REANIMATED_VERSION_MAJOR: null;
@@ -0,0 +1 @@
1
+ export function registerSkiaWorkletSerialization(): void;