react-native-windows 0.81.37 → 0.81.40
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/Microsoft.ReactNative/Fabric/AbiComponentDescriptor.cpp +6 -2
- package/Microsoft.ReactNative/Fabric/AbiShadowNode.cpp +0 -47
- package/Microsoft.ReactNative/Fabric/AbiShadowNode.h +40 -8
- package/Microsoft.ReactNative/Fabric/AbiState.h +26 -8
- package/Microsoft.ReactNative/Fabric/AbiTextInputProps.h +51 -0
- package/Microsoft.ReactNative/Fabric/AbiTextInputShadowNode.cpp +88 -0
- package/Microsoft.ReactNative/Fabric/AbiTextInputShadowNode.h +65 -0
- package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +52 -18
- package/Microsoft.ReactNative/Fabric/AbiViewShadowNode.cpp +0 -18
- package/Microsoft.ReactNative/Fabric/AbiViewShadowNode.h +16 -4
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +1 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +6 -4
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +6 -4
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +22 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/AbiTextInputState.h +38 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/ConcreteTextInputShadowNode.h +272 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +21 -14
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +345 -90
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +24 -4
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +0 -205
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +22 -65
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +2 -1
- package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -1
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +5 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +60 -5
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +3 -0
- package/Microsoft.ReactNative/ViewProps.idl +11 -0
- package/Microsoft.ReactNative/Views/ViewViewManager.cpp +2 -2
- package/Microsoft.ReactNative.Cxx/ComponentView.Experimental.interop.h +12 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +0 -1
- package/PropertySheets/WinUI.props +2 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/Instance.cpp +386 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.h +148 -0
- package/Scripts/EnableInternalWinAppSDKFeed.ps1 +12 -5
- package/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 +2 -2
- package/Shared/Networking/WinRTWebSocketResource.h +1 -5
- package/Shared/OInstance.cpp +13 -8
- package/Shared/Shared.vcxitems +3 -3
- package/Shared/Shared.vcxitems.filters +1 -1
- package/external/folly/folly.vcxitems +10 -0
- package/index.windows.js +5 -0
- package/package.json +4 -4
- package/Microsoft.ReactNative/Fabric/AbiState.cpp +0 -29
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
+
// #include <tom.h>
|
|
7
|
+
// #include <textserv.h>
|
|
8
|
+
struct ITextDocument2;
|
|
9
|
+
class ITextServices2;
|
|
10
|
+
class ITextHost;
|
|
11
|
+
|
|
6
12
|
namespace Microsoft::ReactNative::Composition::Experimental {
|
|
7
13
|
|
|
8
14
|
// This interface will be removed once we complete internal transitions to ContentIsland, and new APIs for hosting
|
|
@@ -11,4 +17,10 @@ struct __declspec(uuid("2A60D68A-57B8-43CA-B1BA-2FAF0FCB344B")) IComponentViewIn
|
|
|
11
17
|
virtual HWND GetHwndForParenting() noexcept = 0;
|
|
12
18
|
};
|
|
13
19
|
|
|
20
|
+
struct __declspec(uuid("ABA4F071-1C26-4D56-A608-75361ED21545")) ITextInputComponentInterop : IUnknown {
|
|
21
|
+
virtual HRESULT GetTextDocument(ITextDocument2 **textDocument) noexcept = 0;
|
|
22
|
+
virtual HRESULT GetTextServices(ITextServices2 **textServices) noexcept = 0;
|
|
23
|
+
virtual HRESULT GetTextHost(ITextHost **textHost) noexcept = 0;
|
|
24
|
+
};
|
|
25
|
+
|
|
14
26
|
} // namespace Microsoft::ReactNative::Composition::Experimental
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.81.
|
|
13
|
+
<ReactNativeWindowsVersion>0.81.40</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>81</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>40</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>be0af08d662d3d6a0583d77541b6abab8233aeca</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<EnableDevServerHBCBundles Condition="'$(EnableDevServerHBCBundles)' == ''">false</EnableDevServerHBCBundles>
|
|
18
18
|
|
|
19
19
|
<UseV8 Condition="'$(UseV8)' == ''">false</UseV8>
|
|
20
|
-
<V8Version Condition="'$(V8Version)' == ''">0.
|
|
20
|
+
<V8Version Condition="'$(V8Version)' == ''">0.79.5</V8Version>
|
|
21
21
|
<V8PackageName>ReactNative.V8Jsi.Windows</V8PackageName>
|
|
22
22
|
<V8PackageName Condition="'$(V8AppPlatform)' != 'win32'">$(V8PackageName).UWP</V8PackageName>
|
|
23
23
|
<V8Package>$(NuGetPackageRoot)\$(V8PackageName).$(V8Version)</V8Package>
|
|
@@ -139,7 +139,6 @@
|
|
|
139
139
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
140
140
|
<ShowIncludes Condition="'$(ShowIncludes)'=='true'">true</ShowIncludes>
|
|
141
141
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
|
142
|
-
<AdditionalOptions Condition="'$(PlatformToolsetVersion)' != '' And $(PlatformToolsetVersion)<145">%(AdditionalOptions) /await</AdditionalOptions>
|
|
143
142
|
<ControlFlowGuard>Guard</ControlFlowGuard>
|
|
144
143
|
<SpectreMitigation>Spectre</SpectreMitigation>
|
|
145
144
|
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
<!--
|
|
6
6
|
Internal versions are typically only located at: https://microsoft.visualstudio.com/DefaultCollection/ProjectReunion/_artifacts/feed/Project.Reunion.nuget.internal/NuGet/Microsoft.WindowsAppSDK/versions
|
|
7
|
-
For local testing of internal versions,
|
|
7
|
+
For local testing of internal versions, set WinUI3ExperimentalVersion and run
|
|
8
|
+
vnext\Scripts\EnableInternalWinAppSDKFeed.ps1 to add the internal source and its package mapping.
|
|
8
9
|
When this version is updated, be sure to update the default for the enableInternalFeed parameter of /.ado/templates/enable-experimental-winui3.yml
|
|
9
10
|
-->
|
|
10
11
|
<WinUI3ExperimentalVersion Condition="'$(WinUI3ExperimentalVersion)'==''">1.8.251106002</WinUI3ExperimentalVersion>
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "Instance.h"
|
|
9
|
+
|
|
10
|
+
#ifndef RCT_FIT_RM_OLD_RUNTIME
|
|
11
|
+
|
|
12
|
+
#include "ErrorUtils.h"
|
|
13
|
+
#include "JSBigString.h"
|
|
14
|
+
#include "JSBundleType.h"
|
|
15
|
+
#include "JSExecutor.h"
|
|
16
|
+
#include "MessageQueueThread.h"
|
|
17
|
+
#include "MethodCall.h"
|
|
18
|
+
#include "NativeToJsBridge.h"
|
|
19
|
+
#include "RAMBundleRegistry.h"
|
|
20
|
+
#include "RecoverableError.h"
|
|
21
|
+
#include "TraceSection.h"
|
|
22
|
+
|
|
23
|
+
#include <cxxreact/JSIndexedRAMBundle.h>
|
|
24
|
+
#include <folly/json.h>
|
|
25
|
+
#include <react/debug/react_native_assert.h>
|
|
26
|
+
|
|
27
|
+
#include <glog/logging.h>
|
|
28
|
+
|
|
29
|
+
#include <condition_variable>
|
|
30
|
+
#include <exception>
|
|
31
|
+
#include <memory>
|
|
32
|
+
#include <mutex>
|
|
33
|
+
#include <string>
|
|
34
|
+
|
|
35
|
+
namespace facebook::react {
|
|
36
|
+
|
|
37
|
+
Instance::~Instance() {
|
|
38
|
+
if (nativeToJsBridge_) {
|
|
39
|
+
nativeToJsBridge_->destroy();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void Instance::unregisterFromInspector() {
|
|
44
|
+
if (inspectorTarget_) {
|
|
45
|
+
assert(runtimeInspectorTarget_);
|
|
46
|
+
inspectorTarget_->unregisterRuntime(*runtimeInspectorTarget_);
|
|
47
|
+
assert(parentInspectorTarget_);
|
|
48
|
+
parentInspectorTarget_->unregisterInstance(*inspectorTarget_);
|
|
49
|
+
parentInspectorTarget_ = nullptr;
|
|
50
|
+
inspectorTarget_ = nullptr;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void Instance::initializeBridge(
|
|
55
|
+
std::unique_ptr<InstanceCallback> callback,
|
|
56
|
+
std::shared_ptr<JSExecutorFactory> jsef,
|
|
57
|
+
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
58
|
+
std::shared_ptr<ModuleRegistry> moduleRegistry,
|
|
59
|
+
jsinspector_modern::HostTarget* parentInspectorTarget) {
|
|
60
|
+
callback_ = std::move(callback);
|
|
61
|
+
moduleRegistry_ = std::move(moduleRegistry);
|
|
62
|
+
parentInspectorTarget_ = parentInspectorTarget;
|
|
63
|
+
|
|
64
|
+
jsQueue->runOnQueueSync([this, &jsef, jsQueue]() mutable {
|
|
65
|
+
nativeToJsBridge_ = std::make_shared<NativeToJsBridge>(
|
|
66
|
+
jsef.get(), moduleRegistry_, jsQueue, callback_);
|
|
67
|
+
|
|
68
|
+
// If a parent inspector HostTarget is provided, perform inspector
|
|
69
|
+
// initialization synchronously.
|
|
70
|
+
if (parentInspectorTarget_ != nullptr) {
|
|
71
|
+
auto inspectorExecutor = parentInspectorTarget_->executorFromThis();
|
|
72
|
+
std::mutex inspectorInitializedMutex;
|
|
73
|
+
std::condition_variable inspectorInitializedCv;
|
|
74
|
+
bool inspectorInitialized = false;
|
|
75
|
+
|
|
76
|
+
// Schedule work on the inspector thread. NOTE: We expect this callback
|
|
77
|
+
// to always execute, given the invariant that `initializeBridge` (this
|
|
78
|
+
// method) completes before `unregisterFromInspector` is called.
|
|
79
|
+
// - On iOS, instance creation and invalidation both run on the main
|
|
80
|
+
// queue (`RCTCxxBridge::start,invalidate` use `RCTAssertMainQueue`).
|
|
81
|
+
// - On Android, `ReactContext` must be initialized with a constructed
|
|
82
|
+
// `CatalystInstance` (in which `Instance::initializeBridge` has
|
|
83
|
+
// completed) before `destroy` can be called.
|
|
84
|
+
inspectorExecutor([this,
|
|
85
|
+
&inspectorInitialized,
|
|
86
|
+
&inspectorInitializedMutex,
|
|
87
|
+
&inspectorInitializedCv](
|
|
88
|
+
jsinspector_modern::HostTarget& hostTarget) {
|
|
89
|
+
// NOTE: By passing *this, we strongly assume the Instance will still
|
|
90
|
+
// be alive by the time this executes.
|
|
91
|
+
// - On iOS, instance creation is done synchronously
|
|
92
|
+
// (`RCTCxxBridge::_initializeBridgeLocked`).
|
|
93
|
+
// - On Android, we explicitly wait for instance creation before
|
|
94
|
+
// destruction (`ReactInstanceManager::mReactContextLock`).
|
|
95
|
+
inspectorTarget_ = &hostTarget.registerInstance(*this);
|
|
96
|
+
RuntimeExecutor runtimeExecutorIfJsi = getRuntimeExecutor();
|
|
97
|
+
runtimeInspectorTarget_ = &inspectorTarget_->registerRuntime(
|
|
98
|
+
nativeToJsBridge_->getInspectorTargetDelegate(),
|
|
99
|
+
runtimeExecutorIfJsi ? runtimeExecutorIfJsi : [](auto) {});
|
|
100
|
+
|
|
101
|
+
// Signal that initialization is complete
|
|
102
|
+
{
|
|
103
|
+
std::lock_guard lock(inspectorInitializedMutex);
|
|
104
|
+
inspectorInitialized = true;
|
|
105
|
+
}
|
|
106
|
+
inspectorInitializedCv.notify_one();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Wait for the initialization work to complete
|
|
110
|
+
{
|
|
111
|
+
std::unique_lock lock(inspectorInitializedMutex);
|
|
112
|
+
inspectorInitializedCv.wait(
|
|
113
|
+
lock, [&inspectorInitialized] { return inspectorInitialized; });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Initialize the JavaScript runtime after we've initialized the inspector
|
|
118
|
+
nativeToJsBridge_->initializeRuntime();
|
|
119
|
+
|
|
120
|
+
// After NativeToJsBridge is created, the jsi::Runtime should exist. Also,
|
|
121
|
+
// the JS message queue thread exists. So, it's safe to schedule all queued
|
|
122
|
+
// up JS calls.
|
|
123
|
+
jsCallInvoker_->setNativeToJsBridgeAndFlushCalls(nativeToJsBridge_);
|
|
124
|
+
|
|
125
|
+
std::scoped_lock lock(m_syncMutex);
|
|
126
|
+
m_syncReady = true;
|
|
127
|
+
m_syncCV.notify_all();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
CHECK(nativeToJsBridge_);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
void Instance::loadBundle(
|
|
134
|
+
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
135
|
+
std::unique_ptr<const JSBigString> string,
|
|
136
|
+
std::string sourceURL) {
|
|
137
|
+
callback_->incrementPendingJSCalls();
|
|
138
|
+
TraceSection s("Instance::loadBundle", "sourceURL", sourceURL);
|
|
139
|
+
nativeToJsBridge_->loadBundle(
|
|
140
|
+
std::move(bundleRegistry), std::move(string), std::move(sourceURL));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void Instance::loadBundleSync(
|
|
144
|
+
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
145
|
+
std::unique_ptr<const JSBigString> string,
|
|
146
|
+
std::string sourceURL) {
|
|
147
|
+
std::unique_lock<std::mutex> lock(m_syncMutex);
|
|
148
|
+
m_syncCV.wait(lock, [this] { return m_syncReady; });
|
|
149
|
+
|
|
150
|
+
TraceSection s("Instance::loadBundleSync", "sourceURL", sourceURL);
|
|
151
|
+
nativeToJsBridge_->loadBundleSync(
|
|
152
|
+
std::move(bundleRegistry), std::move(string), std::move(sourceURL));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
void Instance::setSourceURL(std::string sourceURL) {
|
|
156
|
+
callback_->incrementPendingJSCalls();
|
|
157
|
+
TraceSection s("Instance::setSourceURL", "sourceURL", sourceURL);
|
|
158
|
+
|
|
159
|
+
nativeToJsBridge_->loadBundle(nullptr, nullptr, std::move(sourceURL));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void Instance::loadScriptFromString(
|
|
163
|
+
std::unique_ptr<const JSBigString> string,
|
|
164
|
+
std::string sourceURL,
|
|
165
|
+
bool loadSynchronously) {
|
|
166
|
+
TraceSection s("Instance::loadScriptFromString", "sourceURL", sourceURL);
|
|
167
|
+
if (loadSynchronously) {
|
|
168
|
+
loadBundleSync(nullptr, std::move(string), std::move(sourceURL));
|
|
169
|
+
} else {
|
|
170
|
+
loadBundle(nullptr, std::move(string), std::move(sourceURL));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
void Instance::loadRAMBundleFromString(
|
|
175
|
+
std::unique_ptr<const JSBigString> script,
|
|
176
|
+
const std::string& sourceURL) {
|
|
177
|
+
auto bundle = std::make_unique<JSIndexedRAMBundle>(std::move(script));
|
|
178
|
+
auto startupScript = bundle->getStartupCode();
|
|
179
|
+
auto registry = RAMBundleRegistry::singleBundleRegistry(std::move(bundle));
|
|
180
|
+
loadRAMBundle(std::move(registry), std::move(startupScript), sourceURL, true);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
void Instance::loadRAMBundleFromFile(
|
|
184
|
+
const std::string& sourcePath,
|
|
185
|
+
const std::string& sourceURL,
|
|
186
|
+
bool loadSynchronously) {
|
|
187
|
+
auto bundle = std::make_unique<JSIndexedRAMBundle>(sourcePath.c_str());
|
|
188
|
+
auto startupScript = bundle->getStartupCode();
|
|
189
|
+
auto registry = RAMBundleRegistry::multipleBundlesRegistry(
|
|
190
|
+
std::move(bundle), JSIndexedRAMBundle::buildFactory());
|
|
191
|
+
loadRAMBundle(
|
|
192
|
+
std::move(registry),
|
|
193
|
+
std::move(startupScript),
|
|
194
|
+
sourceURL,
|
|
195
|
+
loadSynchronously);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
void Instance::loadRAMBundle(
|
|
199
|
+
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
200
|
+
std::unique_ptr<const JSBigString> startupScript,
|
|
201
|
+
std::string startupScriptSourceURL,
|
|
202
|
+
bool loadSynchronously) {
|
|
203
|
+
if (loadSynchronously) {
|
|
204
|
+
loadBundleSync(
|
|
205
|
+
std::move(bundleRegistry),
|
|
206
|
+
std::move(startupScript),
|
|
207
|
+
std::move(startupScriptSourceURL));
|
|
208
|
+
} else {
|
|
209
|
+
loadBundle(
|
|
210
|
+
std::move(bundleRegistry),
|
|
211
|
+
std::move(startupScript),
|
|
212
|
+
std::move(startupScriptSourceURL));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
void Instance::setGlobalVariable(
|
|
217
|
+
std::string propName,
|
|
218
|
+
std::unique_ptr<const JSBigString> jsonValue) {
|
|
219
|
+
nativeToJsBridge_->setGlobalVariable(
|
|
220
|
+
std::move(propName), std::move(jsonValue));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
void* Instance::getJavaScriptContext() {
|
|
224
|
+
return nativeToJsBridge_ ? nativeToJsBridge_->getJavaScriptContext()
|
|
225
|
+
: nullptr;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
bool Instance::isInspectable() {
|
|
229
|
+
return nativeToJsBridge_ ? nativeToJsBridge_->isInspectable() : false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
bool Instance::isBatchActive() {
|
|
233
|
+
return nativeToJsBridge_ ? nativeToJsBridge_->isBatchActive() : false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
void Instance::callJSFunction(
|
|
237
|
+
std::string&& module,
|
|
238
|
+
std::string&& method,
|
|
239
|
+
folly::dynamic&& params) {
|
|
240
|
+
callback_->incrementPendingJSCalls();
|
|
241
|
+
nativeToJsBridge_->callFunction(
|
|
242
|
+
std::move(module), std::move(method), std::move(params));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void Instance::callJSCallback(uint64_t callbackId, folly::dynamic&& params) {
|
|
246
|
+
TraceSection s("Instance::callJSCallback");
|
|
247
|
+
callback_->incrementPendingJSCalls();
|
|
248
|
+
nativeToJsBridge_->invokeCallback((double)callbackId, std::move(params));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
void Instance::registerBundle(
|
|
252
|
+
uint32_t bundleId,
|
|
253
|
+
const std::string& bundlePath) {
|
|
254
|
+
nativeToJsBridge_->registerBundle(bundleId, bundlePath);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const ModuleRegistry& Instance::getModuleRegistry() const {
|
|
258
|
+
return *moduleRegistry_;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
ModuleRegistry& Instance::getModuleRegistry() {
|
|
262
|
+
return *moduleRegistry_;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
void Instance::handleMemoryPressure(int pressureLevel) {
|
|
266
|
+
if (nativeToJsBridge_) {
|
|
267
|
+
// This class resets `nativeToJsBridge_` only in the destructor,
|
|
268
|
+
// hence a race is not possible there.
|
|
269
|
+
nativeToJsBridge_->handleMemoryPressure(pressureLevel);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
std::shared_ptr<CallInvoker> Instance::getJSCallInvoker() {
|
|
274
|
+
return std::static_pointer_cast<CallInvoker>(jsCallInvoker_);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
namespace {
|
|
278
|
+
// [Windows] A task on the JS queue can drop the last reference to the Instance.
|
|
279
|
+
// ~Instance then calls NativeToJsBridge::destroy(), which deletes the executor
|
|
280
|
+
// before the task returns, because runOnQueueSync runs inline on its own queue.
|
|
281
|
+
// Call this on the JS queue before using the executor again.
|
|
282
|
+
bool executorSurvivedTask(
|
|
283
|
+
const std::weak_ptr<NativeToJsBridge>& weakNativeToJsBridge) {
|
|
284
|
+
auto nativeToJsBridge = weakNativeToJsBridge.lock();
|
|
285
|
+
return nativeToJsBridge && nativeToJsBridge->hasExecutor();
|
|
286
|
+
}
|
|
287
|
+
} // namespace
|
|
288
|
+
|
|
289
|
+
RuntimeExecutor Instance::getRuntimeExecutor() {
|
|
290
|
+
// HACK: RuntimeExecutor is not compatible with non-JSIExecutor, we return
|
|
291
|
+
// a null callback, which the caller should handle.
|
|
292
|
+
if (!getJavaScriptContext()) {
|
|
293
|
+
return nullptr;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
std::weak_ptr<NativeToJsBridge> weakNativeToJsBridge = nativeToJsBridge_;
|
|
297
|
+
return [weakNativeToJsBridge](
|
|
298
|
+
std::function<void(jsi::Runtime & runtime)>&& callback) {
|
|
299
|
+
if (auto strongNativeToJsBridge = weakNativeToJsBridge.lock()) {
|
|
300
|
+
strongNativeToJsBridge->runOnExecutorQueue(
|
|
301
|
+
[callback = std::move(callback),
|
|
302
|
+
weakNativeToJsBridge](JSExecutor* executor) {
|
|
303
|
+
// Assumes the underlying executor is a JSIExecutor
|
|
304
|
+
jsi::Runtime* runtime =
|
|
305
|
+
(jsi::Runtime*)executor->getJavaScriptContext();
|
|
306
|
+
try {
|
|
307
|
+
react_native_assert(runtime != nullptr);
|
|
308
|
+
callback(*runtime);
|
|
309
|
+
if (executorSurvivedTask(weakNativeToJsBridge)) { // [Windows]
|
|
310
|
+
executor->flush();
|
|
311
|
+
}
|
|
312
|
+
} catch (jsi::JSError& originalError) {
|
|
313
|
+
handleJSError(*runtime, originalError, true);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
std::shared_ptr<NativeMethodCallInvoker>
|
|
321
|
+
Instance::getDecoratedNativeMethodCallInvoker(
|
|
322
|
+
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker) {
|
|
323
|
+
return nativeToJsBridge_->getDecoratedNativeMethodCallInvoker(
|
|
324
|
+
nativeMethodCallInvoker);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
void Instance::JSCallInvoker::setNativeToJsBridgeAndFlushCalls(
|
|
328
|
+
std::weak_ptr<NativeToJsBridge> nativeToJsBridge) {
|
|
329
|
+
std::scoped_lock guard(m_mutex);
|
|
330
|
+
|
|
331
|
+
m_shouldBuffer = false;
|
|
332
|
+
m_nativeToJsBridge = nativeToJsBridge;
|
|
333
|
+
while (m_workBuffer.size() > 0) {
|
|
334
|
+
scheduleAsync(std::move(m_workBuffer.front()));
|
|
335
|
+
m_workBuffer.pop_front();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
void Instance::JSCallInvoker::invokeSync(CallFunc&& /*work*/) {
|
|
340
|
+
// TODO: Replace JS Callinvoker with RuntimeExecutor.
|
|
341
|
+
throw std::runtime_error(
|
|
342
|
+
"Synchronous native -> JS calls are currently not supported.");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
void Instance::JSCallInvoker::invokeAsync(CallFunc&& work) noexcept {
|
|
346
|
+
std::scoped_lock guard(m_mutex);
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Why is is necessary to queue up async work?
|
|
350
|
+
*
|
|
351
|
+
* 1. TurboModuleManager must be created synchronously after the Instance,
|
|
352
|
+
* before we load the source code. This is when the NativeModule system
|
|
353
|
+
* is initialized. RCTDevLoadingView shows bundle download progress.
|
|
354
|
+
* 2. TurboModuleManager requires a JS CallInvoker.
|
|
355
|
+
* 3. The JS CallInvoker requires the NativeToJsBridge, which is created on
|
|
356
|
+
* the JS thread in Instance::initializeBridge.
|
|
357
|
+
*
|
|
358
|
+
* Therefore, although we don't call invokeAsync before the JS bundle is
|
|
359
|
+
* executed, this buffering is implemented anyways to ensure that work
|
|
360
|
+
* isn't discarded.
|
|
361
|
+
*/
|
|
362
|
+
if (m_shouldBuffer) {
|
|
363
|
+
m_workBuffer.push_back(std::move(work));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
scheduleAsync(std::move(work));
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
void Instance::JSCallInvoker::scheduleAsync(CallFunc&& work) noexcept {
|
|
371
|
+
if (auto strongNativeToJsBridge = m_nativeToJsBridge.lock()) {
|
|
372
|
+
strongNativeToJsBridge->runOnExecutorQueue(
|
|
373
|
+
[work = std::move(work),
|
|
374
|
+
weakNativeToJsBridge = m_nativeToJsBridge](JSExecutor* executor) {
|
|
375
|
+
auto* runtime = (jsi::Runtime*)executor->getJavaScriptContext();
|
|
376
|
+
work(*runtime);
|
|
377
|
+
if (executorSurvivedTask(weakNativeToJsBridge)) { // [Windows]
|
|
378
|
+
executor->flush();
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
} // namespace facebook::react
|
|
385
|
+
|
|
386
|
+
#endif // RCT_FIT_RM_OLD_RUNTIME
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#ifndef RCT_FIT_RM_OLD_RUNTIME
|
|
11
|
+
|
|
12
|
+
#include <atomic>
|
|
13
|
+
#include <functional>
|
|
14
|
+
#include <map>
|
|
15
|
+
#include <vector>
|
|
16
|
+
|
|
17
|
+
#include <ReactCommon/CallInvoker.h>
|
|
18
|
+
#include <ReactCommon/RuntimeExecutor.h>
|
|
19
|
+
#include <cxxreact/JSExecutor.h>
|
|
20
|
+
#include <jsinspector-modern/ReactCdp.h>
|
|
21
|
+
|
|
22
|
+
namespace folly {
|
|
23
|
+
struct dynamic;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
namespace facebook::react {
|
|
27
|
+
|
|
28
|
+
struct InstanceCallback;
|
|
29
|
+
class JsToNativeBridge;
|
|
30
|
+
class MessageQueueThread;
|
|
31
|
+
class ModuleRegistry;
|
|
32
|
+
class RAMBundleRegistry;
|
|
33
|
+
|
|
34
|
+
// This class manages calls from native code to JS. It also manages
|
|
35
|
+
// executors and their threads. All functions here can be called from
|
|
36
|
+
// any thread.
|
|
37
|
+
//
|
|
38
|
+
// Except for loadBundleSync(), all void methods will queue
|
|
39
|
+
// work to run on the jsQueue passed to the ctor, and return
|
|
40
|
+
// immediately.
|
|
41
|
+
class NativeToJsBridge {
|
|
42
|
+
public:
|
|
43
|
+
friend class JsToNativeBridge;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* This must be called on the main JS thread.
|
|
47
|
+
*/
|
|
48
|
+
NativeToJsBridge(
|
|
49
|
+
JSExecutorFactory* jsExecutorFactory,
|
|
50
|
+
std::shared_ptr<ModuleRegistry> registry,
|
|
51
|
+
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
52
|
+
std::shared_ptr<InstanceCallback> callback);
|
|
53
|
+
virtual ~NativeToJsBridge();
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Executes a function with the module ID and method ID and any additional
|
|
57
|
+
* arguments in JS.
|
|
58
|
+
*/
|
|
59
|
+
void callFunction(
|
|
60
|
+
std::string&& module,
|
|
61
|
+
std::string&& method,
|
|
62
|
+
folly::dynamic&& args);
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Invokes a callback with the cbID, and optional additional arguments in JS.
|
|
66
|
+
*/
|
|
67
|
+
void invokeCallback(double callbackId, folly::dynamic&& args);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Sets global variables in the JS Context.
|
|
71
|
+
*/
|
|
72
|
+
void initializeRuntime();
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Starts the JS application. If bundleRegistry is non-null, then it is
|
|
76
|
+
* used to fetch JavaScript modules as individual scripts.
|
|
77
|
+
* Otherwise, the script is assumed to include all the modules.
|
|
78
|
+
*/
|
|
79
|
+
void loadBundle(
|
|
80
|
+
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
81
|
+
std::unique_ptr<const JSBigString> startupCode,
|
|
82
|
+
std::string sourceURL);
|
|
83
|
+
void loadBundleSync(
|
|
84
|
+
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
85
|
+
std::unique_ptr<const JSBigString> startupCode,
|
|
86
|
+
std::string sourceURL);
|
|
87
|
+
|
|
88
|
+
void registerBundle(uint32_t bundleId, const std::string& bundlePath);
|
|
89
|
+
void setGlobalVariable(
|
|
90
|
+
std::string propName,
|
|
91
|
+
std::unique_ptr<const JSBigString> jsonValue);
|
|
92
|
+
void* getJavaScriptContext();
|
|
93
|
+
bool isInspectable();
|
|
94
|
+
bool isBatchActive();
|
|
95
|
+
|
|
96
|
+
void handleMemoryPressure(int pressureLevel);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Synchronously tears down the bridge and the main executor.
|
|
100
|
+
*/
|
|
101
|
+
void destroy();
|
|
102
|
+
|
|
103
|
+
// [Windows] Whether the executor still exists. Call only on the JS queue: the
|
|
104
|
+
// executor is created and deleted there, so this read doesn't race. The
|
|
105
|
+
// destructor can also delete it, but not while the caller holds a reference.
|
|
106
|
+
bool hasExecutor() const noexcept {
|
|
107
|
+
return m_executor != nullptr;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void runOnExecutorQueue(std::function<void(JSExecutor*)>&& task) noexcept;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* NativeMethodCallInvoker is used by TurboModules to schedule work on the
|
|
114
|
+
* NativeModule thread(s).
|
|
115
|
+
*/
|
|
116
|
+
std::shared_ptr<NativeMethodCallInvoker> getDecoratedNativeMethodCallInvoker(
|
|
117
|
+
std::shared_ptr<NativeMethodCallInvoker> nativeInvoker) const;
|
|
118
|
+
|
|
119
|
+
jsinspector_modern::RuntimeTargetDelegate& getInspectorTargetDelegate();
|
|
120
|
+
|
|
121
|
+
private:
|
|
122
|
+
// This is used to avoid a race condition where a proxyCallback gets queued
|
|
123
|
+
// after ~NativeToJsBridge(), on the same thread. In that case, the callback
|
|
124
|
+
// will try to run the task on m_callback which will have been destroyed
|
|
125
|
+
// within ~NativeToJsBridge(), thus causing a SIGSEGV.
|
|
126
|
+
std::shared_ptr<bool> m_destroyed;
|
|
127
|
+
std::shared_ptr<JsToNativeBridge> m_delegate;
|
|
128
|
+
std::unique_ptr<JSExecutor> m_executor;
|
|
129
|
+
std::shared_ptr<MessageQueueThread> m_executorMessageQueueThread;
|
|
130
|
+
|
|
131
|
+
// Memoize this on the JS thread, so that it can be inspected from
|
|
132
|
+
// any thread later. This assumes inspectability doesn't change for
|
|
133
|
+
// a JSExecutor instance, which is true for all existing implementations.
|
|
134
|
+
bool m_inspectable;
|
|
135
|
+
|
|
136
|
+
// Keep track of whether the JS bundle containing the application logic causes
|
|
137
|
+
// exception when evaluated initially. If so, more calls to JS will very
|
|
138
|
+
// likely fail as well, so this flag can help prevent them.
|
|
139
|
+
bool m_applicationScriptHasFailure = false;
|
|
140
|
+
|
|
141
|
+
#ifdef WITH_FBSYSTRACE
|
|
142
|
+
std::atomic<uint_least32_t> m_systraceCookie{0};
|
|
143
|
+
#endif
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
} // namespace facebook::react
|
|
147
|
+
|
|
148
|
+
#endif // RCT_FIT_RM_OLD_RUNTIME
|
|
@@ -9,11 +9,18 @@ Set-Location -Path $RepoRoot
|
|
|
9
9
|
try
|
|
10
10
|
{
|
|
11
11
|
[xml] $nugetConfig = Get-Content "NuGet.Config"
|
|
12
|
-
$
|
|
13
|
-
$newFeed
|
|
14
|
-
$newFeed.
|
|
15
|
-
$
|
|
16
|
-
$nugetConfig.
|
|
12
|
+
$feedKey = "Project.Reunion.nuget.internal"
|
|
13
|
+
$newFeed = $nugetConfig.CreateElement("add")
|
|
14
|
+
$newFeed.SetAttribute("key", $feedKey)
|
|
15
|
+
$newFeed.SetAttribute("value", "https://microsoft.pkgs.visualstudio.com/ProjectReunion/_packaging/Project.Reunion.nuget.internal/nuget/v3/index.json")
|
|
16
|
+
[void] $nugetConfig.configuration.packageSources.AppendChild($newFeed)
|
|
17
|
+
$mapping = $nugetConfig.CreateElement("packageSource")
|
|
18
|
+
$mapping.SetAttribute("key", $feedKey)
|
|
19
|
+
$pattern = $nugetConfig.CreateElement("package")
|
|
20
|
+
$pattern.SetAttribute("pattern", "*")
|
|
21
|
+
[void] $mapping.AppendChild($pattern)
|
|
22
|
+
[void] $nugetConfig.configuration.packageSourceMapping.AppendChild($mapping)
|
|
23
|
+
$nugetConfig.Save("$RepoRoot\NuGet.Config")
|
|
17
24
|
}
|
|
18
25
|
finally
|
|
19
26
|
{
|
|
@@ -19,8 +19,8 @@ function Restore-Solution([string] $solution, [string[]] $extraArgs) {
|
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
21
|
# Some node_modules packages ship a NuGet.Config that re-adds the public nuget.org feed. That
|
|
22
|
-
#
|
|
23
|
-
# Strip any nuget.org source so restore
|
|
22
|
+
# bypasses the approved source policy and trips corporate network blocks on api.nuget.org.
|
|
23
|
+
# Strip any nuget.org source so restore uses the approved sources and mappings in the root NuGet.Config.
|
|
24
24
|
Get-ChildItem -File -Recurse -Path $RepoRoot -Filter NuGet.Config -ErrorAction SilentlyContinue |
|
|
25
25
|
Where-Object { $_.FullName -match '\\node_modules\\' } | ForEach-Object {
|
|
26
26
|
$configPath = $_.FullName
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include "IWebSocketResource.h"
|
|
11
11
|
|
|
12
12
|
// Standard Library
|
|
13
|
+
#include <coroutine>
|
|
13
14
|
#include <future>
|
|
14
15
|
#include <mutex>
|
|
15
16
|
#include <queue>
|
|
@@ -27,12 +28,7 @@ class WinRTWebSocketResource2 : public IWebSocketResource,
|
|
|
27
28
|
void operator=(const TaskSequencer &) = delete;
|
|
28
29
|
|
|
29
30
|
private:
|
|
30
|
-
// `experimental` is deprecated starting Visual Studio 2026
|
|
31
|
-
#if _MSC_VER >= 1951
|
|
32
31
|
using CoroHandle = std::coroutine_handle<>;
|
|
33
|
-
#else
|
|
34
|
-
using CoroHandle = std::experimental::coroutine_handle<>;
|
|
35
|
-
#endif
|
|
36
32
|
struct Suspender {
|
|
37
33
|
CoroHandle m_handle;
|
|
38
34
|
|