react-native-worklets 0.7.2 → 0.8.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 (123) hide show
  1. package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.cpp +32 -28
  2. package/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.h +13 -5
  3. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +7 -5
  4. package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +5 -4
  5. package/Common/cpp/worklets/Resources/SynchronizableUnpacker.cpp +5 -5
  6. package/Common/cpp/worklets/RunLoop/AsyncQueueImpl.cpp +42 -19
  7. package/Common/cpp/worklets/RunLoop/AsyncQueueImpl.h +2 -0
  8. package/Common/cpp/worklets/Tools/Defs.h +2 -2
  9. package/Common/cpp/worklets/Tools/ScriptBuffer.h +34 -0
  10. package/Common/cpp/worklets/WorkletRuntime/RuntimeBindings.h +24 -0
  11. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +11 -6
  12. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +82 -0
  13. package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +12 -0
  14. package/RNWorklets.podspec +15 -14
  15. package/android/CMakeLists.txt +8 -2
  16. package/android/build.gradle +92 -56
  17. package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.cpp +67 -0
  18. package/android/src/main/cpp/worklets/android/JScriptBufferWrapper.h +48 -0
  19. package/android/src/main/cpp/worklets/android/JWorkletRuntimeWrapper.cpp +52 -0
  20. package/android/src/main/cpp/worklets/android/JWorkletRuntimeWrapper.h +43 -0
  21. package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +115 -19
  22. package/android/src/main/cpp/worklets/android/WorkletsModule.h +11 -13
  23. package/android/src/main/cpp/worklets/android/WorkletsOnLoad.cpp +6 -0
  24. package/android/src/main/java/com/swmansion/worklets/ScriptBufferWrapper.java +88 -0
  25. package/android/src/networking/com/swmansion/worklets/WorkletRuntimeWrapper.kt +23 -0
  26. package/android/src/networking/com/swmansion/worklets/WorkletsHeaderUtil.kt +30 -0
  27. package/android/src/{legacyBundling → networking}/com/swmansion/worklets/WorkletsModule.java +52 -2
  28. package/android/src/networking/com/swmansion/worklets/WorkletsNetworkEventUtil.kt +268 -0
  29. package/android/src/networking/com/swmansion/worklets/WorkletsNetworking.kt +1084 -0
  30. package/android/src/networking/com/swmansion/worklets/WorkletsOkHttpCallUtil.kt +37 -0
  31. package/android/src/networking/com/swmansion/worklets/WorkletsProgressListener.kt +9 -0
  32. package/android/src/networking/com/swmansion/worklets/WorkletsProgressRequestBody.kt +98 -0
  33. package/android/src/networking/com/swmansion/worklets/WorkletsProgressResponseBody.kt +57 -0
  34. package/android/src/networking/com/swmansion/worklets/WorkletsProgressiveStringDecoder.kt +82 -0
  35. package/android/src/networking/com/swmansion/worklets/WorkletsRequestBodyUtil.kt +177 -0
  36. package/android/src/{experimentalBundling → no-networking}/com/swmansion/worklets/WorkletsModule.java +10 -15
  37. package/apple/worklets/apple/Networking/WorkletsNetworking.h +22 -0
  38. package/apple/worklets/apple/Networking/WorkletsNetworking.mm +706 -0
  39. package/apple/worklets/apple/WorkletsModule.mm +56 -17
  40. package/bundleMode/index.js +2 -6
  41. package/compatibility.json +4 -1
  42. package/lib/module/WorkletsModule/NativeWorklets.native.js +8 -2
  43. package/lib/module/WorkletsModule/NativeWorklets.native.js.map +1 -1
  44. package/lib/module/bundleMode/metroOverrides.native.js +115 -0
  45. package/lib/module/bundleMode/metroOverrides.native.js.map +1 -0
  46. package/lib/module/bundleMode/network.native.js +41 -0
  47. package/lib/module/bundleMode/network.native.js.map +1 -0
  48. package/lib/module/debug/jsVersion.js +1 -1
  49. package/lib/module/debug/jsVersion.js.map +1 -1
  50. package/lib/module/featureFlags/staticFlags.json +2 -0
  51. package/lib/module/featureFlags/types.js +3 -1
  52. package/lib/module/featureFlags/types.js.map +1 -1
  53. package/lib/module/index.js +4 -2
  54. package/lib/module/index.js.map +1 -1
  55. package/lib/module/initializers/initializers.native.js +24 -50
  56. package/lib/module/initializers/initializers.native.js.map +1 -1
  57. package/lib/module/initializers/workletRuntimeEntry.native.js +3 -3
  58. package/lib/module/initializers/workletRuntimeEntry.native.js.map +1 -1
  59. package/lib/module/memory/bundleUnpacker.native.js +2 -2
  60. package/lib/module/memory/bundleUnpacker.native.js.map +1 -1
  61. package/lib/module/memory/serializable.native.js +3 -3
  62. package/lib/module/memory/serializable.native.js.map +1 -1
  63. package/lib/module/memory/synchronizableUnpacker.native.js +3 -3
  64. package/lib/module/memory/synchronizableUnpacker.native.js.map +1 -1
  65. package/lib/module/platformChecker.js +2 -2
  66. package/lib/module/platformChecker.js.map +1 -1
  67. package/lib/module/runtimeKind.js +51 -0
  68. package/lib/module/runtimeKind.js.map +1 -1
  69. package/lib/module/runtimes.js +3 -0
  70. package/lib/module/runtimes.js.map +1 -1
  71. package/lib/module/runtimes.native.js +34 -3
  72. package/lib/module/runtimes.native.js.map +1 -1
  73. package/lib/module/threads.native.js +2 -2
  74. package/lib/module/threads.native.js.map +1 -1
  75. package/lib/typescript/WorkletsModule/NativeWorklets.native.d.ts.map +1 -1
  76. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +2 -1
  77. package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -1
  78. package/lib/typescript/bundleMode/metroOverrides.native.d.ts +28 -0
  79. package/lib/typescript/bundleMode/metroOverrides.native.d.ts.map +1 -0
  80. package/lib/typescript/bundleMode/network.native.d.ts +7 -0
  81. package/lib/typescript/bundleMode/network.native.d.ts.map +1 -0
  82. package/lib/typescript/debug/jsVersion.d.ts +1 -1
  83. package/lib/typescript/debug/jsVersion.d.ts.map +1 -1
  84. package/lib/typescript/featureFlags/types.d.ts +3 -1
  85. package/lib/typescript/featureFlags/types.d.ts.map +1 -1
  86. package/lib/typescript/index.d.ts +2 -2
  87. package/lib/typescript/index.d.ts.map +1 -1
  88. package/lib/typescript/initializers/initializers.native.d.ts +1 -0
  89. package/lib/typescript/initializers/initializers.native.d.ts.map +1 -1
  90. package/lib/typescript/initializers/workletRuntimeEntry.native.d.ts +1 -1
  91. package/lib/typescript/memory/bundleUnpacker.native.d.ts.map +1 -1
  92. package/lib/typescript/memory/synchronizableUnpacker.native.d.ts.map +1 -1
  93. package/lib/typescript/platformChecker.d.ts.map +1 -1
  94. package/lib/typescript/runtimeKind.d.ts +31 -0
  95. package/lib/typescript/runtimeKind.d.ts.map +1 -1
  96. package/lib/typescript/runtimes.d.ts +1 -0
  97. package/lib/typescript/runtimes.d.ts.map +1 -1
  98. package/lib/typescript/runtimes.native.d.ts +20 -2
  99. package/lib/typescript/runtimes.native.d.ts.map +1 -1
  100. package/lib/typescript/threads.native.d.ts +1 -1
  101. package/package.json +8 -6
  102. package/plugin/index.d.ts +109 -0
  103. package/plugin/index.js +59 -9
  104. package/scripts/worklets_utils.rb +21 -5
  105. package/src/WorkletsModule/NativeWorklets.native.ts +14 -4
  106. package/src/WorkletsModule/workletsModuleProxy.ts +6 -3
  107. package/src/bundleMode/metroOverrides.native.ts +151 -0
  108. package/src/bundleMode/network.native.ts +59 -0
  109. package/src/debug/jsVersion.ts +1 -1
  110. package/src/featureFlags/staticFlags.json +2 -0
  111. package/src/featureFlags/types.ts +3 -1
  112. package/src/index.ts +10 -1
  113. package/src/initializers/initializers.native.ts +29 -70
  114. package/src/initializers/workletRuntimeEntry.native.ts +3 -3
  115. package/src/memory/bundleUnpacker.native.ts +2 -4
  116. package/src/memory/serializable.native.ts +3 -3
  117. package/src/memory/synchronizableUnpacker.native.ts +6 -12
  118. package/src/platformChecker.ts +3 -2
  119. package/src/privateGlobals.d.ts +7 -2
  120. package/src/runtimeKind.ts +47 -0
  121. package/src/runtimes.native.ts +43 -2
  122. package/src/runtimes.ts +10 -0
  123. package/src/threads.native.ts +2 -2
@@ -1,12 +1,26 @@
1
1
  #include <worklets/NativeModules/JSIWorkletsModuleProxy.h>
2
+ #include <worklets/Tools/ScriptBuffer.h>
2
3
  #include <worklets/Tools/WorkletsJSIUtils.h>
3
4
  #include <worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h>
5
+ #include <worklets/WorkletRuntime/RuntimeBindings.h>
4
6
  #include <worklets/android/AnimationFrameCallback.h>
5
7
  #include <worklets/android/WorkletsModule.h>
6
8
 
9
+ #if defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
10
+ #include <folly/json/dynamic.h>
11
+ #include <jni.h>
12
+ #include <jsi/JSIDynamic.h>
13
+ #include <react/jni/JCallback.h>
14
+ #include <react/jni/ReadableNativeArray.h>
15
+ #include <react/jni/ReadableNativeMap.h>
16
+ #include <worklets/WorkletRuntime/WorkletRuntime.h>
17
+ #include <worklets/android/JWorkletRuntimeWrapper.h>
18
+ #endif // defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
19
+
7
20
  #include <memory>
8
21
  #include <string>
9
22
  #include <utility>
23
+ #include <vector>
10
24
 
11
25
  namespace worklets {
12
26
 
@@ -14,12 +28,13 @@ using namespace facebook;
14
28
  using namespace react;
15
29
 
16
30
  WorkletsModule::WorkletsModule(
17
- jni::alias_ref<jhybridobject> jThis,
31
+ jni::alias_ref<jhybridobject> jThis, // NOLINT //(performance-unnecessary-value-param)
18
32
  jsi::Runtime *rnRuntime,
19
- jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
33
+ jni::alias_ref<JavaMessageQueueThread::javaobject>
34
+ messageQueueThread, // NOLINT //(performance-unnecessary-value-param)
20
35
  const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
21
36
  const std::shared_ptr<UIScheduler> &uiScheduler,
22
- const std::shared_ptr<const JSBigStringBuffer> &script,
37
+ const std::shared_ptr<const ScriptBuffer> &script,
23
38
  const std::string &sourceURL)
24
39
  : javaPart_(jni::make_global(jThis)),
25
40
  rnRuntime_(rnRuntime),
@@ -29,7 +44,15 @@ WorkletsModule::WorkletsModule(
29
44
  jsCallInvoker,
30
45
  uiScheduler,
31
46
  getIsOnJSQueueThread(),
32
- RuntimeBindings{.requestAnimationFrame = getRequestAnimationFrame()},
47
+ std::make_shared<RuntimeBindings>(RuntimeBindings{
48
+ .requestAnimationFrame = getRequestAnimationFrame()
49
+ #if defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
50
+ ,
51
+ .abortRequest = getAbortRequest(),
52
+ .clearCookies = getClearCookies(),
53
+ .sendRequest = getSendRequest()
54
+ #endif // defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
55
+ }),
33
56
  script,
34
57
  sourceURL)) {
35
58
  auto jsiWorkletsModuleProxy = workletsModuleProxy_->createJSIWorkletsModuleProxy();
@@ -40,27 +63,26 @@ WorkletsModule::WorkletsModule(
40
63
  }
41
64
 
42
65
  jni::local_ref<WorkletsModule::jhybriddata> WorkletsModule::initHybrid(
43
- jni::alias_ref<jhybridobject> jThis,
66
+ jni::alias_ref<jhybridobject> jThis, // NOLINT //(performance-unnecessary-value-param)
44
67
  jlong jsContext,
45
- jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
68
+ jni::alias_ref<JavaMessageQueueThread::javaobject>
69
+ messageQueueThread, // NOLINT //(performance-unnecessary-value-param)
46
70
  jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
47
- jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler
48
- #ifdef WORKLETS_BUNDLE_MODE
49
- ,
50
- jni::alias_ref<facebook::react::BundleWrapper::javaobject> bundleWrapper,
51
- const std::string &sourceURL
52
- #endif // WORKLETS_BUNDLE_MODE
71
+ jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler,
72
+ jni::alias_ref<JScriptBufferWrapper::javaobject>
73
+ jScriptBufferWrapper // NOLINT //(performance-unnecessary-value-param)
53
74
  ) {
54
75
  auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
55
- auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
76
+ auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext); // NOLINT //(performance-no-int-to-ptr)
56
77
  auto uiScheduler = androidUIScheduler->cthis()->getUIScheduler();
57
78
 
58
- std::shared_ptr<const JSBigStringBuffer> script = nullptr;
59
- #ifdef WORKLETS_BUNDLE_MODE
60
- script = bundleWrapper->cthis()->getBundle();
61
- #else
62
- const auto sourceURL = std::string{};
63
- #endif // WORKLETS_BUNDLE_MODE
79
+ std::shared_ptr<const ScriptBuffer> script = nullptr;
80
+ std::string sourceURL;
81
+ #ifdef WORKLETS_BUNDLE_MODE_ENABLED
82
+ auto cxxWrapper = jScriptBufferWrapper->cthis();
83
+ script = cxxWrapper->getScript();
84
+ sourceURL = cxxWrapper->getSourceUrl();
85
+ #endif // WORKLETS_BUNDLE_MODE_ENABLED
64
86
 
65
87
  return makeCxxInstance(jThis, rnRuntime, messageQueueThread, jsCallInvoker, uiScheduler, script, sourceURL);
66
88
  }
@@ -73,6 +95,80 @@ RuntimeBindings::RequestAnimationFrame WorkletsModule::getRequestAnimationFrame(
73
95
  };
74
96
  }
75
97
 
98
+ #if defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
99
+ RuntimeBindings::AbortRequest WorkletsModule::getAbortRequest() {
100
+ return [javaPart = javaPart_](jsi::Runtime &rt, double requestId) -> void {
101
+ static const auto jAbortRequest = javaPart->getClass()->getMethod<void(int, double)>("abortRequest");
102
+ auto workletRuntime = WorkletRuntime::getWeakRuntimeFromJSIRuntime(rt).lock();
103
+ jAbortRequest(javaPart.get(), static_cast<int>(workletRuntime->getRuntimeId()), requestId);
104
+ };
105
+ }
106
+
107
+ RuntimeBindings::ClearCookies WorkletsModule::getClearCookies() {
108
+ return [javaPart = javaPart_](jsi::Runtime &rt, jsi::Function &&responseSender) {
109
+ static const auto jClearCookies = javaPart->getClass()->getMethod<void(JCallback::javaobject)>("clearCookies");
110
+ auto jsiFunction = std::make_shared<jsi::Function>(std::move(responseSender));
111
+ auto workletRuntime = WorkletRuntime::getWeakRuntimeFromJSIRuntime(rt);
112
+ auto callback = [jsiFunction, workletRuntime](folly::dynamic args) {
113
+ if (auto runtime = workletRuntime.lock()) {
114
+ runtime->schedule([jsiFunction, args = std::move(args)](jsi::Runtime &rt) {
115
+ std::vector<jsi::Value> jsArgs;
116
+ for (auto &arg : args) {
117
+ jsArgs.push_back(jsi::valueFromDynamic(rt, arg));
118
+ }
119
+ const jsi::Value *rawData = jsArgs.data();
120
+ size_t size = jsArgs.size();
121
+ jsiFunction->call(rt, rawData, size);
122
+ });
123
+ }
124
+ };
125
+ jClearCookies(javaPart.get(), JCxxCallbackImpl::newObjectCxxArgs(std::move(callback)).get());
126
+ };
127
+ }
128
+
129
+ RuntimeBindings::SendRequest WorkletsModule::getSendRequest() {
130
+ return [javaPart = javaPart_](
131
+ jsi::Runtime &rt,
132
+ jsi::String &method,
133
+ jsi::String &url,
134
+ double requestId,
135
+ jsi::Array &headers,
136
+ jsi::Object &data,
137
+ jsi::String &responseType,
138
+ bool incrementalUpdates,
139
+ double timeout,
140
+ bool withCredentials) {
141
+ static const auto jSendRequest = javaPart->getClass()
142
+ ->getMethod<void(
143
+ JWorkletRuntimeWrapper::javaobject,
144
+ std::string /* method */,
145
+ std::string /* url */,
146
+ double /* requestId */,
147
+ ReadableNativeArray::javaobject /* headers */,
148
+ ReadableNativeMap::javaobject /* data */,
149
+ std::string /* responseType */,
150
+ bool /* incrementalUpdates */,
151
+ double /* timeout */,
152
+ bool /* withCredentials */
153
+ )>("sendRequest");
154
+ auto workletRuntime = WorkletRuntime::getWeakRuntimeFromJSIRuntime(rt).lock();
155
+
156
+ jSendRequest(
157
+ javaPart.get(),
158
+ JWorkletRuntimeWrapper::makeJWorkletRuntimeWrapper(workletRuntime).get(),
159
+ method.utf8(rt),
160
+ url.utf8(rt),
161
+ requestId,
162
+ ReadableNativeArray::newObjectCxxArgs(jsi::dynamicFromValue(rt, jsi::Value(std::move(headers)))).get(),
163
+ ReadableNativeMap::newObjectCxxArgs(jsi::dynamicFromValue(rt, jsi::Value(std::move(data)))).get(),
164
+ responseType.utf8(rt),
165
+ incrementalUpdates,
166
+ timeout,
167
+ withCredentials);
168
+ };
169
+ }
170
+ #endif // defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
171
+
76
172
  std::function<bool()> WorkletsModule::getIsOnJSQueueThread() {
77
173
  return [javaPart = javaPart_]() -> bool {
78
174
  return javaPart->getClass()->getMethod<jboolean()>("isOnJSQueueThread").operator()(javaPart);
@@ -4,14 +4,12 @@
4
4
  #include <fbjni/fbjni.h>
5
5
  #include <jsi/jsi.h>
6
6
  #include <react/jni/JMessageQueueThread.h>
7
- #include <worklets/Tools/Defs.h>
8
- #ifdef WORKLETS_BUNDLE_MODE
9
- #include <react/fabric/BundleWrapper.h>
10
- #endif // WORKLETS_BUNDLE_MODE
11
-
12
7
  #include <worklets/NativeModules/WorkletsModuleProxy.h>
8
+ #include <worklets/Tools/Defs.h>
9
+ #include <worklets/Tools/ScriptBuffer.h>
13
10
  #include <worklets/WorkletRuntime/RuntimeBindings.h>
14
11
  #include <worklets/android/AndroidUIScheduler.h>
12
+ #include <worklets/android/JScriptBufferWrapper.h>
15
13
 
16
14
  #include <memory>
17
15
  #include <string>
@@ -30,13 +28,8 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
30
28
  jlong jsContext,
31
29
  jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
32
30
  jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
33
- jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler
34
- #ifdef WORKLETS_BUNDLE_MODE
35
- ,
36
- jni::alias_ref<facebook::react::BundleWrapper::javaobject> bundleWrapper,
37
- const std::string &sourceURL
38
- #endif // WORKLETS_BUNDLE_MODE
39
- );
31
+ jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler,
32
+ jni::alias_ref<JScriptBufferWrapper::javaobject> jScriptBufferWrapper);
40
33
 
41
34
  static void registerNatives();
42
35
 
@@ -51,7 +44,7 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
51
44
  jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
52
45
  const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
53
46
  const std::shared_ptr<UIScheduler> &uiScheduler,
54
- const std::shared_ptr<const JSBigStringBuffer> &bundle,
47
+ const std::shared_ptr<const ScriptBuffer> &script,
55
48
  const std::string &sourceURL);
56
49
 
57
50
  void invalidateCpp();
@@ -62,6 +55,11 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
62
55
  }
63
56
 
64
57
  RuntimeBindings::RequestAnimationFrame getRequestAnimationFrame();
58
+ #if defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
59
+ RuntimeBindings::AbortRequest getAbortRequest();
60
+ RuntimeBindings::ClearCookies getClearCookies();
61
+ RuntimeBindings::SendRequest getSendRequest();
62
+ #endif // defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
65
63
 
66
64
  std::function<bool()> getIsOnJSQueueThread();
67
65
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  #include <worklets/android/AndroidUIScheduler.h>
4
4
  #include <worklets/android/AnimationFrameCallback.h>
5
+ #include <worklets/android/JScriptBufferWrapper.h>
6
+ #include <worklets/android/JWorkletRuntimeWrapper.h>
5
7
  #include <worklets/android/WorkletsModule.h>
6
8
 
7
9
  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
@@ -9,5 +11,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
9
11
  worklets::WorkletsModule::registerNatives();
10
12
  worklets::AndroidUIScheduler::registerNatives();
11
13
  worklets::AnimationFrameCallback::registerNatives();
14
+ worklets::JScriptBufferWrapper::registerNatives();
15
+ #if defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
16
+ worklets::JWorkletRuntimeWrapper::registerNatives();
17
+ #endif // defined(WORKLETS_BUNDLE_MODE_ENABLED) && defined(WORKLETS_FETCH_PREVIEW_ENABLED)
12
18
  });
13
19
  }
@@ -0,0 +1,88 @@
1
+ package com.swmansion.worklets;
2
+
3
+ import android.annotation.SuppressLint;
4
+ import android.content.res.AssetManager;
5
+ import android.os.Build;
6
+ import com.facebook.jni.HybridData;
7
+ import com.facebook.proguard.annotations.DoNotStrip;
8
+ import com.facebook.proguard.annotations.DoNotStripAny;
9
+ import java.io.IOException;
10
+ import java.io.InputStream;
11
+ import java.net.HttpURLConnection;
12
+ import java.net.URL;
13
+ import java.nio.charset.StandardCharsets;
14
+
15
+ /** A wrapper around a JavaScript bundle that is backed by a native C++ object. */
16
+ @SuppressWarnings("JavaJniMissingFunction")
17
+ @SuppressLint("MissingNativeLoadLibrary")
18
+ @DoNotStripAny
19
+ public class ScriptBufferWrapper {
20
+ public ScriptBufferWrapper(String uri, AssetManager assetManager) {
21
+ String filePrefix = "file://";
22
+ String assetsPrefix = "assets://";
23
+
24
+ if (uri.startsWith(filePrefix)) {
25
+ String fileName = uri.substring(filePrefix.length());
26
+ mHybridData = initHybridFromFile(fileName);
27
+ } else if (uri.startsWith(assetsPrefix)) {
28
+ String assetURL = uri.substring(assetsPrefix.length());
29
+ mHybridData = initHybridFromAssets(assetManager, assetURL);
30
+ } else {
31
+ String scriptContent;
32
+ try {
33
+ scriptContent = downloadScript(uri);
34
+ } catch (IOException e) {
35
+ throw new RuntimeException(e);
36
+ }
37
+ mHybridData = initHybridFromString(scriptContent, uri);
38
+ }
39
+ }
40
+
41
+ private static String downloadScript(String url) throws IOException {
42
+ var scriptUrl = new URL(url);
43
+ HttpURLConnection connection = (HttpURLConnection) scriptUrl.openConnection();
44
+ try {
45
+ byte[] content;
46
+
47
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
48
+ content = connection.getInputStream().readAllBytes();
49
+ } else {
50
+ content = readBytes(connection.getInputStream());
51
+ }
52
+
53
+ return new String(content, StandardCharsets.UTF_8);
54
+ } finally {
55
+ if (connection != null) {
56
+ connection.disconnect();
57
+ }
58
+ }
59
+ }
60
+
61
+ /** Reads all bytes from an InputStream into a byte array for SDKs below 33. */
62
+ private static byte[] readBytes(InputStream inputStream) throws IOException {
63
+ final int BUFFER_SIZE = 4096;
64
+ try {
65
+ java.io.ByteArrayOutputStream byteBuffer = new java.io.ByteArrayOutputStream();
66
+ byte[] buffer = new byte[BUFFER_SIZE];
67
+ int len;
68
+ while ((len = inputStream.read(buffer)) != -1) {
69
+ byteBuffer.write(buffer, 0, len);
70
+ }
71
+ return byteBuffer.toByteArray();
72
+ } finally {
73
+ if (inputStream != null) {
74
+ inputStream.close();
75
+ }
76
+ }
77
+ }
78
+
79
+ private native HybridData initHybridFromAssets(AssetManager assetManager, String assetURL);
80
+
81
+ private native HybridData initHybridFromFile(String fileName);
82
+
83
+ private native HybridData initHybridFromString(String script, String url);
84
+
85
+ @DoNotStrip
86
+ @SuppressWarnings({"unused", "FieldCanBeLocal"})
87
+ private final HybridData mHybridData;
88
+ }
@@ -0,0 +1,23 @@
1
+ package com.swmansion.worklets
2
+
3
+ import com.facebook.jni.HybridData
4
+ import com.facebook.jni.annotations.DoNotStrip
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.WritableNativeArray
7
+
8
+ @Suppress("KotlinJniMissingFunction")
9
+ class WorkletRuntimeWrapper @DoNotStrip private constructor(
10
+ @field:DoNotStrip private val mHybridData: HybridData
11
+ ) {
12
+ fun emitDeviceEvent(eventName: String, params: Any?) {
13
+ cxxEmitDeviceEvent(Arguments.fromJavaArgs(arrayOf(eventName, params)));
14
+ }
15
+
16
+ fun getRuntimeId(): Int {
17
+ return cxxGetRuntimeId();
18
+ }
19
+
20
+ private external fun cxxEmitDeviceEvent(args: WritableNativeArray);
21
+
22
+ private external fun cxxGetRuntimeId(): Int;
23
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Based on HeaderUtil.kt from React Native
3
+ */
4
+
5
+ package com.swmansion.worklets
6
+
7
+ /**
8
+ * The class purpose is to weaken too strict OkHttp restriction on http headers. See:
9
+ * https://github.com/square/okhttp/issues/2016 Auth headers might have an Authentication
10
+ * information. It is better to get 401 from the server in this case, rather than non descriptive
11
+ * error as 401 could be handled to invalidate the wrong token in the client code.
12
+ */
13
+ internal class WorkletsHeaderUtil {
14
+ companion object {
15
+ @JvmStatic
16
+ fun stripHeaderName(name: String): String {
17
+ val builder = StringBuilder(name.length)
18
+ var modified = false
19
+ for (i in 0 until name.length) {
20
+ val c = name[i]
21
+ if (c > '\u0020' && c < '\u007f') {
22
+ builder.append(c)
23
+ } else {
24
+ modified = true
25
+ }
26
+ }
27
+ return if (modified) builder.toString() else name
28
+ }
29
+ }
30
+ }
@@ -3,9 +3,12 @@ package com.swmansion.worklets;
3
3
  import androidx.annotation.OptIn;
4
4
  import com.facebook.jni.HybridData;
5
5
  import com.facebook.proguard.annotations.DoNotStrip;
6
+ import com.facebook.react.bridge.Callback;
6
7
  import com.facebook.react.bridge.LifecycleEventListener;
7
8
  import com.facebook.react.bridge.ReactApplicationContext;
8
9
  import com.facebook.react.bridge.ReactMethod;
10
+ import com.facebook.react.bridge.ReadableNativeArray;
11
+ import com.facebook.react.bridge.ReadableNativeMap;
9
12
  import com.facebook.react.bridge.queue.MessageQueueThread;
10
13
  import com.facebook.react.common.annotations.FrameworkAPI;
11
14
  import com.facebook.react.module.annotations.ReactModule;
@@ -35,6 +38,7 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
35
38
  private final WorkletsMessageQueueThread mMessageQueueThread = new WorkletsMessageQueueThread();
36
39
  private final AndroidUIScheduler mAndroidUIScheduler;
37
40
  private final AnimationFrameQueue mAnimationFrameQueue;
41
+ private final WorkletsNetworking mWorkletsNetworking;
38
42
  private boolean mSlowAnimationsEnabled;
39
43
 
40
44
  /**
@@ -48,7 +52,8 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
48
52
  long jsContext,
49
53
  MessageQueueThread messageQueueThread,
50
54
  CallInvokerHolderImpl jsCallInvokerHolder,
51
- AndroidUIScheduler androidUIScheduler);
55
+ AndroidUIScheduler androidUIScheduler,
56
+ ScriptBufferWrapper scriptBufferWrapper);
52
57
 
53
58
  public WorkletsModule(ReactApplicationContext reactContext) {
54
59
  super(reactContext);
@@ -57,6 +62,7 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
57
62
 
58
63
  mAndroidUIScheduler = new AndroidUIScheduler(reactContext);
59
64
  mAnimationFrameQueue = new AnimationFrameQueue(reactContext);
65
+ mWorkletsNetworking = new WorkletsNetworking();
60
66
  }
61
67
 
62
68
  @OptIn(markerClass = FrameworkAPI.class)
@@ -69,11 +75,55 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
69
75
  var jsContext = Objects.requireNonNull(context.getJavaScriptContextHolder()).get();
70
76
  var jsCallInvokerHolder = JSCallInvokerResolver.getJSCallInvokerHolder(context);
71
77
 
78
+ var sourceURL = context.getSourceURL();
79
+
80
+ ScriptBufferWrapper scriptBufferWrapper = null;
81
+ if (BuildConfig.BUNDLE_MODE_ENABLED) {
82
+ scriptBufferWrapper = new ScriptBufferWrapper(sourceURL, context.getAssets());
83
+ }
84
+
72
85
  mHybridData =
73
- initHybrid(jsContext, mMessageQueueThread, jsCallInvokerHolder, mAndroidUIScheduler);
86
+ initHybrid(
87
+ jsContext,
88
+ mMessageQueueThread,
89
+ jsCallInvokerHolder,
90
+ mAndroidUIScheduler,
91
+ scriptBufferWrapper);
74
92
  return true;
75
93
  }
76
94
 
95
+ public void abortRequest(int runtimeId, double requestIdAsDouble) {
96
+ mWorkletsNetworking.jsiAbortRequest(runtimeId, requestIdAsDouble);
97
+ }
98
+
99
+ public void clearCookies(Callback callback) {
100
+ mWorkletsNetworking.jsiClearCookies(callback);
101
+ }
102
+
103
+ public void sendRequest(
104
+ WorkletRuntimeWrapper runtimeWrapper,
105
+ String method,
106
+ String url,
107
+ double requestIdAsDouble,
108
+ ReadableNativeArray headers,
109
+ ReadableNativeMap data,
110
+ String responseType,
111
+ boolean useIncrementalUpdates,
112
+ double timeoutAsDouble,
113
+ boolean withCredentials) {
114
+ mWorkletsNetworking.jsiSendRequest(
115
+ runtimeWrapper,
116
+ method,
117
+ url,
118
+ requestIdAsDouble,
119
+ headers,
120
+ data,
121
+ responseType,
122
+ useIncrementalUpdates,
123
+ timeoutAsDouble,
124
+ withCredentials);
125
+ }
126
+
77
127
  public void requestAnimationFrame(AnimationFrameCallback animationFrameCallback) {
78
128
  mAnimationFrameQueue.requestAnimationFrame(animationFrameCallback);
79
129
  }