react-native-windows 0.64.25 → 0.64.29

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 (42) hide show
  1. package/CHANGELOG.json +109 -1
  2. package/CHANGELOG.md +44 -4
  3. package/Chakra/Chakra.vcxitems +0 -1
  4. package/Chakra/Chakra.vcxitems.filters +0 -3
  5. package/Chakra/ChakraHelpers.cpp +0 -267
  6. package/Chakra/ChakraInstanceArgs.h +0 -5
  7. package/Chakra/ChakraPlatform.h +0 -4
  8. package/Chakra/ChakraTracing.cpp +0 -33
  9. package/Chakra/ChakraValue.h +0 -4
  10. package/Chakra/Utf8DebugExtensions.cpp +0 -5
  11. package/Chakra/Utf8DebugExtensions.h +0 -6
  12. package/JSI/Desktop/JSI.Desktop.vcxproj +0 -3
  13. package/JSI/Desktop/JSI.Desktop.vcxproj.filters +0 -5
  14. package/JSI/Shared/ChakraApi.cpp +1 -37
  15. package/JSI/Shared/ChakraApi.h +0 -4
  16. package/JSI/Shared/ChakraJsiRuntime_edgemode.cpp +1 -5
  17. package/JSI/Shared/ChakraRuntime.cpp +0 -12
  18. package/JSI/Shared/ChakraRuntimeFactory.h +0 -2
  19. package/Libraries/Components/Pressable/Pressable.windows.js +33 -0
  20. package/Libraries/Pressability/HoverState.js +4 -2
  21. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -2
  22. package/Microsoft.ReactNative/Modules/CreateModules.cpp +2 -2
  23. package/Microsoft.ReactNative/ReactCoreInjection.cpp +4 -11
  24. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +16 -10
  25. package/Microsoft.ReactNative/ReactHost/ReactHost.h +2 -2
  26. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +25 -17
  27. package/Microsoft.ReactNative/TurboModulesProvider.cpp +1 -13
  28. package/Microsoft.ReactNative/TurboModulesProvider.h +0 -1
  29. package/Mso/future/futureWinRT.h +7 -5
  30. package/PropertySheets/React.Cpp.props +2 -0
  31. package/Shared/IWebSocketResource.h +6 -6
  32. package/Shared/Modules/WebSocketModule.cpp +134 -117
  33. package/Shared/Modules/WebSocketModule.h +22 -12
  34. package/Shared/OInstance.cpp +12 -109
  35. package/Shared/WinRTWebSocketResource.cpp +55 -46
  36. package/Shared/WinRTWebSocketResource.h +2 -9
  37. package/package.json +1 -1
  38. package/Chakra/ChakraCoreDebugger.h +0 -147
  39. package/JSI/Desktop/ChakraJsiRuntime_core.cpp +0 -322
  40. package/JSI/Shared/ChakraCoreRuntime.h +0 -59
  41. package/Scripts/Microsoft.ChakraCore.ARM64.nuspec +0 -50
  42. package/Scripts/Microsoft.ChakraCore.ARM64.targets +0 -15
@@ -144,17 +144,9 @@ ChakraApi::JsRefHolder::~JsRefHolder() noexcept {
144
144
  JsPropertyIdRef propertyId{JS_INVALID_REFERENCE};
145
145
  // We use a #ifdef here because we can avoid a UTF-8 to UTF-16 conversion
146
146
  // using ChakraCore's JsCreatePropertyId API.
147
- #ifdef CHAKRACORE
148
- if (React::GetRuntimeOptionBool("JSI.ForceSystemChakra")) {
149
- std::wstring utf16 = Common::Unicode::Utf8ToUtf16(name.data(), name.length());
150
- ChakraVerifyJsErrorElseThrow(JsGetPropertyIdFromName(utf16.data(), &propertyId));
151
- } else {
152
- ChakraVerifyJsErrorElseThrow(JsCreatePropertyId(name.data(), name.length(), &propertyId));
153
- }
154
- #else
155
147
  std::wstring utf16 = Common::Unicode::Utf8ToUtf16(name.data(), name.length());
156
148
  ChakraVerifyJsErrorElseThrow(JsGetPropertyIdFromName(utf16.data(), &propertyId));
157
- #endif
149
+
158
150
  return propertyId;
159
151
  }
160
152
 
@@ -275,18 +267,7 @@ ChakraApi::JsRefHolder::~JsRefHolder() noexcept {
275
267
  /*static*/ JsValueRef ChakraApi::PointerToString(std::string_view value) {
276
268
  ChakraVerifyElseThrow(value.data(), "Cannot convert a nullptr to a JS string.");
277
269
 
278
- // ChakraCore API helps to reduce cost of UTF-8 to UTF-16 conversion.
279
- #ifdef CHAKRACORE
280
- if (React::GetRuntimeOptionBool("JSI.ForceSystemChakra")) {
281
- return PointerToString(Common::Unicode::Utf8ToUtf16(value));
282
- } else {
283
- JsValueRef result{JS_INVALID_REFERENCE};
284
- ChakraVerifyJsErrorElseThrow(JsCreateString(value.data(), value.length(), &result));
285
- return result;
286
- }
287
- #else
288
270
  return PointerToString(Common::Unicode::Utf8ToUtf16(value));
289
- #endif
290
271
  }
291
272
 
292
273
  /*static*/ std::wstring_view ChakraApi::StringToPointer(JsValueRef string) {
@@ -300,24 +281,7 @@ ChakraApi::JsRefHolder::~JsRefHolder() noexcept {
300
281
  ChakraVerifyElseThrow(
301
282
  GetValueType(string) == JsString, "Cannot convert a non JS string ChakraObjectRef to a std::string.");
302
283
 
303
- // We use a #ifdef here because we can avoid a UTF-8 to UTF-16 conversion
304
- // using ChakraCore's JsCopyString API.
305
- #ifdef CHAKRACORE
306
- if (React::GetRuntimeOptionBool("JSI.ForceSystemChakra")) {
307
- return Common::Unicode::Utf16ToUtf8(StringToPointer(string));
308
- } else {
309
- size_t length{0};
310
- ChakraVerifyJsErrorElseThrow(JsCopyString(string, nullptr, 0, &length));
311
-
312
- std::string result(length, 'a');
313
- ChakraVerifyJsErrorElseThrow(JsCopyString(string, result.data(), result.length(), &length));
314
-
315
- ChakraVerifyElseThrow(length == result.length(), "Failed to convert a JS string to a std::string.");
316
- return result;
317
- }
318
- #else
319
284
  return Common::Unicode::Utf16ToUtf8(StringToPointer(string));
320
- #endif
321
285
  }
322
286
 
323
287
  /*static*/ JsValueRef ChakraApi::ConvertValueToString(JsValueRef value) {
@@ -3,14 +3,10 @@
3
3
 
4
4
  #pragma once
5
5
 
6
- #ifdef CHAKRACORE
7
- #include "ChakraCore.h"
8
- #else
9
6
  #ifndef USE_EDGEMODE_JSRT
10
7
  #define USE_EDGEMODE_JSRT
11
8
  #endif
12
9
  #include <jsrt.h>
13
- #endif
14
10
 
15
11
  #include <cassert>
16
12
  #include <cstddef>
@@ -15,7 +15,7 @@ JsStartDebugging();
15
15
 
16
16
  namespace Microsoft::JSI {
17
17
 
18
- #if defined(USE_EDGEMODE_JSRT) && !defined(CHAKRACORE)
18
+ #if defined(USE_EDGEMODE_JSRT)
19
19
  /*static*/ void ChakraRuntime::initRuntimeVersion() noexcept {}
20
20
  #endif
21
21
 
@@ -42,11 +42,7 @@ std::unique_ptr<const facebook::jsi::Buffer> SystemChakraRuntime::generatePrepar
42
42
  const std::wstring scriptUTF16 =
43
43
  Microsoft::Common::Unicode::Utf8ToUtf16(reinterpret_cast<const char *>(sourceBuffer.data()), sourceBuffer.size());
44
44
 
45
- #ifdef CHAKRACORE
46
- unsigned int bytecodeSize = 0;
47
- #else
48
45
  unsigned long bytecodeSize = 0;
49
- #endif
50
46
  if (JsSerializeScript(scriptUTF16.c_str(), nullptr, &bytecodeSize) == JsNoError) {
51
47
  std::unique_ptr<ByteArrayBuffer> bytecodeBuffer(std::make_unique<ByteArrayBuffer>(bytecodeSize));
52
48
  if (JsSerializeScript(scriptUTF16.c_str(), bytecodeBuffer->data(), &bytecodeSize) == JsNoError) {
@@ -17,14 +17,10 @@
17
17
  #include <sstream>
18
18
  #include <unordered_set>
19
19
 
20
- #ifdef CHAKRACORE
21
- #include <ChakraCore.h>
22
- #else
23
20
  #ifndef USE_EDGEMODE_JSRT
24
21
  #define USE_EDGEMODE_JSRT
25
22
  #endif
26
23
  #include <jsrt.h>
27
- #endif
28
24
 
29
25
  namespace Microsoft::JSI {
30
26
 
@@ -1027,15 +1023,7 @@ std::once_flag ChakraRuntime::s_runtimeVersionInitFlag;
1027
1023
  uint64_t ChakraRuntime::s_runtimeVersion = 0;
1028
1024
 
1029
1025
  std::unique_ptr<facebook::jsi::Runtime> makeChakraRuntime(ChakraRuntimeArgs &&args) noexcept {
1030
- #ifdef CHAKRACORE
1031
- if (React::GetRuntimeOptionBool("JSI.ForceSystemChakra")) {
1032
- return MakeSystemChakraRuntime(std::move(args));
1033
- } else {
1034
- return MakeChakraCoreRuntime(std::move(args));
1035
- }
1036
- #else
1037
1026
  return MakeSystemChakraRuntime(std::move(args));
1038
- #endif // CHAKRACORE
1039
1027
  }
1040
1028
 
1041
1029
  } // namespace Microsoft::JSI
@@ -11,7 +11,5 @@ struct ChakraRuntimeArgs;
11
11
 
12
12
  std::unique_ptr<facebook::jsi::Runtime> makeChakraRuntime(ChakraRuntimeArgs &&args) noexcept;
13
13
 
14
- std::unique_ptr<facebook::jsi::Runtime> MakeChakraCoreRuntime(ChakraRuntimeArgs &&args) noexcept;
15
-
16
14
  std::unique_ptr<facebook::jsi::Runtime> MakeSystemChakraRuntime(ChakraRuntimeArgs &&args) noexcept;
17
15
  } // namespace Microsoft::JSI
@@ -29,6 +29,7 @@ import type {
29
29
  LayoutEvent,
30
30
  PressEvent,
31
31
  // [Windows
32
+ MouseEvent,
32
33
  BlurEvent,
33
34
  FocusEvent, // Windows]
34
35
  } from '../../Types/CoreEventTypes';
@@ -66,6 +67,16 @@ type Props = $ReadOnly<{|
66
67
  */
67
68
  children: React.Node | ((state: StateCallbackType) => React.Node),
68
69
 
70
+ /**
71
+ * Duration to wait after hover in before calling `onHoverIn`.
72
+ */
73
+ delayHoverIn?: ?number,
74
+
75
+ /**
76
+ * Duration to wait after hover out before calling `onHoverOut`.
77
+ */
78
+ delayHoverOut?: ?number,
79
+
69
80
  /**
70
81
  * Duration (in milliseconds) from `onPressIn` before `onLongPress` is called.
71
82
  */
@@ -92,6 +103,16 @@ type Props = $ReadOnly<{|
92
103
  */
93
104
  onLayout?: ?(event: LayoutEvent) => void,
94
105
 
106
+ /**
107
+ * Called when the hover is activated to provide visual feedback.
108
+ */
109
+ onHoverIn?: ?(event: MouseEvent) => mixed,
110
+
111
+ /**
112
+ * Called when the hover is deactivated to undo visual feedback.
113
+ */
114
+ onHoverOut?: ?(event: MouseEvent) => mixed,
115
+
95
116
  /**
96
117
  * Called when a long-tap gesture is detected.
97
118
  */
@@ -164,9 +185,13 @@ function Pressable(props: Props, forwardedRef): React.Node {
164
185
  android_disableSound,
165
186
  android_ripple,
166
187
  children,
188
+ delayHoverIn,
189
+ delayHoverOut,
167
190
  delayLongPress,
168
191
  disabled,
169
192
  focusable,
193
+ onHoverIn,
194
+ onHoverOut,
170
195
  onLongPress,
171
196
  onPress,
172
197
  onPressIn,
@@ -221,8 +246,12 @@ function Pressable(props: Props, forwardedRef): React.Node {
221
246
  hitSlop,
222
247
  pressRectOffset: pressRetentionOffset,
223
248
  android_disableSound,
249
+ delayHoverIn,
250
+ delayHoverOut,
224
251
  delayLongPress,
225
252
  delayPressIn: unstable_pressDelay,
253
+ onHoverIn,
254
+ onHoverOut,
226
255
  onLongPress,
227
256
  onPress,
228
257
  onPressIn(event: PressEvent): void {
@@ -252,9 +281,13 @@ function Pressable(props: Props, forwardedRef): React.Node {
252
281
  [
253
282
  android_disableSound,
254
283
  android_rippleConfig,
284
+ delayHoverIn,
285
+ delayHoverOut,
255
286
  delayLongPress,
256
287
  disabled,
257
288
  hitSlop,
289
+ onHoverIn,
290
+ onHoverOut,
258
291
  onLongPress,
259
292
  onPress,
260
293
  onPressIn,
@@ -8,8 +8,6 @@
8
8
  * @format
9
9
  */
10
10
 
11
- 'use strict';
12
-
13
11
  import Platform from '../Utilities/Platform';
14
12
 
15
13
  let isEnabled = false;
@@ -51,6 +49,10 @@ if (Platform.OS === 'web') {
51
49
  document.addEventListener('touchmove', disableHover, true);
52
50
  document.addEventListener('mousemove', enableHover, true);
53
51
  }
52
+ // [Windows
53
+ } else if (Platform.OS === 'windows') {
54
+ isEnabled = true;
55
+ // Windows]
54
56
  }
55
57
 
56
58
  export function isHoverEnabled(): boolean {
@@ -123,8 +123,6 @@
123
123
  REACTWINDOWS_BUILD - building with REACTWINDOWS_API as dll exports
124
124
  OLD_CPPWINRT is a workaround to make target version to 19H1
125
125
  -->
126
- <PreprocessorDefinitions Condition="'$(CHAKRACOREUWP)'=='true'">CHAKRACORE;CHAKRACORE_UWP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
127
- <PreprocessorDefinitions Condition="'$(CHAKRACOREUWP)'!='true'">USE_EDGEMODE_JSRT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
128
126
  <PreprocessorDefinitions>
129
127
  REACTWINDOWS_BUILD;
130
128
  RN_PLATFORM=windows;
@@ -21,9 +21,9 @@ using winrt::Microsoft::ReactNative::implementation::QuirkSettings;
21
21
 
22
22
  namespace Microsoft::React {
23
23
 
24
- std::shared_ptr<IWebSocketResource> IWebSocketResource::Make(std::string &&urlString) {
24
+ std::shared_ptr<IWebSocketResource> IWebSocketResource::Make() {
25
25
  std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> certExceptions;
26
- return std::make_shared<WinRTWebSocketResource>(std::move(urlString), std::move(certExceptions));
26
+ return std::make_shared<WinRTWebSocketResource>(std::move(certExceptions));
27
27
  }
28
28
 
29
29
  std::unique_ptr<facebook::xplat::module::CxxModule> CreateWebSocketModule(
@@ -141,14 +141,9 @@ struct ReactViewInstance : public Mso::UnknownObject<Mso::RefCountStrategy::Weak
141
141
  inline Mso::Future<void> PostInUIQueue(winrt::delegate<ReactNative::IReactViewInstance> const &action) noexcept {
142
142
  Mso::Promise<void> promise;
143
143
 
144
- // ReactViewInstance has shorter lifetime than ReactRootControl. Thus, we capture this WeakPtr.
145
- m_uiDispatcher.Post([weakThis = Mso::WeakPtr{this}, promise, action{std::move(action)}]() mutable noexcept {
146
- if (auto strongThis = weakThis.GetStrongPtr()) {
147
- action(strongThis->m_rootControl);
148
- promise.SetValue();
149
- } else {
150
- promise.TryCancel();
151
- }
144
+ m_uiDispatcher.Post([control = m_rootControl, promise, action{std::move(action)}]() mutable noexcept {
145
+ action(control);
146
+ promise.SetValue();
152
147
  });
153
148
  return promise.AsFuture();
154
149
  }
@@ -161,9 +156,7 @@ winrt::Windows::Foundation::IAsyncAction ReactViewHost::AttachViewInstance(
161
156
  }
162
157
 
163
158
  winrt::Windows::Foundation::IAsyncAction ReactViewHost::DetachViewInstance() noexcept {
164
- Mso::Promise<void> promise;
165
- promise.SetValue();
166
- return make<Mso::AsyncActionFutureAdapter>(promise.AsFuture());
159
+ return make<Mso::AsyncActionFutureAdapter>(m_viewHost->DetachViewInstance());
167
160
  }
168
161
 
169
162
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -245,8 +245,8 @@ size_t ReactHost::PendingUnloadActionId() const noexcept {
245
245
  return m_pendingUnloadActionId;
246
246
  }
247
247
 
248
- bool ReactHost::IsInstanceLoaded() const noexcept {
249
- return m_isInstanceLoaded.Load();
248
+ bool ReactHost::IsInstanceUnloading() const noexcept {
249
+ return m_isInstanceUnloading.Load();
250
250
  }
251
251
 
252
252
  /*static*/ Mso::DispatchQueue ReactHost::EnsureSerialQueue(Mso::DispatchQueue const &queue) noexcept {
@@ -345,10 +345,13 @@ Mso::Future<void> ReactHost::LoadInQueue(ReactOptions &&options) noexcept {
345
345
  }
346
346
  }
347
347
 
348
- return whenLoaded.AsFuture().Then(m_executor, [this](Mso::Maybe<void> && /*value*/) noexcept {
349
- m_isInstanceLoaded.Store(true);
350
-
348
+ return whenLoaded.AsFuture().Then(m_executor, [this](Mso::Maybe<void> &&value) noexcept {
351
349
  std::vector<Mso::Future<void>> loadCompletionList;
350
+
351
+ if (value.IsError()) {
352
+ return Mso::MakeFailedFuture<void>(std::move(value.TakeError()));
353
+ }
354
+
352
355
  ForEachViewHost([&loadCompletionList](auto &viewHost) noexcept {
353
356
  loadCompletionList.push_back(viewHost.UpdateViewInstanceInQueue());
354
357
  });
@@ -370,6 +373,9 @@ Mso::Future<void> ReactHost::UnloadInQueue(size_t unloadActionId) noexcept {
370
373
  // Clear the pending unload action Id
371
374
  m_pendingUnloadActionId = 0;
372
375
 
376
+ // This allows us to avoid initializing any new ReactViews against the old instance that is being unloaded
377
+ m_isInstanceUnloading.Store(true);
378
+
373
379
  std::vector<Mso::Future<void>> unloadCompletionList;
374
380
  ForEachViewHost([&unloadCompletionList](auto &viewHost) noexcept {
375
381
  unloadCompletionList.push_back(viewHost.UninitViewInstanceInQueue(0));
@@ -380,10 +386,10 @@ Mso::Future<void> ReactHost::UnloadInQueue(size_t unloadActionId) noexcept {
380
386
  return Mso::WhenAllCompleted(unloadCompletionList).Then(m_executor, [this](Mso::Maybe<void> && /*value*/) noexcept {
381
387
  Mso::Future<void> onUnloaded;
382
388
  if (auto reactInstance = m_reactInstance.Exchange(nullptr)) {
383
- m_isInstanceLoaded.Store(false);
384
389
  onUnloaded = reactInstance->Destroy();
385
390
  }
386
391
 
392
+ m_isInstanceUnloading.Store(false);
387
393
  m_lastError.Store({});
388
394
 
389
395
  if (!onUnloaded) {
@@ -523,10 +529,10 @@ Mso::Future<void> ReactViewHost::InitViewInstanceInQueue() noexcept {
523
529
  return Mso::MakeCanceledFuture();
524
530
  }
525
531
 
526
- //// We cannot load if instance is not loaded.
527
- // if (!m_reactHost->IsInstanceLoaded()) {
528
- // return Mso::MakeCanceledFuture();
529
- //}
532
+ // We cannot load if instance is in the process of being unloaded.
533
+ if (m_reactHost->IsInstanceUnloading()) {
534
+ return Mso::MakeCanceledFuture();
535
+ }
530
536
 
531
537
  // Make sure that we have a ReactInstance
532
538
  if (!m_reactHost->Instance()) {
@@ -59,7 +59,7 @@ class ReactHost final : public Mso::ActiveObject<IReactHost> {
59
59
  bool IsClosed() const noexcept;
60
60
 
61
61
  size_t PendingUnloadActionId() const noexcept;
62
- bool IsInstanceLoaded() const noexcept;
62
+ bool IsInstanceUnloading() const noexcept;
63
63
 
64
64
  template <class TCallback>
65
65
  Mso::Future<void> PostInQueue(TCallback &&callback) noexcept;
@@ -91,7 +91,7 @@ class ReactHost final : public Mso::ActiveObject<IReactHost> {
91
91
  const Mso::ActiveReadableField<Mso::Promise<void>> m_notifyWhenClosed{nullptr, Queue(), m_mutex};
92
92
  size_t m_pendingUnloadActionId{0};
93
93
  size_t m_nextUnloadActionId{0};
94
- const Mso::ActiveField<bool> m_isInstanceLoaded{false, Queue()};
94
+ const Mso::ActiveField<bool> m_isInstanceUnloading{false, Queue()};
95
95
  };
96
96
 
97
97
  //! Implements a cross-platform host for a React view
@@ -219,9 +219,11 @@ ReactInstanceWin::ReactInstanceWin(
219
219
  m_whenLoaded.AsFuture()
220
220
  .Then<Mso::Executors::Inline>(
221
221
  [onLoaded = m_options.OnInstanceLoaded, reactContext = m_reactContext](Mso::Maybe<void> &&value) noexcept {
222
+ auto errCode = value.IsError() ? value.TakeError() : Mso::ErrorCode();
222
223
  if (onLoaded) {
223
- onLoaded.Get()->Invoke(reactContext, value.IsError() ? value.TakeError() : Mso::ErrorCode());
224
+ onLoaded.Get()->Invoke(reactContext, errCode);
224
225
  }
226
+ return Mso::Maybe<void>(errCode);
225
227
  })
226
228
  .Then(Queue(), [whenLoaded = std::move(whenLoaded)](Mso::Maybe<void> &&value) noexcept {
227
229
  whenLoaded.SetValue(std::move(value));
@@ -467,11 +469,21 @@ void ReactInstanceWin::Initialize() noexcept {
467
469
  m_options.TurboModuleProvider,
468
470
  std::make_unique<BridgeUIBatchInstanceCallback>(weakThis),
469
471
  m_jsMessageThread.Load(),
470
- Mso::Copy(m_batchingUIThread),
472
+ m_nativeMessageThread.Load(),
471
473
  std::move(devSettings));
472
474
 
473
475
  m_instanceWrapper.Exchange(std::move(instanceWrapper));
474
476
 
477
+ // The InstanceCreated event can be used to augment the JS environment for all JS code. So it needs to be
478
+ // triggered before any platform JS code is run. Using m_jsMessageThread instead of jsDispatchQueue avoids
479
+ // waiting for the JSCaller which can delay the event until after certain JS code has already run
480
+ m_jsMessageThread.Load()->runOnQueue(
481
+ [onCreated = m_options.OnInstanceCreated, reactContext = m_reactContext]() noexcept {
482
+ if (onCreated) {
483
+ onCreated.Get()->Invoke(reactContext);
484
+ }
485
+ });
486
+
475
487
  LoadJSBundles();
476
488
 
477
489
  if (UseDeveloperSupport() && State() != ReactInstanceState::HasError) {
@@ -546,7 +558,9 @@ void ReactInstanceWin::LoadJSBundles() noexcept {
546
558
 
547
559
  try {
548
560
  instanceWrapper->loadBundleSync(Mso::Copy(strongThis->JavaScriptBundleFile()));
549
- strongThis->OnReactInstanceLoaded(Mso::ErrorCode{});
561
+ if (strongThis->State() != ReactInstanceState::HasError) {
562
+ strongThis->OnReactInstanceLoaded(Mso::ErrorCode{});
563
+ }
550
564
  } catch (...) {
551
565
  strongThis->OnReactInstanceLoaded(Mso::ExceptionErrorProvider().MakeErrorCode(std::current_exception()));
552
566
  }
@@ -565,7 +579,7 @@ void ReactInstanceWin::OnReactInstanceLoaded(const Mso::ErrorCode &errorCode) no
565
579
  } else {
566
580
  m_state = ReactInstanceState::HasError;
567
581
  m_whenLoaded.SetError(errorCode);
568
- AbandonJSCallQueue();
582
+ OnError(errorCode);
569
583
  }
570
584
  }
571
585
  }
@@ -617,13 +631,6 @@ void ReactInstanceWin::InitJSMessageThread() noexcept {
617
631
  Mso::Copy(m_whenDestroyed));
618
632
  auto jsDispatchQueue = Mso::DispatchQueue::MakeCustomQueue(Mso::CntPtr(scheduler));
619
633
 
620
- // This work item will be processed as a first item in JS queue when the react instance is created.
621
- jsDispatchQueue.Post([onCreated = m_options.OnInstanceCreated, reactContext = m_reactContext]() noexcept {
622
- if (onCreated) {
623
- onCreated.Get()->Invoke(reactContext);
624
- }
625
- });
626
-
627
634
  auto jsDispatcher =
628
635
  winrt::make<winrt::Microsoft::ReactNative::implementation::ReactDispatcher>(Mso::Copy(jsDispatchQueue));
629
636
  m_options.Properties.Set(ReactDispatcherHelper::JSDispatcherProperty(), jsDispatcher);
@@ -758,22 +765,23 @@ std::function<void(std::string)> ReactInstanceWin::GetErrorCallback() noexcept {
758
765
  }
759
766
 
760
767
  void ReactInstanceWin::OnErrorWithMessage(const std::string &errorMessage) noexcept {
768
+ OnError(Mso::React::ReactErrorProvider().MakeErrorCode(Mso::React::ReactError{errorMessage.c_str()}));
769
+ }
770
+
771
+ void ReactInstanceWin::OnError(const Mso::ErrorCode &errorCode) noexcept {
761
772
  m_state = ReactInstanceState::HasError;
762
773
  AbandonJSCallQueue();
763
774
 
764
775
  if (m_redboxHandler && m_redboxHandler->isDevSupportEnabled()) {
765
776
  ErrorInfo errorInfo;
766
- errorInfo.Message = errorMessage;
777
+ errorInfo.Message = errorCode.ToString();
767
778
  errorInfo.Id = 0;
768
779
  m_redboxHandler->showNewError(std::move(errorInfo), ErrorType::Native);
769
780
  }
770
781
 
771
- OnError(Mso::React::ReactErrorProvider().MakeErrorCode(Mso::React::ReactError{errorMessage.c_str()}));
772
- m_updateUI();
773
- }
774
-
775
- void ReactInstanceWin::OnError(const Mso::ErrorCode &errorCode) noexcept {
776
782
  InvokeInQueue([this, errorCode]() noexcept { m_options.OnError(errorCode); });
783
+
784
+ m_updateUI();
777
785
  }
778
786
 
779
787
  void ReactInstanceWin::OnLiveReload() noexcept {
@@ -310,23 +310,13 @@ class TurboModuleImpl : public facebook::react::TurboModule {
310
310
  TurboModulesProvider::TurboModulePtr TurboModulesProvider::getModule(
311
311
  const std::string &moduleName,
312
312
  const CallInvokerPtr &callInvoker) noexcept {
313
- // see if the expected turbo module has been cached
314
- auto pair = std::make_pair(moduleName, callInvoker);
315
- auto itCached = m_cachedModules.find(pair);
316
- if (itCached != m_cachedModules.end()) {
317
- return itCached->second;
318
- }
319
-
320
313
  // fail if the expected turbo module has not been registered
321
314
  auto it = m_moduleProviders.find(moduleName);
322
315
  if (it == m_moduleProviders.end()) {
323
316
  return nullptr;
324
317
  }
325
318
 
326
- // cache and return the turbo module
327
- auto tm = std::make_shared<TurboModuleImpl>(m_reactContext, moduleName, callInvoker, it->second);
328
- m_cachedModules.insert({pair, tm});
329
- return tm;
319
+ return std::make_shared<TurboModuleImpl>(m_reactContext, moduleName, callInvoker, it->second);
330
320
  }
331
321
 
332
322
  std::vector<std::string> TurboModulesProvider::getEagerInitModuleNames() noexcept {
@@ -351,8 +341,6 @@ void TurboModulesProvider::AddModuleProvider(
351
341
  m_moduleProviders.insert({key, moduleProvider});
352
342
  } else {
353
343
  // turbo modules should be replaceable before the first time it is requested
354
- // if a turbo module has been requested, it will be cached in m_cachedModules
355
- // in this case, changing m_moduleProviders affects nothing
356
344
  it->second = moduleProvider;
357
345
  }
358
346
  }
@@ -30,7 +30,6 @@ class TurboModulesProvider final : public facebook::react::TurboModuleRegistry {
30
30
 
31
31
  private:
32
32
  std::unordered_map<std::string, ReactModuleProvider> m_moduleProviders;
33
- std::unordered_map<std::pair<std::string, CallInvokerPtr>, TurboModulePtr> m_cachedModules;
34
33
  IReactContext m_reactContext;
35
34
  };
36
35
 
@@ -27,18 +27,20 @@ struct AsyncActionFutureAdapter : winrt::implements<
27
27
  if (strongThis->m_status == AsyncStatus::Started) {
28
28
  if (result.IsValue()) {
29
29
  strongThis->m_status = AsyncStatus::Completed;
30
- if (strongThis->m_completedAssigned) {
31
- handler = std::move(strongThis->m_completed);
32
- }
33
30
  } else {
34
- strongThis->m_status = AsyncStatus::Error;
35
31
  strongThis->m_error = result.GetError();
32
+ strongThis->m_status = Mso::CancellationErrorProvider().TryGetErrorInfo(strongThis->m_error, false)
33
+ ? AsyncStatus::Canceled
34
+ : AsyncStatus::Error;
35
+ }
36
+ if (strongThis->m_completedAssigned) {
37
+ handler = std::move(strongThis->m_completed);
36
38
  }
37
39
  }
38
40
  }
39
41
 
40
42
  if (handler) {
41
- invoke(handler, *strongThis, AsyncStatus::Completed);
43
+ invoke(handler, *strongThis, strongThis->m_status);
42
44
  }
43
45
  }
44
46
  });
@@ -82,6 +82,7 @@
82
82
  BOOST_NO_TYPEID - Configure boost not to check typeid (not to use RTTI)
83
83
  BOOST_SYSTEM_SOURCE - Build boost::system symbols from sources (drop dependency on boost_system.lib).
84
84
  GTEST_HAS_RTTI - Let GTest know not to use RTTI
85
+ USE_EDGEMODE_JSRT When using Chakra, enforce System Chakra instead of JS9.
85
86
  WIN32_LEAN_AND_MEAN - Reduce the Windows API included surface.
86
87
  WINRT_LEAN_AND_MEAN - Disable rarely used cppwinrt templates that impact compile-time/PCH size.
87
88
  -->
@@ -93,6 +94,7 @@
93
94
  BOOST_NO_TYPEID;
94
95
  BOOST_SYSTEM_SOURCE;
95
96
  GTEST_HAS_RTTI=0;
97
+ USE_EDGEMODE_JSRT;
96
98
  WIN32_LEAN_AND_MEAN;
97
99
  %(PreprocessorDefinitions)
98
100
  </PreprocessorDefinitions>
@@ -79,17 +79,17 @@ struct IWebSocketResource {
79
79
  /// <summary>
80
80
  /// Creates an <c>IWebSocketResource</c> instance.
81
81
  /// </summary>
82
- /// <param name="url">
83
- /// WebSocket URL address the instance will connect to.
84
- /// The address's scheme can be either ws:// or wss://.
85
- /// </param>
86
- static std::shared_ptr<IWebSocketResource> Make(std::string &&url);
82
+ static std::shared_ptr<IWebSocketResource> Make();
87
83
 
88
84
  virtual ~IWebSocketResource() noexcept {}
89
85
 
90
86
  /// <summary>
91
87
  /// Establishes a continuous connection with the remote endpoint.
92
88
  /// </summary>
89
+ /// <param name="url">
90
+ /// WebSocket URL address the instance will connect to.
91
+ /// The address's scheme can be either ws:// or wss://.
92
+ /// </param>
93
93
  /// <param name="protocols">
94
94
  /// Currently unused
95
95
  /// </param>
@@ -97,7 +97,7 @@ struct IWebSocketResource {
97
97
  /// HTTP header fields passed by the remote endpoint, to be used in the
98
98
  /// handshake process.
99
99
  /// </param>
100
- virtual void Connect(const Protocols &protocols = {}, const Options &options = {}) noexcept = 0;
100
+ virtual void Connect(std::string &&url, const Protocols &protocols = {}, const Options &options = {}) noexcept = 0;
101
101
 
102
102
  /// <summary>
103
103
  /// Sends a ping frame to the remote endpoint.