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.
- package/CHANGELOG.json +109 -1
- package/CHANGELOG.md +44 -4
- package/Chakra/Chakra.vcxitems +0 -1
- package/Chakra/Chakra.vcxitems.filters +0 -3
- package/Chakra/ChakraHelpers.cpp +0 -267
- package/Chakra/ChakraInstanceArgs.h +0 -5
- package/Chakra/ChakraPlatform.h +0 -4
- package/Chakra/ChakraTracing.cpp +0 -33
- package/Chakra/ChakraValue.h +0 -4
- package/Chakra/Utf8DebugExtensions.cpp +0 -5
- package/Chakra/Utf8DebugExtensions.h +0 -6
- package/JSI/Desktop/JSI.Desktop.vcxproj +0 -3
- package/JSI/Desktop/JSI.Desktop.vcxproj.filters +0 -5
- package/JSI/Shared/ChakraApi.cpp +1 -37
- package/JSI/Shared/ChakraApi.h +0 -4
- package/JSI/Shared/ChakraJsiRuntime_edgemode.cpp +1 -5
- package/JSI/Shared/ChakraRuntime.cpp +0 -12
- package/JSI/Shared/ChakraRuntimeFactory.h +0 -2
- package/Libraries/Components/Pressable/Pressable.windows.js +33 -0
- package/Libraries/Pressability/HoverState.js +4 -2
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -2
- package/Microsoft.ReactNative/Modules/CreateModules.cpp +2 -2
- package/Microsoft.ReactNative/ReactCoreInjection.cpp +4 -11
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +16 -10
- package/Microsoft.ReactNative/ReactHost/ReactHost.h +2 -2
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +25 -17
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +1 -13
- package/Microsoft.ReactNative/TurboModulesProvider.h +0 -1
- package/Mso/future/futureWinRT.h +7 -5
- package/PropertySheets/React.Cpp.props +2 -0
- package/Shared/IWebSocketResource.h +6 -6
- package/Shared/Modules/WebSocketModule.cpp +134 -117
- package/Shared/Modules/WebSocketModule.h +22 -12
- package/Shared/OInstance.cpp +12 -109
- package/Shared/WinRTWebSocketResource.cpp +55 -46
- package/Shared/WinRTWebSocketResource.h +2 -9
- package/package.json +1 -1
- package/Chakra/ChakraCoreDebugger.h +0 -147
- package/JSI/Desktop/ChakraJsiRuntime_core.cpp +0 -322
- package/JSI/Shared/ChakraCoreRuntime.h +0 -59
- package/Scripts/Microsoft.ChakraCore.ARM64.nuspec +0 -50
- package/Scripts/Microsoft.ChakraCore.ARM64.targets +0 -15
package/JSI/Shared/ChakraApi.cpp
CHANGED
|
@@ -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
|
-
|
|
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) {
|
package/JSI/Shared/ChakraApi.h
CHANGED
|
@@ -15,7 +15,7 @@ JsStartDebugging();
|
|
|
15
15
|
|
|
16
16
|
namespace Microsoft::JSI {
|
|
17
17
|
|
|
18
|
-
#if defined(USE_EDGEMODE_JSRT)
|
|
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(
|
|
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(
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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::
|
|
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::
|
|
249
|
-
return
|
|
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> &&
|
|
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
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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
|
|
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>
|
|
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,
|
|
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
|
-
|
|
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->
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
package/Mso/future/futureWinRT.h
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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.
|