Skip to content

Commit adbbd15

Browse files
authored
feat(Worklets): always compile bundle mode symbols (#9064)
## Summary This PR is a step that makes experimental Bundle Mode less experimental. Having the use of Bundle Mode gated behind #ifdef macros is burdensome for prebuild environments or large scale apps. This PR makes it so the native side receives the information whether to use the Bundle Mode from JavaScript, instead from static feature flags. All Bundle Mode symbols are available without re-compilation, resulting in much faster toggling of the feature. The source of truth for whether the Bundle Mode is enabled is the `babel.config.js` - passing `bundleMode: true` in the config enables the bundle mode. ## Test plan Compiled and ran the example app both with and without the Bundle Mode.
1 parent b788488 commit adbbd15

36 files changed

Lines changed: 300 additions & 265 deletions

apps/fabric-example/ios/Podfile.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/macos-example/macos/Podfile.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/tvos-example/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/react-native-worklets/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <worklets/Tools/Defs.h>
1313
#include <worklets/Tools/FeatureFlags.h>
1414
#include <worklets/Tools/JSLogger.h>
15+
#include <worklets/WorkletRuntime/BundleModeConfig.h>
1516
#include <worklets/WorkletRuntime/UIRuntimeDecorator.h>
1617

1718
#include <memory>
@@ -87,22 +88,20 @@ inline jsi::Value createWorkletRuntime(
8788
return jsi::Object::createFromHostObject(originRuntime, workletRuntime);
8889
}
8990

90-
#ifdef WORKLETS_BUNDLE_MODE_ENABLED
9191
inline jsi::Value propagateModuleUpdate(
9292
const std::shared_ptr<RuntimeManager> &runtimeManager,
9393
const std::string &code,
9494
const std::string &sourceUrl) {
9595
const auto runtimes = runtimeManager->getAllRuntimes();
9696

97-
for (auto runtime : runtimes) {
97+
for (const auto &runtime : runtimes) {
9898
runtime->runSync([code, sourceUrl](jsi::Runtime &rt) -> void {
9999
const auto buffer = std::make_shared<jsi::StringBuffer>(code);
100100
rt.evaluateJavaScript(buffer, sourceUrl);
101101
});
102102
}
103103
return jsi::Value::undefined();
104104
}
105-
#endif // WORKLETS_BUNDLE_MODE_ENABLED
106105

107106
inline jsi::Value reportFatalErrorOnJS(
108107
const std::shared_ptr<JSScheduler> &jsScheduler,
@@ -152,19 +151,17 @@ inline void registerCustomSerializable(
152151

153152
JSIWorkletsModuleProxy::JSIWorkletsModuleProxy(
154153
const bool isDevBundle,
155-
const std::shared_ptr<const ScriptBuffer> &script,
156-
const std::string &sourceUrl,
157154
const std::shared_ptr<MessageQueueThread> &jsQueue,
158155
const std::shared_ptr<JSScheduler> &jsScheduler,
159156
const std::shared_ptr<UIScheduler> &uiScheduler,
160157
const std::shared_ptr<MemoryManager> &memoryManager,
161158
const std::shared_ptr<RuntimeManager> &runtimeManager,
162159
const std::weak_ptr<WorkletRuntime> &uiWorkletRuntime,
163-
const std::shared_ptr<RuntimeBindings> &runtimeBindings)
160+
const std::shared_ptr<RuntimeBindings> &runtimeBindings,
161+
const BundleModeConfig &bundleModeConfig)
164162
: jsi::HostObject(),
165163
isDevBundle_(isDevBundle),
166-
script_(script),
167-
sourceUrl_(sourceUrl),
164+
bundleModeConfig_(bundleModeConfig),
168165
jsQueue_(jsQueue),
169166
jsScheduler_(jsScheduler),
170167
uiScheduler_(uiScheduler),
@@ -219,9 +216,7 @@ std::vector<jsi::PropNameID> JSIWorkletsModuleProxy::getPropertyNames(jsi::Runti
219216

220217
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createShareable"));
221218

222-
#ifdef WORKLETS_BUNDLE_MODE_ENABLED
223219
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "propagateModuleUpdate"));
224-
#endif // WORKLETS_BUNDLE_MODE_ENABLED
225220

226221
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "getUIRuntimeHolder"));
227222
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "getUISchedulerHolder"));
@@ -579,7 +574,6 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
579574
});
580575
}
581576

582-
#ifdef WORKLETS_BUNDLE_MODE_ENABLED
583577
if (name == "propagateModuleUpdate") {
584578
return jsi::Function::createFromHostFunction(
585579
rt,
@@ -593,7 +587,6 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
593587
/* sourceURL */ args[1].asString(rt).utf8(rt));
594588
});
595589
}
596-
#endif // WORKLETS_BUNDLE_MODE_ENABLED
597590

598591
if (name == "getStaticFeatureFlag") {
599592
return jsi::Function::createFromHostFunction(

packages/react-native-worklets/Common/cpp/worklets/NativeModules/JSIWorkletsModuleProxy.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <worklets/SharedItems/Serializable.h>
99
#include <worklets/Tools/Defs.h>
1010
#include <worklets/Tools/ScriptBuffer.h>
11+
#include <worklets/WorkletRuntime/BundleModeConfig.h>
1112
#include <worklets/WorkletRuntime/RuntimeBindings.h>
1213
#include <worklets/WorkletRuntime/RuntimeManager.h>
1314
#include <worklets/WorkletRuntime/UIRuntimeDecorator.h>
@@ -26,15 +27,14 @@ class JSIWorkletsModuleProxy : public jsi::HostObject {
2627
public:
2728
explicit JSIWorkletsModuleProxy(
2829
const bool isDevBundle,
29-
const std::shared_ptr<const ScriptBuffer> &script,
30-
const std::string &sourceUrl,
3130
const std::shared_ptr<MessageQueueThread> &jsQueue,
3231
const std::shared_ptr<JSScheduler> &jsScheduler,
3332
const std::shared_ptr<UIScheduler> &uiScheduler,
3433
const std::shared_ptr<MemoryManager> &memoryManager,
3534
const std::shared_ptr<RuntimeManager> &runtimeManager,
3635
const std::weak_ptr<WorkletRuntime> &uiWorkletRuntime,
37-
const std::shared_ptr<RuntimeBindings> &runtimeBindings);
36+
const std::shared_ptr<RuntimeBindings> &runtimeBindings,
37+
const BundleModeConfig &bundleModeConfig);
3838

3939
JSIWorkletsModuleProxy(const JSIWorkletsModuleProxy &other) = default;
4040

@@ -56,16 +56,20 @@ class JSIWorkletsModuleProxy : public jsi::HostObject {
5656
return uiScheduler_;
5757
}
5858

59+
[[nodiscard]] bool isBundleModeEnabled() const {
60+
return bundleModeConfig_.enabled;
61+
}
62+
5963
[[nodiscard]] bool isDevBundle() const {
6064
return isDevBundle_;
6165
}
6266

6367
[[nodiscard]] std::shared_ptr<const ScriptBuffer> getScript() const {
64-
return script_;
68+
return bundleModeConfig_.script;
6569
}
6670

6771
[[nodiscard]] std::string getSourceUrl() const {
68-
return sourceUrl_;
72+
return bundleModeConfig_.sourceURL;
6973
}
7074

7175
[[nodiscard]] std::shared_ptr<MemoryManager> getMemoryManager() const {
@@ -82,8 +86,7 @@ class JSIWorkletsModuleProxy : public jsi::HostObject {
8286

8387
private:
8488
const bool isDevBundle_;
85-
const std::shared_ptr<const ScriptBuffer> script_;
86-
const std::string sourceUrl_;
89+
const BundleModeConfig bundleModeConfig_;
8790
const std::shared_ptr<MessageQueueThread> jsQueue_;
8891
const std::shared_ptr<JSScheduler> jsScheduler_;
8992
const std::shared_ptr<UIScheduler> uiScheduler_;

packages/react-native-worklets/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <react/renderer/uimanager/UIManagerBinding.h>
22
#include <react/renderer/uimanager/primitives.h>
3-
43
#include <worklets/NativeModules/WorkletsModuleProxy.h>
54
#include <worklets/RunLoop/AsyncQueueImpl.h>
65
#include <worklets/SharedItems/Serializable.h>
@@ -9,19 +8,14 @@
98
#include <worklets/WorkletRuntime/RuntimeBindings.h>
109
#include <worklets/WorkletRuntime/UIRuntimeDecorator.h>
1110

12-
#ifdef __ANDROID__
13-
#include <fbjni/fbjni.h>
14-
#endif // __ANDROID__
15-
1611
#include <memory>
17-
#include <string>
1812
#include <utility>
1913

2014
using namespace facebook;
2115

2216
namespace worklets {
2317

24-
auto isDevBundleFromRNRuntime(jsi::Runtime &rnRuntime) -> bool;
18+
bool isDevBundleFromRNRuntime(jsi::Runtime &rnRuntime);
2519

2620
WorkletsModuleProxy::WorkletsModuleProxy(
2721
jsi::Runtime &rnRuntime,
@@ -30,16 +24,14 @@ WorkletsModuleProxy::WorkletsModuleProxy(
3024
const std::shared_ptr<UIScheduler> &uiScheduler,
3125
std::function<bool()> &&isJavaScriptThread,
3226
const std::shared_ptr<RuntimeBindings> &runtimeBindings,
33-
const std::shared_ptr<const ScriptBuffer> &script,
34-
const std::string &sourceUrl)
27+
const BundleModeConfig &bundleModeConfig)
3528
: isDevBundle_(isDevBundleFromRNRuntime(rnRuntime)),
3629
jsQueue_(jsQueue),
3730
jsScheduler_(std::make_shared<JSScheduler>(rnRuntime, jsCallInvoker, std::move(isJavaScriptThread))),
3831
uiScheduler_(uiScheduler),
3932
jsLogger_(std::make_shared<JSLogger>(jsScheduler_)),
4033
runtimeBindings_(runtimeBindings),
41-
script_(script),
42-
sourceUrl_(sourceUrl),
34+
bundleModeConfig_(bundleModeConfig),
4335
memoryManager_(std::make_shared<MemoryManager>()),
4436
runtimeManager_(std::make_shared<RuntimeManager>()),
4537
uiWorkletRuntime_(
@@ -61,15 +53,14 @@ std::shared_ptr<JSIWorkletsModuleProxy> WorkletsModuleProxy::createJSIWorkletsMo
6153
assert(uiWorkletRuntime_ && "UI Worklet Runtime must be initialized before creating JSI proxy.");
6254
return std::make_shared<JSIWorkletsModuleProxy>(
6355
isDevBundle_,
64-
script_,
65-
sourceUrl_,
6656
jsQueue_,
6757
jsScheduler_,
6858
uiScheduler_,
6959
memoryManager_,
7060
runtimeManager_,
7161
uiWorkletRuntime_,
72-
runtimeBindings_);
62+
runtimeBindings_,
63+
bundleModeConfig_);
7364
}
7465

7566
WorkletsModuleProxy::~WorkletsModuleProxy() {

packages/react-native-worklets/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
#include <worklets/Tools/ScriptBuffer.h>
1313
#include <worklets/Tools/SingleInstanceChecker.h>
1414
#include <worklets/Tools/UIScheduler.h>
15+
#include <worklets/WorkletRuntime/BundleModeConfig.h>
1516
#include <worklets/WorkletRuntime/RuntimeManager.h>
1617
#include <worklets/WorkletRuntime/WorkletRuntime.h>
1718

1819
#include <memory>
19-
#include <string>
2020

2121
namespace worklets {
2222

@@ -29,8 +29,7 @@ class WorkletsModuleProxy : public std::enable_shared_from_this<WorkletsModulePr
2929
const std::shared_ptr<UIScheduler> &uiScheduler,
3030
std::function<bool()> &&isJavaScriptQueue,
3131
const std::shared_ptr<RuntimeBindings> &runtimeBindings,
32-
const std::shared_ptr<const ScriptBuffer> &script,
33-
const std::string &sourceUrl);
32+
const BundleModeConfig &bundleModeConfig);
3433

3534
~WorkletsModuleProxy();
3635

@@ -67,8 +66,7 @@ class WorkletsModuleProxy : public std::enable_shared_from_this<WorkletsModulePr
6766
const std::shared_ptr<UIScheduler> uiScheduler_;
6867
const std::shared_ptr<JSLogger> jsLogger_;
6968
const std::shared_ptr<RuntimeBindings> runtimeBindings_;
70-
const std::shared_ptr<const ScriptBuffer> script_;
71-
const std::string sourceUrl_;
69+
const BundleModeConfig bundleModeConfig_;
7270
const std::shared_ptr<MemoryManager> memoryManager_;
7371
const std::shared_ptr<RuntimeManager> runtimeManager_;
7472
std::shared_ptr<WorkletRuntime> uiWorkletRuntime_;
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
#pragma once
22

3-
/*
4-
On Android JS_RUNTIME_HERMES is set in CMakeList.txt,
5-
but on iOS there is no simple way to defect if Hermes exists
6-
so we have to check if headers are available.
7-
*/
83
#if __APPLE__ && __has_include(<hermes/hermes.h>)
94
#define JS_RUNTIME_HERMES 1
105
#endif
116

12-
#if REACT_NATIVE_MINOR_VERSION >= 84 || defined(WORKLETS_BUNDLE_MODE_ENABLED)
7+
#if REACT_NATIVE_MINOR_VERSION >= 84
138
#include <cxxreact/JSBigString.h>
149
namespace worklets {
1510
using JSBigStringBuffer = facebook::react::JSBigString;
@@ -19,4 +14,4 @@ using JSBigStringBuffer = facebook::react::JSBigString;
1914
namespace worklets {
2015
using JSBigStringBuffer = facebook::react::BigStringBuffer;
2116
}
22-
#endif // REACT_NATIVE_MINOR_VERSION >= 84 || defined(WORKLETS_BUNDLE_MODE_ENABLED)
17+
#endif // REACT_NATIVE_MINOR_VERSION >= 84

packages/react-native-worklets/Common/cpp/worklets/Tools/ScriptBuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

3-
#include <cxxreact/JSBigString.h>
43
#include <jsi/jsi.h>
4+
#include <worklets/Tools/Defs.h>
55

66
#include <memory>
77
#include <utility>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include <jsi/jsi.h>
4+
#include <worklets/Tools/ScriptBuffer.h>
5+
6+
#include <memory>
7+
#include <string>
8+
9+
namespace worklets {
10+
11+
struct BundleModeConfig {
12+
bool enabled;
13+
std::shared_ptr<const ScriptBuffer> script;
14+
std::string sourceURL;
15+
};
16+
17+
} // namespace worklets

0 commit comments

Comments
 (0)