react-native-unistyles 3.0.0-alpha.22 → 3.0.0-alpha.24

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.
@@ -149,3 +149,29 @@ core::DependencyMap core::UnistylesRegistry::buildDependencyMap(jsi::Runtime& rt
149
149
 
150
150
  return dependencyMap;
151
151
  }
152
+
153
+ std::vector<std::shared_ptr<core::StyleSheet>> core::UnistylesRegistry::getStyleSheetsToRefresh(jsi::Runtime& rt, bool themeDidChange, bool runtimeDidChange) {
154
+ std::vector<std::shared_ptr<core::StyleSheet>> stylesheetsToRefresh{};
155
+
156
+ if (!themeDidChange && !runtimeDidChange) {
157
+ return stylesheetsToRefresh;
158
+ }
159
+
160
+ auto& styleSheets = this->_styleSheetRegistry[&rt];
161
+
162
+ std::for_each(styleSheets.begin(), styleSheets.end(), [&](std::pair<int, std::shared_ptr<core::StyleSheet>> pair){
163
+ auto& [_, styleSheet] = pair;
164
+
165
+ if (styleSheet->type == StyleSheetType::ThemableWithMiniRuntime && runtimeDidChange) {
166
+ stylesheetsToRefresh.emplace_back(styleSheet);
167
+
168
+ return;
169
+ }
170
+
171
+ if (styleSheet->type == StyleSheetType::Themable && themeDidChange) {
172
+ stylesheetsToRefresh.emplace_back(styleSheet);
173
+ }
174
+ });
175
+
176
+ return stylesheetsToRefresh;
177
+ }
@@ -36,6 +36,7 @@ struct UnistylesRegistry: public StyleSheetRegistry {
36
36
 
37
37
  UnistylesState& getState(jsi::Runtime& rt);
38
38
  void createState(jsi::Runtime& rt);
39
+ std::vector<std::shared_ptr<core::StyleSheet>> getStyleSheetsToRefresh(jsi::Runtime& rt, bool themeDidChange, bool runtimeDidChange);
39
40
  void linkShadowNodeWithUnistyle(jsi::Runtime& rt, const ShadowNodeFamily*, std::vector<core::Unistyle::Shared>& unistyles, Variants& variants, std::vector<folly::dynamic>&);
40
41
  void unlinkShadowNodeWithUnistyles(jsi::Runtime& rt, const ShadowNodeFamily*);
41
42
  std::shared_ptr<core::StyleSheet> addStyleSheet(jsi::Runtime& rt, int tag, core::StyleSheetType type, jsi::Object&& rawValue);
@@ -223,18 +223,24 @@ void HybridStyleSheet::onPlatformDependenciesChange(std::vector<UnistyleDependen
223
223
 
224
224
  // check if color scheme changed and then if Unistyles state depend on it (adaptive themes)
225
225
  auto colorSchemeIt = std::find(dependencies.begin(), dependencies.end(), UnistyleDependency::COLORSCHEME);
226
-
227
- if (colorSchemeIt != dependencies.end()) {
226
+ auto hasNewColorScheme = colorSchemeIt != dependencies.end();
227
+
228
+ // in a later step, we will rebuild only Unistyles with mounted StyleSheets
229
+ // however, user may have StyleSheets with components that haven't mounted yet
230
+ // we need to rebuild all dependent StyleSheets as well
231
+ auto dependentStyleSheets = registry.getStyleSheetsToRefresh(rt, hasNewColorScheme, dependencies.size() > 1);
232
+
233
+ if (hasNewColorScheme) {
228
234
  this->_unistylesRuntime->includeDependenciesForColorSchemeChange(dependencies);
229
235
  }
230
-
236
+
231
237
  auto dependencyMap = registry.buildDependencyMap(rt, dependencies);
232
238
 
233
239
  if (dependencyMap.size() == 0) {
234
240
  return;
235
241
  }
236
242
 
237
- parser.rebuildUnistylesInDependencyMap(rt, dependencyMap);
243
+ parser.rebuildUnistylesInDependencyMap(rt, dependencyMap, dependentStyleSheets);
238
244
 
239
245
  // this is required, otherwise shadow tree will ignore Unistyles commit
240
246
  registry.trafficController.setHasUnistylesCommit(true);
@@ -99,9 +99,16 @@ void parser::Parser::rebuildUnistylesWithVariants(jsi::Runtime& rt, std::shared_
99
99
  }
100
100
 
101
101
  // rebuild all unistyles that are affected by platform event
102
- void parser::Parser::rebuildUnistylesInDependencyMap(jsi::Runtime& rt, DependencyMap& dependencyMap) {
102
+ void parser::Parser::rebuildUnistylesInDependencyMap(jsi::Runtime& rt, DependencyMap& dependencyMap, std::vector<std::shared_ptr<core::StyleSheet>> styleSheets) {
103
103
  std::unordered_map<std::shared_ptr<StyleSheet>, jsi::Value> parsedStyleSheets{};
104
+ std::unordered_map<std::shared_ptr<core::Unistyle>, bool> parsedUnistyles{};
104
105
 
106
+ // parse all stylesheets that depends on changes
107
+ for (auto styleSheet : styleSheets) {
108
+ parsedStyleSheets.emplace(styleSheet, this->unwrapStyleSheet(rt, styleSheet));
109
+ }
110
+
111
+ // then parse all visible Unistyles
105
112
  for (auto& [shadowNode, unistyles] : dependencyMap) {
106
113
  auto styleSheet = unistyles.begin()->get()->unistyle->parent;
107
114
 
@@ -116,6 +123,10 @@ void parser::Parser::rebuildUnistylesInDependencyMap(jsi::Runtime& rt, Dependenc
116
123
  // for RN styles or inline styles, compute styles only once
117
124
  if (unistyle->styleKey == helpers::EXOTIC_STYLE_KEY.c_str() && !unistyleData->parsedStyle.has_value()) {
118
125
  unistyleData->parsedStyle = jsi::Value(rt, unistyle->rawValue).asObject(rt);
126
+
127
+ if (!parsedUnistyles.contains(unistyle)) {
128
+ parsedUnistyles.emplace(unistyle, true);
129
+ }
119
130
 
120
131
  continue;
121
132
  }
@@ -128,6 +139,21 @@ void parser::Parser::rebuildUnistylesInDependencyMap(jsi::Runtime& rt, Dependenc
128
139
  unistyle->rawValue = parsedStyleSheets[styleSheet].asObject(rt).getProperty(rt, unistyle->styleKey.c_str()).asObject(rt);
129
140
  this->rebuildUnistyle(rt, styleSheet, unistyle, unistyleData->variants, unistyleData->dynamicFunctionMetadata);
130
141
  unistyleData->parsedStyle = jsi::Value(rt, unistyle->parsedStyle.value()).asObject(rt);
142
+
143
+ if (!parsedUnistyles.contains(unistyle)) {
144
+ parsedUnistyles.emplace(unistyle, true);
145
+ }
146
+ }
147
+ }
148
+
149
+ // parse whatever left in StyleSheets
150
+ for (auto styleSheet : styleSheets) {
151
+ for (auto& [_, unistyle] : styleSheet->unistyles) {
152
+ if (!parsedUnistyles.contains(unistyle)) {
153
+ parsedUnistyles.emplace(unistyle, true);
154
+ unistyle->rawValue = parsedStyleSheets[styleSheet].asObject(rt).getProperty(rt, unistyle->styleKey.c_str()).asObject(rt);
155
+ this->rebuildUnistyle(rt, styleSheet, unistyle, {}, std::nullopt);
156
+ }
131
157
  }
132
158
  }
133
159
  }
@@ -24,7 +24,7 @@ struct Parser {
24
24
  void buildUnistyles(jsi::Runtime& rt, std::shared_ptr<StyleSheet> styleSheet);
25
25
  void parseUnistyles(jsi::Runtime& rt, std::shared_ptr<StyleSheet> styleSheet);
26
26
  void rebuildUnistylesWithVariants(jsi::Runtime& rt, std::shared_ptr<StyleSheet> styleSheet, Variants& variants);
27
- void rebuildUnistylesInDependencyMap(jsi::Runtime& rt, core::DependencyMap& dependencyMap);
27
+ void rebuildUnistylesInDependencyMap(jsi::Runtime& rt, core::DependencyMap& dependencyMap, std::vector<std::shared_ptr<core::StyleSheet>> styleSheets);
28
28
  shadow::ShadowLeafUpdates dependencyMapToShadowLeafUpdates(core::DependencyMap& dependencyMap);
29
29
 
30
30
  private:
@@ -1,12 +1,14 @@
1
1
  #if os(iOS)
2
2
 
3
3
  import Foundation
4
+ import Combine
4
5
  import NitroModules
5
6
 
6
7
  typealias CxxListener = (Array<UnistyleDependency>) -> Void
7
8
 
8
9
  class NativeIOSPlatform: HybridNativePlatformSpec {
9
10
  var miniRuntime: UnistylesNativeMiniRuntime?
11
+ var cancellables = Set<AnyCancellable>()
10
12
 
11
13
  var listeners: Array<CxxListener> = []
12
14
  var hybridContext = margelo.nitro.HybridContext()
@@ -2,16 +2,18 @@ import Foundation
2
2
 
3
3
  extension NativeIOSPlatform {
4
4
  func setupPlatformListeners() {
5
- NotificationCenter.default.addObserver(
6
- self,
7
- selector: #selector(onWindowChange(_:)),
8
- name: NSNotification.Name("RCTWindowFrameDidChangeNotification"),
9
- object: nil
10
- )
5
+ NotificationCenter.default.publisher(for: NSNotification.Name("RCTWindowFrameDidChangeNotification"))
6
+ // add small delay (10ms) to make sure all values are up ot date
7
+ // we MUST call it on current thread, otherwise random crashes occurs
8
+ .delay(for: .milliseconds(10), scheduler: RunLoop.current)
9
+ .sink { [weak self] notification in
10
+ self?.onWindowChange(notification)
11
+ }
12
+ .store(in: &cancellables)
11
13
  }
12
14
 
13
15
  func removePlatformListeners() {
14
- NotificationCenter.default.removeObserver(self, name: NSNotification.Name("RCTWindowFrameDidChangeNotification"), object: nil)
16
+ cancellables.removeAll()
15
17
  }
16
18
 
17
19
  func registerPlatformListener(callback: @escaping (CxxListener)) throws {
@@ -24,18 +26,16 @@ extension NativeIOSPlatform {
24
26
 
25
27
  @objc func onWindowChange(_ notification: Notification) {
26
28
  // add small delay (10ms) to make sure all values are up ot date
27
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
28
- guard let currentMiniRuntime = self.miniRuntime else {
29
- return
30
- }
31
-
32
- let newMiniRuntime = self.buildMiniRuntime()
33
- let changedDependencies = UnistylesNativeMiniRuntime.diff(lhs: currentMiniRuntime, rhs: newMiniRuntime)
34
-
35
- if (changedDependencies.count > 0) {
36
- self.miniRuntime = newMiniRuntime
37
- self.emitCxxEvent(dependencies: changedDependencies)
38
- }
29
+ guard let currentMiniRuntime = self.miniRuntime else {
30
+ return
31
+ }
32
+
33
+ let newMiniRuntime = self.buildMiniRuntime()
34
+ let changedDependencies = UnistylesNativeMiniRuntime.diff(lhs: currentMiniRuntime, rhs: newMiniRuntime)
35
+
36
+ if (changedDependencies.count > 0) {
37
+ self.miniRuntime = newMiniRuntime
38
+ self.emitCxxEvent(dependencies: changedDependencies)
39
39
  }
40
40
  }
41
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-unistyles",
3
- "version": "3.0.0-alpha.22",
3
+ "version": "3.0.0-alpha.24",
4
4
  "description": "Level up your React Native StyleSheet",
5
5
  "scripts": {
6
6
  "test": "jest",