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
@@ -33,7 +33,7 @@ inline jsi::Value runOnRuntimeGuarded(
33
33
  return getCallGuard(rt).call(rt, function, args...);
34
34
  #else
35
35
  return function.asObject(rt).asFunction(rt).call(rt, args...);
36
- #endif
36
+ #endif // NDEBUG
37
37
  }
38
38
 
39
39
  inline void cleanupIfRuntimeExists(
@@ -78,12 +78,16 @@ class Shareable {
78
78
  StringType,
79
79
  ObjectType,
80
80
  ArrayType,
81
+ MapType,
82
+ SetType,
81
83
  WorkletType,
82
84
  RemoteFunctionType,
83
85
  HandleType,
84
86
  HostObjectType,
85
87
  HostFunctionType,
86
88
  ArrayBufferType,
89
+ TurboModuleLikeType,
90
+ ImportType,
87
91
  };
88
92
 
89
93
  explicit Shareable(ValueType valueType) : valueType_(valueType) {}
@@ -157,6 +161,49 @@ jsi::Value makeShareableUndefined(jsi::Runtime &rt);
157
161
 
158
162
  jsi::Value makeShareableNull(jsi::Runtime &rt);
159
163
 
164
+ jsi::Value makeShareableTurboModuleLike(
165
+ jsi::Runtime &rt,
166
+ const jsi::Object &object,
167
+ const std::shared_ptr<jsi::HostObject> &proto);
168
+
169
+ jsi::Value makeShareableObject(
170
+ jsi::Runtime &rt,
171
+ jsi::Object object,
172
+ bool shouldRetainRemote,
173
+ const jsi::Value &nativeStateSource);
174
+
175
+ jsi::Value makeShareableImport(
176
+ jsi::Runtime &rt,
177
+ const double source,
178
+ const jsi::String &imported);
179
+
180
+ jsi::Value makeShareableHostObject(
181
+ jsi::Runtime &rt,
182
+ const std::shared_ptr<jsi::HostObject> &value);
183
+
184
+ jsi::Value makeShareableArray(
185
+ jsi::Runtime &rt,
186
+ const jsi::Array &array,
187
+ const jsi::Value &shouldRetainRemote);
188
+
189
+ jsi::Value makeShareableMap(
190
+ jsi::Runtime &rt,
191
+ const jsi::Array &keys,
192
+ const jsi::Array &values);
193
+
194
+ jsi::Value makeShareableSet(jsi::Runtime &rt, const jsi::Array &values);
195
+
196
+ jsi::Value makeShareableInitializer(
197
+ jsi::Runtime &rt,
198
+ const jsi::Object &initializerObject);
199
+
200
+ jsi::Value makeShareableFunction(jsi::Runtime &rt, jsi::Function function);
201
+
202
+ jsi::Value makeShareableWorklet(
203
+ jsi::Runtime &rt,
204
+ const jsi::Object &object,
205
+ const bool &shouldRetainRemote);
206
+
160
207
  std::shared_ptr<Shareable> extractShareableOrThrow(
161
208
  jsi::Runtime &rt,
162
209
  const jsi::Value &maybeShareableValue,
@@ -203,6 +250,30 @@ class ShareableObject : public Shareable {
203
250
  std::shared_ptr<jsi::NativeState> nativeState_;
204
251
  };
205
252
 
253
+ class ShareableMap : public Shareable {
254
+ public:
255
+ ShareableMap(
256
+ jsi::Runtime &rt,
257
+ const jsi::Array &keys,
258
+ const jsi::Array &values);
259
+
260
+ jsi::Value toJSValue(jsi::Runtime &rt) override;
261
+
262
+ protected:
263
+ std::vector<std::pair<std::shared_ptr<Shareable>, std::shared_ptr<Shareable>>>
264
+ data_;
265
+ };
266
+
267
+ class ShareableSet : public Shareable {
268
+ public:
269
+ ShareableSet(jsi::Runtime &rt, const jsi::Array &values);
270
+
271
+ jsi::Value toJSValue(jsi::Runtime &rt) override;
272
+
273
+ protected:
274
+ std::vector<std::shared_ptr<Shareable>> data_;
275
+ };
276
+
206
277
  class ShareableHostObject : public Shareable {
207
278
  public:
208
279
  ShareableHostObject(
@@ -220,9 +291,7 @@ class ShareableHostFunction : public Shareable {
220
291
  public:
221
292
  ShareableHostFunction(jsi::Runtime &rt, jsi::Function function)
222
293
  : Shareable(HostFunctionType),
223
- hostFunction_(
224
- (assert(function.isHostFunction(rt)),
225
- function.getHostFunction(rt))),
294
+ hostFunction_(function.getHostFunction(rt)),
226
295
  name_(function.getProperty(rt, "name").asString(rt).utf8(rt)),
227
296
  paramCount_(function.getProperty(rt, "length").asNumber()) {}
228
297
 
@@ -258,6 +327,21 @@ class ShareableWorklet : public ShareableObject {
258
327
  jsi::Value toJSValue(jsi::Runtime &rt) override;
259
328
  };
260
329
 
330
+ class ShareableImport : public Shareable {
331
+ public:
332
+ ShareableImport(
333
+ jsi::Runtime &rt,
334
+ const double source,
335
+ const jsi::String &imported)
336
+ : Shareable(ImportType), source_(source), imported_(imported.utf8(rt)) {}
337
+
338
+ jsi::Value toJSValue(jsi::Runtime &rt) override;
339
+
340
+ protected:
341
+ const double source_;
342
+ const std::string imported_;
343
+ };
344
+
261
345
  class ShareableRemoteFunction
262
346
  : public Shareable,
263
347
  public std::enable_shared_from_this<ShareableRemoteFunction> {
@@ -285,7 +369,7 @@ class ShareableRemoteFunction
285
369
  jsi::Value toJSValue(jsi::Runtime &rt) override;
286
370
  };
287
371
 
288
- class ShareableHandle : public Shareable {
372
+ class ShareableInitializer : public Shareable {
289
373
  private:
290
374
  // We don't release the initializer since the handle can get
291
375
  // initialized in parallel on multiple threads. However this is not a problem,
@@ -297,12 +381,12 @@ class ShareableHandle : public Shareable {
297
381
  jsi::Runtime *remoteRuntime_;
298
382
 
299
383
  public:
300
- ShareableHandle(jsi::Runtime &rt, const jsi::Object &initializerObject)
384
+ ShareableInitializer(jsi::Runtime &rt, const jsi::Object &initializerObject)
301
385
  : Shareable(HandleType),
302
386
  initializer_(std::make_unique<ShareableObject>(rt, initializerObject)) {
303
387
  }
304
388
 
305
- ~ShareableHandle() {
389
+ ~ShareableInitializer() {
306
390
  cleanupIfRuntimeExists(remoteRuntime_, remoteValue_);
307
391
  }
308
392
 
@@ -354,4 +438,21 @@ class ShareableScalar : public Shareable {
354
438
  Data data_;
355
439
  };
356
440
 
441
+ class ShareableTurboModuleLike : public Shareable {
442
+ public:
443
+ ShareableTurboModuleLike(
444
+ jsi::Runtime &rt,
445
+ const jsi::Object &object,
446
+ const std::shared_ptr<jsi::HostObject> &proto)
447
+ : Shareable(TurboModuleLikeType),
448
+ proto_(std::make_unique<ShareableHostObject>(rt, proto)),
449
+ properties_(std::make_unique<ShareableObject>(rt, object)) {}
450
+
451
+ jsi::Value toJSValue(jsi::Runtime &rt) override;
452
+
453
+ private:
454
+ const std::unique_ptr<ShareableHostObject> proto_;
455
+ const std::unique_ptr<ShareableObject> properties_;
456
+ };
457
+
357
458
  } // namespace worklets
@@ -1,16 +1,68 @@
1
1
  #include <worklets/Tools/JSLogger.h>
2
+
2
3
  #include <memory>
4
+ #include <utility>
3
5
 
4
6
  namespace worklets {
5
7
 
6
8
  void JSLogger::warnOnJS(const std::string &warning) const {
7
9
  #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));
10
+ jsScheduler_->scheduleOnJS([warning](jsi::Runtime &rnRuntime) {
11
+ auto console = rnRuntime.global().getPropertyAsObject(rnRuntime, "console");
12
+ auto warn = console.getPropertyAsFunction(rnRuntime, "warn");
13
+ warn.call(rnRuntime, jsi::String::createFromUtf8(rnRuntime, warning));
12
14
  });
13
15
  #endif // NDEBUG
14
16
  }
15
17
 
18
+ void JSLogger::reportFatalErrorOnJS(
19
+ const std::shared_ptr<JSScheduler> &jsScheduler,
20
+ JSErrorData &&jsErrorData,
21
+ bool force) {
22
+ auto job = [jsErrorData = std::move(jsErrorData),
23
+ force](jsi::Runtime &rnRuntime) {
24
+ reportFatalErrorOnJS(rnRuntime, jsErrorData, force);
25
+ };
26
+ if (jsScheduler->canInvokeSyncOnJS()) {
27
+ jsScheduler->invokeSyncOnJS(job);
28
+ } else {
29
+ jsScheduler->scheduleOnJS(job);
30
+ }
31
+ }
32
+
33
+ void JSLogger::reportFatalErrorOnJS(
34
+ jsi::Runtime &rnRuntime,
35
+ const JSErrorData &jsErrorData,
36
+ bool force) {
37
+ const auto &global = rnRuntime.global();
38
+ const auto errorInstance = rnRuntime.global()
39
+ .getPropertyAsFunction(rnRuntime, "Error")
40
+ .callAsConstructor(rnRuntime)
41
+ .asObject(rnRuntime);
42
+
43
+ errorInstance.setProperty(
44
+ rnRuntime,
45
+ "message",
46
+ jsi::String::createFromUtf8(rnRuntime, jsErrorData.message));
47
+
48
+ errorInstance.setProperty(
49
+ rnRuntime,
50
+ "stack",
51
+ jsi::String::createFromUtf8(rnRuntime, jsErrorData.stack));
52
+
53
+ errorInstance.setProperty(
54
+ rnRuntime,
55
+ "name",
56
+ jsi::String::createFromUtf8(rnRuntime, jsErrorData.name));
57
+
58
+ errorInstance.setProperty(
59
+ rnRuntime,
60
+ "jsEngine",
61
+ jsi::String::createFromUtf8(rnRuntime, jsErrorData.jsEngine));
62
+
63
+ const auto &reportFatalErrorFunction =
64
+ global.getPropertyAsFunction(rnRuntime, "__reportFatalRemoteError");
65
+ reportFatalErrorFunction.call(rnRuntime, errorInstance, force);
66
+ }
67
+
16
68
  } // namespace worklets
@@ -7,13 +7,30 @@
7
7
 
8
8
  namespace worklets {
9
9
 
10
+ struct JSErrorData {
11
+ std::string message;
12
+ std::string stack;
13
+ std::string name;
14
+ std::string jsEngine;
15
+ };
16
+
10
17
  class JSLogger {
11
18
  public:
12
19
  explicit JSLogger(const std::shared_ptr<JSScheduler> &jsScheduler)
13
20
  : jsScheduler_(jsScheduler) {}
14
21
  void warnOnJS(const std::string &warning) const;
15
22
 
23
+ static void reportFatalErrorOnJS(
24
+ const std::shared_ptr<JSScheduler> &jsScheduler,
25
+ JSErrorData &&jsErrorData,
26
+ bool force = false);
27
+
16
28
  private:
29
+ static void reportFatalErrorOnJS(
30
+ jsi::Runtime &rnRuntime,
31
+ const JSErrorData &jsErrorData,
32
+ bool force = false);
33
+
17
34
  const std::shared_ptr<JSScheduler> jsScheduler_;
18
35
  };
19
36
 
@@ -1,3 +1,4 @@
1
+ #include <react/debug/react_native_assert.h>
1
2
  #include <worklets/Tools/JSScheduler.h>
2
3
 
3
4
  #include <utility>
@@ -9,4 +10,15 @@ void JSScheduler::scheduleOnJS(Job job) {
9
10
  [job = std::move(job), &rt = rnRuntime_] { job(rt); });
10
11
  }
11
12
 
13
+ bool JSScheduler::canInvokeSyncOnJS() {
14
+ return isJavaScriptQueue_();
15
+ }
16
+
17
+ void JSScheduler::invokeSyncOnJS(Job job) {
18
+ react_native_assert(
19
+ canInvokeSyncOnJS() &&
20
+ "JSScheduler::invokeSyncOnJS should only be called from the JS thread");
21
+ job(rnRuntime_);
22
+ }
23
+
12
24
  } // namespace worklets
@@ -16,14 +16,22 @@ class JSScheduler {
16
16
  public:
17
17
  explicit JSScheduler(
18
18
  jsi::Runtime &rnRuntime,
19
- const std::shared_ptr<CallInvoker> &jsCallInvoker)
20
- : rnRuntime_(rnRuntime), jsCallInvoker_(jsCallInvoker) {}
19
+ const std::shared_ptr<CallInvoker> &jsCallInvoker,
20
+ std::function<bool()> &&isJavaScriptQueue)
21
+ : rnRuntime_(rnRuntime),
22
+ jsCallInvoker_(jsCallInvoker),
23
+ isJavaScriptQueue_(isJavaScriptQueue) {}
21
24
 
22
25
  void scheduleOnJS(std::function<void(jsi::Runtime &rt)> job);
23
26
 
27
+ void invokeSyncOnJS(std::function<void(jsi::Runtime &rt)> job);
28
+
29
+ bool canInvokeSyncOnJS();
30
+
24
31
  protected:
25
32
  jsi::Runtime &rnRuntime_;
26
33
  const std::shared_ptr<CallInvoker> jsCallInvoker_;
34
+ const std::function<bool()> isJavaScriptQueue_;
27
35
  };
28
36
 
29
37
  } // namespace worklets
@@ -2,6 +2,8 @@
2
2
 
3
3
  #ifndef NDEBUG
4
4
 
5
+ #include <react/debug/react_native_assert.h>
6
+
5
7
  #include <cxxabi.h>
6
8
 
7
9
  #include <atomic>
@@ -35,7 +37,7 @@ class SingleInstanceChecker {
35
37
  #endif
36
38
 
37
39
  #ifdef IS_REANIMATED_EXAMPLE_APP
38
- assert(false);
40
+ react_native_assert(false && "SingleInstanceChecker failed");
39
41
  #endif
40
42
  }
41
43
  }
@@ -1,4 +1,9 @@
1
1
  #include <worklets/Tools/WorkletsJSIUtils.h>
2
+
3
+ #include <react/debug/react_native_assert.h>
4
+
5
+ #include <memory>
6
+ #include <sstream>
2
7
  #include <vector>
3
8
 
4
9
  using namespace facebook;
@@ -15,7 +20,9 @@ jsi::Array convertStringToArray(
15
20
  std::istream_iterator<float>(stringStream),
16
21
  std::istream_iterator<float>(),
17
22
  std::back_inserter(transformMatrixList));
18
- assert(transformMatrixList.size() == expectedSize);
23
+ react_native_assert(
24
+ transformMatrixList.size() == expectedSize &&
25
+ "Transform matrix list size is different than expected");
19
26
  jsi::Array matrix(rt, expectedSize);
20
27
  for (unsigned int i = 0; i < expectedSize; i++) {
21
28
  matrix.setValueAtIndex(rt, i, transformMatrixList[i]);
@@ -23,4 +30,15 @@ jsi::Array convertStringToArray(
23
30
  return matrix;
24
31
  }
25
32
 
33
+ jsi::Object optimizedFromHostObject(
34
+ jsi::Runtime &rt,
35
+ std::shared_ptr<jsi::HostObject> &&hostObject) {
36
+ auto optimizedObject = jsi::Object(rt);
37
+ for (const auto &propertyName : hostObject->getPropertyNames(rt)) {
38
+ optimizedObject.setProperty(
39
+ rt, propertyName, hostObject->get(rt, propertyName));
40
+ }
41
+ return optimizedObject;
42
+ }
43
+
26
44
  } // namespace worklets::jsi_utils
@@ -1,7 +1,8 @@
1
1
  #pragma once
2
2
 
3
3
  #include <jsi/jsi.h>
4
- #include <sstream>
4
+ #include <react/debug/react_native_assert.h>
5
+ #include <memory>
5
6
  #include <string>
6
7
  #include <tuple>
7
8
  #include <utility>
@@ -83,7 +84,9 @@ std::tuple<Args...> getArgsForFunction(
83
84
  jsi::Runtime &rt,
84
85
  const jsi::Value *args,
85
86
  const size_t count) {
86
- assert(sizeof...(Args) == count);
87
+ react_native_assert(
88
+ sizeof...(Args) == count &&
89
+ "Argument list has different length than expected");
87
90
  return convertArgs<Args...>(rt, args);
88
91
  }
89
92
 
@@ -96,7 +99,9 @@ std::tuple<jsi::Runtime &, Args...> getArgsForFunction(
96
99
  jsi::Runtime &rt,
97
100
  const jsi::Value *args,
98
101
  const size_t count) {
99
- assert(sizeof...(Args) == count);
102
+ react_native_assert(
103
+ sizeof...(Args) == count &&
104
+ "Argument list has different length than expected");
100
105
  return std::tuple_cat(std::tie(rt), convertArgs<Args...>(rt, args));
101
106
  }
102
107
 
@@ -196,4 +201,8 @@ jsi::Array convertStringToArray(
196
201
  const std::string &value,
197
202
  const unsigned int expectedSize);
198
203
 
204
+ jsi::Object optimizedFromHostObject(
205
+ jsi::Runtime &rt,
206
+ std::shared_ptr<jsi::HostObject> &&hostObject);
207
+
199
208
  } // namespace worklets::jsi_utils
@@ -0,0 +1,136 @@
1
+ #pragma once
2
+ #include <string>
3
+ #include <vector>
4
+
5
+ #ifdef WORKLETS_PROFILING
6
+
7
+ #if defined(__APPLE__)
8
+ #include <os/trace_base.h>
9
+
10
+ #if OS_LOG_TARGET_HAS_10_15_FEATURES
11
+ #include <os/log.h>
12
+ #include <os/signpost.h>
13
+ #include <sstream>
14
+ #endif // OS_LOG_TARGET_HAS_10_15_FEATURES
15
+
16
+ #elif defined(ANDROID)
17
+
18
+ #include <android/trace.h>
19
+
20
+ #endif // defined(ANDROID)
21
+
22
+ #endif // WORKLETS_PROFILING
23
+
24
+ namespace worklets {
25
+
26
+ #if defined(ANDROID) && defined(WORKLETS_PROFILING)
27
+
28
+ // avg 6.10 min 2.87 max 7.68 dev 0.42
29
+ // avg 6.09 min 3.29 max 8.62 dev 0.50
30
+
31
+ struct WorkletsSystraceSection {
32
+ public:
33
+ template <typename... ConvertsToStringPiece>
34
+ explicit WorkletsSystraceSection(
35
+ const char *name,
36
+ ConvertsToStringPiece &&...args) {
37
+ ATrace_beginSection(name);
38
+ }
39
+
40
+ ~WorkletsSystraceSection() {
41
+ ATrace_endSection();
42
+ }
43
+ };
44
+
45
+ // The apple part is copied from React Native
46
+ // from
47
+ // https://github.com/facebook/react-native/blob/5697d923a05119314b4cfcd556cb243986637764/packages/react-native/ReactCommon/cxxreact/SystraceSection.h
48
+ #elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES && \
49
+ defined(WORKLETS_PROFILING)
50
+
51
+ template <typename T, typename = void>
52
+ struct renderer {
53
+ static std::string render(const T &t) {
54
+ std::ostringstream oss;
55
+ oss << t;
56
+ return oss.str();
57
+ }
58
+ };
59
+
60
+ template <typename T>
61
+ static auto render(const T &t)
62
+ -> decltype(renderer<T>::render(std::declval<const T &>())) {
63
+ return renderer<T>::render(t);
64
+ }
65
+
66
+ inline os_log_t instrumentsLogHandle = nullptr;
67
+
68
+ static inline os_log_t getOrCreateInstrumentsLogHandle() {
69
+ if (!instrumentsLogHandle) {
70
+ instrumentsLogHandle = os_log_create(
71
+ "dev.worklets.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
72
+ }
73
+ return instrumentsLogHandle;
74
+ }
75
+
76
+ struct WorkletsSystraceSection {
77
+ public:
78
+ template <typename... ConvertsToStringPiece>
79
+ explicit WorkletsSystraceSection(
80
+ const char *name,
81
+ ConvertsToStringPiece &&...args) {
82
+ os_log_t instrumentsLogHandle = worklets::getOrCreateInstrumentsLogHandle();
83
+
84
+ // If the log isn't enabled, we don't want the performance overhead of the
85
+ // rest of the code below.
86
+ if (!os_signpost_enabled(instrumentsLogHandle)) {
87
+ return;
88
+ }
89
+
90
+ name_ = name;
91
+
92
+ const auto argsVector = std::vector<std::string>{worklets::render(args)...};
93
+ std::string argsString = "";
94
+ for (size_t i = 0; i < argsVector.size(); i += 2) {
95
+ argsString += argsVector[i] + "=" + argsVector[i + 1] + ";";
96
+ }
97
+
98
+ signpostID_ = os_signpost_id_make_with_pointer(instrumentsLogHandle, this);
99
+
100
+ os_signpost_interval_begin(
101
+ instrumentsLogHandle,
102
+ signpostID_,
103
+ "Worklets",
104
+ "%s begin: %s",
105
+ name,
106
+ argsString.c_str());
107
+ }
108
+
109
+ ~WorkletsSystraceSection() {
110
+ os_signpost_interval_end(
111
+ worklets::instrumentsLogHandle,
112
+ signpostID_,
113
+ "Worklets",
114
+ "%s end",
115
+ name_.data());
116
+ }
117
+
118
+ private:
119
+ os_signpost_id_t signpostID_ = OS_SIGNPOST_ID_INVALID;
120
+ std::string_view name_;
121
+ };
122
+
123
+ #else
124
+
125
+ struct WorkletsSystraceSection {
126
+ public:
127
+ template <typename... ConvertsToStringPiece>
128
+ explicit WorkletsSystraceSection(
129
+ const char *name,
130
+ ConvertsToStringPiece &&...args) {}
131
+ };
132
+
133
+ #endif // defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES &&
134
+ // defined(WORKLETS_PROFILING)
135
+
136
+ } // namespace worklets
@@ -1,11 +1,13 @@
1
1
  #include <worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h>
2
2
  #include <worklets/WorkletRuntime/WorkletRuntimeCollector.h>
3
3
 
4
+ #include <utility>
5
+
4
6
  namespace worklets {
5
7
 
6
8
  void RNRuntimeWorkletDecorator::decorate(
7
9
  jsi::Runtime &rnRuntime,
8
- const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy) {
10
+ jsi::Object &&jsiWorkletsModuleProxy) {
9
11
  rnRuntime.global().setProperty(rnRuntime, "_WORKLET", false);
10
12
 
11
13
  // TODO: Remove _IS_FABRIC sometime in the future
@@ -13,9 +15,7 @@ void RNRuntimeWorkletDecorator::decorate(
13
15
  rnRuntime.global().setProperty(rnRuntime, "_IS_FABRIC", true);
14
16
 
15
17
  rnRuntime.global().setProperty(
16
- rnRuntime,
17
- "__workletsModuleProxy",
18
- jsi::Object::createFromHostObject(rnRuntime, workletsModuleProxy));
18
+ rnRuntime, "__workletsModuleProxy", std::move(jsiWorkletsModuleProxy));
19
19
 
20
20
  WorkletRuntimeCollector::install(rnRuntime);
21
21
  }
@@ -13,7 +13,7 @@ class RNRuntimeWorkletDecorator {
13
13
  public:
14
14
  static void decorate(
15
15
  jsi::Runtime &rnRuntime,
16
- const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy);
16
+ jsi::Object &&jsiWorkletsModuleProxy);
17
17
  };
18
18
 
19
19
  } // namespace worklets
@@ -0,0 +1,85 @@
1
+ #include <worklets/NativeModules/JSIWorkletsModuleProxy.h>
2
+ #include <worklets/WorkletRuntime/RuntimeManager.h>
3
+
4
+ #include <utility>
5
+
6
+ namespace worklets {
7
+
8
+ const std::string uiRuntimeName{"UI"};
9
+
10
+ std::shared_ptr<WorkletRuntime> RuntimeManager::getRuntime(uint64_t runtimeId) {
11
+ std::shared_lock lock(weakRuntimesMutex_);
12
+ if (weakRuntimes_.contains(runtimeId)) {
13
+ return weakRuntimes_.at(runtimeId).lock();
14
+ }
15
+ return nullptr;
16
+ }
17
+
18
+ std::shared_ptr<WorkletRuntime> RuntimeManager::getRuntime(
19
+ const std::string &name) {
20
+ std::shared_lock lock(weakRuntimesMutex_);
21
+ if (nameToRuntimeId_.contains(name)) {
22
+ return getRuntime(nameToRuntimeId_.at(name));
23
+ }
24
+ return nullptr;
25
+ }
26
+
27
+ std::vector<std::shared_ptr<WorkletRuntime>> RuntimeManager::getAllRuntimes() {
28
+ std::shared_lock lock(weakRuntimesMutex_);
29
+
30
+ std::vector<std::shared_ptr<WorkletRuntime>> runtimes;
31
+ runtimes.reserve(weakRuntimes_.size());
32
+
33
+ for (const auto &[id, weakRuntime] : weakRuntimes_) {
34
+ if (auto runtime = weakRuntime.lock()) {
35
+ runtimes.push_back(runtime);
36
+ }
37
+ }
38
+
39
+ return runtimes;
40
+ }
41
+
42
+ std::shared_ptr<WorkletRuntime> RuntimeManager::getUIRuntime() {
43
+ return getRuntime(uiRuntimeId);
44
+ }
45
+
46
+ std::shared_ptr<WorkletRuntime> RuntimeManager::createWorkletRuntime(
47
+ std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy,
48
+ const bool supportsLocking,
49
+ const std::string &name,
50
+ std::shared_ptr<ShareableWorklet> initializer) {
51
+ const auto runtimeId = getNextRuntimeId();
52
+ const auto jsQueue = jsiWorkletsModuleProxy->getJSQueue();
53
+
54
+ auto workletRuntime = std::make_shared<WorkletRuntime>(
55
+ runtimeId, jsQueue, name, true /* supportsLocking */
56
+ );
57
+
58
+ workletRuntime->init(std::move(jsiWorkletsModuleProxy));
59
+
60
+ if (initializer) {
61
+ workletRuntime->runGuarded(initializer);
62
+ }
63
+
64
+ std::unique_lock lock(weakRuntimesMutex_);
65
+ weakRuntimes_[runtimeId] = workletRuntime;
66
+ nameToRuntimeId_[name] = runtimeId;
67
+
68
+ return workletRuntime;
69
+ }
70
+
71
+ std::shared_ptr<WorkletRuntime> RuntimeManager::createUninitializedUIRuntime(
72
+ const std::shared_ptr<MessageQueueThread> &jsQueue) {
73
+ const auto uiRuntime = std::make_shared<WorkletRuntime>(
74
+ uiRuntimeId, jsQueue, uiRuntimeName, true /* supportsLocking */
75
+ );
76
+ std::unique_lock lock(weakRuntimesMutex_);
77
+ weakRuntimes_[uiRuntimeId] = uiRuntime;
78
+ return uiRuntime;
79
+ }
80
+
81
+ uint64_t RuntimeManager::getNextRuntimeId() {
82
+ return nextRuntimeId_.fetch_add(1, std::memory_order_relaxed);
83
+ }
84
+
85
+ } // namespace worklets