react-native-windows 0.0.0-canary.950 → 0.0.0-canary.951

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 (61) hide show
  1. package/Directory.Build.props +1 -1
  2. package/Libraries/Components/View/ViewAccessibility.d.ts +48 -1
  3. package/Libraries/NativeComponent/BaseViewConfig.windows.js +1 -0
  4. package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +4 -25
  5. package/Microsoft.ReactNative/AsynchronousEventBeat.h +0 -3
  6. package/Microsoft.ReactNative/{JSDispatcherWriter.cpp → CallInvokerWriter.cpp} +58 -56
  7. package/Microsoft.ReactNative/{JSDispatcherWriter.h → CallInvokerWriter.h} +9 -8
  8. package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +100 -0
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +31 -0
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +12 -0
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +1 -0
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +0 -2
  13. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +0 -1
  14. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +7 -0
  15. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +58 -0
  16. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +5 -0
  17. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +0 -1
  18. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/CompositionAccessibilityProps.h +67 -0
  19. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +5 -0
  20. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +2 -0
  21. package/Microsoft.ReactNative/JsiApi.cpp +8 -0
  22. package/Microsoft.ReactNative/JsiApi.h +1 -0
  23. package/Microsoft.ReactNative/JsiApi.idl +1 -0
  24. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
  25. package/Microsoft.ReactNative/QuirkSettings.cpp +0 -16
  26. package/Microsoft.ReactNative/QuirkSettings.h +0 -3
  27. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +11 -1
  28. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +66 -61
  29. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +0 -1
  30. package/Microsoft.ReactNative/TurboModulesProvider.cpp +12 -12
  31. package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +37 -31
  32. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +1 -0
  33. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +2 -0
  34. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +1 -1
  35. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +13 -6
  36. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +7 -6
  37. package/Microsoft.ReactNative.Cxx/JSI/decorator.h +220 -0
  38. package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +28 -0
  39. package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +6 -0
  40. package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +241 -4
  41. package/Microsoft.ReactNative.Cxx/JSI/jsi.h +207 -19
  42. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +2 -2
  43. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +1267 -614
  44. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +4 -2
  45. package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +81 -20
  46. package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +47 -2
  47. package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +13 -0
  48. package/PropertySheets/Generated/PackageVersion.g.props +2 -2
  49. package/PropertySheets/JSEngine.props +1 -1
  50. package/PropertySheets/React.Cpp.props +1 -1
  51. package/ReactCommon/cgmanifest.json +1 -1
  52. package/Shared/HermesRuntimeHolder.cpp +6 -0
  53. package/Shared/JSI/ChakraRuntime.cpp +4 -0
  54. package/Shared/JSI/ChakraRuntime.h +2 -0
  55. package/Shared/Shared.vcxitems +5 -6
  56. package/Shared/Shared.vcxitems.filters +4 -1
  57. package/Shared/TurboModuleManager.cpp +0 -15
  58. package/index.windows.js +4 -2
  59. package/package.json +1 -1
  60. package/Microsoft.ReactNative/SynchronousEventBeat.cpp +0 -51
  61. package/Microsoft.ReactNative/SynchronousEventBeat.h +0 -31
@@ -0,0 +1,67 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <react/renderer/core/PropsParserContext.h>
7
+ #include <react/renderer/core/propsConversions.h>
8
+ #include <optional>
9
+ #include <unordered_map>
10
+
11
+ namespace facebook::react {
12
+ struct AccessibilityAnnotation {
13
+ std::string typeID{};
14
+ std::string typeName{};
15
+ std::string author{};
16
+ std::string dateTime{};
17
+ std::string target{};
18
+ };
19
+
20
+ constexpr bool operator==(const AccessibilityAnnotation &lhs, const AccessibilityAnnotation &rhs) {
21
+ return lhs.typeID == rhs.typeID && lhs.typeName == rhs.typeName && lhs.author == rhs.author &&
22
+ lhs.dateTime == rhs.dateTime && lhs.target == rhs.target;
23
+ }
24
+
25
+ constexpr bool operator!=(const AccessibilityAnnotation &lhs, const AccessibilityAnnotation &rhs) {
26
+ return !(rhs == lhs);
27
+ }
28
+
29
+ inline void fromRawValue(const PropsParserContext &context, const RawValue &value, AccessibilityAnnotation &result) {
30
+ auto map = (std::unordered_map<std::string, RawValue>)value;
31
+
32
+ auto typeID = map.find("typeID");
33
+ if (typeID != map.end()) {
34
+ if (typeID->second.hasType<std::string>()) {
35
+ result.typeID = (std::string)typeID->second;
36
+ }
37
+ }
38
+
39
+ auto typeName = map.find("typeName");
40
+ if (typeName != map.end()) {
41
+ if (typeName->second.hasType<std::string>()) {
42
+ result.typeName = (std::string)typeName->second;
43
+ }
44
+ }
45
+
46
+ auto author = map.find("author");
47
+ if (author != map.end()) {
48
+ if (author->second.hasType<std::string>()) {
49
+ result.author = (std::string)author->second;
50
+ }
51
+ }
52
+
53
+ auto dateTime = map.find("dateTime");
54
+ if (dateTime != map.end()) {
55
+ if (dateTime->second.hasType<std::string>()) {
56
+ result.dateTime = (std::string)dateTime->second;
57
+ }
58
+ }
59
+
60
+ auto target = map.find("target");
61
+ if (target != map.end()) {
62
+ if (target->second.hasType<std::string>()) {
63
+ result.target = (std::string)target->second;
64
+ }
65
+ }
66
+ }
67
+ } // namespace facebook::react
@@ -20,6 +20,10 @@ HostPlatformViewProps::HostPlatformViewProps(
20
20
  ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
21
21
  ? sourceProps.windowsEvents
22
22
  : convertRawProp(context, rawProps, sourceProps.windowsEvents, {})),
23
+ accessibilityAnnotation(
24
+ ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
25
+ ? sourceProps.accessibilityAnnotation
26
+ : convertRawProp(context, rawProps, "accessibilityAnnotation", sourceProps.accessibilityAnnotation, {})),
23
27
  enableFocusRing(
24
28
  ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
25
29
  ? sourceProps.enableFocusRing
@@ -85,6 +89,7 @@ void HostPlatformViewProps::setProp(
85
89
  WINDOWS_VIEW_EVENT_CASE(MouseEnter);
86
90
  WINDOWS_VIEW_EVENT_CASE(MouseLeave);
87
91
  RAW_SET_PROP_SWITCH_CASE_BASIC(enableFocusRing);
92
+ RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityAnnotation);
88
93
  RAW_SET_PROP_SWITCH_CASE_BASIC(focusable);
89
94
  RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityPosInSet);
90
95
  RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilitySetSize);
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include <react/renderer/components/view/BaseViewProps.h>
7
7
  #include <react/renderer/core/PropsParserContext.h>
8
+ #include "CompositionAccessibilityProps.h"
8
9
  #include "KeyEvent.h"
9
10
  #include "WindowsViewEvents.h"
10
11
 
@@ -28,6 +29,7 @@ class HostPlatformViewProps : public BaseViewProps {
28
29
  int accessibilitySetSize{0};
29
30
  std::string accessibilityLiveRegion{"none"};
30
31
  int accessibilityLevel{0};
32
+ std::optional<AccessibilityAnnotation> accessibilityAnnotation{};
31
33
 
32
34
  // std::optional<std::string> overflowAnchor{};
33
35
  std::optional<std::string> tooltip{};
@@ -553,6 +553,14 @@ bool JsiRuntime::DrainMicrotasks(int32_t maxMicrotasksHint) try {
553
553
  throw;
554
554
  }
555
555
 
556
+ void JsiRuntime::QueueMicrotask(JsiObjectRef callback) try {
557
+ auto funcPtr = RuntimeAccessor::AsPointerValue(callback);
558
+ auto const &jsiFunc = RuntimeAccessor::AsFunction(&funcPtr);
559
+ m_runtimeAccessor->queueMicrotask(jsiFunc);
560
+ } catch (JSI_SET_ERROR) {
561
+ throw;
562
+ }
563
+
556
564
  JsiObjectRef JsiRuntime::Global() try {
557
565
  return PointerAccessor::MakeJsiObjectData(m_runtimeAccessor->global());
558
566
  } catch (JSI_SET_ERROR) {
@@ -77,6 +77,7 @@ struct JsiRuntime : JsiRuntimeT<JsiRuntime> {
77
77
  ReactNative::JsiPreparedJavaScript PrepareJavaScript(IJsiByteBuffer const &buffer, hstring const &sourceUrl);
78
78
  JsiValueRef EvaluatePreparedJavaScript(ReactNative::JsiPreparedJavaScript const &js);
79
79
  bool DrainMicrotasks(int32_t maxMicrotasksHint);
80
+ void QueueMicrotask(JsiObjectRef callback);
80
81
  JsiObjectRef Global();
81
82
  hstring Description();
82
83
  bool IsInspectable();
@@ -249,6 +249,7 @@ namespace Microsoft.ReactNative
249
249
  JsiPreparedJavaScript PrepareJavaScript(IJsiByteBuffer buffer, String sourceUrl);
250
250
  JsiValueRef EvaluatePreparedJavaScript(JsiPreparedJavaScript js);
251
251
  Boolean DrainMicrotasks(Int32 maxMicrotasksHint);
252
+ void QueueMicrotask(JsiObjectRef callback);
252
253
  JsiObjectRef Global { get; };
253
254
  String Description { get; };
254
255
  Boolean IsInspectable { get; };
@@ -201,7 +201,7 @@
201
201
  <ClInclude Include="DynamicWriter.h">
202
202
  <DependentUpon>IJSValueWriter.idl</DependentUpon>
203
203
  </ClInclude>
204
- <ClInclude Include="JSDispatcherWriter.h">
204
+ <ClInclude Include="CallInvokerWriter.h">
205
205
  <DependentUpon>IJSValueWriter.idl</DependentUpon>
206
206
  </ClInclude>
207
207
  <ClInclude Include="HResult.h" />
@@ -77,22 +77,6 @@ winrt::Microsoft::ReactNative::ReactPropertyId<bool> UseRuntimeSchedulerProperty
77
77
  return propId;
78
78
  }
79
79
 
80
- winrt::Microsoft::ReactNative::ReactPropertyId<bool> IsBridgelessProperty() noexcept {
81
- winrt::Microsoft::ReactNative::ReactPropertyId<bool> propId{L"ReactNative", L"IsBridgeless"};
82
-
83
- return propId;
84
- }
85
-
86
- /*static*/ bool QuirkSettings::GetIsBridgeless(winrt::Microsoft::ReactNative::ReactPropertyBag properties) noexcept {
87
- return properties.Get(IsBridgelessProperty()).value_or(false);
88
- }
89
-
90
- /*static*/ void QuirkSettings::SetIsBridgeless(
91
- const winrt::Microsoft::ReactNative::ReactPropertyBag &properties,
92
- bool value) noexcept {
93
- properties.Set(IsBridgelessProperty(), value);
94
- }
95
-
96
80
  #pragma region IDL interface
97
81
 
98
82
  /*static*/ void QuirkSettings::SetMatchAndroidAndIOSStretchBehavior(
@@ -39,9 +39,6 @@ struct QuirkSettings : QuirkSettingsT<QuirkSettings> {
39
39
  static bool GetMapWindowDeactivatedToAppStateInactive(
40
40
  winrt::Microsoft::ReactNative::ReactPropertyBag properties) noexcept;
41
41
 
42
- static bool GetIsBridgeless(winrt::Microsoft::ReactNative::ReactPropertyBag properties) noexcept;
43
- static void SetIsBridgeless(const winrt::Microsoft::ReactNative::ReactPropertyBag &properties, bool value) noexcept;
44
-
45
42
  #pragma region Public API - part of IDL interface
46
43
  static void SetMatchAndroidAndIOSStretchBehavior(
47
44
  winrt::Microsoft::ReactNative::ReactInstanceSettings settings,
@@ -6,6 +6,8 @@
6
6
  #include <ReactPropertyBag.h>
7
7
  #include <winrt/Windows.Foundation.h>
8
8
 
9
+ #include <CppRuntimeOptions.h>
10
+
9
11
  #include <react/featureflags/ReactNativeFeatureFlags.h>
10
12
  #include <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
11
13
 
@@ -283,7 +285,15 @@ bool ReactOptions::EnableDefaultCrashHandler() const noexcept {
283
285
  class ReactNativeWindowsFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults {
284
286
  public:
285
287
  bool disableEventLoopOnBridgeless() override {
286
- return true; // Disable event loop until we are on a JSI version that supports microtasks
288
+ return Microsoft::React::GetRuntimeOptionBool("ReactFeatureFlag.enableEventLoopOnBridgeless");
289
+ }
290
+
291
+ bool enableBridgelessArchitecture() override {
292
+ #ifdef USE_FABRIC
293
+ return true;
294
+ #else
295
+ return false;
296
+ #endif
287
297
  }
288
298
 
289
299
  bool enableCppPropsIteratorSetter() override {
@@ -350,12 +350,10 @@ void ReactInstanceWin::LoadModules(
350
350
  #endif
351
351
 
352
352
  #if !defined(CORE_ABI) && !defined(USE_FABRIC)
353
- if (!IsBridgeless()) {
354
- registerTurboModule(
355
- L"UIManager",
356
- // TODO: Use MakeTurboModuleProvider after it satisfies ReactNativeSpecs::UIManagerSpec
357
- winrt::Microsoft::ReactNative::MakeModuleProvider<::Microsoft::ReactNative::UIManager>());
358
- }
353
+ registerTurboModule(
354
+ L"UIManager",
355
+ // TODO: Use MakeTurboModuleProvider after it satisfies ReactNativeSpecs::UIManagerSpec
356
+ winrt::Microsoft::ReactNative::MakeModuleProvider<::Microsoft::ReactNative::UIManager>());
359
357
  #endif
360
358
 
361
359
  #ifndef CORE_ABI
@@ -489,7 +487,7 @@ void ReactInstanceWin::LoadModules(
489
487
  //! Initialize() is called from the native queue.
490
488
  void ReactInstanceWin::Initialize() noexcept {
491
489
  #ifdef USE_FABRIC
492
- if (IsBridgeless()) {
490
+ if (Microsoft::ReactNative::IsFabricEnabled(m_reactContext->Properties())) {
493
491
  InitializeBridgeless();
494
492
  } else
495
493
  #endif
@@ -649,9 +647,9 @@ void ReactInstanceWin::InitializeBridgeless() noexcept {
649
647
  winrt::make<winrt::Microsoft::ReactNative::implementation::ReactDispatcher>(Mso::Copy(jsDispatchQueue));
650
648
  m_options.Properties.Set(ReactDispatcherHelper::JSDispatcherProperty(), jsDispatcher);
651
649
  m_jsMessageThread.Exchange(std::make_shared<Mso::React::MessageDispatchQueue>(
652
- jsDispatchQueue,
653
- Mso::MakeWeakMemberFunctor(this, &ReactInstanceWin::OnError),
654
- Mso::Copy(m_whenDestroyed)));
650
+ jsDispatchQueue, Mso::MakeWeakMemberFunctor(this, &ReactInstanceWin::OnError)));
651
+
652
+ m_jsDispatchQueue.Exchange(std::move(jsDispatchQueue));
655
653
 
656
654
  m_jsMessageThread.Load()->runOnQueueSync([&]() {
657
655
  SetJSThreadDescription();
@@ -688,54 +686,62 @@ void ReactInstanceWin::InitializeBridgeless() noexcept {
688
686
  m_bridgelessReactInstance->getRuntimeScheduler());
689
687
  });
690
688
 
691
- facebook::react::ReactInstance::JSRuntimeFlags options;
692
- m_bridgelessReactInstance->initializeRuntime(options, [=](facebook::jsi::Runtime &runtime) {
693
- auto logger = [loggingHook = GetLoggingCallback()](const std::string &message, unsigned int logLevel) {
694
- if (loggingHook)
695
- loggingHook(static_cast<facebook::react::RCTLogLevel>(logLevel), message.c_str());
696
- };
697
- facebook::react::bindNativeLogger(runtime, logger);
698
-
699
- auto turboModuleManager = std::make_shared<facebook::react::TurboModuleManager>(
700
- m_options.TurboModuleProvider,
701
- std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(
702
- m_bridgelessReactInstance->getRuntimeScheduler()));
703
-
704
- auto binding =
705
- [turboModuleManager](const std::string &name) -> std::shared_ptr<facebook::react::TurboModule> {
706
- return turboModuleManager->getModule(name);
707
- };
708
-
709
- // Use a legacy native module binding that always returns null
710
- // This means that calls to NativeModules.XXX will always return null, rather than crashing on access
711
- auto legacyNativeModuleBinding =
712
- [](const std::string & /*name*/) -> std::shared_ptr<facebook::react::TurboModule> { return nullptr; };
713
-
714
- facebook::react::TurboModuleBinding::install(
715
- runtime,
716
- std::function(binding),
717
- std::function(legacyNativeModuleBinding),
718
- m_options.TurboModuleProvider->LongLivedObjectCollection());
719
-
720
- auto componentDescriptorRegistry =
721
- Microsoft::ReactNative::WindowsComponentDescriptorRegistry::FromProperties(
722
- winrt::Microsoft::ReactNative::ReactPropertyBag(m_options.Properties));
723
- auto hasComponentProvider = [componentDescriptorRegistry](const std::string &name) -> bool {
724
- return componentDescriptorRegistry->hasComponentProvider(
725
- facebook::react::componentNameByReactViewName(name));
726
- };
727
- facebook::react::bindHasComponentProvider(runtime, std::move(hasComponentProvider));
728
-
729
- // init TurboModule
730
- for (const auto &moduleName : turboModuleManager->getEagerInitModuleNames()) {
731
- turboModuleManager->getModule(moduleName);
732
- }
733
- });
734
-
735
689
  m_options.TurboModuleProvider->SetReactContext(
736
690
  winrt::make<implementation::ReactContext>(Mso::Copy(m_reactContext)));
737
691
 
738
- FireInstanceCreatedCallback();
692
+ facebook::react::ReactInstance::JSRuntimeFlags options;
693
+ m_bridgelessReactInstance->initializeRuntime(
694
+ options,
695
+ [=, onCreated = m_options.OnInstanceCreated, reactContext = m_reactContext](
696
+ facebook::jsi::Runtime &runtime) {
697
+ auto logger = [loggingHook = GetLoggingCallback()](
698
+ const std::string &message, unsigned int logLevel) {
699
+ if (loggingHook)
700
+ loggingHook(static_cast<facebook::react::RCTLogLevel>(logLevel), message.c_str());
701
+ };
702
+ facebook::react::bindNativeLogger(runtime, logger);
703
+
704
+ auto turboModuleManager = std::make_shared<facebook::react::TurboModuleManager>(
705
+ m_options.TurboModuleProvider,
706
+ std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(
707
+ m_bridgelessReactInstance->getRuntimeScheduler()));
708
+
709
+ auto binding =
710
+ [turboModuleManager](const std::string &name) -> std::shared_ptr<facebook::react::TurboModule> {
711
+ return turboModuleManager->getModule(name);
712
+ };
713
+
714
+ // Use a legacy native module binding that always returns null
715
+ // This means that calls to NativeModules.XXX will always return null, rather than crashing on access
716
+ auto legacyNativeModuleBinding =
717
+ [](const std::string & /*name*/) -> std::shared_ptr<facebook::react::TurboModule> {
718
+ return nullptr;
719
+ };
720
+
721
+ facebook::react::TurboModuleBinding::install(
722
+ runtime,
723
+ std::function(binding),
724
+ std::function(legacyNativeModuleBinding),
725
+ m_options.TurboModuleProvider->LongLivedObjectCollection());
726
+
727
+ auto componentDescriptorRegistry =
728
+ Microsoft::ReactNative::WindowsComponentDescriptorRegistry::FromProperties(
729
+ winrt::Microsoft::ReactNative::ReactPropertyBag(m_options.Properties));
730
+ auto hasComponentProvider = [componentDescriptorRegistry](const std::string &name) -> bool {
731
+ return componentDescriptorRegistry->hasComponentProvider(
732
+ facebook::react::componentNameByReactViewName(name));
733
+ };
734
+ facebook::react::bindHasComponentProvider(runtime, std::move(hasComponentProvider));
735
+
736
+ // init TurboModule
737
+ for (const auto &moduleName : turboModuleManager->getEagerInitModuleNames()) {
738
+ turboModuleManager->getModule(moduleName);
739
+ }
740
+
741
+ if (onCreated) {
742
+ onCreated.Get()->Invoke(reactContext);
743
+ }
744
+ });
739
745
 
740
746
  LoadJSBundlesBridgeless(devSettings);
741
747
  SetupHMRClient();
@@ -1081,6 +1087,7 @@ Mso::Future<void> ReactInstanceWin::Destroy() noexcept {
1081
1087
 
1082
1088
  #ifdef USE_FABRIC
1083
1089
  if (m_bridgelessReactInstance) {
1090
+ auto jsDispatchQueue = m_jsDispatchQueue.Exchange(nullptr);
1084
1091
  if (auto jsMessageThread = m_jsMessageThread.Exchange(nullptr)) {
1085
1092
  jsMessageThread->runOnQueueSync([&]() noexcept {
1086
1093
  {
@@ -1092,9 +1099,12 @@ Mso::Future<void> ReactInstanceWin::Destroy() noexcept {
1092
1099
  }
1093
1100
  this->m_bridgelessReactInstance = nullptr;
1094
1101
  jsMessageThread->quitSynchronous();
1102
+ if (jsDispatchQueue) {
1103
+ jsDispatchQueue.Shutdown(PendingTaskAction::Complete);
1104
+ }
1105
+ m_whenDestroyed.SetValue();
1095
1106
  });
1096
1107
  }
1097
- m_jsDispatchQueue.Exchange(nullptr);
1098
1108
  }
1099
1109
  #endif
1100
1110
 
@@ -1161,11 +1171,6 @@ void ReactInstanceWin::InitUIMessageThread() noexcept {
1161
1171
  });
1162
1172
  }
1163
1173
 
1164
- bool ReactInstanceWin::IsBridgeless() noexcept {
1165
- return winrt::Microsoft::ReactNative::implementation::QuirkSettings::GetIsBridgeless(
1166
- winrt::Microsoft::ReactNative::ReactPropertyBag(m_reactContext->Properties()));
1167
- }
1168
-
1169
1174
  #if !defined(CORE_ABI) && !defined(USE_FABRIC)
1170
1175
  void ReactInstanceWin::InitUIManager() noexcept {
1171
1176
  std::vector<std::unique_ptr<Microsoft::ReactNative::IViewManager>> viewManagers;
@@ -136,7 +136,6 @@ class ReactInstanceWin final : public Mso::ActiveObject<IReactInstanceInternal>
136
136
  std::shared_ptr<Mso::React::IRedBoxHandler> GetRedBoxHandler() noexcept;
137
137
  std::function<void()> GetWaitingForDebuggerCallback() noexcept;
138
138
  std::function<void()> GetDebuggerAttachCallback() noexcept;
139
- bool IsBridgeless() noexcept;
140
139
 
141
140
  void OnError(const Mso::ErrorCode &errorcode) noexcept;
142
141
  void OnErrorWithMessage(const std::string &errorMessage) noexcept;
@@ -9,7 +9,7 @@
9
9
  #include "TurboModulesProvider.h"
10
10
  #include <ReactCommon/TurboModuleUtils.h>
11
11
  #include <react/bridging/EventEmitter.h>
12
- #include "JSDispatcherWriter.h"
12
+ #include "CallInvokerWriter.h"
13
13
  #include "JSValueWriter.h"
14
14
  #include "JsiApi.h"
15
15
  #include "JsiReader.h"
@@ -202,7 +202,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
202
202
  runtime,
203
203
  propName,
204
204
  0,
205
- [jsDispatcher = m_reactContext.JSDispatcher(),
205
+ [jsInvoker = jsInvoker_,
206
206
  method = methodInfo.Method,
207
207
  longLivedObjectCollection = m_longLivedObjectCollection](
208
208
  facebook::jsi::Runtime &rt,
@@ -214,7 +214,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
214
214
  auto jsiRuntimeHolder = LongLivedJsiRuntime::CreateWeak(strongLongLivedObjectCollection, rt);
215
215
  method(
216
216
  winrt::make<JsiReader>(rt, args, argCount - 1),
217
- winrt::make<JSDispatcherWriter>(jsDispatcher, jsiRuntimeHolder),
217
+ winrt::make<CallInvokerWriter>(jsInvoker, jsiRuntimeHolder),
218
218
  MakeCallback(rt, strongLongLivedObjectCollection, args[argCount - 1]),
219
219
  nullptr);
220
220
  }
@@ -225,7 +225,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
225
225
  runtime,
226
226
  propName,
227
227
  0,
228
- [jsDispatcher = m_reactContext.JSDispatcher(),
228
+ [jsInvoker = jsInvoker_,
229
229
  method = methodInfo.Method,
230
230
  longLivedObjectCollection = m_longLivedObjectCollection](
231
231
  facebook::jsi::Runtime &rt,
@@ -242,9 +242,9 @@ class TurboModuleImpl : public facebook::react::TurboModule {
242
242
 
243
243
  method(
244
244
  winrt::make<JsiReader>(rt, args, argCount - 2),
245
- winrt::make<JSDispatcherWriter>(jsDispatcher, jsiRuntimeHolder),
245
+ winrt::make<CallInvokerWriter>(jsInvoker, jsiRuntimeHolder),
246
246
  [weakCallback1, weakCallback2, jsiRuntimeHolder](const IJSValueWriter &writer) noexcept {
247
- writer.as<JSDispatcherWriter>()->WithResultArgs(
247
+ writer.as<CallInvokerWriter>()->WithResultArgs(
248
248
  [weakCallback1, weakCallback2, jsiRuntimeHolder](
249
249
  facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t count) {
250
250
  if (auto callback1 = weakCallback1.lock()) {
@@ -260,7 +260,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
260
260
  });
261
261
  },
262
262
  [weakCallback1, weakCallback2, jsiRuntimeHolder](const IJSValueWriter &writer) noexcept {
263
- writer.as<JSDispatcherWriter>()->WithResultArgs(
263
+ writer.as<CallInvokerWriter>()->WithResultArgs(
264
264
  [weakCallback1, weakCallback2, jsiRuntimeHolder](
265
265
  facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t count) {
266
266
  if (auto callback2 = weakCallback2.lock()) {
@@ -283,7 +283,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
283
283
  runtime,
284
284
  propName,
285
285
  0,
286
- [jsDispatcher = m_reactContext.JSDispatcher(),
286
+ [jsInvoker = jsInvoker_,
287
287
  method = methodInfo.Method,
288
288
  longLivedObjectCollection = m_longLivedObjectCollection](
289
289
  facebook::jsi::Runtime &rt,
@@ -293,7 +293,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
293
293
  if (auto strongLongLivedObjectCollection = longLivedObjectCollection.lock()) {
294
294
  auto jsiRuntimeHolder = LongLivedJsiRuntime::CreateWeak(strongLongLivedObjectCollection, rt);
295
295
  auto argReader = winrt::make<JsiReader>(rt, args, count);
296
- auto argWriter = winrt::make<JSDispatcherWriter>(jsDispatcher, jsiRuntimeHolder);
296
+ auto argWriter = winrt::make<CallInvokerWriter>(jsInvoker, jsiRuntimeHolder);
297
297
  return facebook::react::createPromiseAsJSIValue(
298
298
  rt,
299
299
  [method, argReader, argWriter, strongLongLivedObjectCollection, jsiRuntimeHolder](
@@ -306,7 +306,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
306
306
  argReader,
307
307
  argWriter,
308
308
  [weakResolve, weakReject, jsiRuntimeHolder](const IJSValueWriter &writer) {
309
- writer.as<JSDispatcherWriter>()->WithResultArgs(
309
+ writer.as<CallInvokerWriter>()->WithResultArgs(
310
310
  [weakResolve, weakReject, jsiRuntimeHolder](
311
311
  facebook::jsi::Runtime &runtime,
312
312
  facebook::jsi::Value const *args,
@@ -325,7 +325,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
325
325
  });
326
326
  },
327
327
  [weakResolve, weakReject, jsiRuntimeHolder](const IJSValueWriter &writer) {
328
- writer.as<JSDispatcherWriter>()->WithResultArgs(
328
+ writer.as<CallInvokerWriter>()->WithResultArgs(
329
329
  [weakResolve, weakReject, jsiRuntimeHolder](
330
330
  facebook::jsi::Runtime &runtime,
331
331
  facebook::jsi::Value const *args,
@@ -438,7 +438,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
438
438
  auto weakCallback =
439
439
  LongLivedJsiFunction::CreateWeak(longLivedObjectCollection, rt, callback.getObject(rt).getFunction(rt));
440
440
  return [weakCallback = std::move(weakCallback)](const IJSValueWriter &writer) noexcept {
441
- writer.as<JSDispatcherWriter>()->WithResultArgs(
441
+ writer.as<CallInvokerWriter>()->WithResultArgs(
442
442
  [weakCallback](facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t count) {
443
443
  if (auto callback = weakCallback.lock()) {
444
444
  callback->Value().call(rt, args, count);
@@ -54,38 +54,44 @@ std::string GetBundleFromEmbeddedResource(const winrt::Windows::Foundation::Uri
54
54
  }
55
55
 
56
56
  std::future<std::string> LocalBundleReader::LoadBundleAsync(const std::wstring bundleUri) {
57
- co_await winrt::resume_background();
58
-
59
- winrt::Windows::Storage::StorageFile file{nullptr};
60
-
61
- // Supports "ms-appx://" or "ms-appdata://"
62
- if (bundleUri.starts_with(L"ms-app")) {
63
- winrt::Windows::Foundation::Uri uri(bundleUri);
64
- file = co_await winrt::Windows::Storage::StorageFile::GetFileFromApplicationUriAsync(uri);
65
- } else if (bundleUri.starts_with(L"resource://")) {
66
- winrt::Windows::Foundation::Uri uri(bundleUri);
67
- co_return GetBundleFromEmbeddedResource(uri);
68
- } else {
69
- file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(bundleUri);
57
+ try {
58
+ co_await winrt::resume_background();
59
+
60
+ winrt::Windows::Storage::StorageFile file{nullptr};
61
+
62
+ // Supports "ms-appx://" or "ms-appdata://"
63
+ if (bundleUri.starts_with(L"ms-app")) {
64
+ winrt::Windows::Foundation::Uri uri(bundleUri);
65
+ file = co_await winrt::Windows::Storage::StorageFile::GetFileFromApplicationUriAsync(uri);
66
+ } else if (bundleUri.starts_with(L"resource://")) {
67
+ winrt::Windows::Foundation::Uri uri(bundleUri);
68
+ co_return GetBundleFromEmbeddedResource(uri);
69
+ } else {
70
+ file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(bundleUri);
71
+ }
72
+
73
+ // Read the buffer manually to avoid a Utf8 -> Utf16 -> Utf8 encoding
74
+ // roundtrip.
75
+ auto fileBuffer{co_await winrt::Windows::Storage::FileIO::ReadBufferAsync(file)};
76
+ auto dataReader{winrt::Windows::Storage::Streams::DataReader::FromBuffer(fileBuffer)};
77
+
78
+ // No need to use length + 1, STL guarantees that string storage is null-terminated.
79
+ std::string script(fileBuffer.Length(), '\0');
80
+
81
+ // Construct the array_view to slice into the first fileBuffer.Length bytes.
82
+ // DataReader.ReadBytes will read as many bytes as are present in the
83
+ // array_view. The backing string has fileBuffer.Length() + 1 bytes, without
84
+ // an explicit end it will read 1 byte to many and throw.
85
+ dataReader.ReadBytes(winrt::array_view<uint8_t>{
86
+ reinterpret_cast<uint8_t *>(&script[0]), reinterpret_cast<uint8_t *>(&script[script.length()])});
87
+ dataReader.Close();
88
+
89
+ co_return script;
90
+ }
91
+ // RuntimeScheduler only handles std::exception or jsi::JSError
92
+ catch (winrt::hresult_error const &e) {
93
+ throw std::exception(winrt::to_string(e.message()).c_str());
70
94
  }
71
-
72
- // Read the buffer manually to avoid a Utf8 -> Utf16 -> Utf8 encoding
73
- // roundtrip.
74
- auto fileBuffer{co_await winrt::Windows::Storage::FileIO::ReadBufferAsync(file)};
75
- auto dataReader{winrt::Windows::Storage::Streams::DataReader::FromBuffer(fileBuffer)};
76
-
77
- // No need to use length + 1, STL guarantees that string storage is null-terminated.
78
- std::string script(fileBuffer.Length(), '\0');
79
-
80
- // Construct the array_view to slice into the first fileBuffer.Length bytes.
81
- // DataReader.ReadBytes will read as many bytes as are present in the
82
- // array_view. The backing string has fileBuffer.Length() + 1 bytes, without
83
- // an explicit end it will read 1 byte to many and throw.
84
- dataReader.ReadBytes(winrt::array_view<uint8_t>{
85
- reinterpret_cast<uint8_t *>(&script[0]), reinterpret_cast<uint8_t *>(&script[script.length()])});
86
- dataReader.Close();
87
-
88
- co_return script;
89
95
  }
90
96
 
91
97
  std::string LocalBundleReader::LoadBundle(const std::wstring &bundlePath) {
@@ -9,6 +9,7 @@ EXTERN_C_START
9
9
  extern napi_status NAPI_CDECL default_jsr_open_napi_env_scope(napi_env env, jsr_napi_env_scope *scope);
10
10
  extern napi_status NAPI_CDECL default_jsr_close_napi_env_scope(napi_env env, jsr_napi_env_scope scope);
11
11
  extern napi_status NAPI_CDECL default_jsr_get_description(napi_env env, const char **result);
12
+ extern napi_status NAPI_CDECL default_jsr_queue_microtask(napi_env env, napi_value callback);
12
13
  extern napi_status NAPI_CDECL default_jsr_drain_microtasks(napi_env env, int32_t max_count_hint, bool *result);
13
14
  extern napi_status NAPI_CDECL default_jsr_is_inspectable(napi_env env, bool *result);
14
15
 
@@ -17,6 +17,7 @@
17
17
  JSR_FUNC(jsr_collect_garbage)
18
18
  JSR_FUNC(jsr_config_enable_gc_api)
19
19
  JSR_FUNC(jsr_config_enable_inspector)
20
+ JSR_FUNC(jsr_config_set_explicit_microtasks)
20
21
  JSR_FUNC(jsr_config_set_inspector_break_on_start)
21
22
  JSR_FUNC(jsr_config_set_inspector_port)
22
23
  JSR_FUNC(jsr_config_set_inspector_runtime_name)
@@ -33,6 +34,7 @@ JSR_FUNC(jsr_runtime_get_node_api_env)
33
34
 
34
35
  // The JS runtime functions needed for JSI.
35
36
  JSR_JSI_FUNC(jsr_close_napi_env_scope)
37
+ JSR_JSI_FUNC(jsr_queue_microtask)
36
38
  JSR_JSI_FUNC(jsr_drain_microtasks)
37
39
  JSR_JSI_FUNC(jsr_get_description)
38
40
  JSR_JSI_FUNC(jsr_is_inspectable)
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
- #include "LibLoader.h"
4
+ #include "NodeApi.h"
5
5
 
6
6
  namespace Microsoft::NodeApiJsi {
7
7