react-native-unistyles 3.1.0 → 3.2.0

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 (57) hide show
  1. package/README.md +180 -0
  2. package/android/src/main/cxx/NativeUnistylesModule.cpp +2 -5
  3. package/android/src/main/cxx/NativeUnistylesModule.h +1 -7
  4. package/android/src/main/java/com/unistyles/Equatable.kt +5 -1
  5. package/android/src/main/java/com/unistyles/NativePlatform+android.kt +6 -1
  6. package/android/src/main/java/com/unistyles/NativePlatform+listener.kt +21 -3
  7. package/cxx/core/UnistyleWrapper.h +2 -2
  8. package/cxx/core/UnistylesRegistry.cpp +57 -48
  9. package/cxx/core/UnistylesRegistry.h +16 -14
  10. package/cxx/core/UnistylesState.cpp +22 -20
  11. package/cxx/core/UnistylesState.h +5 -6
  12. package/cxx/hybridObjects/HybridShadowRegistry.cpp +14 -3
  13. package/cxx/hybridObjects/HybridShadowRegistry.h +5 -0
  14. package/cxx/hybridObjects/HybridStyleSheet.cpp +71 -45
  15. package/cxx/hybridObjects/HybridUnistylesRuntime.cpp +22 -32
  16. package/cxx/hybridObjects/HybridUnistylesRuntime.h +3 -4
  17. package/cxx/parser/Parser.cpp +14 -14
  18. package/ios/UnistylesModuleOnLoad.mm +3 -10
  19. package/lib/commonjs/core/useProxifiedUnistyles/useProxifiedUnistyles.js +4 -1
  20. package/lib/commonjs/core/useProxifiedUnistyles/useProxifiedUnistyles.js.map +1 -1
  21. package/lib/commonjs/specs/ShadowRegistry/index.js +20 -1
  22. package/lib/commonjs/specs/ShadowRegistry/index.js.map +1 -1
  23. package/lib/commonjs/web/convert/style.js +6 -6
  24. package/lib/commonjs/web/convert/style.js.map +1 -1
  25. package/lib/commonjs/web/listener.js +6 -0
  26. package/lib/commonjs/web/listener.js.map +1 -1
  27. package/lib/commonjs/web/utils/createUnistylesRef.js +1 -1
  28. package/lib/commonjs/web/utils/createUnistylesRef.js.map +1 -1
  29. package/lib/module/core/useProxifiedUnistyles/useProxifiedUnistyles.js +4 -1
  30. package/lib/module/core/useProxifiedUnistyles/useProxifiedUnistyles.js.map +1 -1
  31. package/lib/module/specs/ShadowRegistry/index.js +20 -1
  32. package/lib/module/specs/ShadowRegistry/index.js.map +1 -1
  33. package/lib/module/web/convert/style.js +6 -6
  34. package/lib/module/web/convert/style.js.map +1 -1
  35. package/lib/module/web/listener.js +6 -0
  36. package/lib/module/web/listener.js.map +1 -1
  37. package/lib/module/web/utils/createUnistylesRef.js +1 -1
  38. package/lib/module/web/utils/createUnistylesRef.js.map +1 -1
  39. package/lib/typescript/src/core/useProxifiedUnistyles/useProxifiedUnistyles.d.ts.map +1 -1
  40. package/lib/typescript/src/specs/ShadowRegistry/index.d.ts +2 -1
  41. package/lib/typescript/src/specs/ShadowRegistry/index.d.ts.map +1 -1
  42. package/lib/typescript/src/web/listener.d.ts.map +1 -1
  43. package/nitrogen/generated/android/c++/JColorScheme.hpp +1 -1
  44. package/nitrogen/generated/android/c++/JDimensions.hpp +1 -1
  45. package/nitrogen/generated/android/c++/JFunc_void_UnistylesNativeMiniRuntime.hpp +2 -2
  46. package/nitrogen/generated/android/c++/JFunc_void_std__vector_UnistyleDependency__UnistylesNativeMiniRuntime.hpp +2 -2
  47. package/nitrogen/generated/android/c++/JHybridNativePlatformSpec.hpp +2 -2
  48. package/nitrogen/generated/android/c++/JInsets.hpp +1 -1
  49. package/nitrogen/generated/android/c++/JOrientation.hpp +1 -1
  50. package/nitrogen/generated/android/c++/JUnistyleDependency.hpp +1 -1
  51. package/nitrogen/generated/android/c++/JUnistylesNativeMiniRuntime.hpp +1 -1
  52. package/package.json +3 -3
  53. package/src/core/useProxifiedUnistyles/useProxifiedUnistyles.ts +4 -1
  54. package/src/specs/ShadowRegistry/index.ts +36 -2
  55. package/src/web/convert/style.ts +6 -6
  56. package/src/web/listener.ts +6 -0
  57. package/src/web/utils/createUnistylesRef.ts +1 -1
@@ -12,7 +12,9 @@ bool core::UnistylesState::hasAdaptiveThemes() {
12
12
  }
13
13
 
14
14
  void core::UnistylesState::setTheme(std::string themeName) {
15
- helpers::assertThat(*_rt, helpers::vecContainsKeys(this->_registeredThemeNames, {themeName}), "Unistyles: You're trying to set theme to: '" + std::string(themeName) + "', but it wasn't registered.");
15
+ if (!helpers::vecContainsKeys(this->_registeredThemeNames, {themeName})) {
16
+ throw std::runtime_error("Unistyles: You're trying to set theme to: '" + std::string(themeName) + "', but it wasn't registered.");
17
+ }
16
18
 
17
19
  if (themeName != this->_currentThemeName) {
18
20
  this->_currentThemeName = themeName;
@@ -23,33 +25,33 @@ std::optional<std::string>& core::UnistylesState::getCurrentThemeName() {
23
25
  return this->_currentThemeName;
24
26
  }
25
27
 
26
- jsi::Object core::UnistylesState::getCurrentJSTheme() {
28
+ jsi::Object core::UnistylesState::getCurrentJSTheme(jsi::Runtime& rt) {
27
29
  auto hasSomeThemes = _registeredThemeNames.size() > 0;
28
30
 
29
31
  if (!hasSomeThemes && !this->hasUserConfig) {
30
- helpers::assertThat(*_rt, false, "Unistyles: One of your stylesheets is trying to get the theme, but no theme has been selected yet. Did you forget to call StyleSheet.configure? If you called it, make sure you did so before any StyleSheet.create.");
32
+ helpers::assertThat(rt, false, "Unistyles: One of your stylesheets is trying to get the theme, but no theme has been selected yet. Did you forget to call StyleSheet.configure? If you called it, make sure you did so before any StyleSheet.create.");
31
33
  }
32
34
 
33
35
  // return empty object, if user didn't register any themes
34
36
  if (!hasSomeThemes) {
35
- return jsi::Object(*_rt);
37
+ return jsi::Object(rt);
36
38
  }
37
39
 
38
- helpers::assertThat(*_rt, _currentThemeName.has_value(), "Unistyles: One of your stylesheets is trying to get the theme, but no theme has been selected yet. Did you forget to select an initial theme?");
40
+ helpers::assertThat(rt, _currentThemeName.has_value(), "Unistyles: One of your stylesheets is trying to get the theme, but no theme has been selected yet. Did you forget to select an initial theme?");
39
41
 
40
42
  auto it = this->_jsThemes.find(_currentThemeName.value());
41
43
 
42
- helpers::assertThat(*_rt, it != this->_jsThemes.end(), "Unistyles: You're trying to get theme '" + _currentThemeName.value() + "', but it was not registered. Did you forget to register it with StyleSheet.configure?");
44
+ helpers::assertThat(rt, it != this->_jsThemes.end(), "Unistyles: You're trying to get theme '" + _currentThemeName.value() + "', but it was not registered. Did you forget to register it with StyleSheet.configure?");
43
45
 
44
- return it->second.asObject(*_rt);
46
+ return it->second.asObject(rt);
45
47
  }
46
48
 
47
- jsi::Object core::UnistylesState::getJSThemeByName(std::string& themeName) {
49
+ jsi::Object core::UnistylesState::getJSThemeByName(jsi::Runtime& rt, std::string& themeName) {
48
50
  auto it = this->_jsThemes.find(themeName);
49
51
 
50
- helpers::assertThat(*_rt, it != this->_jsThemes.end(), "Unistyles: You're trying to get theme '" + themeName + "', but it was not registered. Did you forget to register it with StyleSheet.configure?");
52
+ helpers::assertThat(rt, it != this->_jsThemes.end(), "Unistyles: You're trying to get theme '" + themeName + "', but it was not registered. Did you forget to register it with StyleSheet.configure?");
51
53
 
52
- return it->second.asObject(*_rt);
54
+ return it->second.asObject(rt);
53
55
  }
54
56
 
55
57
  void core::UnistylesState::computeCurrentBreakpoint(int screenWidth) {
@@ -99,28 +101,28 @@ void core::UnistylesState::registerParseBoxShadowString(jsi::Function&& fn) {
99
101
  this->_parseBoxShadowStringFn = std::make_shared<jsi::Function>(std::move(fn));
100
102
  }
101
103
 
102
- int core::UnistylesState::parseColor(jsi::Value& maybeColor) {
104
+ int core::UnistylesState::parseColor(jsi::Runtime& rt, jsi::Value& maybeColor) {
103
105
  if (!maybeColor.isString()) {
104
106
  return 0;
105
107
  }
106
108
 
107
- auto colorString = maybeColor.asString(*_rt);
109
+ auto colorString = maybeColor.asString(rt);
108
110
 
109
- if (!this->_colorCache.contains(colorString.utf8(*_rt).c_str())) {
111
+ if (!this->_colorCache.contains(colorString.utf8(rt).c_str())) {
110
112
  #ifdef ANDROID
111
- int color = this->_processColorFn.get()->call(*_rt, colorString).asNumber();
113
+ int color = this->_processColorFn.get()->call(rt, colorString).asNumber();
112
114
  #else
113
- uint32_t color = this->_processColorFn.get()->call(*_rt, colorString).asNumber();
115
+ uint32_t color = this->_processColorFn.get()->call(rt, colorString).asNumber();
114
116
  #endif
115
117
 
116
- this->_colorCache[colorString.utf8(*_rt).c_str()] = color ? color : 0;
118
+ this->_colorCache[colorString.utf8(rt).c_str()] = color ? color : 0;
117
119
  }
118
120
 
119
- return this->_colorCache[colorString.utf8(*_rt).c_str()];
121
+ return this->_colorCache[colorString.utf8(rt).c_str()];
120
122
  }
121
123
 
122
- jsi::Array core::UnistylesState::parseBoxShadowString(std::string&& boxShadowString) {
123
- jsi::Value result = this->_parseBoxShadowStringFn.get()->call(*_rt, boxShadowString);
124
+ jsi::Array core::UnistylesState::parseBoxShadowString(jsi::Runtime& rt, std::string&& boxShadowString) {
125
+ jsi::Value result = this->_parseBoxShadowStringFn.get()->call(rt, boxShadowString);
124
126
 
125
- return result.asObject(*_rt).asArray(*_rt);
127
+ return result.asObject(rt).asArray(rt);
126
128
  }
@@ -13,7 +13,7 @@ struct UnistylesRegistry;
13
13
  using namespace facebook;
14
14
 
15
15
  struct UnistylesState {
16
- UnistylesState(jsi::Runtime& rt): _rt{&rt} {}
16
+ UnistylesState() = default;
17
17
  UnistylesState(const UnistylesState&) = delete;
18
18
  UnistylesState(const UnistylesState&&) = delete;
19
19
 
@@ -29,16 +29,15 @@ struct UnistylesState {
29
29
  std::optional<std::string> getCurrentBreakpointName();
30
30
  std::vector<std::pair<std::string, double>> getSortedBreakpointPairs();
31
31
 
32
- jsi::Object getCurrentJSTheme();
33
- jsi::Object getJSThemeByName(std::string& themeName);
34
- int parseColor(jsi::Value& color);
35
- jsi::Array parseBoxShadowString(std::string&& boxShadowString);
32
+ jsi::Object getCurrentJSTheme(jsi::Runtime& rt);
33
+ jsi::Object getJSThemeByName(jsi::Runtime& rt, std::string& themeName);
34
+ int parseColor(jsi::Runtime& rt, jsi::Value& color);
35
+ jsi::Array parseBoxShadowString(jsi::Runtime& rt, std::string&& boxShadowString);
36
36
  void computeCurrentBreakpoint(int screenWidth);
37
37
  void registerProcessColorFunction(jsi::Function&& fn);
38
38
  void registerParseBoxShadowString(jsi::Function&& fn);
39
39
 
40
40
  private:
41
- jsi::Runtime* _rt;
42
41
  std::unordered_map<std::string, jsi::Value> _jsThemes{};
43
42
  std::optional<bool> _prefersAdaptiveThemes = std::nullopt;
44
43
  std::optional<std::string> _initialThemeName = std::nullopt;
@@ -13,7 +13,7 @@ jsi::Value HybridShadowRegistry::link(jsi::Runtime &rt, const jsi::Value &thisVa
13
13
  auto& registry = core::UnistylesRegistry::get();
14
14
 
15
15
  // this is special case for Animated, and prevents appending same unistyles to node
16
- registry.removeDuplicatedUnistyles(rt, &shadowNodeWrapper->getFamily(), unistyleWrappers);
16
+ registry.removeDuplicatedUnistyles(&shadowNodeWrapper->getFamily(), unistyleWrappers);
17
17
 
18
18
  if (unistyleWrappers.empty()) {
19
19
  return jsi::Value::undefined();
@@ -45,7 +45,7 @@ jsi::Value HybridShadowRegistry::link(jsi::Runtime &rt, const jsi::Value &thisVa
45
45
  if (scopedTheme.has_value()) {
46
46
  auto themeName = scopedTheme.value();
47
47
 
48
- helpers::assertThat(rt, registry.getState(rt).hasTheme(themeName), "Unistyles: You're trying to use scoped theme '" + themeName + "' but it wasn't registered.");
48
+ helpers::assertThat(rt, registry.getState().hasTheme(themeName), "Unistyles: You're trying to use scoped theme '" + themeName + "' but it wasn't registered.");
49
49
  }
50
50
 
51
51
  auto parser = parser::Parser(this->_unistylesRuntime);
@@ -107,7 +107,18 @@ jsi::Value HybridShadowRegistry::unlink(jsi::Runtime &rt, const jsi::Value &this
107
107
 
108
108
  auto& registry = core::UnistylesRegistry::get();
109
109
 
110
- registry.unlinkShadowNodeWithUnistyles(rt, &shadowNodeWrapper->getFamily());
110
+ registry.unlinkShadowNodeWithUnistyles(&shadowNodeWrapper->getFamily());
111
+
112
+ return jsi::Value::undefined();
113
+ }
114
+
115
+ jsi::Value HybridShadowRegistry::suspend(jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
116
+ helpers::assertThat(rt, count == 1, "Unistyles: Invalid babel transform 'ShadowRegistry suspend' expected 1 argument.");
117
+
118
+ auto shadowNodeWrapper = getShadowNodeFromRef(rt, args[0]);
119
+ auto& registry = core::UnistylesRegistry::get();
120
+
121
+ registry.suspendShadowNode(&shadowNodeWrapper->getFamily());
111
122
 
112
123
  return jsi::Value::undefined();
113
124
  }
@@ -22,6 +22,10 @@ struct HybridShadowRegistry: public HybridUnistylesShadowRegistrySpec {
22
22
  const jsi::Value& thisValue,
23
23
  const jsi::Value* args,
24
24
  size_t count);
25
+ jsi::Value suspend(jsi::Runtime& rt,
26
+ const jsi::Value& thisValue,
27
+ const jsi::Value* args,
28
+ size_t count);
25
29
  jsi::Value flush(jsi::Runtime& rt,
26
30
  const jsi::Value& thisValue,
27
31
  const jsi::Value* args,
@@ -41,6 +45,7 @@ struct HybridShadowRegistry: public HybridUnistylesShadowRegistrySpec {
41
45
  registerHybrids(this, [](Prototype& prototype) {
42
46
  prototype.registerRawHybridMethod("link", 2, &HybridShadowRegistry::link);
43
47
  prototype.registerRawHybridMethod("unlink", 1, &HybridShadowRegistry::unlink);
48
+ prototype.registerRawHybridMethod("suspend", 1, &HybridShadowRegistry::suspend);
44
49
  prototype.registerRawHybridMethod("flush", 0, &HybridShadowRegistry::flush);
45
50
  prototype.registerRawHybridMethod("setScopedTheme", 1, &HybridShadowRegistry::setScopedTheme);
46
51
  prototype.registerRawHybridMethod("getScopedTheme", 0, &HybridShadowRegistry::getScopedTheme);
@@ -61,7 +61,7 @@ jsi::Value HybridStyleSheet::configure(jsi::Runtime &rt, const jsi::Value &thisV
61
61
 
62
62
  verifyAndSelectTheme(rt);
63
63
 
64
- auto& state = core::UnistylesRegistry::get().getState(rt);
64
+ auto& state = core::UnistylesRegistry::get().getState();
65
65
 
66
66
  state.hasUserConfig = true;
67
67
 
@@ -76,7 +76,7 @@ jsi::Value HybridStyleSheet::init(jsi::Runtime &rt, const jsi::Value &thisVal, c
76
76
  // create new state
77
77
  auto& registry = core::UnistylesRegistry::get();
78
78
 
79
- registry.createState(rt);
79
+ registry.createState();
80
80
 
81
81
  loadExternalMethods(thisVal, rt);
82
82
 
@@ -95,7 +95,7 @@ void HybridStyleSheet::parseSettings(jsi::Runtime &rt, jsi::Object settings) {
95
95
  if (propertyName == "adaptiveThemes") {
96
96
  helpers::assertThat(rt, propertyValue.isBool(), "StyleSheet.configure's adaptiveThemes must be of boolean type.");
97
97
 
98
- registry.setPrefersAdaptiveThemes(rt, propertyValue.asBool());
98
+ registry.setPrefersAdaptiveThemes(propertyValue.asBool());
99
99
 
100
100
  return;
101
101
  }
@@ -108,12 +108,12 @@ void HybridStyleSheet::parseSettings(jsi::Runtime &rt, jsi::Object settings) {
108
108
 
109
109
  helpers::assertThat(rt, result.isString(), "StyleSheet.configure's initialTheme resolved from function is not a string. Please check your initialTheme function.");
110
110
 
111
- return registry.setInitialThemeName(rt, result.asString(rt).utf8(rt));
111
+ return registry.setInitialThemeName(result.asString(rt).utf8(rt));
112
112
  }
113
113
 
114
114
  helpers::assertThat(rt, propertyValue.isString(), "StyleSheet.configure's initialTheme must be either a string or a function.");
115
115
 
116
- registry.setInitialThemeName(rt, propertyValue.asString(rt).utf8(rt));
116
+ registry.setInitialThemeName(propertyValue.asString(rt).utf8(rt));
117
117
 
118
118
  return;
119
119
  }
@@ -147,9 +147,9 @@ void HybridStyleSheet::parseBreakpoints(jsi::Runtime &rt, jsi::Object breakpoint
147
147
  helpers::assertThat(rt, sortedBreakpoints.front().second == 0, "StyleSheet.configure's first breakpoint must start from 0.");
148
148
 
149
149
  auto& registry = core::UnistylesRegistry::get();
150
- auto& state = registry.getState(rt);
150
+ auto& state = registry.getState();
151
151
 
152
- registry.registerBreakpoints(rt, sortedBreakpoints);
152
+ registry.registerBreakpoints(sortedBreakpoints);
153
153
 
154
154
  auto rawWidth = this->_unistylesRuntime->getScreen().width;
155
155
  auto width = registry.shouldUsePointsForBreakpoints
@@ -170,7 +170,7 @@ void HybridStyleSheet::parseThemes(jsi::Runtime &rt, jsi::Object themes) {
170
170
  }
171
171
 
172
172
  void HybridStyleSheet::verifyAndSelectTheme(jsi::Runtime &rt) {
173
- auto& state = core::UnistylesRegistry::get().getState(rt);
173
+ auto& state = core::UnistylesRegistry::get().getState();
174
174
 
175
175
  bool hasInitialTheme = state.hasInitialTheme();
176
176
  bool prefersAdaptiveThemes = state.getPrefersAdaptiveThemes();
@@ -217,7 +217,7 @@ void HybridStyleSheet::verifyAndSelectTheme(jsi::Runtime &rt) {
217
217
  }
218
218
 
219
219
  void HybridStyleSheet::setThemeFromColorScheme(jsi::Runtime& rt) {
220
- auto& state = core::UnistylesRegistry::get().getState(rt);
220
+ auto& state = core::UnistylesRegistry::get().getState();
221
221
  auto colorScheme = static_cast<ColorScheme>(this->_unistylesRuntime->getColorScheme());
222
222
 
223
223
  switch (colorScheme) {
@@ -250,7 +250,7 @@ void HybridStyleSheet::loadExternalMethods(const jsi::Value& thisValue, jsi::Run
250
250
  auto processColorFn = maybeProcessColorFn.asObject(rt).asFunction(rt);
251
251
  auto parseBoxShadowStringFn = maybeParseBoxShadowStringFn.asObject(rt).asFunction(rt);
252
252
  auto& registry = core::UnistylesRegistry::get();
253
- auto& state = registry.getState(rt);
253
+ auto& state = registry.getState();
254
254
 
255
255
  state.registerProcessColorFunction(std::move(processColorFn));
256
256
  state.registerParseBoxShadowString(std::move(parseBoxShadowStringFn));
@@ -262,32 +262,42 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vector<UnistyleDependen
262
262
  return;
263
263
  }
264
264
 
265
- auto& registry = core::UnistylesRegistry::get();
266
- auto& rt = this->_unistylesRuntime->getRuntime();
267
- auto parser = parser::Parser(this->_unistylesRuntime);
268
- auto dependencyMap = registry.buildDependencyMap(rt, dependencies);
265
+ auto weakSelf = weak_from_this();
269
266
 
270
- if (dependencyMap.empty()) {
271
- this->notifyJSListeners(dependencies);
272
- }
267
+ this->_unistylesRuntime->runOnJSThread([weakSelf, dependencies](jsi::Runtime& rt) {
268
+ auto self = std::dynamic_pointer_cast<HybridStyleSheet>(weakSelf.lock());
273
269
 
274
- // in a later step, we will rebuild only Unistyles with mounted StyleSheets
275
- // however, user may have StyleSheets with components that haven't mounted yet
276
- // we need to rebuild all dependent StyleSheets as well
277
- auto dependentStyleSheets = registry.getStyleSheetsToRefresh(rt, dependencies);
270
+ if (!self) {
271
+ return;
272
+ }
278
273
 
279
- parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, std::nullopt);
274
+ auto& registry = core::UnistylesRegistry::get();
275
+ auto parser = parser::Parser(self->_unistylesRuntime);
276
+ auto unistyleDependencies = dependencies;
277
+ auto dependencyMap = registry.buildDependencyMap(unistyleDependencies);
280
278
 
281
- // we need to stop here if there is nothing to update at the moment,
282
- // but we need to compute dependentStyleSheets
283
- if (dependencyMap.empty()) {
284
- return;
285
- }
279
+ if (dependencyMap.empty()) {
280
+ self->notifyJSListeners(unistyleDependencies);
281
+ }
282
+
283
+ // in a later step, we will rebuild only Unistyles with mounted StyleSheets
284
+ // however, user may have StyleSheets with components that haven't mounted yet
285
+ // we need to rebuild all dependent StyleSheets as well
286
+ auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies);
287
+
288
+ parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, std::nullopt);
289
+
290
+ // we need to stop here if there is nothing to update at the moment,
291
+ // but we need to compute dependentStyleSheets
292
+ if (dependencyMap.empty()) {
293
+ return;
294
+ }
286
295
 
287
- parser.rebuildShadowLeafUpdates(rt, dependencyMap);
296
+ parser.rebuildShadowLeafUpdates(rt, dependencyMap);
288
297
 
289
- this->notifyJSListeners(dependencies);
290
- shadow::ShadowTreeManager::updateShadowTree(rt);
298
+ self->notifyJSListeners(unistyleDependencies);
299
+ shadow::ShadowTreeManager::updateShadowTree(rt);
300
+ });
291
301
  }
292
302
 
293
303
  void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector<UnistyleDependency> dependencies, UnistylesNativeMiniRuntime miniRuntime) {
@@ -296,21 +306,29 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector<UnistyleDe
296
306
  return;
297
307
  }
298
308
 
299
- this->_unistylesRuntime->runOnJSThread([this, dependencies, miniRuntime](jsi::Runtime& rt){
309
+ auto weakSelf = weak_from_this();
310
+
311
+ this->_unistylesRuntime->runOnJSThread([weakSelf, dependencies, miniRuntime](jsi::Runtime& rt){
312
+ auto self = std::dynamic_pointer_cast<HybridStyleSheet>(weakSelf.lock());
313
+
314
+ if (!self) {
315
+ return;
316
+ }
317
+
300
318
  auto& registry = core::UnistylesRegistry::get();
301
- auto parser = parser::Parser(this->_unistylesRuntime);
319
+ auto parser = parser::Parser(self->_unistylesRuntime);
302
320
  auto unistyleDependencies = std::move(dependencies);
303
321
 
304
322
  // re-compute new breakpoint
305
323
  auto dimensionsIt = std::find(dependencies.begin(), dependencies.end(), UnistyleDependency::DIMENSIONS);
306
324
 
307
325
  if (dimensionsIt != dependencies.end()) {
308
- auto rawWidth = this->_unistylesRuntime->getScreen().width;
326
+ auto rawWidth = self->_unistylesRuntime->getScreen().width;
309
327
  auto width = registry.shouldUsePointsForBreakpoints
310
- ? rawWidth / this->_unistylesRuntime->getPixelRatio()
328
+ ? rawWidth / self->_unistylesRuntime->getPixelRatio()
311
329
  : rawWidth;
312
330
 
313
- registry.getState(rt).computeCurrentBreakpoint(width);
331
+ registry.getState().computeCurrentBreakpoint(width);
314
332
  }
315
333
 
316
334
  // check if color scheme changed and then if Unistyles state depend on it (adaptive themes)
@@ -318,19 +336,19 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector<UnistyleDe
318
336
  auto hasNewColorScheme = colorSchemeIt != dependencies.end();
319
337
 
320
338
  if (hasNewColorScheme) {
321
- this->_unistylesRuntime->includeDependenciesForColorSchemeChange(unistyleDependencies);
339
+ self->_unistylesRuntime->includeDependenciesForColorSchemeChange(unistyleDependencies);
322
340
  }
323
341
 
324
- auto dependencyMap = registry.buildDependencyMap(rt, unistyleDependencies);
342
+ auto dependencyMap = registry.buildDependencyMap(unistyleDependencies);
325
343
 
326
344
  if (dependencyMap.empty()) {
327
- this->notifyJSListeners(unistyleDependencies);
345
+ self->notifyJSListeners(unistyleDependencies);
328
346
  }
329
347
 
330
348
  // in a later step, we will rebuild only Unistyles with mounted StyleSheets
331
349
  // however, user may have StyleSheets with components that haven't mounted yet
332
350
  // we need to rebuild all dependent StyleSheets as well
333
- auto dependentStyleSheets = registry.getStyleSheetsToRefresh(rt, unistyleDependencies);
351
+ auto dependentStyleSheets = registry.getStyleSheetsToRefresh(unistyleDependencies);
334
352
 
335
353
  parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime);
336
354
 
@@ -342,7 +360,7 @@ void HybridStyleSheet::onPlatformNativeDependenciesChange(std::vector<UnistyleDe
342
360
 
343
361
  parser.rebuildShadowLeafUpdates(rt, dependencyMap);
344
362
 
345
- this->notifyJSListeners(unistyleDependencies);
363
+ self->notifyJSListeners(unistyleDependencies);
346
364
  shadow::ShadowTreeManager::updateShadowTree(rt);
347
365
  });
348
366
  }
@@ -352,14 +370,22 @@ void HybridStyleSheet::onImeChange(UnistylesNativeMiniRuntime miniRuntime) {
352
370
  return;
353
371
  }
354
372
 
355
- this->_unistylesRuntime->runOnJSThread([this, miniRuntime](jsi::Runtime& rt){
373
+ auto weakSelf = weak_from_this();
374
+
375
+ this->_unistylesRuntime->runOnJSThread([weakSelf, miniRuntime](jsi::Runtime& rt){
376
+ auto self = std::dynamic_pointer_cast<HybridStyleSheet>(weakSelf.lock());
377
+
378
+ if (!self) {
379
+ return;
380
+ }
381
+
356
382
  std::vector<UnistyleDependency> dependencies{UnistyleDependency::IME};
357
383
  auto& registry = core::UnistylesRegistry::get();
358
- auto parser = parser::Parser(this->_unistylesRuntime);
359
- auto dependencyMap = registry.buildDependencyMap(rt, dependencies);
384
+ auto parser = parser::Parser(self->_unistylesRuntime);
385
+ auto dependencyMap = registry.buildDependencyMap(dependencies);
360
386
 
361
387
  if (dependencyMap.empty()) {
362
- this->notifyJSListeners(dependencies);
388
+ self->notifyJSListeners(dependencies);
363
389
 
364
390
  return;
365
391
  }
@@ -371,7 +397,7 @@ void HybridStyleSheet::onImeChange(UnistylesNativeMiniRuntime miniRuntime) {
371
397
  parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets, miniRuntime);
372
398
  parser.rebuildShadowLeafUpdates(rt, dependencyMap);
373
399
 
374
- this->notifyJSListeners(dependencies);
400
+ self->notifyJSListeners(dependencies);
375
401
  shadow::ShadowTreeManager::updateShadowTree(rt);
376
402
  });
377
403
  }
@@ -3,6 +3,10 @@
3
3
 
4
4
  using namespace margelo::nitro::unistyles;
5
5
 
6
+ core::UnistylesState& HybridUnistylesRuntime::getState() {
7
+ return core::UnistylesRegistry::get().getState();
8
+ }
9
+
6
10
  ColorScheme HybridUnistylesRuntime::getColorScheme() {
7
11
  auto colorScheme = this->_nativePlatform->getColorScheme();
8
12
 
@@ -10,9 +14,7 @@ ColorScheme HybridUnistylesRuntime::getColorScheme() {
10
14
  }
11
15
 
12
16
  bool HybridUnistylesRuntime::getHasAdaptiveThemes() {
13
- auto& state = core::UnistylesRegistry::get().getState(*_rt);
14
-
15
- return state.hasAdaptiveThemes();
17
+ return this->getState().hasAdaptiveThemes();
16
18
  };
17
19
 
18
20
  Dimensions HybridUnistylesRuntime::getScreen() {
@@ -22,14 +24,12 @@ Dimensions HybridUnistylesRuntime::getScreen() {
22
24
  std::optional<std::string> HybridUnistylesRuntime::getThemeName() {
23
25
  auto& registry = core::UnistylesRegistry::get();
24
26
  auto maybeScopedTheme = registry.getScopedTheme();
25
-
27
+
26
28
  if (maybeScopedTheme.has_value()) {
27
29
  return maybeScopedTheme.value();
28
30
  }
29
-
30
- auto& state = registry.getState(*_rt);
31
-
32
- return state.getCurrentThemeName();
31
+
32
+ return this->getState().getCurrentThemeName();
33
33
  };
34
34
 
35
35
  std::string HybridUnistylesRuntime::getContentSizeCategory() {
@@ -37,9 +37,7 @@ std::string HybridUnistylesRuntime::getContentSizeCategory() {
37
37
  };
38
38
 
39
39
  std::optional<std::string> HybridUnistylesRuntime::getBreakpoint() {
40
- auto& state = core::UnistylesRegistry::get().getState(*_rt);
41
-
42
- return state.getCurrentBreakpointName();
40
+ return this->getState().getCurrentBreakpointName();
43
41
  };
44
42
 
45
43
  bool HybridUnistylesRuntime::getRtl() {
@@ -73,8 +71,7 @@ double HybridUnistylesRuntime::getFontScale() {
73
71
  };
74
72
 
75
73
  std::unordered_map<std::string, double> HybridUnistylesRuntime::getBreakpoints() {
76
- auto& state = core::UnistylesRegistry::get().getState(*_rt);
77
- auto sortedBreakpointPairs = state.getSortedBreakpointPairs();
74
+ auto sortedBreakpointPairs = this->getState().getSortedBreakpointPairs();
78
75
  std::unordered_map<std::string, double> breakpoints{};
79
76
 
80
77
  std::for_each(sortedBreakpointPairs.begin(), sortedBreakpointPairs.end(), [&breakpoints](std::pair<std::string, double>& pair){
@@ -85,12 +82,13 @@ std::unordered_map<std::string, double> HybridUnistylesRuntime::getBreakpoints()
85
82
  }
86
83
 
87
84
  void HybridUnistylesRuntime::setTheme(const std::string &themeName) {
88
- helpers::assertThat(*_rt, !this->getHasAdaptiveThemes(), "Unistyles: You're trying to set theme to: '" + themeName + "', but adaptiveThemes are enabled.");
85
+ if (this->getHasAdaptiveThemes()) {
86
+ throw std::runtime_error("Unistyles: You're trying to set theme to: '" + themeName + "', but adaptiveThemes are enabled.");
87
+ }
89
88
 
90
- auto& state = core::UnistylesRegistry::get().getState(*_rt);
91
- auto currentThemeName = state.getCurrentThemeName();
89
+ auto currentThemeName = this->getState().getCurrentThemeName();
92
90
 
93
- state.setTheme(themeName);
91
+ this->getState().setTheme(themeName);
94
92
 
95
93
  if (currentThemeName.value() != themeName) {
96
94
  this->_onDependenciesChange({UnistyleDependency::THEME, UnistyleDependency::THEMENAME});
@@ -106,7 +104,7 @@ void HybridUnistylesRuntime::setAdaptiveThemes(bool isEnabled) {
106
104
 
107
105
  bool hadAdaptiveThemes = this->getHasAdaptiveThemes();
108
106
 
109
- registry.setPrefersAdaptiveThemes(*_rt, isEnabled);
107
+ registry.setPrefersAdaptiveThemes(isEnabled);
110
108
 
111
109
  bool haveAdaptiveThemes = this->getHasAdaptiveThemes();
112
110
 
@@ -128,7 +126,6 @@ void HybridUnistylesRuntime::setAdaptiveThemes(bool isEnabled) {
128
126
  };
129
127
 
130
128
  void HybridUnistylesRuntime::calculateNewThemeAndDependencies(std::vector<UnistyleDependency>& changedDependencies) {
131
- auto& state = core::UnistylesRegistry::get().getState(*_rt);
132
129
  auto colorScheme = this->getColorScheme();
133
130
  auto currentThemeName = this->getThemeName();
134
131
  auto nextTheme = colorScheme == ColorScheme::LIGHT
@@ -139,18 +136,18 @@ void HybridUnistylesRuntime::calculateNewThemeAndDependencies(std::vector<Unisty
139
136
  changedDependencies.push_back(UnistyleDependency::THEME);
140
137
  changedDependencies.push_back(UnistyleDependency::THEMENAME);
141
138
 
142
- state.setTheme(nextTheme);
139
+ this->getState().setTheme(nextTheme);
143
140
  }
144
141
  }
145
142
 
146
143
  jsi::Value HybridUnistylesRuntime::getTheme(jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
147
144
  helpers::assertThat(rt, count <= 1, "UnistylesRuntime.getTheme expected to be called with 0 or 1 argument.");
148
145
 
149
- auto& state = core::UnistylesRegistry::get().getState(*_rt);
146
+ auto& state = this->getState();
150
147
 
151
148
  if (count == 1) {
152
149
  if (args[0].isUndefined()) {
153
- return state.getCurrentJSTheme();
150
+ return state.getCurrentJSTheme(rt);
154
151
  }
155
152
 
156
153
  helpers::assertThat(rt, args[0].isString(), "UnistylesRuntime.getTheme expected to be called with string.");
@@ -159,10 +156,10 @@ jsi::Value HybridUnistylesRuntime::getTheme(jsi::Runtime &rt, const jsi::Value &
159
156
 
160
157
  helpers::assertThat(rt, state.hasTheme(themeName), "Unistyles: You're trying to get theme '" + themeName + "' but it wasn't registered.");
161
158
 
162
- return state.getJSThemeByName(themeName);
159
+ return state.getJSThemeByName(rt, themeName);
163
160
  }
164
161
 
165
- return state.getCurrentJSTheme();
162
+ return state.getCurrentJSTheme(rt);
166
163
  }
167
164
 
168
165
  jsi::Value HybridUnistylesRuntime::updateTheme(jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
@@ -292,17 +289,10 @@ void HybridUnistylesRuntime::unregisterNativePlatformListeners() {
292
289
  }
293
290
 
294
291
  void HybridUnistylesRuntime::includeDependenciesForColorSchemeChange(std::vector<UnistyleDependency>& deps) {
295
- auto& registry = core::UnistylesRegistry::get();
296
- auto& state = registry.getState(*this->_rt);
297
-
298
292
  // ignore color scheme changes if user has no adaptive themes
299
- if (!state.hasAdaptiveThemes()) {
293
+ if (!this->getState().hasAdaptiveThemes()) {
300
294
  return;
301
295
  }
302
296
 
303
297
  this->calculateNewThemeAndDependencies(deps);
304
298
  }
305
-
306
- jsi::Runtime& HybridUnistylesRuntime::getRuntime() {
307
- return *this->_rt;
308
- }
@@ -13,8 +13,8 @@
13
13
  namespace margelo::nitro::unistyles {
14
14
 
15
15
  struct HybridUnistylesRuntime: public HybridUnistylesRuntimeSpec {
16
- HybridUnistylesRuntime(std::shared_ptr<HybridNativePlatformSpec> nativePlatform, jsi::Runtime& rt, std::function<void(std::function<void(jsi::Runtime&)>&&)> runOnJSThread)
17
- : HybridObject(TAG), _nativePlatform{nativePlatform}, _rt{&rt}, runOnJSThread(std::move(runOnJSThread)) {}
16
+ HybridUnistylesRuntime(std::shared_ptr<HybridNativePlatformSpec> nativePlatform, std::function<void(std::function<void(jsi::Runtime&)>&&)> runOnJSThread)
17
+ : HybridObject(TAG), _nativePlatform{nativePlatform}, runOnJSThread(std::move(runOnJSThread)) {}
18
18
 
19
19
  jsi::Value getTheme(jsi::Runtime& rt,
20
20
  const jsi::Value& thisValue,
@@ -69,7 +69,7 @@ struct HybridUnistylesRuntime: public HybridUnistylesRuntimeSpec {
69
69
  UnistylesCxxMiniRuntime getMiniRuntime() override;
70
70
  std::unordered_map<std::string, double> getBreakpoints() override;
71
71
 
72
- jsi::Runtime& getRuntime();
72
+ core::UnistylesState& getState();
73
73
  UnistylesCxxMiniRuntime buildMiniRuntimeFromNativeRuntime(UnistylesNativeMiniRuntime& nativeMiniRuntime);
74
74
  jsi::Value getMiniRuntimeAsValue(jsi::Runtime& rt, std::optional<UnistylesNativeMiniRuntime> maybeMiniRuntime);
75
75
  void includeDependenciesForColorSchemeChange(std::vector<UnistyleDependency>& deps);
@@ -77,7 +77,6 @@ struct HybridUnistylesRuntime: public HybridUnistylesRuntimeSpec {
77
77
  std::function<void(std::function<void(jsi::Runtime&)>&&)> runOnJSThread;
78
78
 
79
79
  private:
80
- jsi::Runtime* _rt;
81
80
  std::shared_ptr<HybridNavigationBar> _navigationBar;
82
81
  std::shared_ptr<HybridStatusBar> _statusBar;
83
82
  std::shared_ptr<HybridNativePlatformSpec> _nativePlatform;