react-native-windows 0.81.36 → 0.81.38
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/CompositionEventHandler.cpp +3 -2
- 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 +328 -75
- 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/TurboModulesProvider.cpp +30 -13
- package/Microsoft.ReactNative/ViewProps.idl +11 -0
- package/Microsoft.ReactNative.Cxx/ComponentView.Experimental.interop.h +12 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- 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/Shared.vcxitems +3 -3
- package/Shared/Shared.vcxitems.filters +1 -1
- package/index.windows.js +5 -0
- package/package.json +2 -2
- package/Microsoft.ReactNative/Fabric/AbiState.cpp +0 -29
|
@@ -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
|
package/Shared/Shared.vcxitems
CHANGED
|
@@ -190,6 +190,9 @@
|
|
|
190
190
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewProps.cpp">
|
|
191
191
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
192
192
|
</ClCompile>
|
|
193
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiTextInputShadowNode.cpp">
|
|
194
|
+
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
195
|
+
</ClCompile>
|
|
193
196
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiShadowNode.cpp">
|
|
194
197
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
195
198
|
</ClCompile>
|
|
@@ -199,9 +202,6 @@
|
|
|
199
202
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewShadowNode.cpp">
|
|
200
203
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
201
204
|
</ClCompile>
|
|
202
|
-
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiState.cpp">
|
|
203
|
-
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
204
|
-
</ClCompile>
|
|
205
205
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\ComponentView.cpp">
|
|
206
206
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
207
207
|
</ClCompile>
|
|
@@ -273,7 +273,6 @@
|
|
|
273
273
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\platform\react\renderer\graphics\PlatformColorUtils.cpp" />
|
|
274
274
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiPortalShadowNode.cpp" />
|
|
275
275
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiViewShadowNode.cpp" />
|
|
276
|
-
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiState.cpp" />
|
|
277
276
|
<ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Utils\ThemeUtils.cpp" />
|
|
278
277
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\DebuggingOverlayComponentView.cpp" />
|
|
279
278
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\CompositionViewComponentView.cpp" />
|
|
@@ -338,6 +337,7 @@
|
|
|
338
337
|
</ClCompile>
|
|
339
338
|
<ClCompile Include="$(ReactNativeDir)\ReactCommon\cxxreact\Instance.cpp" />
|
|
340
339
|
<ClCompile Include="$(ReactNativeDir)\ReactCommon\cxxreact\JSExecutor.cpp" />
|
|
340
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiTextInputShadowNode.cpp" />
|
|
341
341
|
</ItemGroup>
|
|
342
342
|
<ItemGroup>
|
|
343
343
|
<Filter Include="Source Files">
|
package/index.windows.js
CHANGED
|
@@ -369,6 +369,11 @@ module.exports = {
|
|
|
369
369
|
get AppTheme() {
|
|
370
370
|
return require('./Libraries/AppTheme/AppTheme').AppTheme;
|
|
371
371
|
},
|
|
372
|
+
// Export this to allow custom native textinput components to provide a full view spec
|
|
373
|
+
get TextInputViewSpec() {
|
|
374
|
+
return require('./Libraries/Components/TextInput/WindowsTextInputNativeComponent')
|
|
375
|
+
.__INTERNAL_VIEW_CONFIG;
|
|
376
|
+
},
|
|
372
377
|
} as ReactNativePublicAPI;
|
|
373
378
|
|
|
374
379
|
if (__DEV__) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.38",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@react-native-community/cli": "17.0.0",
|
|
27
27
|
"@react-native-community/cli-platform-android": "17.0.0",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "17.0.0",
|
|
29
|
-
"@react-native-windows/cli": "0.81.
|
|
29
|
+
"@react-native-windows/cli": "0.81.11",
|
|
30
30
|
"@react-native/assets": "1.0.0",
|
|
31
31
|
"@react-native/assets-registry": "0.81.6",
|
|
32
32
|
"@react-native/codegen": "0.81.6",
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
|
|
4
|
-
#include "AbiState.h"
|
|
5
|
-
|
|
6
|
-
namespace Microsoft::ReactNative {
|
|
7
|
-
|
|
8
|
-
AbiComponentState::AbiComponentState(facebook::react::State::Shared const &state) {
|
|
9
|
-
m_state = std::static_pointer_cast<facebook::react::ConcreteState<AbiStateData> const>(state);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
winrt::Windows::Foundation::IInspectable AbiComponentState::Data() noexcept {
|
|
13
|
-
return m_state->getData().userdata;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
void AbiComponentState::UpdateState(const winrt::Windows::Foundation::IInspectable &data) noexcept {
|
|
17
|
-
AbiStateData state;
|
|
18
|
-
state.userdata = data;
|
|
19
|
-
m_state->updateState(std::move(state));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
void AbiComponentState::UpdateStateWithMutation(
|
|
23
|
-
const winrt::Microsoft::ReactNative::StateUpdateMutation &mutation) noexcept {
|
|
24
|
-
m_state->updateState([mutation](const AbiStateData &oldData) {
|
|
25
|
-
return std::make_shared<AbiStateData const>(mutation(oldData.userdata));
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
} // namespace Microsoft::ReactNative
|