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
@@ -10,10 +10,7 @@
10
10
  #include <fbjni/fbjni.h>
11
11
  #endif // __ANDROID__
12
12
 
13
- #include <jsi/jsi.h>
14
-
15
13
  #include <memory>
16
- #include <string>
17
14
  #include <utility>
18
15
 
19
16
  using namespace facebook;
@@ -27,137 +24,58 @@ WorkletsModuleProxy::WorkletsModuleProxy(
27
24
  const std::shared_ptr<MessageQueueThread> &jsQueue,
28
25
  const std::shared_ptr<CallInvoker> &jsCallInvoker,
29
26
  const std::shared_ptr<UIScheduler> &uiScheduler,
27
+ std::function<bool()> &&isJavaScriptThread,
30
28
  std::function<void(std::function<void(const double)>)>
31
- &&forwardedRequestAnimationFrame)
32
- : WorkletsModuleProxySpec(jsCallInvoker),
33
- isDevBundle_(isDevBundleFromRNRuntime(rnRuntime)),
29
+ &&forwardedRequestAnimationFrame,
30
+ const std::shared_ptr<const BigStringBuffer> &script,
31
+ const std::string &sourceUrl)
32
+ : isDevBundle_(isDevBundleFromRNRuntime(rnRuntime)),
34
33
  jsQueue_(jsQueue),
35
- jsScheduler_(std::make_shared<JSScheduler>(rnRuntime, jsCallInvoker)),
36
- uiScheduler_(uiScheduler),
37
- uiWorkletRuntime_(std::make_shared<WorkletRuntime>(
34
+ jsScheduler_(std::make_shared<JSScheduler>(
38
35
  rnRuntime,
39
- jsQueue,
40
- jsScheduler_,
41
- "Reanimated UI runtime",
42
- true /* supportsLocking */,
43
- isDevBundle_)),
44
- animationFrameBatchinator_(std::make_shared<AnimationFrameBatchinator>(
45
- uiWorkletRuntime_->getJSIRuntime(),
46
- std::move(forwardedRequestAnimationFrame))) {
36
+ jsCallInvoker,
37
+ std::move(isJavaScriptThread))),
38
+ uiScheduler_(uiScheduler),
39
+ script_(script),
40
+ sourceUrl_(sourceUrl),
41
+ runtimeManager_(std::make_shared<RuntimeManager>()),
42
+ uiWorkletRuntime_(
43
+ runtimeManager_->createUninitializedUIRuntime(jsQueue_)) {
44
+ /**
45
+ * We must call `init` in the body of the constructor, because
46
+ * JSIWorkletsModuleProxy needs a weak_ptr to the UI Runtime.
47
+ */
48
+ uiWorkletRuntime_->init(createJSIWorkletsModuleProxy());
49
+
50
+ animationFrameBatchinator_ = std::make_shared<AnimationFrameBatchinator>(
51
+ uiWorkletRuntime_->getJSIRuntime(),
52
+ std::move(forwardedRequestAnimationFrame));
53
+
47
54
  UIRuntimeDecorator::decorate(
48
55
  uiWorkletRuntime_->getJSIRuntime(),
49
56
  animationFrameBatchinator_->getJsiRequestAnimationFrame());
50
57
  }
51
58
 
52
- WorkletsModuleProxy::~WorkletsModuleProxy() {
53
- animationFrameBatchinator_.reset();
54
- jsQueue_->quitSynchronous();
55
- uiWorkletRuntime_.reset();
56
- }
57
-
58
- jsi::Value WorkletsModuleProxy::makeShareableClone(
59
- jsi::Runtime &rt,
60
- const jsi::Value &value,
61
- const jsi::Value &shouldRetainRemote,
62
- const jsi::Value &nativeStateSource) {
63
- // TODO: It might be a good idea to rename one of these methods to avoid
64
- // confusion.
65
- return worklets::makeShareableClone(
66
- rt, value, shouldRetainRemote, nativeStateSource);
67
- }
68
-
69
- jsi::Value WorkletsModuleProxy::makeShareableString(
70
- jsi::Runtime &rt,
71
- const jsi::String &string) {
72
- return worklets::makeShareableString(rt, string);
73
- }
74
-
75
- jsi::Value WorkletsModuleProxy::makeShareableNumber(
76
- jsi::Runtime &rt,
77
- double number) {
78
- return worklets::makeShareableNumber(rt, number);
79
- }
80
-
81
- jsi::Value WorkletsModuleProxy::makeShareableBoolean(
82
- jsi::Runtime &rt,
83
- bool boolean) {
84
- return worklets::makeShareableBoolean(rt, boolean);
85
- }
86
-
87
- jsi::Value WorkletsModuleProxy::makeShareableBigInt(
88
- jsi::Runtime &rt,
89
- const jsi::BigInt &bigint) {
90
- return worklets::makeShareableBigInt(rt, bigint);
91
- }
92
-
93
- jsi::Value WorkletsModuleProxy::makeShareableUndefined(jsi::Runtime &rt) {
94
- return worklets::makeShareableUndefined(rt);
95
- }
96
-
97
- jsi::Value WorkletsModuleProxy::makeShareableNull(jsi::Runtime &rt) {
98
- return worklets::makeShareableNull(rt);
99
- }
100
-
101
- void WorkletsModuleProxy::scheduleOnUI(
102
- jsi::Runtime &rt,
103
- const jsi::Value &worklet) {
104
- auto shareableWorklet = extractShareableOrThrow<ShareableWorklet>(
105
- rt, worklet, "[Worklets] Only worklets can be scheduled to run on UI.");
106
- uiScheduler_->scheduleOnUI([shareableWorklet, weakThis = weak_from_this()] {
107
- // This callback can outlive the WorkletsModuleProxy object during the
108
- // invalidation of React Native. This happens when WorkletsModuleProxy
109
- // destructor is called on the JS thread and the UI thread is executing
110
- // callbacks from the `scheduleOnUI` queue. Therefore, we need to
111
- // make sure it's still alive before we try to access it.
112
- auto strongThis = weakThis.lock();
113
- if (!strongThis) {
114
- return;
115
- }
116
-
117
- auto uiWorkletRuntime = strongThis->getUIWorkletRuntime();
118
-
119
- #if JS_RUNTIME_HERMES
120
- // JSI's scope defined here allows for JSI-objects to be cleared up
121
- // after each runtime loop. Within these loops we typically create some
122
- // temporary JSI objects and hence it allows for such objects to be
123
- // garbage collected much sooner. Apparently the scope API is only
124
- // supported on Hermes at the moment.
125
- const auto scope = jsi::Scope(uiWorkletRuntime->getJSIRuntime());
126
- #endif // JS_RUNTIME_HERMES
127
-
128
- uiWorkletRuntime->runGuarded(shareableWorklet);
129
- });
130
- }
131
-
132
- jsi::Value WorkletsModuleProxy::executeOnUIRuntimeSync(
133
- jsi::Runtime &rt,
134
- const jsi::Value &worklet) {
135
- return uiWorkletRuntime_->executeSync(rt, worklet);
136
- }
137
-
138
- jsi::Value WorkletsModuleProxy::createWorkletRuntime(
139
- jsi::Runtime &rt,
140
- const jsi::Value &name,
141
- const jsi::Value &initializer) {
142
- auto workletRuntime = std::make_shared<WorkletRuntime>(
143
- rt,
59
+ std::shared_ptr<JSIWorkletsModuleProxy>
60
+ WorkletsModuleProxy::createJSIWorkletsModuleProxy() const {
61
+ assert(
62
+ uiWorkletRuntime_ != nullptr &&
63
+ "UI Worklet Runtime must be initialized before creating JSI proxy.");
64
+ return std::make_shared<JSIWorkletsModuleProxy>(
65
+ isDevBundle_,
66
+ script_,
67
+ sourceUrl_,
144
68
  jsQueue_,
145
69
  jsScheduler_,
146
- name.asString(rt).utf8(rt),
147
- true /* supportsLocking */,
148
- isDevBundle_);
149
- auto initializerShareable = extractShareableOrThrow<ShareableWorklet>(
150
- rt, initializer, "[Worklets] Initializer must be a worklet.");
151
- workletRuntime->runGuarded(initializerShareable);
152
- return jsi::Object::createFromHostObject(rt, workletRuntime);
70
+ uiScheduler_,
71
+ runtimeManager_,
72
+ uiWorkletRuntime_);
153
73
  }
154
74
 
155
- jsi::Value WorkletsModuleProxy::scheduleOnRuntime(
156
- jsi::Runtime &rt,
157
- const jsi::Value &workletRuntimeValue,
158
- const jsi::Value &shareableWorkletValue) {
159
- worklets::scheduleOnRuntime(rt, workletRuntimeValue, shareableWorkletValue);
160
- return jsi::Value::undefined();
75
+ WorkletsModuleProxy::~WorkletsModuleProxy() {
76
+ animationFrameBatchinator_.reset();
77
+ jsQueue_->quitSynchronous();
78
+ uiWorkletRuntime_.reset();
161
79
  }
162
80
 
163
81
  auto isDevBundleFromRNRuntime(jsi::Runtime &rnRuntime) -> bool {
@@ -1,11 +1,14 @@
1
1
  #pragma once
2
2
 
3
3
  #include <cxxreact/MessageQueueThread.h>
4
+ #include <jsi/jsi.h>
5
+ #include <jsireact/JSIExecutor.h>
4
6
  #include <worklets/AnimationFrameQueue/AnimationFrameBatchinator.h>
5
- #include <worklets/NativeModules/WorkletsModuleProxySpec.h>
7
+ #include <worklets/NativeModules/JSIWorkletsModuleProxy.h>
6
8
  #include <worklets/Tools/JSScheduler.h>
7
9
  #include <worklets/Tools/SingleInstanceChecker.h>
8
10
  #include <worklets/Tools/UIScheduler.h>
11
+ #include <worklets/WorkletRuntime/RuntimeManager.h>
9
12
  #include <worklets/WorkletRuntime/WorkletRuntime.h>
10
13
 
11
14
  #include <memory>
@@ -14,53 +17,20 @@
14
17
  namespace worklets {
15
18
 
16
19
  class WorkletsModuleProxy
17
- : public WorkletsModuleProxySpec,
18
- public std::enable_shared_from_this<WorkletsModuleProxy> {
20
+ : public std::enable_shared_from_this<WorkletsModuleProxy> {
19
21
  public:
20
22
  explicit WorkletsModuleProxy(
21
23
  jsi::Runtime &rnRuntime,
22
24
  const std::shared_ptr<MessageQueueThread> &jsQueue,
23
25
  const std::shared_ptr<CallInvoker> &jsCallInvoker,
24
26
  const std::shared_ptr<UIScheduler> &uiScheduler,
27
+ std::function<bool()> &&isJavaScriptQueue,
25
28
  std::function<void(std::function<void(const double)>)>
26
- &&forwardedRequestAnimationFrame);
29
+ &&forwardedRequestAnimationFrame,
30
+ const std::shared_ptr<const BigStringBuffer> &script,
31
+ const std::string &sourceUrl);
27
32
 
28
- ~WorkletsModuleProxy() override;
29
-
30
- jsi::Value makeShareableClone(
31
- jsi::Runtime &rt,
32
- const jsi::Value &value,
33
- const jsi::Value &shouldRetainRemote,
34
- const jsi::Value &nativeStateSource) override;
35
-
36
- jsi::Value makeShareableString(jsi::Runtime &rt, const jsi::String &string)
37
- override;
38
-
39
- jsi::Value makeShareableNumber(jsi::Runtime &rt, double number) override;
40
-
41
- jsi::Value makeShareableBoolean(jsi::Runtime &rt, bool boolean) override;
42
-
43
- jsi::Value makeShareableBigInt(jsi::Runtime &rt, const jsi::BigInt &bigint)
44
- override;
45
-
46
- jsi::Value makeShareableUndefined(jsi::Runtime &rt) override;
47
-
48
- jsi::Value makeShareableNull(jsi::Runtime &rt) override;
49
-
50
- void scheduleOnUI(jsi::Runtime &rt, const jsi::Value &worklet) override;
51
-
52
- jsi::Value executeOnUIRuntimeSync(jsi::Runtime &rt, const jsi::Value &worklet)
53
- override;
54
-
55
- jsi::Value createWorkletRuntime(
56
- jsi::Runtime &rt,
57
- const jsi::Value &name,
58
- const jsi::Value &initializer) override;
59
-
60
- jsi::Value scheduleOnRuntime(
61
- jsi::Runtime &rt,
62
- const jsi::Value &workletRuntimeValue,
63
- const jsi::Value &shareableWorkletValue) override;
33
+ ~WorkletsModuleProxy();
64
34
 
65
35
  [[nodiscard]] inline std::shared_ptr<MessageQueueThread> getJSQueue() const {
66
36
  return jsQueue_;
@@ -79,6 +49,9 @@ class WorkletsModuleProxy
79
49
  return uiWorkletRuntime_;
80
50
  }
81
51
 
52
+ [[nodiscard]] std::shared_ptr<JSIWorkletsModuleProxy>
53
+ createJSIWorkletsModuleProxy() const;
54
+
82
55
  [[nodiscard]] inline bool isDevBundle() const {
83
56
  return isDevBundle_;
84
57
  }
@@ -88,6 +61,9 @@ class WorkletsModuleProxy
88
61
  const std::shared_ptr<MessageQueueThread> jsQueue_;
89
62
  const std::shared_ptr<JSScheduler> jsScheduler_;
90
63
  const std::shared_ptr<UIScheduler> uiScheduler_;
64
+ const std::shared_ptr<const BigStringBuffer> script_;
65
+ const std::string sourceUrl_;
66
+ const std::shared_ptr<RuntimeManager> runtimeManager_;
91
67
  std::shared_ptr<WorkletRuntime> uiWorkletRuntime_;
92
68
  std::shared_ptr<AnimationFrameBatchinator> animationFrameBatchinator_;
93
69
  #ifndef NDEBUG
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  #include <jsi/jsi.h>
4
+ #include <react/debug/react_native_assert.h>
4
5
 
5
6
  #include <mutex>
6
7
  #include <set>
@@ -30,7 +31,7 @@ class WorkletRuntimeRegistry {
30
31
 
31
32
  public:
32
33
  static bool isRuntimeAlive(jsi::Runtime *runtime) {
33
- assert(runtime != nullptr);
34
+ react_native_assert(runtime != nullptr && "runtime is nullptr");
34
35
  std::lock_guard<std::mutex> lock(mutex_);
35
36
  return registry_.find(runtime) != registry_.end();
36
37
  }
@@ -48,7 +48,7 @@ const char ValueUnpackerCode[] =
48
48
  fun.__remoteFunction = objectToUnpack;
49
49
  return fun;
50
50
  } else {
51
- throw new Error("[Worklets] Data type in category \"".concat(category, "\" not recognized by value unpacker: \"").concat(_toString(objectToUnpack), "\"."));
51
+ throw new Error("[Worklets] Data type in category \"".concat(category, "\" not recognized by value unpacker: \"").concat(globalThis._toString(objectToUnpack), "\"."));
52
52
  }
53
53
  })VALUE_UNPACKER";
54
54
  } // namespace worklets
@@ -1,3 +1,4 @@
1
+ #include <jsi/jsi.h>
1
2
  #include <worklets/SharedItems/Shareables.h>
2
3
 
3
4
  using namespace facebook;
@@ -6,7 +7,7 @@ namespace worklets {
6
7
 
7
8
  jsi::Function getValueUnpacker(jsi::Runtime &rt) {
8
9
  auto valueUnpacker = rt.global().getProperty(rt, "__valueUnpacker");
9
- assert(valueUnpacker.isObject() && "valueUnpacker not found");
10
+ react_native_assert(valueUnpacker.isObject() && "valueUnpacker not found");
10
11
  return valueUnpacker.asObject(rt).asFunction(rt);
11
12
  }
12
13
 
@@ -47,23 +48,14 @@ jsi::Value makeShareableClone(
47
48
  if (value.isObject()) {
48
49
  auto object = value.asObject(rt);
49
50
  if (!object.getProperty(rt, "__workletHash").isUndefined()) {
50
- if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
51
- shareable =
52
- std::make_shared<RetainingShareable<ShareableWorklet>>(rt, object);
53
- } else {
54
- shareable = std::make_shared<ShareableWorklet>(rt, object);
55
- }
51
+ // We pass `false` because this function is invoked only
52
+ // by `makeShareableCloneOnUIRecursive` which doesn't
53
+ // make Retaining Shareables.
54
+ return makeShareableWorklet(rt, object, false);
56
55
  } else if (!object.getProperty(rt, "__init").isUndefined()) {
57
- shareable = std::make_shared<ShareableHandle>(rt, object);
56
+ return makeShareableInitializer(rt, object);
58
57
  } else if (object.isFunction(rt)) {
59
- auto function = object.asFunction(rt);
60
- if (function.isHostFunction(rt)) {
61
- shareable =
62
- std::make_shared<ShareableHostFunction>(rt, std::move(function));
63
- } else {
64
- shareable =
65
- std::make_shared<ShareableRemoteFunction>(rt, std::move(function));
66
- }
58
+ return makeShareableFunction(rt, object.asFunction(rt));
67
59
  } else if (object.isArray(rt)) {
68
60
  if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
69
61
  shareable = std::make_shared<RetainingShareable<ShareableArray>>(
@@ -116,32 +108,132 @@ jsi::Value makeShareableClone(
116
108
  }
117
109
 
118
110
  jsi::Value makeShareableString(jsi::Runtime &rt, const jsi::String &string) {
119
- auto shareable = std::make_shared<ShareableString>(string.utf8(rt));
111
+ const auto shareable = std::make_shared<ShareableString>(string.utf8(rt));
120
112
  return ShareableJSRef::newHostObject(rt, shareable);
121
113
  }
122
114
 
123
115
  jsi::Value makeShareableNumber(jsi::Runtime &rt, double number) {
124
- auto shareable = std::make_shared<ShareableScalar>(number);
116
+ const auto shareable = std::make_shared<ShareableScalar>(number);
125
117
  return ShareableJSRef::newHostObject(rt, shareable);
126
118
  }
127
119
 
128
120
  jsi::Value makeShareableBoolean(jsi::Runtime &rt, bool boolean) {
129
- auto shareable = std::make_shared<ShareableScalar>(boolean);
121
+ const auto shareable = std::make_shared<ShareableScalar>(boolean);
130
122
  return ShareableJSRef::newHostObject(rt, shareable);
131
123
  }
132
124
 
133
125
  jsi::Value makeShareableBigInt(jsi::Runtime &rt, const jsi::BigInt &bigint) {
134
- auto shareable = std::make_shared<ShareableBigInt>(rt, bigint);
126
+ const auto shareable = std::make_shared<ShareableBigInt>(rt, bigint);
135
127
  return ShareableJSRef::newHostObject(rt, shareable);
136
128
  }
137
129
 
138
130
  jsi::Value makeShareableUndefined(jsi::Runtime &rt) {
139
- auto shareable = std::make_shared<ShareableScalar>();
131
+ const auto shareable = std::make_shared<ShareableScalar>();
140
132
  return ShareableJSRef::newHostObject(rt, shareable);
141
133
  }
142
134
 
143
135
  jsi::Value makeShareableNull(jsi::Runtime &rt) {
144
- auto shareable = std::make_shared<ShareableScalar>(nullptr);
136
+ const auto shareable = std::make_shared<ShareableScalar>(nullptr);
137
+ return ShareableJSRef::newHostObject(rt, shareable);
138
+ }
139
+
140
+ jsi::Value makeShareableWorklet(
141
+ jsi::Runtime &rt,
142
+ const jsi::Object &object,
143
+ const bool &shouldRetainRemote) {
144
+ std::shared_ptr<Shareable> shareable;
145
+ if (shouldRetainRemote) {
146
+ shareable =
147
+ std::make_shared<RetainingShareable<ShareableWorklet>>(rt, object);
148
+ } else {
149
+ shareable = std::make_shared<ShareableWorklet>(rt, object);
150
+ }
151
+ return ShareableJSRef::newHostObject(rt, shareable);
152
+ }
153
+
154
+ jsi::Value makeShareableInitializer(
155
+ jsi::Runtime &rt,
156
+ const jsi::Object &initializerObject) {
157
+ const auto shareable =
158
+ std::make_shared<ShareableInitializer>(rt, initializerObject);
159
+ return ShareableJSRef::newHostObject(rt, shareable);
160
+ }
161
+
162
+ jsi::Value makeShareableFunction(jsi::Runtime &rt, jsi::Function function) {
163
+ std::shared_ptr<Shareable> shareable;
164
+ if (function.isHostFunction(rt)) {
165
+ shareable =
166
+ std::make_shared<ShareableHostFunction>(rt, std::move(function));
167
+ } else {
168
+ shareable =
169
+ std::make_shared<ShareableRemoteFunction>(rt, std::move(function));
170
+ }
171
+ return ShareableJSRef::newHostObject(rt, shareable);
172
+ }
173
+
174
+ jsi::Value makeShareableArray(
175
+ jsi::Runtime &rt,
176
+ const jsi::Array &array,
177
+ const jsi::Value &shouldRetainRemote) {
178
+ std::shared_ptr<Shareable> shareable;
179
+ if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
180
+ shareable = std::make_shared<RetainingShareable<ShareableArray>>(rt, array);
181
+ } else {
182
+ shareable = std::make_shared<ShareableArray>(rt, array);
183
+ }
184
+ return ShareableJSRef::newHostObject(rt, shareable);
185
+ }
186
+
187
+ jsi::Value makeShareableMap(
188
+ jsi::Runtime &rt,
189
+ const jsi::Array &keys,
190
+ const jsi::Array &values) {
191
+ auto shareable = std::make_shared<ShareableMap>(rt, keys, values);
192
+ return ShareableJSRef::newHostObject(rt, shareable);
193
+ }
194
+
195
+ jsi::Value makeShareableSet(jsi::Runtime &rt, const jsi::Array &values) {
196
+ auto shareable = std::make_shared<ShareableSet>(rt, values);
197
+ return ShareableJSRef::newHostObject(rt, shareable);
198
+ }
199
+
200
+ jsi::Value makeShareableHostObject(
201
+ jsi::Runtime &rt,
202
+ const std::shared_ptr<jsi::HostObject> &value) {
203
+ const auto shareable = std::make_shared<ShareableHostObject>(rt, value);
204
+ return ShareableJSRef::newHostObject(rt, shareable);
205
+ }
206
+
207
+ jsi::Value makeShareableTurboModuleLike(
208
+ jsi::Runtime &rt,
209
+ const jsi::Object &object,
210
+ const std::shared_ptr<jsi::HostObject> &proto) {
211
+ const auto shareable =
212
+ std::make_shared<ShareableTurboModuleLike>(rt, object, proto);
213
+ return ShareableJSRef::newHostObject(rt, shareable);
214
+ }
215
+
216
+ jsi::Value makeShareableImport(
217
+ jsi::Runtime &rt,
218
+ const double source,
219
+ const jsi::String &imported) {
220
+ auto shareable = std::make_shared<ShareableImport>(rt, source, imported);
221
+ return ShareableJSRef::newHostObject(rt, shareable);
222
+ }
223
+
224
+ jsi::Value makeShareableObject(
225
+ jsi::Runtime &rt,
226
+ jsi::Object object,
227
+ bool shouldRetainRemote,
228
+ const jsi::Value &nativeStateSource) {
229
+ std::shared_ptr<Shareable> shareable;
230
+ if (shouldRetainRemote) {
231
+ shareable = std::make_shared<RetainingShareable<ShareableObject>>(
232
+ rt, object, nativeStateSource);
233
+ } else {
234
+ shareable =
235
+ std::make_shared<ShareableObject>(rt, object, nativeStateSource);
236
+ }
145
237
  return ShareableJSRef::newHostObject(rt, shareable);
146
238
  }
147
239
 
@@ -263,6 +355,61 @@ jsi::Value ShareableObject::toJSValue(jsi::Runtime &rt) {
263
355
  return obj;
264
356
  }
265
357
 
358
+ ShareableMap::ShareableMap(
359
+ jsi::Runtime &rt,
360
+ const jsi::Array &keys,
361
+ const jsi::Array &values)
362
+ : Shareable(MapType) {
363
+ auto size = keys.size(rt);
364
+ react_native_assert(
365
+ size == values.size(rt) &&
366
+ "Keys and values arrays must have the same size.");
367
+ data_.reserve(size);
368
+ for (size_t i = 0; i < size; i++) {
369
+ auto key = extractShareableOrThrow(rt, keys.getValueAtIndex(rt, i));
370
+ auto value = extractShareableOrThrow(rt, values.getValueAtIndex(rt, i));
371
+ data_.emplace_back(key, value);
372
+ }
373
+ }
374
+
375
+ jsi::Value ShareableMap::toJSValue(jsi::Runtime &rt) {
376
+ const auto keyValues = jsi::Array(rt, data_.size());
377
+ for (size_t i = 0, size = data_.size(); i < size; i++) {
378
+ const auto pair = jsi::Array(rt, 2);
379
+ pair.setValueAtIndex(rt, 0, data_[i].first->toJSValue(rt));
380
+ pair.setValueAtIndex(rt, 1, data_[i].second->toJSValue(rt));
381
+ keyValues.setValueAtIndex(rt, i, std::move(pair));
382
+ }
383
+
384
+ const auto &global = rt.global();
385
+ auto map = global.getPropertyAsFunction(rt, "Map").callAsConstructor(
386
+ rt, std::move(keyValues));
387
+
388
+ return map;
389
+ }
390
+
391
+ ShareableSet::ShareableSet(jsi::Runtime &rt, const jsi::Array &values)
392
+ : Shareable(SetType) {
393
+ auto size = values.size(rt);
394
+ data_.reserve(size);
395
+ for (size_t i = 0; i < size; i++) {
396
+ data_.push_back(extractShareableOrThrow(rt, values.getValueAtIndex(rt, i)));
397
+ }
398
+ }
399
+
400
+ jsi::Value ShareableSet::toJSValue(jsi::Runtime &rt) {
401
+ const auto values = jsi::Array(rt, data_.size());
402
+ for (size_t i = 0, size = data_.size(); i < size; i++) {
403
+ values.setValueAtIndex(rt, i, data_[i]->toJSValue(rt));
404
+ }
405
+
406
+ const auto &global = rt.global();
407
+ auto set = global.getPropertyAsFunction(rt, "Set").callAsConstructor(
408
+ rt, std::move(values));
409
+
410
+ return set;
411
+ }
412
+
266
413
  jsi::Value ShareableHostObject::toJSValue(jsi::Runtime &rt) {
267
414
  return jsi::Object::createFromHostObject(rt, hostObject_);
268
415
  }
@@ -273,7 +420,7 @@ jsi::Value ShareableHostFunction::toJSValue(jsi::Runtime &rt) {
273
420
  }
274
421
 
275
422
  jsi::Value ShareableWorklet::toJSValue(jsi::Runtime &rt) {
276
- assert(
423
+ react_native_assert(
277
424
  std::any_of(
278
425
  data_.cbegin(),
279
426
  data_.cend(),
@@ -284,6 +431,24 @@ jsi::Value ShareableWorklet::toJSValue(jsi::Runtime &rt) {
284
431
  rt, obj, jsi::String::createFromAscii(rt, "Worklet"));
285
432
  }
286
433
 
434
+ jsi::Value ShareableImport::toJSValue(jsi::Runtime &rt) {
435
+ /**
436
+ * The only way to obtain a module in runtime is to use the Metro's require
437
+ * method implementation, which is injected into the global object as `__r`.
438
+ */
439
+ const auto metroRequire = rt.global().getProperty(rt, "__r");
440
+ if (metroRequire.isUndefined()) {
441
+ return jsi::Value::undefined();
442
+ }
443
+
444
+ const auto imported = jsi::String::createFromUtf8(rt, imported_);
445
+ return metroRequire.asObject(rt)
446
+ .asFunction(rt)
447
+ .call(rt, source_)
448
+ .asObject(rt)
449
+ .getProperty(rt, imported);
450
+ }
451
+
287
452
  jsi::Value ShareableRemoteFunction::toJSValue(jsi::Runtime &rt) {
288
453
  if (&rt == runtime_) {
289
454
  return jsi::Value(rt, *function_);
@@ -300,7 +465,7 @@ jsi::Value ShareableRemoteFunction::toJSValue(jsi::Runtime &rt) {
300
465
  }
301
466
  }
302
467
 
303
- jsi::Value ShareableHandle::toJSValue(jsi::Runtime &rt) {
468
+ jsi::Value ShareableInitializer::toJSValue(jsi::Runtime &rt) {
304
469
  if (remoteValue_ == nullptr) {
305
470
  auto initObj = initializer_->toJSValue(rt);
306
471
  auto value = std::make_unique<jsi::Value>(getValueUnpacker(rt).call(
@@ -353,4 +518,15 @@ jsi::Value ShareableScalar::toJSValue(jsi::Runtime &) {
353
518
  }
354
519
  }
355
520
 
521
+ jsi::Value ShareableTurboModuleLike::toJSValue(jsi::Runtime &rt) {
522
+ auto obj = properties_->toJSValue(rt).asObject(rt);
523
+ const auto prototype = proto_->toJSValue(rt);
524
+ rt.global()
525
+ .getPropertyAsObject(rt, "Object")
526
+ .getPropertyAsFunction(rt, "setPrototypeOf")
527
+ .call(rt, obj, prototype);
528
+
529
+ return obj;
530
+ }
531
+
356
532
  } // namespace worklets