react-native-worklets 0.0.1-alpha → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/Common/cpp/worklets/AnimationFrameQueue/AnimationFrameBatchinator.cpp +71 -0
  2. package/Common/cpp/worklets/AnimationFrameQueue/AnimationFrameBatchinator.h +38 -0
  3. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +131 -0
  4. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +82 -0
  5. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.cpp +72 -0
  6. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.h +44 -0
  7. package/Common/cpp/worklets/Registries/EventHandlerRegistry.cpp +94 -0
  8. package/Common/cpp/worklets/Registries/EventHandlerRegistry.h +49 -0
  9. package/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.cpp +8 -0
  10. package/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.h +39 -0
  11. package/Common/cpp/worklets/SharedItems/Shareables.cpp +326 -0
  12. package/Common/cpp/worklets/SharedItems/Shareables.h +345 -0
  13. package/Common/cpp/worklets/Tools/AsyncQueue.cpp +52 -0
  14. package/Common/cpp/worklets/Tools/AsyncQueue.h +35 -0
  15. package/Common/cpp/worklets/Tools/Defs.h +10 -0
  16. package/Common/cpp/worklets/Tools/JSISerializer.cpp +342 -0
  17. package/Common/cpp/worklets/Tools/JSISerializer.h +47 -0
  18. package/Common/cpp/worklets/Tools/JSLogger.cpp +16 -0
  19. package/Common/cpp/worklets/Tools/JSLogger.h +20 -0
  20. package/Common/cpp/worklets/Tools/JSScheduler.cpp +10 -0
  21. package/Common/cpp/worklets/Tools/JSScheduler.h +29 -0
  22. package/Common/cpp/worklets/Tools/PlatformLogger.h +16 -0
  23. package/Common/cpp/worklets/Tools/SingleInstanceChecker.h +72 -0
  24. package/Common/cpp/worklets/Tools/ThreadSafeQueue.h +49 -0
  25. package/Common/cpp/worklets/Tools/UIScheduler.cpp +19 -0
  26. package/Common/cpp/worklets/Tools/UIScheduler.h +22 -0
  27. package/Common/cpp/worklets/Tools/WorkletEventHandler.cpp +29 -0
  28. package/Common/cpp/worklets/Tools/WorkletEventHandler.h +41 -0
  29. package/Common/cpp/worklets/Tools/WorkletsJSIUtils.cpp +26 -0
  30. package/Common/cpp/worklets/Tools/WorkletsJSIUtils.h +199 -0
  31. package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp +20 -0
  32. package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h +19 -0
  33. package/Common/cpp/worklets/WorkletRuntime/RuntimeInitialization.md +191 -0
  34. package/Common/cpp/worklets/WorkletRuntime/UIRuntimeDecorator.cpp +19 -0
  35. package/Common/cpp/worklets/WorkletRuntime/UIRuntimeDecorator.h +16 -0
  36. package/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.cpp +108 -0
  37. package/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.h +127 -0
  38. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +183 -0
  39. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +90 -0
  40. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeCollector.h +36 -0
  41. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +179 -0
  42. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +22 -0
  43. package/LICENSE +20 -0
  44. package/README.md +27 -0
  45. package/RNWorklets.podspec +70 -0
  46. package/android/CMakeLists.txt +56 -0
  47. package/android/build.gradle +313 -0
  48. package/android/gradle.properties +5 -0
  49. package/android/proguard-rules.pro +3 -0
  50. package/android/spotless.gradle +9 -0
  51. package/android/src/main/AndroidManifest.xml +2 -0
  52. package/android/src/main/cpp/worklets/CMakeLists.txt +85 -0
  53. package/android/src/main/cpp/worklets/android/AndroidUIScheduler.cpp +63 -0
  54. package/android/src/main/cpp/worklets/android/AndroidUIScheduler.h +41 -0
  55. package/android/src/main/cpp/worklets/android/AnimationFrameCallback.h +32 -0
  56. package/android/src/main/cpp/worklets/android/PlatformLogger.cpp +29 -0
  57. package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +83 -0
  58. package/android/src/main/cpp/worklets/android/WorkletsModule.h +63 -0
  59. package/android/src/main/cpp/worklets/android/WorkletsOnLoad.cpp +13 -0
  60. package/android/src/main/java/com/swmansion/worklets/AndroidUIScheduler.java +60 -0
  61. package/android/src/main/java/com/swmansion/worklets/AnimationFrameQueue/AnimationFrameCallback.java +20 -0
  62. package/android/src/main/java/com/swmansion/worklets/AnimationFrameQueue/AnimationFrameQueue.java +113 -0
  63. package/android/src/main/java/com/swmansion/worklets/JSCallInvokerResolver.java +27 -0
  64. package/android/src/main/java/com/swmansion/worklets/WorkletsMessageQueueThread.java +16 -0
  65. package/android/src/main/java/com/swmansion/worklets/WorkletsMessageQueueThreadBase.java +72 -0
  66. package/android/src/main/java/com/swmansion/worklets/WorkletsModule.java +106 -0
  67. package/android/src/main/java/com/swmansion/worklets/WorkletsPackage.java +49 -0
  68. package/android/src/paper/com/swmansion/worklets/NativeWorkletsModuleSpec.java +26 -0
  69. package/apple/worklets/apple/AnimationFrameQueue.h +15 -0
  70. package/apple/worklets/apple/AnimationFrameQueue.mm +81 -0
  71. package/apple/worklets/apple/AssertJavaScriptQueue.h +14 -0
  72. package/apple/worklets/apple/AssertTurboModuleManagerQueue.h +16 -0
  73. package/apple/worklets/apple/IOSUIScheduler.h +14 -0
  74. package/apple/worklets/apple/IOSUIScheduler.mm +24 -0
  75. package/apple/worklets/apple/PlatformLogger.mm +31 -0
  76. package/apple/worklets/apple/SlowAnimations.h +8 -0
  77. package/apple/worklets/apple/SlowAnimations.mm +47 -0
  78. package/apple/worklets/apple/WorkletsDisplayLink.h +21 -0
  79. package/apple/worklets/apple/WorkletsMessageThread.h +16 -0
  80. package/apple/worklets/apple/WorkletsMessageThread.mm +32 -0
  81. package/apple/worklets/apple/WorkletsModule.h +10 -0
  82. package/apple/worklets/apple/WorkletsModule.mm +85 -0
  83. package/lib/module/PlatformChecker.js +35 -0
  84. package/lib/module/PlatformChecker.js.map +1 -0
  85. package/lib/module/WorkletsError.js +13 -0
  86. package/lib/module/WorkletsError.js.map +1 -0
  87. package/lib/module/WorkletsModule/JSWorklets.js +36 -0
  88. package/lib/module/WorkletsModule/JSWorklets.js.map +1 -0
  89. package/lib/module/WorkletsModule/NativeWorklets.js +39 -0
  90. package/lib/module/WorkletsModule/NativeWorklets.js.map +1 -0
  91. package/lib/module/WorkletsModule/index.js +4 -0
  92. package/lib/module/WorkletsModule/index.js.map +1 -0
  93. package/lib/module/WorkletsModule/workletsModuleInstance.js +7 -0
  94. package/lib/module/WorkletsModule/workletsModuleInstance.js.map +1 -0
  95. package/lib/module/WorkletsModule/workletsModuleInstance.web.js +5 -0
  96. package/lib/module/WorkletsModule/workletsModuleInstance.web.js.map +1 -0
  97. package/lib/module/WorkletsModule/workletsModuleProxy.js +4 -0
  98. package/lib/module/WorkletsModule/workletsModuleProxy.js.map +1 -0
  99. package/lib/module/animationFrameQueue/mockedRequestAnimationFrame.js +10 -0
  100. package/lib/module/animationFrameQueue/mockedRequestAnimationFrame.js.map +1 -0
  101. package/lib/module/animationFrameQueue/requestAnimationFrame.js +36 -0
  102. package/lib/module/animationFrameQueue/requestAnimationFrame.js.map +1 -0
  103. package/lib/module/errors.js +78 -0
  104. package/lib/module/errors.js.map +1 -0
  105. package/lib/module/index.js +17 -0
  106. package/lib/module/index.js.map +1 -0
  107. package/lib/module/initializers.js +158 -0
  108. package/lib/module/initializers.js.map +1 -0
  109. package/lib/module/logger/LogBox.js +15 -0
  110. package/lib/module/logger/LogBox.js.map +1 -0
  111. package/lib/module/logger/index.js +5 -0
  112. package/lib/module/logger/index.js.map +1 -0
  113. package/lib/module/logger/logger.js +137 -0
  114. package/lib/module/logger/logger.js.map +1 -0
  115. package/lib/module/privateGlobals.d.js +8 -0
  116. package/lib/module/privateGlobals.d.js.map +1 -0
  117. package/lib/module/runtimes.js +63 -0
  118. package/lib/module/runtimes.js.map +1 -0
  119. package/lib/module/shareableMappingCache.js +39 -0
  120. package/lib/module/shareableMappingCache.js.map +1 -0
  121. package/lib/module/shareables.js +417 -0
  122. package/lib/module/shareables.js.map +1 -0
  123. package/lib/module/specs/NativeWorkletsModule.js +5 -0
  124. package/lib/module/specs/NativeWorkletsModule.js.map +1 -0
  125. package/lib/module/specs/index.js +5 -0
  126. package/lib/module/specs/index.js.map +1 -0
  127. package/lib/module/threads.js +204 -0
  128. package/lib/module/threads.js.map +1 -0
  129. package/lib/module/valueUnpacker.js +83 -0
  130. package/lib/module/valueUnpacker.js.map +1 -0
  131. package/lib/module/workletFunction.js +37 -0
  132. package/lib/module/workletFunction.js.map +1 -0
  133. package/lib/module/workletTypes.js +12 -0
  134. package/lib/module/workletTypes.js.map +1 -0
  135. package/lib/typescript/PlatformChecker.d.ts +7 -0
  136. package/lib/typescript/PlatformChecker.d.ts.map +1 -0
  137. package/lib/typescript/WorkletsError.d.ts +3 -0
  138. package/lib/typescript/WorkletsError.d.ts.map +1 -0
  139. package/lib/typescript/WorkletsModule/JSWorklets.d.ts +3 -0
  140. package/lib/typescript/WorkletsModule/JSWorklets.d.ts.map +1 -0
  141. package/lib/typescript/WorkletsModule/NativeWorklets.d.ts +5 -0
  142. package/lib/typescript/WorkletsModule/NativeWorklets.d.ts.map +1 -0
  143. package/lib/typescript/WorkletsModule/index.d.ts +3 -0
  144. package/lib/typescript/WorkletsModule/index.d.ts.map +1 -0
  145. package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts +2 -0
  146. package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts.map +1 -0
  147. package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts +2 -0
  148. package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts.map +1 -0
  149. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +12 -0
  150. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -0
  151. package/lib/typescript/animationFrameQueue/mockedRequestAnimationFrame.d.ts +6 -0
  152. package/lib/typescript/animationFrameQueue/mockedRequestAnimationFrame.d.ts.map +1 -0
  153. package/lib/typescript/animationFrameQueue/requestAnimationFrame.d.ts +2 -0
  154. package/lib/typescript/animationFrameQueue/requestAnimationFrame.d.ts.map +1 -0
  155. package/lib/typescript/errors.d.ts +19 -0
  156. package/lib/typescript/errors.d.ts.map +1 -0
  157. package/lib/typescript/index.d.ts +13 -0
  158. package/lib/typescript/index.d.ts.map +1 -0
  159. package/lib/typescript/initializers.d.ts +6 -0
  160. package/lib/typescript/initializers.d.ts.map +1 -0
  161. package/lib/typescript/logger/LogBox.d.ts +32 -0
  162. package/lib/typescript/logger/LogBox.d.ts.map +1 -0
  163. package/lib/typescript/logger/index.d.ts +3 -0
  164. package/lib/typescript/logger/index.d.ts.map +1 -0
  165. package/lib/typescript/logger/logger.d.ts +52 -0
  166. package/lib/typescript/logger/logger.d.ts.map +1 -0
  167. package/lib/typescript/runtimes.d.ts +16 -0
  168. package/lib/typescript/runtimes.d.ts.map +1 -0
  169. package/lib/typescript/shareableMappingCache.d.ts +16 -0
  170. package/lib/typescript/shareableMappingCache.d.ts.map +1 -0
  171. package/lib/typescript/shareables.d.ts +15 -0
  172. package/lib/typescript/shareables.d.ts.map +1 -0
  173. package/lib/typescript/specs/NativeWorkletsModule.d.ts +7 -0
  174. package/lib/typescript/specs/NativeWorkletsModule.d.ts.map +1 -0
  175. package/lib/typescript/specs/index.d.ts +3 -0
  176. package/lib/typescript/specs/index.d.ts.map +1 -0
  177. package/lib/typescript/threads.d.ts +49 -0
  178. package/lib/typescript/threads.d.ts.map +1 -0
  179. package/lib/typescript/valueUnpacker.d.ts +2 -0
  180. package/lib/typescript/valueUnpacker.d.ts.map +1 -0
  181. package/lib/typescript/workletFunction.d.ts +27 -0
  182. package/lib/typescript/workletFunction.d.ts.map +1 -0
  183. package/lib/typescript/workletTypes.d.ts +49 -0
  184. package/lib/typescript/workletTypes.d.ts.map +1 -0
  185. package/package.json +106 -8
  186. package/plugin/index.js +3 -0
  187. package/scripts/worklets_utils.rb +53 -0
  188. package/src/PlatformChecker.ts +43 -0
  189. package/src/WorkletsError.ts +13 -0
  190. package/src/WorkletsModule/JSWorklets.ts +57 -0
  191. package/src/WorkletsModule/NativeWorklets.ts +68 -0
  192. package/src/WorkletsModule/index.ts +7 -0
  193. package/src/WorkletsModule/workletsModuleInstance.ts +9 -0
  194. package/src/WorkletsModule/workletsModuleInstance.web.ts +5 -0
  195. package/src/WorkletsModule/workletsModuleProxy.ts +30 -0
  196. package/src/animationFrameQueue/mockedRequestAnimationFrame.ts +11 -0
  197. package/src/animationFrameQueue/requestAnimationFrame.ts +41 -0
  198. package/src/errors.ts +103 -0
  199. package/src/index.ts +42 -0
  200. package/src/initializers.ts +175 -0
  201. package/src/logger/LogBox.ts +55 -0
  202. package/src/logger/index.ts +3 -0
  203. package/src/logger/logger.ts +155 -0
  204. package/src/privateGlobals.d.ts +41 -0
  205. package/src/runtimes.ts +92 -0
  206. package/src/shareableMappingCache.ts +44 -0
  207. package/src/shareables.ts +577 -0
  208. package/src/specs/NativeWorkletsModule.ts +9 -0
  209. package/src/specs/index.ts +5 -0
  210. package/src/threads.ts +275 -0
  211. package/src/valueUnpacker.ts +110 -0
  212. package/src/workletFunction.ts +47 -0
  213. package/src/workletTypes.ts +76 -0
  214. package/Animated.js +0 -13
  215. package/AnimatedEvent.js +0 -167
  216. package/AnimatedImplementation.js +0 -666
  217. package/CoreAnimated.js +0 -43
  218. package/Easing.js +0 -236
  219. package/NativeAnimatedHelper.js +0 -226
  220. package/SpringConfig.js +0 -79
  221. package/animations/Animation.js +0 -36
  222. package/animations/DecayAnimation.js +0 -70
  223. package/animations/SpringAnimation.js +0 -125
  224. package/animations/TimingAnimation.js +0 -70
  225. package/bezier.js +0 -128
  226. package/createAnimatedComponent.js +0 -188
  227. package/nodes/AnimatedBlock.js +0 -19
  228. package/nodes/AnimatedClock.js +0 -76
  229. package/nodes/AnimatedCond.js +0 -23
  230. package/nodes/AnimatedDetach.js +0 -15
  231. package/nodes/AnimatedInterpolation.js +0 -338
  232. package/nodes/AnimatedNode.js +0 -97
  233. package/nodes/AnimatedOnChange.js +0 -28
  234. package/nodes/AnimatedOp.js +0 -17
  235. package/nodes/AnimatedProps.js +0 -154
  236. package/nodes/AnimatedSet.js +0 -19
  237. package/nodes/AnimatedStartClock.js +0 -21
  238. package/nodes/AnimatedStopClock.js +0 -21
  239. package/nodes/AnimatedStyle.js +0 -89
  240. package/nodes/AnimatedTracking.js +0 -36
  241. package/nodes/AnimatedTransform.js +0 -93
  242. package/nodes/AnimatedValue.js +0 -271
  243. package/nodes/AnimatedWithInput.js +0 -21
  244. package/nodes/SpringNode.js +0 -106
  245. package/nodes/TimingStep.js +0 -44
  246. package/utils.js +0 -28
@@ -0,0 +1,52 @@
1
+ #include <worklets/Tools/AsyncQueue.h>
2
+
3
+ #include <utility>
4
+
5
+ namespace worklets {
6
+
7
+ AsyncQueue::AsyncQueue(std::string name)
8
+ : state_(std::make_shared<AsyncQueueState>()) {
9
+ auto thread = std::thread([name, state = state_] {
10
+ #if __APPLE__
11
+ pthread_setname_np(name.c_str());
12
+ #endif
13
+ while (state->running) {
14
+ std::unique_lock<std::mutex> lock(state->mutex);
15
+ state->cv.wait(
16
+ lock, [state] { return !state->queue.empty() || !state->running; });
17
+ if (!state->running) {
18
+ return;
19
+ }
20
+ if (state->queue.empty()) {
21
+ continue;
22
+ }
23
+ auto job = std::move(state->queue.front());
24
+ state->queue.pop();
25
+ lock.unlock();
26
+ job();
27
+ }
28
+ });
29
+ #ifdef ANDROID
30
+ pthread_setname_np(thread.native_handle(), name.c_str());
31
+ #endif
32
+ thread.detach();
33
+ }
34
+
35
+ AsyncQueue::~AsyncQueue() {
36
+ {
37
+ std::unique_lock<std::mutex> lock(state_->mutex);
38
+ state_->running = false;
39
+ state_->queue = {};
40
+ }
41
+ state_->cv.notify_all();
42
+ }
43
+
44
+ void AsyncQueue::push(std::function<void()> &&job) {
45
+ {
46
+ std::unique_lock<std::mutex> lock(state_->mutex);
47
+ state_->queue.emplace(job);
48
+ }
49
+ state_->cv.notify_one();
50
+ }
51
+
52
+ } // namespace worklets
@@ -0,0 +1,35 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+
5
+ #include <atomic>
6
+ #include <condition_variable>
7
+ #include <memory>
8
+ #include <queue>
9
+ #include <string>
10
+ #include <thread>
11
+ #include <utility>
12
+ #include <vector>
13
+
14
+ namespace worklets {
15
+
16
+ struct AsyncQueueState {
17
+ std::atomic_bool running{true};
18
+ std::mutex mutex;
19
+ std::condition_variable cv;
20
+ std::queue<std::function<void()>> queue;
21
+ };
22
+
23
+ class AsyncQueue {
24
+ public:
25
+ explicit AsyncQueue(std::string name);
26
+
27
+ ~AsyncQueue();
28
+
29
+ void push(std::function<void()> &&job);
30
+
31
+ private:
32
+ const std::shared_ptr<AsyncQueueState> state_;
33
+ };
34
+
35
+ } // namespace worklets
@@ -0,0 +1,10 @@
1
+ #pragma once
2
+
3
+ /*
4
+ On Android JS_RUNTIME_HERMES is set in CMakeList.txt,
5
+ but on iOS there is no simple way to defect if Hermes exists
6
+ so we have to check if headers are available.
7
+ */
8
+ #if __APPLE__ && __has_include(<hermes/hermes.h>)
9
+ #define JS_RUNTIME_HERMES 1
10
+ #endif
@@ -0,0 +1,342 @@
1
+ #include <worklets/Tools/JSISerializer.h>
2
+
3
+ #include <cxxabi.h>
4
+ #include <iostream>
5
+ #include <sstream>
6
+
7
+ namespace worklets {
8
+
9
+ const std::vector<std::string> SUPPORTED_ERROR_TYPES = {
10
+ "Error",
11
+ "AggregateError",
12
+ "EvalError",
13
+ "RangeError",
14
+ "ReferenceError",
15
+ "SyntaxError",
16
+ "TypeError",
17
+ "URIError",
18
+ "InternalError"};
19
+
20
+ const std::vector<std::string> SUPPORTED_INDEXED_COLLECTION_TYPES = {
21
+ "Int8Array",
22
+ "Uint8Array",
23
+ "Uint8ClampedArray",
24
+ "Int16Array",
25
+ "Uint16Array",
26
+ "Int32Array",
27
+ "Uint32Array",
28
+ "BigInt64Array",
29
+ "BigUint64Array",
30
+ "Float32Array",
31
+ "Float64Array",
32
+ };
33
+
34
+ const std::vector<std::string> SUPPORTED_STRUCTURED_DATA_TYPES = {
35
+ "ArrayBuffer",
36
+ "SharedArrayBuffer",
37
+ "DataView",
38
+ "Atomics",
39
+ "JSON",
40
+ };
41
+
42
+ const std::vector<std::string> SUPPORTED_MANAGING_MEMORY_TYPES = {
43
+ "WeakRef",
44
+ "FinalizationRegistry",
45
+ };
46
+
47
+ const std::vector<std::string> SUPPORTED_ABSTRACTION_OBJECT_TYPES = {
48
+ "Iterator",
49
+ "AsyncIterator",
50
+ "Promise",
51
+ "GeneratorFunction",
52
+ "AsyncGeneratorFunction",
53
+ "Generator",
54
+ "AsyncGenerator",
55
+ "AsyncFunction",
56
+ };
57
+
58
+ const std::vector<std::string> SUPPORTED_REFLECTION_TYPES = {
59
+ "Reflect",
60
+ "Proxy",
61
+ };
62
+
63
+ static inline std::string getObjectTypeName(
64
+ jsi::Runtime &rt,
65
+ const jsi::Object &object) {
66
+ return object.getPropertyAsObject(rt, "constructor")
67
+ .getProperty(rt, "name")
68
+ .toString(rt)
69
+ .utf8(rt);
70
+ }
71
+
72
+ static inline bool isInstanceOf(
73
+ jsi::Runtime &rt,
74
+ const jsi::Object &object,
75
+ const std::string &type) {
76
+ return getObjectTypeName(rt, object) == type;
77
+ }
78
+
79
+ static inline bool isInstanceOfAny(
80
+ jsi::Runtime &rt,
81
+ const jsi::Object &object,
82
+ const std::vector<std::string> &supportedTypes) {
83
+ auto instanceType = getObjectTypeName(rt, object);
84
+
85
+ return std::find(
86
+ supportedTypes.begin(), supportedTypes.end(), instanceType) !=
87
+ supportedTypes.end();
88
+ }
89
+
90
+ JSISerializer::JSISerializer(jsi::Runtime &rt)
91
+ : rt_(rt),
92
+ visitedNodes_(rt_.global()
93
+ .getPropertyAsFunction(rt_, "Set")
94
+ .callAsConstructor(rt_)
95
+ .asObject(rt_)) {}
96
+
97
+ std::string JSISerializer::stringifyWithName(const jsi::Object &object) {
98
+ std::stringstream ss;
99
+ ss << '[' << getObjectTypeName(rt_, object) << ']';
100
+
101
+ return ss.str();
102
+ }
103
+
104
+ std::string JSISerializer::stringifyArray(const jsi::Array &arr) {
105
+ std::stringstream ss;
106
+ ss << '[';
107
+
108
+ for (size_t i = 0, length = arr.size(rt_); i < length; i++) {
109
+ jsi::Value element = arr.getValueAtIndex(rt_, i);
110
+ ss << stringifyJSIValueRecursively(element);
111
+ if (i != length - 1) {
112
+ ss << ", ";
113
+ }
114
+ }
115
+
116
+ ss << ']';
117
+
118
+ return ss.str();
119
+ }
120
+
121
+ std::string JSISerializer::stringifyFunction(const jsi::Function &func) {
122
+ std::stringstream ss;
123
+ auto kind = (func.isHostFunction(rt_) ? "jsi::HostFunction" : "Function");
124
+ auto name = func.getProperty(rt_, "name").toString(rt_).utf8(rt_);
125
+ name = name.empty() ? "anonymous" : name;
126
+
127
+ ss << '[' << kind << ' ' << name << ']';
128
+ return ss.str();
129
+ }
130
+
131
+ std::string JSISerializer::stringifyHostObject(jsi::HostObject &hostObject) {
132
+ int status = -1;
133
+ char *hostObjClassName =
134
+ abi::__cxa_demangle(typeid(hostObject).name(), NULL, NULL, &status);
135
+ if (status != 0) {
136
+ return "[jsi::HostObject]";
137
+ }
138
+
139
+ std::stringstream ss;
140
+ ss << "[jsi::HostObject(" << hostObjClassName << ")";
141
+ std::free(hostObjClassName);
142
+
143
+ auto props = hostObject.getPropertyNames(rt_);
144
+ auto propsCount = props.size();
145
+
146
+ if (propsCount > 0) {
147
+ ss << " {";
148
+ auto lastKey = props.back().utf8(rt_);
149
+ for (const auto &key : props) {
150
+ auto formattedKey = key.utf8(rt_);
151
+ auto value = hostObject.get(rt_, key);
152
+ ss << '"' << formattedKey << '"' << ": "
153
+ << stringifyJSIValueRecursively(value);
154
+ if (formattedKey != lastKey) {
155
+ ss << ", ";
156
+ }
157
+ }
158
+ ss << '}';
159
+ }
160
+ ss << ']';
161
+
162
+ return ss.str();
163
+ }
164
+
165
+ std::string JSISerializer::stringifyObject(const jsi::Object &object) {
166
+ std::stringstream ss;
167
+ ss << '{';
168
+
169
+ auto props = object.getPropertyNames(rt_);
170
+
171
+ for (size_t i = 0, propsCount = props.size(rt_); i < propsCount; i++) {
172
+ jsi::String propName = props.getValueAtIndex(rt_, i).toString(rt_);
173
+ ss << '"' << propName.utf8(rt_) << '"' << ": "
174
+ << stringifyJSIValueRecursively(object.getProperty(rt_, propName));
175
+ if (i != propsCount - 1) {
176
+ ss << ", ";
177
+ }
178
+ }
179
+
180
+ ss << '}';
181
+
182
+ return ss.str();
183
+ }
184
+
185
+ std::string JSISerializer::stringifyError(const jsi::Object &object) {
186
+ std::stringstream ss;
187
+ ss << '[' << object.getProperty(rt_, "name").toString(rt_).utf8(rt_) << ": "
188
+ << object.getProperty(rt_, "message").toString(rt_).utf8(rt_) << ']';
189
+ return ss.str();
190
+ }
191
+
192
+ std::string JSISerializer::stringifySet(const jsi::Object &object) {
193
+ std::stringstream ss;
194
+ jsi::Function arrayFrom = rt_.global()
195
+ .getPropertyAsObject(rt_, "Array")
196
+ .getPropertyAsFunction(rt_, "from");
197
+ jsi::Object result = arrayFrom.call(rt_, object).asObject(rt_);
198
+
199
+ if (!result.isArray(rt_)) {
200
+ return "[Set]";
201
+ }
202
+
203
+ auto arr = result.asArray(rt_);
204
+ ss << "Set {";
205
+
206
+ for (size_t i = 0, length = arr.size(rt_); i < length; i++) {
207
+ ss << stringifyJSIValueRecursively(arr.getValueAtIndex(rt_, i));
208
+ if (i != length - 1) {
209
+ ss << ", ";
210
+ }
211
+ }
212
+
213
+ ss << '}';
214
+
215
+ return ss.str();
216
+ }
217
+
218
+ std::string JSISerializer::stringifyMap(const jsi::Object &object) {
219
+ std::stringstream ss;
220
+ jsi::Function arrayFrom = rt_.global()
221
+ .getPropertyAsObject(rt_, "Array")
222
+ .getPropertyAsFunction(rt_, "from");
223
+ jsi::Object result = arrayFrom.call(rt_, object).asObject(rt_);
224
+
225
+ if (!result.isArray(rt_)) {
226
+ return "[Map]";
227
+ }
228
+
229
+ auto arr = result.asArray(rt_);
230
+ ss << "Map {";
231
+
232
+ for (size_t i = 0, length = arr.size(rt_); i < length; i++) {
233
+ auto pair = arr.getValueAtIndex(rt_, i).asObject(rt_).getArray(rt_);
234
+ auto key = pair.getValueAtIndex(rt_, 0);
235
+ auto value = pair.getValueAtIndex(rt_, 1);
236
+ ss << stringifyJSIValueRecursively(key) << ": "
237
+ << stringifyJSIValueRecursively(value);
238
+ if (i != length - 1) {
239
+ ss << ", ";
240
+ }
241
+ }
242
+
243
+ ss << '}';
244
+
245
+ return ss.str();
246
+ }
247
+
248
+ std::string JSISerializer::stringifyRecursiveType(const jsi::Object &object) {
249
+ auto type = getObjectTypeName(rt_, object);
250
+
251
+ if (type == "Array") {
252
+ return "[...]";
253
+ }
254
+ if (type == "Object") {
255
+ return "{...}";
256
+ }
257
+ return "...";
258
+ }
259
+
260
+ std::string JSISerializer::stringifyWithToString(const jsi::Object &object) {
261
+ return object.getPropertyAsFunction(rt_, "toString")
262
+ .callWithThis(rt_, object)
263
+ .toString(rt_)
264
+ .utf8(rt_);
265
+ }
266
+
267
+ std::string JSISerializer::stringifyJSIValueRecursively(
268
+ const jsi::Value &value,
269
+ bool isTopLevel) {
270
+ if (value.isBool() || value.isNumber()) {
271
+ return value.toString(rt_).utf8(rt_);
272
+ }
273
+ if (value.isString()) {
274
+ return isTopLevel ? value.getString(rt_).utf8(rt_)
275
+ : '"' + value.getString(rt_).utf8(rt_) + '"';
276
+ }
277
+ if (value.isSymbol()) {
278
+ return value.getSymbol(rt_).toString(rt_);
279
+ }
280
+ if (value.isBigInt()) {
281
+ return value.getBigInt(rt_).toString(rt_).utf8(rt_) + 'n';
282
+ }
283
+ if (value.isUndefined()) {
284
+ return "undefined";
285
+ }
286
+ if (value.isNull()) {
287
+ return "null";
288
+ }
289
+ if (value.isObject()) {
290
+ jsi::Object object = value.asObject(rt_);
291
+
292
+ if (hasBeenVisited(object)) {
293
+ return stringifyRecursiveType(object);
294
+ }
295
+ markAsVisited(object);
296
+
297
+ if (object.isArray(rt_)) {
298
+ return stringifyArray(object.getArray(rt_));
299
+ }
300
+ if (object.isFunction(rt_)) {
301
+ return stringifyFunction(object.getFunction(rt_));
302
+ }
303
+ if (object.isHostObject(rt_)) {
304
+ return stringifyHostObject(*object.getHostObject(rt_));
305
+ }
306
+ if (isInstanceOfAny(rt_, object, SUPPORTED_ERROR_TYPES)) {
307
+ return stringifyError(object);
308
+ }
309
+ if (isInstanceOfAny(rt_, object, SUPPORTED_INDEXED_COLLECTION_TYPES) ||
310
+ isInstanceOfAny(rt_, object, SUPPORTED_STRUCTURED_DATA_TYPES) ||
311
+ isInstanceOfAny(rt_, object, SUPPORTED_MANAGING_MEMORY_TYPES) ||
312
+ isInstanceOfAny(rt_, object, SUPPORTED_ABSTRACTION_OBJECT_TYPES) ||
313
+ isInstanceOfAny(rt_, object, SUPPORTED_REFLECTION_TYPES) ||
314
+ isInstanceOf(rt_, object, "Intl") ||
315
+ isInstanceOf(rt_, object, "WeakMap") ||
316
+ isInstanceOf(rt_, object, "WeakSet")) {
317
+ // TODO: Consider extending this log info
318
+ return stringifyWithName(object);
319
+ }
320
+ if (isInstanceOf(rt_, object, "Date") ||
321
+ isInstanceOf(rt_, object, "RegExp")) {
322
+ return stringifyWithToString(object);
323
+ }
324
+ if (isInstanceOf(rt_, object, "Map")) {
325
+ return stringifyMap(object);
326
+ }
327
+ if (isInstanceOf(rt_, object, "Set")) {
328
+ return stringifySet(object);
329
+ }
330
+ return stringifyObject(object);
331
+ }
332
+
333
+ throw std::runtime_error("[Worklets] Unsupported value type.");
334
+ }
335
+
336
+ std::string stringifyJSIValue(jsi::Runtime &rt, const jsi::Value &value) {
337
+ JSISerializer serializer(rt);
338
+
339
+ return serializer.stringifyJSIValueRecursively(value, true);
340
+ }
341
+
342
+ } // namespace worklets
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <string>
5
+ #include <vector>
6
+
7
+ using namespace facebook;
8
+
9
+ namespace worklets {
10
+
11
+ class JSISerializer {
12
+ public:
13
+ explicit JSISerializer(jsi::Runtime &rt);
14
+ std::string stringifyJSIValueRecursively(
15
+ const jsi::Value &value,
16
+ bool isTopLevel = false);
17
+
18
+ private:
19
+ std::string stringifyArray(const jsi::Array &arr);
20
+ std::string stringifyFunction(const jsi::Function &func);
21
+ std::string stringifyHostObject(jsi::HostObject &hostObject);
22
+ std::string stringifyObject(const jsi::Object &object);
23
+ std::string stringifyError(const jsi::Object &object);
24
+ std::string stringifySet(const jsi::Object &object);
25
+ std::string stringifyMap(const jsi::Object &object);
26
+ std::string stringifyWithName(const jsi::Object &object);
27
+ std::string stringifyWithToString(const jsi::Object &object);
28
+ std::string stringifyRecursiveType(const jsi::Object &object);
29
+
30
+ bool hasBeenVisited(const jsi::Object &object) {
31
+ return visitedNodes_.getPropertyAsFunction(rt_, "has")
32
+ .callWithThis(rt_, visitedNodes_, object)
33
+ .getBool();
34
+ }
35
+
36
+ void markAsVisited(const jsi::Object &object) {
37
+ visitedNodes_.getPropertyAsFunction(rt_, "add")
38
+ .callWithThis(rt_, visitedNodes_, object);
39
+ }
40
+
41
+ jsi::Runtime &rt_;
42
+ jsi::Object visitedNodes_;
43
+ };
44
+
45
+ std::string stringifyJSIValue(jsi::Runtime &rt, const jsi::Value &value);
46
+
47
+ } // namespace worklets
@@ -0,0 +1,16 @@
1
+ #include <worklets/Tools/JSLogger.h>
2
+ #include <memory>
3
+
4
+ namespace worklets {
5
+
6
+ void JSLogger::warnOnJS(const std::string &warning) const {
7
+ #ifndef NDEBUG
8
+ jsScheduler_->scheduleOnJS([warning](jsi::Runtime &rt) {
9
+ auto console = rt.global().getPropertyAsObject(rt, "console");
10
+ auto warn = console.getPropertyAsFunction(rt, "warn");
11
+ warn.call(rt, jsi::String::createFromUtf8(rt, warning));
12
+ });
13
+ #endif // NDEBUG
14
+ }
15
+
16
+ } // namespace worklets
@@ -0,0 +1,20 @@
1
+ #pragma once
2
+
3
+ #include <worklets/Tools/JSScheduler.h>
4
+
5
+ #include <memory>
6
+ #include <string>
7
+
8
+ namespace worklets {
9
+
10
+ class JSLogger {
11
+ public:
12
+ explicit JSLogger(const std::shared_ptr<JSScheduler> &jsScheduler)
13
+ : jsScheduler_(jsScheduler) {}
14
+ void warnOnJS(const std::string &warning) const;
15
+
16
+ private:
17
+ const std::shared_ptr<JSScheduler> jsScheduler_;
18
+ };
19
+
20
+ } // namespace worklets
@@ -0,0 +1,10 @@
1
+ #include <worklets/Tools/JSScheduler.h>
2
+
3
+ namespace worklets {
4
+
5
+ void JSScheduler::scheduleOnJS(Job job) {
6
+ jsCallInvoker_->invokeAsync(
7
+ [job = std::move(job), &rt = rnRuntime_] { job(rt); });
8
+ }
9
+
10
+ } // namespace worklets
@@ -0,0 +1,29 @@
1
+ #pragma once
2
+
3
+ #include <ReactCommon/CallInvoker.h>
4
+ #include <jsi/jsi.h>
5
+
6
+ #include <memory>
7
+
8
+ using namespace facebook;
9
+ using namespace react;
10
+
11
+ namespace worklets {
12
+
13
+ class JSScheduler {
14
+ using Job = std::function<void(jsi::Runtime &rt)>;
15
+
16
+ public:
17
+ explicit JSScheduler(
18
+ jsi::Runtime &rnRuntime,
19
+ const std::shared_ptr<CallInvoker> &jsCallInvoker)
20
+ : rnRuntime_(rnRuntime), jsCallInvoker_(jsCallInvoker) {}
21
+
22
+ void scheduleOnJS(std::function<void(jsi::Runtime &rt)> job);
23
+
24
+ protected:
25
+ jsi::Runtime &rnRuntime_;
26
+ const std::shared_ptr<CallInvoker> jsCallInvoker_;
27
+ };
28
+
29
+ } // namespace worklets
@@ -0,0 +1,16 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ namespace worklets {
6
+
7
+ class PlatformLogger {
8
+ public:
9
+ static void log(const char *str);
10
+ static void log(const std::string &str);
11
+ static void log(const double d);
12
+ static void log(const int i);
13
+ static void log(const bool b);
14
+ };
15
+
16
+ } // namespace worklets
@@ -0,0 +1,72 @@
1
+ #pragma once
2
+
3
+ #ifndef NDEBUG
4
+
5
+ #include <cxxabi.h>
6
+
7
+ #include <atomic>
8
+ #include <cassert>
9
+ #include <iostream>
10
+ #include <string>
11
+
12
+ #ifdef ANDROID
13
+ #include <android/log.h>
14
+ #endif // ANDROID
15
+
16
+ namespace worklets {
17
+
18
+ // This is a class that counts how many instances of a different class there
19
+ // are. It is meant only to be used with classes that should only have one
20
+ // instance.
21
+
22
+ template <class T>
23
+ class SingleInstanceChecker {
24
+ public:
25
+ SingleInstanceChecker();
26
+ ~SingleInstanceChecker();
27
+
28
+ private:
29
+ void assertWithMessage(bool condition, std::string message) {
30
+ if (!condition) {
31
+ #ifdef ANDROID
32
+ __android_log_print(
33
+ ANDROID_LOG_WARN, "Worklets", "%s", message.c_str());
34
+ #else
35
+ std::cerr << "[Worklets] " << message << std::endl;
36
+ #endif
37
+
38
+ #ifdef IS_REANIMATED_EXAMPLE_APP
39
+ assert(false);
40
+ #endif
41
+ }
42
+ }
43
+
44
+ // A static field will exist separately for every class template.
45
+ // This has to be inline for automatic initialization.
46
+ inline static std::atomic<int> instanceCount_;
47
+ };
48
+
49
+ template <class T>
50
+ SingleInstanceChecker<T>::SingleInstanceChecker() {
51
+ int status = 0;
52
+ std::string className =
53
+ __cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
54
+
55
+ // React Native can spawn up to two instances of a Native Module at the same
56
+ // time. This happens during a reload when a new instance of React Native is
57
+ // created while simultaneously the old one is torn down.
58
+ instanceCount_++;
59
+ assertWithMessage(
60
+ instanceCount_ <= 2,
61
+ "[Worklets] More than two instances of " + className +
62
+ " present. This may indicate a memory leak due to a retain cycle.");
63
+ }
64
+
65
+ template <class T>
66
+ SingleInstanceChecker<T>::~SingleInstanceChecker() {
67
+ instanceCount_--;
68
+ }
69
+
70
+ } // namespace worklets
71
+
72
+ #endif // NDEBUG