react-native-windows 0.69.4 → 0.69.7

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.
@@ -8,77 +8,183 @@
8
8
  namespace winrt::Microsoft::ReactNative::implementation {
9
9
 
10
10
  //=============================================================================
11
- // ReactNotificationSubscription implementation
11
+ // IReactNotificationSubscription implementation
12
12
  //=============================================================================
13
13
 
14
- ReactNotificationSubscription::ReactNotificationSubscription(
15
- IReactNotificationSubscription const &parentSubscription,
16
- weak_ref<ReactNotificationService> &&notificationService,
17
- IReactPropertyName const &notificationName,
18
- IReactDispatcher const &dispatcher) noexcept
19
- : m_parentSubscription{parentSubscription},
20
- m_notificationService{std::move(notificationService)},
21
- m_notificationName{notificationName},
22
- m_dispatcher{dispatcher} {}
23
-
24
- ReactNotificationSubscription::ReactNotificationSubscription(
25
- weak_ref<ReactNotificationService> &&notificationService,
26
- IReactPropertyName const &notificationName,
27
- IReactDispatcher const &dispatcher,
28
- ReactNotificationHandler const &handler) noexcept
29
- : m_notificationService{std::move(notificationService)},
30
- m_notificationName{notificationName},
31
- m_dispatcher{dispatcher},
32
- m_handler{handler} {}
33
-
34
- ReactNotificationSubscription::~ReactNotificationSubscription() noexcept {
35
- Unsubscribe();
36
- }
14
+ // Common interface to share functionality between ReactNotificationSubscription and ReactNotificationSubscriptionView
15
+ MSO_GUID(IReactNotificationSubscriptionPrivate, "09437980-3508-4690-930c-7c310e205e6b")
16
+ struct IReactNotificationSubscriptionPrivate : ::IUnknown {
17
+ virtual void SetParent(IReactNotificationSubscription const &parentSubscription) noexcept = 0;
18
+ virtual void CallHandler(
19
+ Windows::Foundation::IInspectable const &sender,
20
+ Windows::Foundation::IInspectable const &data) noexcept = 0;
21
+ };
22
+
23
+ // The Notification subscription class.
24
+ // Instances of this class are stored in the "child" notification services.
25
+ struct ReactNotificationSubscription
26
+ : implements<ReactNotificationSubscription, IReactNotificationSubscription, IReactNotificationSubscriptionPrivate> {
27
+ ReactNotificationSubscription(
28
+ Mso::RefCountedPtr<std::mutex> const &mutex,
29
+ weak_ref<ReactNotificationService> &&notificationService,
30
+ IReactPropertyName const &notificationName,
31
+ IReactDispatcher const &dispatcher,
32
+ ReactNotificationHandler const &handler) noexcept
33
+ : m_mutex{mutex},
34
+ m_notificationService{std::move(notificationService)},
35
+ m_notificationName{notificationName},
36
+ m_dispatcher{dispatcher},
37
+ m_handler{handler} {}
38
+
39
+ ~ReactNotificationSubscription() noexcept {
40
+ Unsubscribe();
41
+ }
37
42
 
38
- IReactNotificationService ReactNotificationSubscription::NotificationService() const noexcept {
39
- return m_notificationService.get().as<IReactNotificationService>();
40
- }
43
+ public: // IReactNotificationSubscription implementation
44
+ IReactNotificationService NotificationService() const noexcept {
45
+ return m_notificationService.get().as<IReactNotificationService>();
46
+ }
41
47
 
42
- IReactPropertyName ReactNotificationSubscription::NotificationName() const noexcept {
43
- return m_notificationName;
44
- }
48
+ IReactPropertyName NotificationName() const noexcept {
49
+ return m_notificationName;
50
+ }
45
51
 
46
- IReactDispatcher ReactNotificationSubscription::Dispatcher() const noexcept {
47
- return m_dispatcher;
48
- }
52
+ IReactDispatcher Dispatcher() const noexcept {
53
+ return m_dispatcher;
54
+ }
49
55
 
50
- bool ReactNotificationSubscription::IsSubscribed() const noexcept {
51
- return m_isSubscribed;
52
- }
56
+ bool IsSubscribed() const noexcept {
57
+ return GetHandler() != nullptr;
58
+ }
53
59
 
54
- void ReactNotificationSubscription::Unsubscribe() noexcept {
55
- if (m_parentSubscription) {
56
- m_parentSubscription.Unsubscribe();
60
+ void Unsubscribe() noexcept {
61
+ if (m_parentSubscription) {
62
+ m_parentSubscription.Unsubscribe();
63
+ }
64
+
65
+ bool isSubscribed{false};
66
+ {
67
+ std::scoped_lock lock{*m_mutex};
68
+ if (m_handler) {
69
+ isSubscribed = true;
70
+ // Remove handler to free any objects captured by it.
71
+ m_handler = nullptr;
72
+ }
73
+ }
74
+
75
+ if (isSubscribed) {
76
+ if (auto notificationService = m_notificationService.get()) {
77
+ notificationService->Unsubscribe(*this);
78
+ }
79
+ }
80
+ }
81
+
82
+ public: // IReactNotificationSubscriptionPrivate implementation
83
+ void SetParent(IReactNotificationSubscription const &parentSubscription) noexcept override {
84
+ m_parentSubscription = parentSubscription;
57
85
  }
58
86
 
59
- if (m_isSubscribed.exchange(false)) {
60
- if (auto notificationService = m_notificationService.get()) {
61
- notificationService->Unsubscribe(*this);
87
+ void CallHandler(IInspectable const &sender, IInspectable const &data) noexcept override {
88
+ auto args = make<ReactNotificationArgs>(*this, data);
89
+ if (auto handler = GetHandler()) {
90
+ if (m_dispatcher) {
91
+ m_dispatcher.Post([thisPtr = get_strong(), sender, args]() noexcept {
92
+ if (auto handler = thisPtr->GetHandler()) {
93
+ handler(sender, args);
94
+ }
95
+ });
96
+ } else {
97
+ handler(sender, args);
98
+ }
62
99
  }
63
100
  }
64
- }
65
101
 
66
- void ReactNotificationSubscription::CallHandler(
67
- IInspectable const &sender,
68
- IReactNotificationArgs const &args) noexcept {
69
- VerifyElseCrashSz(!m_parentSubscription, "CallHandler must not be called on the child subscription.");
70
- if (IsSubscribed()) {
71
- if (m_dispatcher) {
72
- m_dispatcher.Post([thisPtr = get_strong(), sender, args]() noexcept {
73
- if (thisPtr->IsSubscribed()) {
74
- thisPtr->m_handler(sender, args);
75
- }
76
- });
102
+ private:
103
+ ReactNotificationHandler GetHandler() const noexcept {
104
+ std::scoped_lock lock{*m_mutex};
105
+ return m_handler;
106
+ }
107
+
108
+ private:
109
+ Mso::RefCountedPtr<std::mutex> m_mutex;
110
+ IReactNotificationSubscription m_parentSubscription{nullptr};
111
+ const weak_ref<ReactNotificationService> m_notificationService{nullptr};
112
+ const IReactPropertyName m_notificationName{nullptr};
113
+ const IReactDispatcher m_dispatcher{nullptr};
114
+ ReactNotificationHandler m_handler{nullptr};
115
+ };
116
+
117
+ // The notification subscription view to wrap up child notification service.
118
+ // Instances of this class are stored in the parent notification services.
119
+ struct ReactNotificationSubscriptionView : implements<
120
+ ReactNotificationSubscriptionView,
121
+ IReactNotificationSubscription,
122
+ IReactNotificationSubscriptionPrivate> {
123
+ ReactNotificationSubscriptionView(
124
+ weak_ref<ReactNotificationService> &&notificationService,
125
+ IReactNotificationSubscription const &childSubscription) noexcept
126
+ : m_notificationService{std::move(notificationService)}, m_childSubscription{weak_ref(childSubscription)} {
127
+ childSubscription.as<IReactNotificationSubscriptionPrivate>()->SetParent(*this);
128
+ }
129
+
130
+ ~ReactNotificationSubscriptionView() noexcept {
131
+ Unsubscribe();
132
+ }
133
+
134
+ public: // IReactNotificationSubscription implementation
135
+ IReactNotificationService NotificationService() const noexcept {
136
+ return m_notificationService.get().as<IReactNotificationService>();
137
+ }
138
+
139
+ IReactPropertyName NotificationName() const noexcept {
140
+ if (auto childSubscription = m_childSubscription.get()) {
141
+ return childSubscription.NotificationName();
77
142
  } else {
78
- m_handler(sender, args);
143
+ return IReactPropertyName{nullptr};
79
144
  }
80
145
  }
81
- }
146
+
147
+ IReactDispatcher Dispatcher() const noexcept {
148
+ if (auto childSubscription = m_childSubscription.get()) {
149
+ return childSubscription.Dispatcher();
150
+ } else {
151
+ return IReactDispatcher{nullptr};
152
+ }
153
+ }
154
+
155
+ bool IsSubscribed() const noexcept {
156
+ return m_isSubscribed;
157
+ }
158
+
159
+ void Unsubscribe() noexcept {
160
+ if (m_parentSubscription) {
161
+ m_parentSubscription.Unsubscribe();
162
+ }
163
+
164
+ if (m_isSubscribed.exchange(false)) {
165
+ if (auto notificationService = m_notificationService.get()) {
166
+ notificationService->Unsubscribe(*this);
167
+ }
168
+ }
169
+ }
170
+
171
+ public: // IReactNotificationSubscriptionPrivate implementation
172
+ void SetParent(IReactNotificationSubscription const &parentSubscription) noexcept override {
173
+ m_parentSubscription = parentSubscription;
174
+ }
175
+
176
+ void CallHandler(IInspectable const &sender, IInspectable const &data) noexcept override {
177
+ if (auto childSubscription = m_childSubscription.get()) {
178
+ childSubscription.as<IReactNotificationSubscriptionPrivate>()->CallHandler(sender, data);
179
+ }
180
+ }
181
+
182
+ private:
183
+ IReactNotificationSubscription m_parentSubscription{nullptr};
184
+ const weak_ref<IReactNotificationSubscription> m_childSubscription{nullptr};
185
+ const weak_ref<ReactNotificationService> m_notificationService{nullptr};
186
+ std::atomic_bool m_isSubscribed{true};
187
+ };
82
188
 
83
189
  //=============================================================================
84
190
  // ReactNotificationService implementation
@@ -99,7 +205,7 @@ void ReactNotificationService::ModifySubscriptions(
99
205
  // Get the current snapshot under the lock
100
206
  SubscriptionSnapshotPtr currentSnapshotPtr;
101
207
  {
102
- std::scoped_lock lock{m_mutex};
208
+ std::scoped_lock lock{*m_mutex};
103
209
  auto it = m_subscriptions.find(notificationName);
104
210
  if (it != m_subscriptions.end()) {
105
211
  currentSnapshotPtr = it->second;
@@ -113,7 +219,7 @@ void ReactNotificationService::ModifySubscriptions(
113
219
 
114
220
  // Try to set the new snapshot under the lock
115
221
  SubscriptionSnapshotPtr snapshotPtr;
116
- std::scoped_lock lock{m_mutex};
222
+ std::scoped_lock lock{*m_mutex};
117
223
  auto it = m_subscriptions.find(notificationName);
118
224
  if (it != m_subscriptions.end()) {
119
225
  snapshotPtr = it->second;
@@ -146,20 +252,42 @@ IReactNotificationSubscription ReactNotificationService::Subscribe(
146
252
  IReactPropertyName const &notificationName,
147
253
  IReactDispatcher const &dispatcher,
148
254
  ReactNotificationHandler const &handler) noexcept {
149
- // Make sure that parent notification service also subscribes to this notification.
150
- auto parentSubscription = m_parentNotificationService
151
- ? m_parentNotificationService.Subscribe(notificationName, dispatcher, handler)
152
- : IReactNotificationSubscription{nullptr};
153
- auto subscription = parentSubscription
154
- ? make<ReactNotificationSubscription>(parentSubscription, get_weak(), notificationName, dispatcher)
155
- : make<ReactNotificationSubscription>(get_weak(), notificationName, dispatcher, handler);
255
+ VerifyElseCrashSz(notificationName, "notificationName must be not null");
256
+ VerifyElseCrashSz(handler, "handler must be not null");
257
+
258
+ IReactNotificationSubscription subscription =
259
+ make<ReactNotificationSubscription>(m_mutex, get_weak(), notificationName, dispatcher, handler);
260
+ AddSubscription(notificationName, subscription);
261
+ AddSubscriptionToParent(notificationName, subscription);
262
+ return subscription;
263
+ }
264
+
265
+ void ReactNotificationService::AddSubscription(
266
+ IReactPropertyName const &notificationName,
267
+ IReactNotificationSubscription const &subscription) noexcept {
156
268
  ModifySubscriptions(
157
269
  notificationName, [&subscription](std::vector<IReactNotificationSubscription> const &snapshot) noexcept {
158
270
  auto newSnapshot = std::vector<IReactNotificationSubscription>(snapshot);
159
271
  newSnapshot.push_back(subscription);
160
272
  return newSnapshot;
161
273
  });
162
- return subscription;
274
+ }
275
+
276
+ void ReactNotificationService::AddSubscriptionToParent(
277
+ IReactPropertyName const &notificationName,
278
+ IReactNotificationSubscription const &subscription) noexcept {
279
+ if (m_parentNotificationService) {
280
+ get_self<ReactNotificationService>(m_parentNotificationService)
281
+ ->AddSubscriptionFromChild(notificationName, subscription);
282
+ }
283
+ }
284
+
285
+ void ReactNotificationService::AddSubscriptionFromChild(
286
+ IReactPropertyName const &notificationName,
287
+ IReactNotificationSubscription const &childSubscription) noexcept {
288
+ auto subscription = make<ReactNotificationSubscriptionView>(get_weak(), childSubscription);
289
+ AddSubscription(notificationName, subscription);
290
+ AddSubscriptionToParent(notificationName, subscription);
163
291
  }
164
292
 
165
293
  void ReactNotificationService::Unsubscribe(IReactNotificationSubscription const &subscription) noexcept {
@@ -180,7 +308,7 @@ void ReactNotificationService::UnsubscribeAll() noexcept {
180
308
  // The subscription will call the parent Unsubscribe on its own.
181
309
  decltype(m_subscriptions) subscriptions;
182
310
  {
183
- std::scoped_lock lock{m_mutex};
311
+ std::scoped_lock lock{*m_mutex};
184
312
  subscriptions = std::move(m_subscriptions);
185
313
  }
186
314
 
@@ -203,7 +331,7 @@ void ReactNotificationService::SendNotification(
203
331
  SubscriptionSnapshotPtr currentSnapshotPtr;
204
332
 
205
333
  {
206
- std::scoped_lock lock{m_mutex};
334
+ std::scoped_lock lock{*m_mutex};
207
335
  auto it = m_subscriptions.find(notificationName);
208
336
  if (it != m_subscriptions.end()) {
209
337
  currentSnapshotPtr = it->second;
@@ -213,8 +341,7 @@ void ReactNotificationService::SendNotification(
213
341
  // Call notification handlers outside of lock.
214
342
  if (currentSnapshotPtr) {
215
343
  for (auto &subscription : *currentSnapshotPtr) {
216
- auto args = make<ReactNotificationArgs>(subscription, data);
217
- get_self<ReactNotificationSubscription>(subscription)->CallHandler(sender, args);
344
+ subscription.as<IReactNotificationSubscriptionPrivate>()->CallHandler(sender, data);
218
345
  }
219
346
  }
220
347
  }
@@ -91,9 +91,19 @@ struct ReactNotificationService : implements<ReactNotificationService, IReactNot
91
91
  IReactPropertyName const &notificationName,
92
92
  Mso::FunctorRef<SubscriptionSnapshot(SubscriptionSnapshot const &)> const &modifySnapshot);
93
93
 
94
+ void AddSubscription(
95
+ IReactPropertyName const &notificationName,
96
+ IReactNotificationSubscription const &subscription) noexcept;
97
+ void AddSubscriptionToParent(
98
+ IReactPropertyName const &notificationName,
99
+ IReactNotificationSubscription const &subscription) noexcept;
100
+ void AddSubscriptionFromChild(
101
+ IReactPropertyName const &notificationName,
102
+ IReactNotificationSubscription const &childSubscription) noexcept;
103
+
94
104
  private:
95
105
  const IReactNotificationService m_parentNotificationService;
96
- std::mutex m_mutex;
106
+ Mso::RefCountedPtr<std::mutex> m_mutex{Mso::Make_RefCounted<std::mutex>()};
97
107
  std::unordered_map<IReactPropertyName, SubscriptionSnapshotPtr> m_subscriptions;
98
108
  };
99
109
 
@@ -103,35 +113,6 @@ struct ReactNotificationServiceHelper {
103
113
  static IReactNotificationService CreateNotificationService() noexcept;
104
114
  };
105
115
 
106
- struct ReactNotificationSubscription : implements<ReactNotificationSubscription, IReactNotificationSubscription> {
107
- ReactNotificationSubscription(
108
- IReactNotificationSubscription const &parentSubscription,
109
- weak_ref<ReactNotificationService> &&notificationService,
110
- IReactPropertyName const &notificationName,
111
- IReactDispatcher const &dispatcher) noexcept;
112
- ReactNotificationSubscription(
113
- weak_ref<ReactNotificationService> &&notificationService,
114
- IReactPropertyName const &notificationName,
115
- IReactDispatcher const &dispatcher,
116
- ReactNotificationHandler const &handler) noexcept;
117
- ~ReactNotificationSubscription() noexcept;
118
-
119
- IReactNotificationService NotificationService() const noexcept;
120
- IReactPropertyName NotificationName() const noexcept;
121
- IReactDispatcher Dispatcher() const noexcept;
122
- bool IsSubscribed() const noexcept;
123
- void Unsubscribe() noexcept;
124
- void CallHandler(IInspectable const &sender, IReactNotificationArgs const &args) noexcept;
125
-
126
- private:
127
- const IReactNotificationSubscription m_parentSubscription{nullptr};
128
- const weak_ref<ReactNotificationService> m_notificationService;
129
- const IReactPropertyName m_notificationName;
130
- const IReactDispatcher m_dispatcher;
131
- const ReactNotificationHandler m_handler;
132
- std::atomic_bool m_isSubscribed{true};
133
- };
134
-
135
116
  } // namespace winrt::Microsoft::ReactNative::implementation
136
117
 
137
118
  namespace winrt::Microsoft::ReactNative::factory_implementation {
@@ -8,35 +8,57 @@
8
8
 
9
9
  namespace winrt::Microsoft::ReactNative {
10
10
 
11
+ // Special IJSValueWriter that does nothing.
12
+ // We use it instead of JsiWriter when JSI runtime is not available anymore.
13
+ struct JSNoopWriter : winrt::implements<JSNoopWriter, IJSValueWriter> {
14
+ public: // IJSValueWriter
15
+ void WriteNull() noexcept;
16
+ void WriteBoolean(bool value) noexcept;
17
+ void WriteInt64(int64_t value) noexcept;
18
+ void WriteDouble(double value) noexcept;
19
+ void WriteString(const winrt::hstring &value) noexcept;
20
+ void WriteObjectBegin() noexcept;
21
+ void WritePropertyName(const winrt::hstring &name) noexcept;
22
+ void WriteObjectEnd() noexcept;
23
+ void WriteArrayBegin() noexcept;
24
+ void WriteArrayEnd() noexcept;
25
+ };
26
+
11
27
  //===========================================================================
12
28
  // JSDispatcherWriter implementation
13
29
  //===========================================================================
14
30
 
15
31
  JSDispatcherWriter::JSDispatcherWriter(
16
32
  IReactDispatcher const &jsDispatcher,
17
- facebook::jsi::Runtime &jsiRuntime) noexcept
18
- : m_jsDispatcher(jsDispatcher), m_jsiRuntime(jsiRuntime) {}
33
+ std::weak_ptr<LongLivedJsiRuntime> jsiRuntimeHolder) noexcept
34
+ : m_jsDispatcher(jsDispatcher), m_jsiRuntimeHolder(std::move(jsiRuntimeHolder)) {}
19
35
 
20
36
  void JSDispatcherWriter::WithResultArgs(
21
37
  Mso::Functor<void(facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t argCount)>
22
38
  handler) noexcept {
23
39
  if (m_jsDispatcher.HasThreadAccess()) {
24
40
  VerifyElseCrash(!m_dynamicWriter);
25
- const facebook::jsi::Value *args{nullptr};
26
- size_t argCount{0};
27
- m_jsiWriter->AccessResultAsArgs(args, argCount);
28
- handler(m_jsiRuntime, args, argCount);
41
+ if (auto jsiRuntimeHolder = m_jsiRuntimeHolder.lock()) {
42
+ const facebook::jsi::Value *args{nullptr};
43
+ size_t argCount{0};
44
+ m_jsiWriter->AccessResultAsArgs(args, argCount);
45
+ handler(jsiRuntimeHolder->Runtime(), args, argCount);
46
+ m_jsiWriter = nullptr;
47
+ }
29
48
  } else {
30
49
  VerifyElseCrash(!m_jsiWriter);
31
50
  folly::dynamic dynValue = m_dynamicWriter->TakeValue();
32
- m_jsDispatcher.Post([handler, dynValue, &runtime = m_jsiRuntime]() {
33
- VerifyElseCrash(dynValue.isArray());
34
- std::vector<facebook::jsi::Value> args;
35
- args.reserve(dynValue.size());
36
- for (auto const &item : dynValue) {
37
- args.emplace_back(facebook::jsi::valueFromDynamic(runtime, item));
51
+ VerifyElseCrash(dynValue.isArray());
52
+ m_jsDispatcher.Post([handler, dynValue = std::move(dynValue), weakJsiRuntimeHolder = m_jsiRuntimeHolder]() {
53
+ if (auto jsiRuntimeHolder = weakJsiRuntimeHolder.lock()) {
54
+ std::vector<facebook::jsi::Value> args;
55
+ args.reserve(dynValue.size());
56
+ auto &runtime = jsiRuntimeHolder->Runtime();
57
+ for (auto const &item : dynValue) {
58
+ args.emplace_back(facebook::jsi::valueFromDynamic(runtime, item));
59
+ }
60
+ handler(runtime, args.data(), args.size());
38
61
  }
39
- handler(runtime, args.data(), args.size());
40
62
  });
41
63
  }
42
64
  }
@@ -82,20 +104,36 @@ void JSDispatcherWriter::WriteArrayEnd() noexcept {
82
104
  }
83
105
 
84
106
  IJSValueWriter JSDispatcherWriter::GetWriter() noexcept {
85
- if (m_jsDispatcher.HasThreadAccess()) {
86
- VerifyElseCrash(!m_dynamicWriter);
87
- if (!m_jsiWriter) {
88
- m_jsiWriter = winrt::make_self<JsiWriter>(m_jsiRuntime);
89
- m_writer = m_jsiWriter.as<IJSValueWriter>();
90
- }
91
- } else {
92
- VerifyElseCrash(!m_jsiWriter);
93
- if (!m_dynamicWriter) {
107
+ if (!m_writer) {
108
+ if (m_jsDispatcher.HasThreadAccess()) {
109
+ if (auto jsiRuntimeHolder = m_jsiRuntimeHolder.lock()) {
110
+ m_jsiWriter = winrt::make_self<JsiWriter>(jsiRuntimeHolder->Runtime());
111
+ m_writer = m_jsiWriter.as<IJSValueWriter>();
112
+ } else {
113
+ m_writer = winrt::make<JSNoopWriter>();
114
+ }
115
+ } else {
94
116
  m_dynamicWriter = winrt::make_self<DynamicWriter>();
95
117
  m_writer = m_dynamicWriter.as<IJSValueWriter>();
96
118
  }
97
119
  }
120
+ Debug(VerifyElseCrash(m_dynamicWriter != nullptr || m_jsDispatcher.HasThreadAccess()));
98
121
  return m_writer;
99
122
  }
100
123
 
124
+ //===========================================================================
125
+ // JSNoopWriter implementation
126
+ //===========================================================================
127
+
128
+ void JSNoopWriter::WriteNull() noexcept {}
129
+ void JSNoopWriter::WriteBoolean(bool /*value*/) noexcept {}
130
+ void JSNoopWriter::WriteInt64(int64_t /*value*/) noexcept {}
131
+ void JSNoopWriter::WriteDouble(double /*value*/) noexcept {}
132
+ void JSNoopWriter::WriteString(const winrt::hstring & /*value*/) noexcept {}
133
+ void JSNoopWriter::WriteObjectBegin() noexcept {}
134
+ void JSNoopWriter::WritePropertyName(const winrt::hstring & /*name*/) noexcept {}
135
+ void JSNoopWriter::WriteObjectEnd() noexcept {}
136
+ void JSNoopWriter::WriteArrayBegin() noexcept {}
137
+ void JSNoopWriter::WriteArrayEnd() noexcept {}
138
+
101
139
  } // namespace winrt::Microsoft::ReactNative
@@ -2,10 +2,10 @@
2
2
  // Licensed under the MIT License.
3
3
  #pragma once
4
4
 
5
+ #include <JSI/LongLivedJsiValue.h>
5
6
  #include <functional/functor.h>
6
7
  #include "DynamicWriter.h"
7
8
  #include "JsiWriter.h"
8
- #include "folly/dynamic.h"
9
9
  #include "winrt/Microsoft.ReactNative.h"
10
10
 
11
11
  namespace winrt::Microsoft::ReactNative {
@@ -14,7 +14,9 @@ namespace winrt::Microsoft::ReactNative {
14
14
  // In case if writing is done outside of JSDispatcher, it uses DynamicWriter to create
15
15
  // folly::dynamic which then is written to JsiWriter in JSDispatcher.
16
16
  struct JSDispatcherWriter : winrt::implements<JSDispatcherWriter, IJSValueWriter> {
17
- JSDispatcherWriter(IReactDispatcher const &jsDispatcher, facebook::jsi::Runtime &jsiRuntime) noexcept;
17
+ JSDispatcherWriter(
18
+ IReactDispatcher const &jsDispatcher,
19
+ std::weak_ptr<LongLivedJsiRuntime> jsiRuntimeHolder) noexcept;
18
20
  void WithResultArgs(Mso::Functor<void(facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t argCount)>
19
21
  handler) noexcept;
20
22
 
@@ -35,7 +37,7 @@ struct JSDispatcherWriter : winrt::implements<JSDispatcherWriter, IJSValueWriter
35
37
 
36
38
  private:
37
39
  IReactDispatcher m_jsDispatcher;
38
- facebook::jsi::Runtime &m_jsiRuntime;
40
+ std::weak_ptr<LongLivedJsiRuntime> m_jsiRuntimeHolder;
39
41
  winrt::com_ptr<DynamicWriter> m_dynamicWriter;
40
42
  winrt::com_ptr<JsiWriter> m_jsiWriter;
41
43
  IJSValueWriter m_writer;
@@ -132,7 +132,8 @@ struct BridgeUIBatchInstanceCallback final : public facebook::react::InstanceCal
132
132
  virtual ~BridgeUIBatchInstanceCallback() = default;
133
133
  void onBatchComplete() override {
134
134
  if (auto instance = m_wkInstance.GetStrongPtr()) {
135
- if (instance->IsLoaded()) {
135
+ auto state = instance->State();
136
+ if (state != ReactInstanceState::HasError && state != ReactInstanceState::Unloaded) {
136
137
  if (instance->UseWebDebugger()) {
137
138
  // While using a CxxModule for UIManager (which we do when running under webdebugger)
138
139
  // We need to post the batch complete to the NativeQueue to ensure that the UIManager
@@ -510,6 +511,7 @@ void ReactInstanceWin::Initialize() noexcept {
510
511
  std::move(bundleRootPath), // bundleRootPath
511
512
  std::move(cxxModules),
512
513
  m_options.TurboModuleProvider,
514
+ m_options.TurboModuleProvider->LongLivedObjectCollection(),
513
515
  std::make_unique<BridgeUIBatchInstanceCallback>(weakThis),
514
516
  m_jsMessageThread.Load(),
515
517
  m_nativeMessageThread.Load(),