react-native-worklets 0.3.0 → 0.4.0-bundle-mode-preview-1

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 (202) hide show
  1. package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.cpp +532 -0
  2. package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.h +88 -0
  3. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +40 -122
  4. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +16 -40
  5. package/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.h +2 -1
  6. package/Common/cpp/worklets/Resources/ValueUnpacker.cpp +1 -1
  7. package/Common/cpp/worklets/SharedItems/Shareables.cpp +200 -24
  8. package/Common/cpp/worklets/SharedItems/Shareables.h +108 -7
  9. package/Common/cpp/worklets/Tools/JSLogger.cpp +56 -4
  10. package/Common/cpp/worklets/Tools/JSLogger.h +17 -0
  11. package/Common/cpp/worklets/Tools/JSScheduler.cpp +12 -0
  12. package/Common/cpp/worklets/Tools/JSScheduler.h +10 -2
  13. package/Common/cpp/worklets/Tools/SingleInstanceChecker.h +3 -1
  14. package/Common/cpp/worklets/Tools/WorkletsJSIUtils.cpp +19 -1
  15. package/Common/cpp/worklets/Tools/WorkletsJSIUtils.h +12 -3
  16. package/Common/cpp/worklets/Tools/WorkletsSystraceSection.h +136 -0
  17. package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp +4 -4
  18. package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h +1 -1
  19. package/Common/cpp/worklets/WorkletRuntime/RuntimeManager.cpp +85 -0
  20. package/Common/cpp/worklets/WorkletRuntime/RuntimeManager.h +55 -0
  21. package/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.h +8 -4
  22. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +70 -24
  23. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +24 -4
  24. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +53 -1
  25. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +2 -1
  26. package/RNWorklets.podspec +9 -4
  27. package/android/CMakeLists.txt +14 -36
  28. package/android/build.gradle +16 -33
  29. package/android/src/experimentalBundling/com/swmansion/worklets/WorkletsModule.java +149 -0
  30. package/android/src/{main/java → legacyBundling}/com/swmansion/worklets/WorkletsModule.java +17 -2
  31. package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +49 -8
  32. package/android/src/main/cpp/worklets/android/WorkletsModule.h +17 -2
  33. package/android/src/main/java/com/swmansion/worklets/WorkletsPackage.java +1 -1
  34. package/apple/worklets/apple/WorkletsMessageThread.mm +4 -0
  35. package/apple/worklets/apple/WorkletsModule.h +16 -1
  36. package/apple/worklets/apple/WorkletsModule.mm +29 -2
  37. package/bundleMode/index.d.ts +3 -0
  38. package/bundleMode/index.js +55 -0
  39. package/lib/module/PlatformChecker/PlatformChecker.js +8 -0
  40. package/lib/module/PlatformChecker/PlatformChecker.js.map +1 -0
  41. package/lib/module/PlatformChecker/index.js +17 -0
  42. package/lib/module/PlatformChecker/index.js.map +1 -0
  43. package/lib/module/WorkletsError.js +2 -1
  44. package/lib/module/WorkletsError.js.map +1 -1
  45. package/lib/module/WorkletsModule/JSWorklets.js +36 -4
  46. package/lib/module/WorkletsModule/JSWorklets.js.map +1 -1
  47. package/lib/module/WorkletsModule/NativeWorklets.js +35 -15
  48. package/lib/module/WorkletsModule/NativeWorklets.js.map +1 -1
  49. package/lib/module/WorkletsModule/workletsModuleInstance.js +2 -2
  50. package/lib/module/WorkletsModule/workletsModuleInstance.js.map +1 -1
  51. package/lib/module/bundleUnpacker.js +47 -0
  52. package/lib/module/bundleUnpacker.js.map +1 -0
  53. package/lib/module/callGuard.js +30 -0
  54. package/lib/module/callGuard.js.map +1 -0
  55. package/lib/module/errors.js +30 -11
  56. package/lib/module/errors.js.map +1 -1
  57. package/lib/module/index.js +10 -7
  58. package/lib/module/index.js.map +1 -1
  59. package/lib/module/initializers.js +123 -103
  60. package/lib/module/initializers.js.map +1 -1
  61. package/lib/module/logger.js +15 -0
  62. package/lib/module/logger.js.map +1 -0
  63. package/lib/module/privateGlobals.d.js +0 -1
  64. package/lib/module/privateGlobals.d.js.map +1 -1
  65. package/lib/module/publicGlobals.js +5 -0
  66. package/lib/module/publicGlobals.js.map +1 -0
  67. package/lib/module/runLoop/mockedRequestAnimationFrame.js.map +1 -0
  68. package/lib/module/runLoop/requestAnimationFrame.js +50 -0
  69. package/lib/module/runLoop/requestAnimationFrame.js.map +1 -0
  70. package/lib/module/runLoop/setImmediatePolyfill.js +15 -0
  71. package/lib/module/runLoop/setImmediatePolyfill.js.map +1 -0
  72. package/lib/module/runLoop/setIntervalPolyfill.js +26 -0
  73. package/lib/module/runLoop/setIntervalPolyfill.js.map +1 -0
  74. package/lib/module/runLoop/setTimeoutPolyfill.js +32 -0
  75. package/lib/module/runLoop/setTimeoutPolyfill.js.map +1 -0
  76. package/lib/module/runtimes.js +6 -10
  77. package/lib/module/runtimes.js.map +1 -1
  78. package/lib/module/shareableMappingCache.js +1 -3
  79. package/lib/module/shareableMappingCache.js.map +1 -1
  80. package/lib/module/shareables.js +116 -34
  81. package/lib/module/shareables.js.map +1 -1
  82. package/lib/module/specs/index.js +2 -2
  83. package/lib/module/specs/index.js.map +1 -1
  84. package/lib/module/threads.js +49 -54
  85. package/lib/module/threads.js.map +1 -1
  86. package/lib/module/valueUnpacker.js +3 -3
  87. package/lib/module/valueUnpacker.js.map +1 -1
  88. package/lib/module/workletRuntimeEntry.js +30 -0
  89. package/lib/module/workletRuntimeEntry.js.map +1 -0
  90. package/lib/typescript/PlatformChecker/PlatformChecker.d.ts +5 -0
  91. package/lib/typescript/PlatformChecker/PlatformChecker.d.ts.map +1 -0
  92. package/lib/typescript/PlatformChecker/index.d.ts +10 -0
  93. package/lib/typescript/PlatformChecker/index.d.ts.map +1 -0
  94. package/lib/typescript/WorkletsError.d.ts.map +1 -1
  95. package/lib/typescript/WorkletsModule/JSWorklets.d.ts.map +1 -1
  96. package/lib/typescript/WorkletsModule/NativeWorklets.d.ts +1 -3
  97. package/lib/typescript/WorkletsModule/NativeWorklets.d.ts.map +1 -1
  98. package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts +1 -1
  99. package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts.map +1 -1
  100. package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts +1 -1
  101. package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts.map +1 -1
  102. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +12 -2
  103. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -1
  104. package/lib/typescript/bundleUnpacker.d.ts +7 -0
  105. package/lib/typescript/bundleUnpacker.d.ts.map +1 -0
  106. package/lib/typescript/callGuard.d.ts +4 -0
  107. package/lib/typescript/callGuard.d.ts.map +1 -0
  108. package/lib/typescript/errors.d.ts +13 -5
  109. package/lib/typescript/errors.d.ts.map +1 -1
  110. package/lib/typescript/index.d.ts +1 -2
  111. package/lib/typescript/index.d.ts.map +1 -1
  112. package/lib/typescript/initializers.d.ts +16 -5
  113. package/lib/typescript/initializers.d.ts.map +1 -1
  114. package/lib/typescript/logger.d.ts +5 -0
  115. package/lib/typescript/logger.d.ts.map +1 -0
  116. package/lib/typescript/publicGlobals.d.ts +22 -0
  117. package/lib/typescript/publicGlobals.d.ts.map +1 -0
  118. package/lib/typescript/runLoop/mockedRequestAnimationFrame.d.ts.map +1 -0
  119. package/lib/typescript/runLoop/requestAnimationFrame.d.ts.map +1 -0
  120. package/lib/typescript/runLoop/setImmediatePolyfill.d.ts +2 -0
  121. package/lib/typescript/runLoop/setImmediatePolyfill.d.ts.map +1 -0
  122. package/lib/typescript/runLoop/setIntervalPolyfill.d.ts +2 -0
  123. package/lib/typescript/runLoop/setIntervalPolyfill.d.ts.map +1 -0
  124. package/lib/typescript/runLoop/setTimeoutPolyfill.d.ts +2 -0
  125. package/lib/typescript/runLoop/setTimeoutPolyfill.d.ts.map +1 -0
  126. package/lib/typescript/runtimes.d.ts.map +1 -1
  127. package/lib/typescript/shareableMappingCache.d.ts.map +1 -1
  128. package/lib/typescript/shareables.d.ts +3 -2
  129. package/lib/typescript/shareables.d.ts.map +1 -1
  130. package/lib/typescript/specs/NativeWorkletsModule.d.ts +1 -1
  131. package/lib/typescript/specs/NativeWorkletsModule.d.ts.map +1 -1
  132. package/lib/typescript/specs/index.d.ts +2 -2
  133. package/lib/typescript/specs/index.d.ts.map +1 -1
  134. package/lib/typescript/threads.d.ts.map +1 -1
  135. package/lib/typescript/workletRuntimeEntry.d.ts +14 -0
  136. package/lib/typescript/workletRuntimeEntry.d.ts.map +1 -0
  137. package/lib/typescript/workletTypes.d.ts +14 -3
  138. package/lib/typescript/workletTypes.d.ts.map +1 -1
  139. package/package.json +17 -8
  140. package/plugin/index.js +145 -52
  141. package/scripts/worklets_utils.rb +9 -0
  142. package/src/PlatformChecker/PlatformChecker.ts +7 -0
  143. package/src/PlatformChecker/index.ts +29 -0
  144. package/src/WorkletsError.ts +2 -1
  145. package/src/WorkletsModule/JSWorklets.ts +71 -4
  146. package/src/WorkletsModule/NativeWorklets.ts +83 -21
  147. package/src/WorkletsModule/workletsModuleInstance.ts +2 -2
  148. package/src/WorkletsModule/workletsModuleProxy.ts +49 -1
  149. package/src/bundleUnpacker.ts +75 -0
  150. package/src/callGuard.ts +33 -0
  151. package/src/errors.ts +35 -18
  152. package/src/index.ts +12 -12
  153. package/src/initializers.ts +143 -113
  154. package/src/logger.ts +16 -0
  155. package/src/privateGlobals.d.ts +22 -6
  156. package/src/publicGlobals.ts +26 -0
  157. package/src/runLoop/requestAnimationFrame.ts +67 -0
  158. package/src/runLoop/setImmediatePolyfill.ts +20 -0
  159. package/src/runLoop/setIntervalPolyfill.ts +38 -0
  160. package/src/runLoop/setTimeoutPolyfill.ts +40 -0
  161. package/src/runtimes.ts +6 -11
  162. package/src/shareableMappingCache.ts +1 -3
  163. package/src/shareables.ts +179 -65
  164. package/src/specs/NativeWorkletsModule.ts +1 -1
  165. package/src/specs/index.ts +5 -2
  166. package/src/threads.ts +75 -65
  167. package/src/valueUnpacker.ts +3 -3
  168. package/src/workletRuntimeEntry.ts +30 -0
  169. package/src/workletTypes.ts +22 -5
  170. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.cpp +0 -139
  171. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.h +0 -61
  172. package/android/src/paper/com/swmansion/worklets/NativeWorkletsModuleSpec.java +0 -26
  173. package/lib/module/PlatformChecker.js +0 -26
  174. package/lib/module/PlatformChecker.js.map +0 -1
  175. package/lib/module/animationFrameQueue/mockedRequestAnimationFrame.js.map +0 -1
  176. package/lib/module/animationFrameQueue/requestAnimationFrame.js +0 -36
  177. package/lib/module/animationFrameQueue/requestAnimationFrame.js.map +0 -1
  178. package/lib/module/logger/LogBox.js +0 -15
  179. package/lib/module/logger/LogBox.js.map +0 -1
  180. package/lib/module/logger/index.js +0 -5
  181. package/lib/module/logger/index.js.map +0 -1
  182. package/lib/module/logger/logger.js +0 -137
  183. package/lib/module/logger/logger.js.map +0 -1
  184. package/lib/typescript/PlatformChecker.d.ts +0 -6
  185. package/lib/typescript/PlatformChecker.d.ts.map +0 -1
  186. package/lib/typescript/animationFrameQueue/mockedRequestAnimationFrame.d.ts.map +0 -1
  187. package/lib/typescript/animationFrameQueue/requestAnimationFrame.d.ts.map +0 -1
  188. package/lib/typescript/logger/LogBox.d.ts +0 -32
  189. package/lib/typescript/logger/LogBox.d.ts.map +0 -1
  190. package/lib/typescript/logger/index.d.ts +0 -3
  191. package/lib/typescript/logger/index.d.ts.map +0 -1
  192. package/lib/typescript/logger/logger.d.ts +0 -52
  193. package/lib/typescript/logger/logger.d.ts.map +0 -1
  194. package/src/PlatformChecker.ts +0 -30
  195. package/src/animationFrameQueue/requestAnimationFrame.ts +0 -41
  196. package/src/logger/LogBox.ts +0 -55
  197. package/src/logger/index.ts +0 -3
  198. package/src/logger/logger.ts +0 -155
  199. /package/lib/module/{animationFrameQueue → runLoop}/mockedRequestAnimationFrame.js +0 -0
  200. /package/lib/typescript/{animationFrameQueue → runLoop}/mockedRequestAnimationFrame.d.ts +0 -0
  201. /package/lib/typescript/{animationFrameQueue → runLoop}/requestAnimationFrame.d.ts +0 -0
  202. /package/src/{animationFrameQueue → runLoop}/mockedRequestAnimationFrame.ts +0 -0
@@ -0,0 +1,55 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <worklets/Tools/UIScheduler.h>
5
+ #include <worklets/WorkletRuntime/WorkletRuntime.h>
6
+
7
+ #include <atomic>
8
+ #include <map>
9
+ #include <memory>
10
+ #include <shared_mutex>
11
+ #include <string>
12
+ #include <vector>
13
+
14
+ namespace worklets {
15
+
16
+ /**
17
+ * Forward declaration to avoid circular dependencies.
18
+ */
19
+ class JSIWorkletsModuleProxy;
20
+
21
+ /**
22
+ * Unused, but kept for possible future use.
23
+ */
24
+ constexpr uint64_t rnRuntimeId{0};
25
+ constexpr uint64_t uiRuntimeId{1};
26
+ extern const std::string uiRuntimeName;
27
+
28
+ class RuntimeManager {
29
+ public:
30
+ std::shared_ptr<WorkletRuntime> getRuntime(uint64_t runtimeId);
31
+ std::shared_ptr<WorkletRuntime> getRuntime(const std::string &name);
32
+
33
+ std::vector<std::shared_ptr<WorkletRuntime>> getAllRuntimes();
34
+
35
+ std::shared_ptr<WorkletRuntime> getUIRuntime();
36
+
37
+ std::shared_ptr<WorkletRuntime> createWorkletRuntime(
38
+ std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy,
39
+ const bool supportsLocking,
40
+ const std::string &name,
41
+ std::shared_ptr<ShareableWorklet> initializer = nullptr);
42
+
43
+ std::shared_ptr<WorkletRuntime> createUninitializedUIRuntime(
44
+ const std::shared_ptr<MessageQueueThread> &jsQueue);
45
+
46
+ private:
47
+ uint64_t getNextRuntimeId();
48
+
49
+ std::atomic_uint64_t nextRuntimeId_{uiRuntimeId + 1};
50
+ std::map<uint64_t, std::weak_ptr<WorkletRuntime>> weakRuntimes_;
51
+ std::shared_mutex weakRuntimesMutex_;
52
+ std::map<std::string, uint64_t> nameToRuntimeId_;
53
+ };
54
+
55
+ } // namespace worklets
@@ -10,6 +10,7 @@
10
10
  #include <hermes/hermes.h>
11
11
  #include <jsi/decorator.h>
12
12
  #include <jsi/jsi.h>
13
+ #include <react/debug/react_native_assert.h>
13
14
 
14
15
  #include <atomic>
15
16
  #include <memory>
@@ -61,13 +62,15 @@ struct WorkletsReentrancyCheck {
61
62
  // Returns true if tid and expected were the same. If they
62
63
  // were, then the stored tid referred to no thread, and we
63
64
  // atomically saved this thread's tid. Now increment depth.
64
- assert(depth == 0 && "[Worklets] No thread id, but depth != 0");
65
+ react_native_assert(
66
+ depth == 0 && "[Worklets] No thread id, but depth != 0");
65
67
  ++depth;
66
68
  } else if (expected == this_id) {
67
69
  // If the stored tid referred to a thread, expected was set to
68
70
  // that value. If that value is this thread's tid, that's ok,
69
71
  // just increment depth again.
70
- assert(depth != 0 && "[Worklets] Thread id was set, but depth == 0");
72
+ react_native_assert(
73
+ depth != 0 && "[Worklets] Thread id was set, but depth == 0");
71
74
  ++depth;
72
75
  } else {
73
76
  // The stored tid was some other thread. This indicates a bad
@@ -79,7 +82,7 @@ struct WorkletsReentrancyCheck {
79
82
  }
80
83
 
81
84
  void after() {
82
- assert(
85
+ react_native_assert(
83
86
  tid.load(std::memory_order_relaxed) == std::this_thread::get_id() &&
84
87
  "[Worklets] No thread id in after()");
85
88
  if (--depth == 0) {
@@ -87,7 +90,8 @@ struct WorkletsReentrancyCheck {
87
90
  std::thread::id expected = std::this_thread::get_id();
88
91
  bool didWrite = tid.compare_exchange_strong(
89
92
  expected, std::thread::id(), std::memory_order_relaxed);
90
- assert(didWrite && "[Worklets] Decremented to zero, but no tid write");
93
+ react_native_assert(
94
+ didWrite && "[Worklets] Decremented to zero, but no tid write");
91
95
  }
92
96
  }
93
97
 
@@ -1,6 +1,9 @@
1
+ #include <worklets/NativeModules/JSIWorkletsModuleProxy.h>
1
2
  #include <worklets/Resources/ValueUnpacker.h>
2
3
  #include <worklets/Tools/Defs.h>
3
4
  #include <worklets/Tools/JSISerializer.h>
5
+ #include <worklets/Tools/JSLogger.h>
6
+ #include <worklets/Tools/WorkletsJSIUtils.h>
4
7
  #include <worklets/WorkletRuntime/WorkletRuntime.h>
5
8
  #include <worklets/WorkletRuntime/WorkletRuntimeCollector.h>
6
9
  #include <worklets/WorkletRuntime/WorkletRuntimeDecorator.h>
@@ -14,8 +17,6 @@
14
17
 
15
18
  #if JS_RUNTIME_HERMES
16
19
  #include <worklets/WorkletRuntime/WorkletHermesRuntime.h>
17
- #elif JS_RUNTIME_V8
18
- #include <v8runtime/V8RuntimeFactory.h>
19
20
  #else
20
21
  #include <jsc/JSCRuntime.h>
21
22
  #endif // JS_RUNTIME
@@ -52,24 +53,16 @@ class LockableRuntime : public jsi::WithRuntimeDecorator<AroundLock> {
52
53
  };
53
54
 
54
55
  static std::shared_ptr<jsi::Runtime> makeRuntime(
55
- jsi::Runtime &rnRuntime,
56
56
  const std::shared_ptr<MessageQueueThread> &jsQueue,
57
57
  const std::string &name,
58
58
  const bool supportsLocking,
59
59
  const std::shared_ptr<std::recursive_mutex> &runtimeMutex) {
60
60
  std::shared_ptr<jsi::Runtime> jsiRuntime;
61
61
  #if JS_RUNTIME_HERMES
62
- (void)rnRuntime; // used only by V8
63
62
  auto hermesRuntime = facebook::hermes::makeHermesRuntime();
64
63
  jsiRuntime = std::make_shared<WorkletHermesRuntime>(
65
64
  std::move(hermesRuntime), jsQueue, name);
66
- #elif JS_RUNTIME_V8
67
- auto config = std::make_unique<rnv8::V8RuntimeConfig>();
68
- config->enableInspector = false;
69
- config->appName = name;
70
- jsiRuntime = rnv8::createSharedV8Runtime(&rnRuntime, std::move(config));
71
65
  #else
72
- (void)rnRuntime; // used only by V8
73
66
  jsiRuntime = facebook::jsc::makeJSCRuntime();
74
67
  #endif
75
68
 
@@ -81,36 +74,75 @@ static std::shared_ptr<jsi::Runtime> makeRuntime(
81
74
  }
82
75
 
83
76
  WorkletRuntime::WorkletRuntime(
84
- jsi::Runtime &rnRuntime,
77
+ uint64_t runtimeId,
85
78
  const std::shared_ptr<MessageQueueThread> &jsQueue,
86
- const std::shared_ptr<JSScheduler> &jsScheduler,
87
79
  const std::string &name,
88
- const bool supportsLocking,
89
- const bool isDevBundle)
90
- : runtimeMutex_(std::make_shared<std::recursive_mutex>()),
91
- runtime_(makeRuntime(
92
- rnRuntime,
93
- jsQueue,
94
- name,
95
- supportsLocking,
96
- runtimeMutex_)),
80
+ const bool supportsLocking)
81
+ : runtimeId_(runtimeId),
82
+ runtimeMutex_(std::make_shared<std::recursive_mutex>()),
83
+ runtime_(makeRuntime(jsQueue, name, supportsLocking, runtimeMutex_)),
97
84
  #ifndef NDEBUG
98
85
  supportsLocking_(supportsLocking),
99
- #endif
86
+ #endif // NDEBUG
100
87
  name_(name) {
101
88
  jsi::Runtime &rt = *runtime_;
102
89
  WorkletRuntimeCollector::install(rt);
103
- WorkletRuntimeDecorator::decorate(rt, name, jsScheduler, isDevBundle);
90
+ }
91
+
92
+ void WorkletRuntime::init(
93
+ std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy) {
94
+ jsi::Runtime &rt = *runtime_;
95
+ const auto jsScheduler = jsiWorkletsModuleProxy->getJSScheduler();
96
+ const auto isDevBundle = jsiWorkletsModuleProxy->isDevBundle();
97
+ #ifdef WORKLETS_BUNDLE_MODE
98
+ auto script = jsiWorkletsModuleProxy->getScript();
99
+ const auto &sourceUrl = jsiWorkletsModuleProxy->getSourceUrl();
100
+ #endif // WORKLETS_BUNDLE_MODE
101
+
102
+ auto optimizedJsiWorkletsModuleProxy =
103
+ jsi_utils::optimizedFromHostObject(rt, std::move(jsiWorkletsModuleProxy));
104
104
 
105
+ WorkletRuntimeDecorator::decorate(
106
+ rt,
107
+ name_,
108
+ jsScheduler,
109
+ isDevBundle,
110
+ std::move(optimizedJsiWorkletsModuleProxy));
111
+
112
+ #ifdef WORKLETS_BUNDLE_MODE
113
+ if (!script) {
114
+ throw std::runtime_error(
115
+ "[Worklets] Expected to receive the bundle, but got nullptr instead.");
116
+ }
117
+
118
+ try {
119
+ rt.evaluateJavaScript(script, sourceUrl);
120
+ } catch (facebook::jsi::JSError error) {
121
+ const auto &message = error.getMessage();
122
+ const auto &stack = error.getStack();
123
+ if (!message.starts_with("[Worklets] Worklets initialized successfully")) {
124
+ const auto newMessage =
125
+ "[Worklets] Failed to initialize runtime. Reason: " + message;
126
+ JSLogger::reportFatalErrorOnJS(
127
+ jsScheduler,
128
+ {.message = newMessage,
129
+ .stack = stack,
130
+ .name = "WorkletsError",
131
+ .jsEngine = "Worklets"});
132
+ }
133
+ }
134
+ #else
135
+ // Legacy behavior
105
136
  auto valueUnpackerBuffer =
106
137
  std::make_shared<const jsi::StringBuffer>(ValueUnpackerCode);
107
138
  rt.evaluateJavaScript(valueUnpackerBuffer, "valueUnpacker");
139
+ #endif // WORKLETS_BUNDLE_MODE
108
140
  }
109
141
 
110
142
  jsi::Value WorkletRuntime::executeSync(
111
143
  jsi::Runtime &rt,
112
144
  const jsi::Value &worklet) const {
113
- assert(
145
+ react_native_assert(
114
146
  supportsLocking_ &&
115
147
  ("[Worklets] Runtime \"" + name_ + "\" doesn't support locking.")
116
148
  .c_str());
@@ -126,6 +158,20 @@ jsi::Value WorkletRuntime::executeSync(
126
158
  return shareableResult->toJSValue(rt);
127
159
  }
128
160
 
161
+ jsi::Value WorkletRuntime::executeSync(
162
+ std::function<jsi::Value(jsi::Runtime &)> &&job) const {
163
+ auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
164
+ jsi::Runtime &uiRuntime = getJSIRuntime();
165
+ return job(uiRuntime);
166
+ }
167
+
168
+ jsi::Value WorkletRuntime::executeSync(
169
+ const std::function<jsi::Value(jsi::Runtime &)> &job) const {
170
+ auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
171
+ jsi::Runtime &uiRuntime = getJSIRuntime();
172
+ return job(uiRuntime);
173
+ }
174
+
129
175
  jsi::Value WorkletRuntime::get(
130
176
  jsi::Runtime &rt,
131
177
  const jsi::PropNameID &propName) {
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <cxxreact/MessageQueueThread.h>
4
4
  #include <jsi/jsi.h>
5
+ #include <jsireact/JSIExecutor.h>
5
6
 
6
7
  #include <worklets/SharedItems/Shareables.h>
7
8
  #include <worklets/Tools/AsyncQueue.h>
@@ -17,16 +18,21 @@ using namespace react;
17
18
 
18
19
  namespace worklets {
19
20
 
21
+ /**
22
+ * Forward declaration to avoid circular dependencies.
23
+ */
24
+ class JSIWorkletsModuleProxy;
25
+
20
26
  class WorkletRuntime : public jsi::HostObject,
21
27
  public std::enable_shared_from_this<WorkletRuntime> {
22
28
  public:
23
29
  explicit WorkletRuntime(
24
- jsi::Runtime &rnRuntime,
30
+ uint64_t runtimeId,
25
31
  const std::shared_ptr<MessageQueueThread> &jsQueue,
26
- const std::shared_ptr<JSScheduler> &jsScheduler,
27
32
  const std::string &name,
28
- const bool supportsLocking,
29
- const bool isDevBundle);
33
+ const bool supportsLocking);
34
+
35
+ void init(std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy);
30
36
 
31
37
  jsi::Runtime &getJSIRuntime() const {
32
38
  return *runtime_;
@@ -58,6 +64,11 @@ class WorkletRuntime : public jsi::HostObject,
58
64
 
59
65
  jsi::Value executeSync(jsi::Runtime &rt, const jsi::Value &worklet) const;
60
66
 
67
+ jsi::Value executeSync(std::function<jsi::Value(jsi::Runtime &)> &&job) const;
68
+
69
+ jsi::Value executeSync(
70
+ const std::function<jsi::Value(jsi::Runtime &)> &job) const;
71
+
61
72
  std::string toString() const {
62
73
  return "[WorkletRuntime \"" + name_ + "\"]";
63
74
  }
@@ -66,7 +77,16 @@ class WorkletRuntime : public jsi::HostObject,
66
77
 
67
78
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
68
79
 
80
+ [[nodiscard]] auto getRuntimeId() const -> uint64_t {
81
+ return runtimeId_;
82
+ }
83
+
84
+ [[nodiscard]] auto getRuntimeName() const -> std::string {
85
+ return name_;
86
+ }
87
+
69
88
  private:
89
+ const uint64_t runtimeId_;
70
90
  const std::shared_ptr<std::recursive_mutex> runtimeMutex_;
71
91
  const std::shared_ptr<jsi::Runtime> runtime_;
72
92
  #ifndef NDEBUG
@@ -5,6 +5,7 @@
5
5
  #include <worklets/WorkletRuntime/WorkletRuntime.h>
6
6
  #include <worklets/WorkletRuntime/WorkletRuntimeDecorator.h>
7
7
 
8
+ #include <utility>
8
9
  #include <vector>
9
10
 
10
11
  namespace worklets {
@@ -40,7 +41,8 @@ void WorkletRuntimeDecorator::decorate(
40
41
  jsi::Runtime &rt,
41
42
  const std::string &name,
42
43
  const std::shared_ptr<JSScheduler> &jsScheduler,
43
- const bool isDevBundle) {
44
+ const bool isDevBundle,
45
+ jsi::Object &&jsiWorkletsModuleProxy) {
44
46
  // resolves "ReferenceError: Property 'global' doesn't exist at ..."
45
47
  rt.global().setProperty(rt, "global", rt.global());
46
48
 
@@ -54,6 +56,9 @@ void WorkletRuntimeDecorator::decorate(
54
56
 
55
57
  rt.global().setProperty(rt, "__DEV__", isDevBundle);
56
58
 
59
+ rt.global().setProperty(
60
+ rt, "__workletsModuleProxy", std::move(jsiWorkletsModuleProxy));
61
+
57
62
  #ifndef NDEBUG
58
63
  auto evalWithSourceUrl = [](jsi::Runtime &rt,
59
64
  const jsi::Value &thisValue,
@@ -98,6 +103,13 @@ void WorkletRuntimeDecorator::decorate(
98
103
  rt, value, shouldRetainRemote, nativeStateSource);
99
104
  });
100
105
 
106
+ jsi_utils::installJsiFunction(
107
+ rt,
108
+ "_makeShareableHostObject",
109
+ [](jsi::Runtime &rt, const jsi::Value &value) {
110
+ return makeShareableHostObject(rt, value.asObject(rt).asHostObject(rt));
111
+ });
112
+
101
113
  jsi_utils::installJsiFunction(
102
114
  rt,
103
115
  "_makeShareableString",
@@ -131,10 +143,50 @@ void WorkletRuntimeDecorator::decorate(
131
143
  return makeShareableUndefined(rt);
132
144
  });
133
145
 
146
+ jsi_utils::installJsiFunction(
147
+ rt, "_makeShareableArray", [](jsi::Runtime &rt, const jsi::Value &value) {
148
+ return makeShareableArray(rt, value.asObject(rt).asArray(rt), false);
149
+ });
150
+
134
151
  jsi_utils::installJsiFunction(rt, "_makeShareableNull", [](jsi::Runtime &rt) {
135
152
  return makeShareableNull(rt);
136
153
  });
137
154
 
155
+ jsi_utils::installJsiFunction(
156
+ rt,
157
+ "_makeShareableObject",
158
+ [](jsi::Runtime &rt,
159
+ const jsi::Value &value,
160
+ const jsi::Value &shouldRetainRemote,
161
+ const jsi::Value &nativeStateSource) {
162
+ return makeShareableObject(
163
+ rt,
164
+ value.getObject(rt),
165
+ shouldRetainRemote.getBool(),
166
+ nativeStateSource);
167
+ });
168
+
169
+ jsi_utils::installJsiFunction(
170
+ rt,
171
+ "_makeShareableWorklet",
172
+ [](jsi::Runtime &rt, const jsi::Value &value) {
173
+ return makeShareableWorklet(rt, value.asObject(rt), false);
174
+ });
175
+
176
+ jsi_utils::installJsiFunction(
177
+ rt,
178
+ "_makeShareableInitializer",
179
+ [](jsi::Runtime &rt, const jsi::Value &value) {
180
+ return makeShareableInitializer(rt, value.asObject(rt));
181
+ });
182
+
183
+ jsi_utils::installJsiFunction(
184
+ rt,
185
+ "_makeShareableFunction",
186
+ [](jsi::Runtime &rt, const jsi::Value &value) {
187
+ return makeShareableFunction(rt, value.asObject(rt).asFunction(rt));
188
+ });
189
+
138
190
  jsi_utils::installJsiFunction(
139
191
  rt,
140
192
  "_scheduleRemoteFunctionOnJS",
@@ -17,7 +17,8 @@ class WorkletRuntimeDecorator {
17
17
  jsi::Runtime &rt,
18
18
  const std::string &name,
19
19
  const std::shared_ptr<JSScheduler> &jsScheduler,
20
- const bool isDevBundle);
20
+ const bool isDevBundle,
21
+ jsi::Object &&jsiWorkletsModuleProxy);
21
22
  };
22
23
 
23
24
  } // namespace worklets
@@ -5,6 +5,9 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
5
5
  $worklets_config = worklets_find_config()
6
6
  worklets_assert_minimal_react_native_version($worklets_config)
7
7
 
8
+ $new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] != '0'
9
+ worklets_assert_new_architecture_enabled($new_arch_enabled)
10
+
8
11
  ios_min_version = '13.4'
9
12
 
10
13
  Pod::Spec.new do |s|
@@ -42,7 +45,9 @@ Pod::Spec.new do |s|
42
45
  # HERMESVM_PROFILER_OPCODE
43
46
  # HERMESVM_PROFILER_BB
44
47
  # which shouldn't be defined in standard setups.
45
- hermes_debug_hidden_flags = '$(inherited) HERMES_ENABLE_DEBUGGER=1'
48
+ hermes_debug_hidden_flags = 'HERMES_ENABLE_DEBUGGER=1'
49
+
50
+ bundle_mode_flag = $worklets_config[:bundle_mode] ? 'WORKLETS_BUNDLE_MODE=1' : ''
46
51
 
47
52
  s.pod_target_xcconfig = {
48
53
  "USE_HEADERMAP" => "YES",
@@ -58,9 +63,9 @@ Pod::Spec.new do |s|
58
63
  '"$(PODS_ROOT)/Headers/Private/Yoga"',
59
64
  ].join(' '),
60
65
  "FRAMEWORK_SEARCH_PATHS" => '"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes"',
61
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
62
- "GCC_PREPROCESSOR_DEFINITIONS[config=*Debug*]" => hermes_debug_hidden_flags,
63
- "GCC_PREPROCESSOR_DEFINITIONS[config=*Release*]" => '$(inherited)',
66
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
67
+ "GCC_PREPROCESSOR_DEFINITIONS[config=*Debug*]" => "$(inherited) #{hermes_debug_hidden_flags} #{bundle_mode_flag}",
68
+ "GCC_PREPROCESSOR_DEFINITIONS[config=*Release*]" => "$(inherited) #{bundle_mode_flag}",
64
69
  }
65
70
  s.xcconfig = {
66
71
  "HEADER_SEARCH_PATHS" => [
@@ -18,13 +18,12 @@ string(APPEND CMAKE_CXX_FLAGS
18
18
  " -fexceptions -fno-omit-frame-pointer -frtti -fstack-protector-all \
19
19
  -std=c++${CMAKE_CXX_STANDARD} -Wall -Werror")
20
20
 
21
- if(${IS_NEW_ARCHITECTURE_ENABLED})
22
- string(APPEND CMAKE_CXX_FLAGS " -DRCT_NEW_ARCH_ENABLED")
23
- endif()
24
-
25
21
  if(${IS_REANIMATED_EXAMPLE_APP})
26
22
  string(APPEND CMAKE_CXX_FLAGS " -DIS_REANIMATED_EXAMPLE_APP -Wpedantic")
27
23
  endif()
24
+ if(${WORKLETS_BUNDLE_MODE})
25
+ string(APPEND CMAKE_CXX_FLAGS " -DWORKLETS_BUNDLE_MODE")
26
+ endif()
28
27
 
29
28
  if(NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug")
30
29
  string(APPEND CMAKE_CXX_FLAGS " -DNDEBUG")
@@ -34,17 +33,10 @@ if(${JS_RUNTIME} STREQUAL "hermes")
34
33
  string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_HERMES=1")
35
34
  elseif(${JS_RUNTIME} STREQUAL "jsc")
36
35
  string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_JSC=1")
37
- elseif(${JS_RUNTIME} STREQUAL "v8")
38
- string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_V8=1")
39
36
  else()
40
37
  message(FATAL_ERROR "Unknown JS runtime ${JS_RUNTIME}.")
41
38
  endif()
42
39
 
43
- # Resolves "CMake Warning: Manually-specified variables were not used by the
44
- # project" when any of the following variables is not used in some build
45
- # configuration.
46
- set(IGNORE_ME "${JS_RUNTIME_DIR}")
47
-
48
40
  set(BUILD_DIR "${CMAKE_SOURCE_DIR}/build")
49
41
  set(ANDROID_CPP_DIR "${CMAKE_SOURCE_DIR}/src/main/cpp")
50
42
  set(COMMON_CPP_DIR "${CMAKE_SOURCE_DIR}/../Common/cpp")
@@ -72,24 +64,20 @@ target_include_directories(worklets PUBLIC "${COMMON_CPP_DIR}"
72
64
  target_include_directories(
73
65
  worklets
74
66
  PRIVATE "${REACT_NATIVE_DIR}/ReactCommon"
67
+ "${REACT_NATIVE_DIR}/ReactCommon/yoga"
75
68
  "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/turbomodule"
76
69
  "${REACT_NATIVE_DIR}/ReactCommon/react/nativemodule/core/ReactCommon"
77
70
  "${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
78
- "${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor")
79
-
80
- if(${IS_NEW_ARCHITECTURE_ENABLED})
81
- target_include_directories(
82
- worklets
83
- PRIVATE
84
- "${REACT_NATIVE_DIR}/ReactCommon/yoga"
85
- "${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx")
86
-
87
- if(ReactAndroid_VERSION_MINOR LESS 76)
88
- target_link_libraries(
89
- worklets ReactAndroid::fabricjni ReactAndroid::react_debug
90
- ReactAndroid::react_render_core
91
- ReactAndroid::react_render_componentregistry ReactAndroid::rrc_view)
92
- endif()
71
+ "${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor"
72
+ "${REACT_NATIVE_DIR}/ReactCommon/jsiexecutor"
73
+ "${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx"
74
+ )
75
+
76
+ if(ReactAndroid_VERSION_MINOR LESS 76)
77
+ target_link_libraries(
78
+ worklets ReactAndroid::fabricjni ReactAndroid::react_debug
79
+ ReactAndroid::react_render_core
80
+ ReactAndroid::react_render_componentregistry ReactAndroid::rrc_view)
93
81
  endif()
94
82
 
95
83
  # build shared lib
@@ -122,14 +110,4 @@ elseif(${JS_RUNTIME} STREQUAL "jsc")
122
110
  else()
123
111
  target_link_libraries(worklets ReactAndroid::jscexecutor)
124
112
  endif()
125
- elseif(${JS_RUNTIME} STREQUAL "v8")
126
- # TODO: Refactor this when adding support for newest V8
127
- target_include_directories(worklets PRIVATE "${JS_RUNTIME_DIR}/src")
128
- file(GLOB V8_SO_DIR "${JS_RUNTIME_DIR}/android/build/intermediates/\
129
- library_jni/**/jni/${ANDROID_ABI}")
130
- find_library(
131
- V8EXECUTOR_LIB v8executor
132
- PATHS ${V8_SO_DIR}
133
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
134
- target_link_libraries(worklets ${V8EXECUTOR_LIB})
135
113
  endif()
@@ -72,6 +72,7 @@ def REACT_NATIVE_MINOR_VERSION = getReactNativeMinorVersion()
72
72
  def WORKLETS_VERSION = getWorkletsVersion()
73
73
  def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled()
74
74
  def IS_REANIMATED_EXAMPLE_APP = safeAppExtGet("isReanimatedExampleApp", false)
75
+ def BUNDLE_MODE = safeAppExtGet("workletsBundleMode", false)
75
76
 
76
77
  // Set version for prefab
77
78
  version WORKLETS_VERSION
@@ -84,12 +85,6 @@ def JS_RUNTIME = {
84
85
  return System.getenv("JS_RUNTIME")
85
86
  }
86
87
 
87
- // Enable V8 runtime if react-native-v8 is installed
88
- def v8Project = rootProject.getSubprojects().find { project -> project.name == "react-native-v8" }
89
- if (v8Project != null) {
90
- return "v8"
91
- }
92
-
93
88
  // Check if Hermes is enabled in app setup
94
89
  def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
95
90
  if (appProject?.hermesEnabled?.toBoolean() || appProject?.ext?.react?.enableHermes?.toBoolean()) {
@@ -100,16 +95,6 @@ def JS_RUNTIME = {
100
95
  return "jsc"
101
96
  }.call()
102
97
 
103
- def jsRuntimeDir = {
104
- if (JS_RUNTIME == "hermes") {
105
- return Paths.get(reactNativeRootDir.path, "sdks", "hermes")
106
- } else if (JS_RUNTIME == "v8") {
107
- return findProject(":react-native-v8").getProjectDir().getParent()
108
- } else {
109
- return Paths.get(reactNativeRootDir.path, "ReactCommon", "jsi")
110
- }
111
- }.call()
112
-
113
98
  def reactNativeArchitectures() {
114
99
  def value = project.getProperties().get("reactNativeArchitectures")
115
100
  return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
@@ -169,7 +154,7 @@ android {
169
154
  buildConfigField("boolean", "IS_INTERNAL_BUILD", "false")
170
155
  buildConfigField("int", "EXOPACKAGE_FLAGS", "0")
171
156
  buildConfigField("int", "REACT_NATIVE_MINOR_VERSION", REACT_NATIVE_MINOR_VERSION.toString())
172
- buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString())
157
+ buildConfigField("boolean", "BUNDLE_MODE", BUNDLE_MODE.toString())
173
158
 
174
159
  externalNativeBuild {
175
160
  cmake {
@@ -178,9 +163,8 @@ android {
178
163
  "-DANDROID_TOOLCHAIN=clang",
179
164
  "-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}",
180
165
  "-DJS_RUNTIME=${JS_RUNTIME}",
181
- "-DJS_RUNTIME_DIR=${jsRuntimeDir}",
182
- "-DIS_NEW_ARCHITECTURE_ENABLED=${IS_NEW_ARCHITECTURE_ENABLED}",
183
166
  "-DIS_REANIMATED_EXAMPLE_APP=${IS_REANIMATED_EXAMPLE_APP}",
167
+ "-DWORKLETS_BUNDLE_MODE=${BUNDLE_MODE}",
184
168
  "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
185
169
  abiFilters (*reactNativeArchitectures())
186
170
  targets("worklets")
@@ -243,7 +227,6 @@ android {
243
227
  "**/libreact_render*.so",
244
228
  "**/librrc_root.so",
245
229
  "**/libjscexecutor.so",
246
- "**/libv8executor.so",
247
230
  ]
248
231
  }
249
232
  compileOptions {
@@ -253,8 +236,10 @@ android {
253
236
  sourceSets {
254
237
  main {
255
238
  java {
256
- if (!IS_NEW_ARCHITECTURE_ENABLED) {
257
- srcDirs += "src/worklets/paper"
239
+ if (BUNDLE_MODE) {
240
+ srcDirs += "src/experimentalBundling"
241
+ } else {
242
+ srcDirs += "src/legacyBundling"
258
243
  }
259
244
  }
260
245
  }
@@ -288,6 +273,15 @@ task assertMinimalReactNativeVersionTask {
288
273
 
289
274
  preBuild.dependsOn(assertMinimalReactNativeVersionTask)
290
275
 
276
+ task assertNewArchitectureEnabledTask {
277
+ onlyIf { !IS_NEW_ARCHITECTURE_ENABLED }
278
+ doFirst {
279
+ throw new GradleException("[Worklets] Worklets require new architecture to be enabled. Please enable it by setting `newArchEnabled` to `true` in `gradle.properties`.")
280
+ }
281
+ }
282
+
283
+ preBuild.dependsOn(assertNewArchitectureEnabledTask)
284
+
291
285
  task prepareWorkletsHeadersForPrefabs(type: Copy) {
292
286
  from("$projectDir/src/main/cpp")
293
287
  from("$projectDir/../Common/cpp")
@@ -319,14 +313,3 @@ dependencies {
319
313
  }
320
314
 
321
315
  preBuild.dependsOn(prepareWorkletsHeadersForPrefabs)
322
-
323
- afterEvaluate {
324
- if (JS_RUNTIME == "v8") {
325
- def buildTasks = tasks.findAll({ task ->
326
- !task.name.contains("Clean") && (task.name.contains("externalNative") || task.name.contains("CMake") || task.name.startsWith("generateJsonModel")) })
327
- buildTasks.forEach { task ->
328
- def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
329
- task.dependsOn(":react-native-v8:copy${buildType}JniLibsProjectOnly")
330
- }
331
- }
332
- }