react-native-windows 0.71.24 → 0.71.26
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/Directory.Build.props +5 -0
- package/Libraries/Network/RCTNetworking.windows.js +10 -16
- package/Microsoft.ReactNative/IReactDispatcher.cpp +4 -0
- package/Microsoft.ReactNative/IReactDispatcher.h +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +3 -7
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -7
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +43 -21
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +0 -2
- package/Microsoft.ReactNative/Views/DevMenu.cpp +3 -3
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiLoader.cpp +16 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +43 -12
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +17 -6
- package/Microsoft.ReactNative.Managed/packages.lock.json +73 -4
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +4 -4
- package/PropertySheets/React.Cpp.props +3 -3
- package/PropertySheets/Warnings.props +6 -0
- package/ReactCommon/ReactCommon.vcxproj +53 -1
- package/ReactCommon/cgmanifest.json +15 -0
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +36 -0
- package/Shared/BaseFileReaderResource.cpp +95 -0
- package/Shared/BaseFileReaderResource.h +41 -0
- package/Shared/CreateModules.h +27 -5
- package/Shared/DevSupportManager.cpp +2 -9
- package/Shared/DevSupportManager.h +2 -6
- package/Shared/HermesRuntimeHolder.cpp +344 -84
- package/Shared/HermesRuntimeHolder.h +32 -21
- package/Shared/HermesSamplingProfiler.cpp +66 -14
- package/Shared/HermesSamplingProfiler.h +5 -3
- package/Shared/IFileReaderResource.h +36 -0
- package/Shared/InspectorPackagerConnection.cpp +62 -108
- package/Shared/InspectorPackagerConnection.h +9 -21
- package/Shared/JSI/RuntimeHolder.h +2 -2
- package/Shared/JSI/ScriptStore.h +18 -20
- package/Shared/JSI/V8RuntimeHolder.cpp +260 -0
- package/Shared/JSI/V8RuntimeHolder.h +37 -0
- package/Shared/Modules/BlobModule.cpp +93 -298
- package/Shared/Modules/BlobModule.h +25 -91
- package/Shared/Modules/CxxModuleUtilities.cpp +32 -0
- package/Shared/Modules/CxxModuleUtilities.h +17 -0
- package/Shared/Modules/FileReaderModule.cpp +118 -51
- package/Shared/Modules/FileReaderModule.h +27 -1
- package/Shared/Modules/HttpModule.cpp +143 -32
- package/Shared/Modules/HttpModule.h +33 -1
- package/Shared/Modules/IRequestBodyHandler.h +6 -4
- package/Shared/Modules/IResponseHandler.h +3 -3
- package/Shared/Modules/IUriHandler.h +3 -3
- package/Shared/Modules/IWebSocketModuleContentHandler.h +6 -4
- package/Shared/Modules/WebSocketModule.cpp +190 -7
- package/Shared/Modules/WebSocketTurboModule.h +52 -0
- package/Shared/Networking/DefaultBlobResource.cpp +328 -0
- package/Shared/Networking/DefaultBlobResource.h +133 -0
- package/Shared/Networking/IBlobResource.h +56 -0
- package/Shared/Networking/IHttpResource.h +6 -5
- package/Shared/Networking/WinRTHttpResource.cpp +49 -32
- package/Shared/Networking/WinRTHttpResource.h +4 -3
- package/Shared/Networking/WinRTTypes.h +3 -3
- package/Shared/OInstance.cpp +32 -68
- package/Shared/SafeLoadLibrary.cpp +41 -0
- package/Shared/SafeLoadLibrary.h +15 -0
- package/Shared/Shared.vcxitems +27 -9
- package/Shared/Shared.vcxitems.filters +47 -33
- package/package.json +2 -2
- package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +1 -1
- package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +0 -59
- package/Microsoft.ReactNative/Base/CoreNativeModules.h +0 -30
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +0 -2103
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +0 -73
- package/Shared/HermesShim.cpp +0 -118
- package/Shared/HermesShim.h +0 -21
- package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +0 -209
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +0 -44
- package/Shared/V8JSIRuntimeHolder.cpp +0 -70
- package/Shared/V8JSIRuntimeHolder.h +0 -53
- /package/Shared/{Modules/IBlobPersistor.h → IBlobPersistor.h} +0 -0
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
// React Native
|
|
10
10
|
#include <cxxreact/Instance.h>
|
|
11
11
|
|
|
12
|
+
// React Native Windows
|
|
13
|
+
#include <ReactContext.h>
|
|
14
|
+
|
|
12
15
|
// Standard Library
|
|
13
16
|
#include <memory>
|
|
14
17
|
#include <string>
|
|
@@ -20,4 +23,18 @@ void SendEvent(
|
|
|
20
23
|
std::string &&eventName,
|
|
21
24
|
folly::dynamic &&args);
|
|
22
25
|
|
|
26
|
+
void SendEvent(
|
|
27
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
28
|
+
std::wstring_view &&eventName,
|
|
29
|
+
winrt::Microsoft::ReactNative::JSValueObject &&args) noexcept;
|
|
30
|
+
|
|
31
|
+
void SendEvent(
|
|
32
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
33
|
+
std::wstring_view &&eventName,
|
|
34
|
+
winrt::Microsoft::ReactNative::JSValueArray &&args) noexcept;
|
|
35
|
+
|
|
36
|
+
winrt::Microsoft::ReactNative::JSValue ToJSValue(folly::dynamic &value) noexcept;
|
|
37
|
+
|
|
38
|
+
folly::dynamic ToDynamic(const winrt::Microsoft::ReactNative::JSValue &value) noexcept;
|
|
39
|
+
|
|
23
40
|
} // namespace Microsoft::React::Modules
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#include "FileReaderModule.h"
|
|
5
5
|
|
|
6
|
+
#include <CreateModules.h>
|
|
6
7
|
#include <ReactPropertyBag.h>
|
|
7
8
|
#include <sstream>
|
|
8
9
|
|
|
@@ -19,17 +20,18 @@
|
|
|
19
20
|
|
|
20
21
|
using namespace facebook::xplat;
|
|
21
22
|
|
|
23
|
+
namespace msrn = winrt::Microsoft::ReactNative;
|
|
24
|
+
|
|
22
25
|
using folly::dynamic;
|
|
23
26
|
using std::string;
|
|
24
27
|
using std::weak_ptr;
|
|
25
|
-
using winrt::Microsoft::ReactNative::IReactPropertyBag;
|
|
26
|
-
using winrt::Microsoft::ReactNative::ReactNonAbiValue;
|
|
27
|
-
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
28
|
-
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
29
28
|
using winrt::Windows::Foundation::IInspectable;
|
|
30
29
|
|
|
31
30
|
namespace {
|
|
32
|
-
constexpr char
|
|
31
|
+
constexpr char s_moduleName[] = "FileReaderModule";
|
|
32
|
+
constexpr wchar_t s_moduleNameW[] = L"FileReaderModule";
|
|
33
|
+
|
|
34
|
+
msrn::ReactModuleProvider s_moduleProvider = msrn::MakeTurboModuleProvider<Microsoft::React::FileReaderTurboModule>();
|
|
33
35
|
} // namespace
|
|
34
36
|
|
|
35
37
|
namespace Microsoft::React {
|
|
@@ -37,7 +39,7 @@ namespace Microsoft::React {
|
|
|
37
39
|
#pragma region FileReaderModule
|
|
38
40
|
|
|
39
41
|
FileReaderModule::FileReaderModule(weak_ptr<IBlobPersistor> weakBlobPersistor) noexcept
|
|
40
|
-
:
|
|
42
|
+
: m_resource{IFileReaderResource::Make(weakBlobPersistor)} {}
|
|
41
43
|
|
|
42
44
|
FileReaderModule::~FileReaderModule() noexcept /*override*/
|
|
43
45
|
{}
|
|
@@ -45,7 +47,7 @@ FileReaderModule::~FileReaderModule() noexcept /*override*/
|
|
|
45
47
|
#pragma region CxxModule
|
|
46
48
|
|
|
47
49
|
string FileReaderModule::getName() {
|
|
48
|
-
return
|
|
50
|
+
return s_moduleName;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
std::map<string, dynamic> FileReaderModule::getConstants() {
|
|
@@ -61,41 +63,28 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
|
61
63
|
/// </param>
|
|
62
64
|
///
|
|
63
65
|
"readAsDataURL",
|
|
64
|
-
[
|
|
65
|
-
if (!blobPersistor) {
|
|
66
|
-
return reject({"Could not find Blob persistor"});
|
|
67
|
-
}
|
|
68
|
-
|
|
66
|
+
[resource = m_resource](dynamic args, Callback resolve, Callback reject) {
|
|
69
67
|
auto blob = jsArgAsObject(args, 0);
|
|
70
68
|
|
|
71
69
|
auto blobId = blob["blobId"].asString();
|
|
72
70
|
auto offset = blob["offset"].asInt();
|
|
73
71
|
auto size = blob["size"].asInt();
|
|
74
72
|
|
|
75
|
-
winrt::array_view<uint8_t const> bytes;
|
|
76
|
-
try {
|
|
77
|
-
bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
|
|
78
|
-
} catch (const std::exception &e) {
|
|
79
|
-
return reject({e.what()});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
auto result = string{"data:"};
|
|
83
73
|
auto typeItr = blob.find("type");
|
|
74
|
+
string type{};
|
|
84
75
|
if (typeItr == blob.items().end()) {
|
|
85
|
-
|
|
76
|
+
type = "application/octet-stream";
|
|
86
77
|
} else {
|
|
87
|
-
|
|
78
|
+
type = (*typeItr).second.asString();
|
|
88
79
|
}
|
|
89
|
-
result += ";base64,";
|
|
90
|
-
|
|
91
|
-
// https://www.boost.org/doc/libs/1_76_0/libs/serialization/doc/dataflow.html
|
|
92
|
-
using namespace boost::archive::iterators;
|
|
93
|
-
typedef base64_from_binary<transform_width<const char *, 6, 8>> encode_base64;
|
|
94
|
-
std::ostringstream oss;
|
|
95
|
-
std::copy(encode_base64(bytes.cbegin()), encode_base64(bytes.cend()), ostream_iterator<char>(oss));
|
|
96
|
-
result += oss.str();
|
|
97
80
|
|
|
98
|
-
|
|
81
|
+
resource->ReadAsDataUrl(
|
|
82
|
+
std::move(blobId),
|
|
83
|
+
offset,
|
|
84
|
+
size,
|
|
85
|
+
std::move(type),
|
|
86
|
+
[&resolve](string &&message) { resolve({std::move(message)}); },
|
|
87
|
+
[&reject](string &&message) { reject({std::move(message)}); });
|
|
99
88
|
}},
|
|
100
89
|
{///
|
|
101
90
|
/// <param name="args">
|
|
@@ -105,11 +94,7 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
|
105
94
|
/// </param>
|
|
106
95
|
///
|
|
107
96
|
"readAsText",
|
|
108
|
-
[
|
|
109
|
-
if (!blobPersistor) {
|
|
110
|
-
return reject({"Could not find Blob persistor"});
|
|
111
|
-
}
|
|
112
|
-
|
|
97
|
+
[resource = m_resource](dynamic args, Callback resolve, Callback reject) {
|
|
113
98
|
auto blob = jsArgAsObject(args, 0);
|
|
114
99
|
auto encoding = jsArgAsString(args, 1); // Default: "UTF-8"
|
|
115
100
|
|
|
@@ -117,18 +102,13 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
|
117
102
|
auto offset = blob["offset"].asInt();
|
|
118
103
|
auto size = blob["size"].asInt();
|
|
119
104
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// #9982 - Handle non-UTF8 encodings
|
|
128
|
-
// See https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/charset/Charset.html
|
|
129
|
-
auto result = string{bytes.cbegin(), bytes.cend()};
|
|
130
|
-
|
|
131
|
-
resolve({std::move(result)});
|
|
105
|
+
resource->ReadAsText(
|
|
106
|
+
std::move(blobId),
|
|
107
|
+
offset,
|
|
108
|
+
size,
|
|
109
|
+
std::move(encoding),
|
|
110
|
+
[&resolve](string &&message) { resolve({std::move(message)}); },
|
|
111
|
+
[&reject](string &&message) { reject({std::move(message)}); });
|
|
132
112
|
}}};
|
|
133
113
|
}
|
|
134
114
|
|
|
@@ -136,14 +116,93 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
|
136
116
|
|
|
137
117
|
#pragma endregion FileReaderModule
|
|
138
118
|
|
|
119
|
+
#pragma region FileReaderTurboModule
|
|
120
|
+
|
|
121
|
+
void FileReaderTurboModule::Initialize(msrn::ReactContext const &reactContext) noexcept {
|
|
122
|
+
auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
123
|
+
auto props = reactContext.Properties();
|
|
124
|
+
auto prop = props.Get(propId);
|
|
125
|
+
m_resource = IFileReaderResource::Make(prop.Value());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
///
|
|
129
|
+
/// <param name="data">
|
|
130
|
+
/// Blob object with the following fields:
|
|
131
|
+
/// - blobId
|
|
132
|
+
/// - offset
|
|
133
|
+
/// - size
|
|
134
|
+
/// - type (optional)
|
|
135
|
+
/// </param>
|
|
136
|
+
/// <param name="result">
|
|
137
|
+
/// Either resolves or rejects the current method with a given text message.
|
|
138
|
+
/// </param>
|
|
139
|
+
///
|
|
140
|
+
void FileReaderTurboModule::ReadAsDataUrl(msrn::JSValue &&data, msrn::ReactPromise<msrn::JSValue> &&result) noexcept {
|
|
141
|
+
auto &blob = data.AsObject();
|
|
142
|
+
auto blobId = blob["blobId"].AsString();
|
|
143
|
+
auto offset = blob["offset"].AsInt64();
|
|
144
|
+
auto size = blob["size"].AsInt64();
|
|
145
|
+
|
|
146
|
+
auto typeItr = blob.find("type");
|
|
147
|
+
string type{};
|
|
148
|
+
if (typeItr == blob.end()) {
|
|
149
|
+
type = "application/octet-stream";
|
|
150
|
+
} else {
|
|
151
|
+
type = (*typeItr).second.AsString();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
m_resource->ReadAsDataUrl(
|
|
155
|
+
std::move(blobId),
|
|
156
|
+
offset,
|
|
157
|
+
size,
|
|
158
|
+
std::move(type),
|
|
159
|
+
[&result](string &&message) { result.Resolve(std::move(message)); },
|
|
160
|
+
[&result](string &&message) { result.Reject(winrt::to_hstring(std::move(message)).c_str()); });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
///
|
|
164
|
+
/// <param name="data">
|
|
165
|
+
/// Blob object with the following fields:
|
|
166
|
+
/// - blobId
|
|
167
|
+
/// - offset
|
|
168
|
+
/// - size
|
|
169
|
+
/// - type (optional)
|
|
170
|
+
/// </param>
|
|
171
|
+
/// <param name="encoding">
|
|
172
|
+
/// Text encoding to proces data with.
|
|
173
|
+
/// </param>
|
|
174
|
+
/// <param name="result">
|
|
175
|
+
/// Either resolves or rejects the current method with a given text message.
|
|
176
|
+
/// </param>
|
|
177
|
+
///
|
|
178
|
+
void FileReaderTurboModule::ReadAsText(
|
|
179
|
+
msrn::JSValue &&data,
|
|
180
|
+
string &&encoding,
|
|
181
|
+
msrn::ReactPromise<msrn::JSValue> &&result) noexcept {
|
|
182
|
+
auto &blob = data.AsObject();
|
|
183
|
+
auto blobId = blob["blobId"].AsString();
|
|
184
|
+
auto offset = blob["offset"].AsInt64();
|
|
185
|
+
auto size = blob["size"].AsInt64();
|
|
186
|
+
|
|
187
|
+
m_resource->ReadAsText(
|
|
188
|
+
std::move(blobId),
|
|
189
|
+
offset,
|
|
190
|
+
size,
|
|
191
|
+
std::move(encoding),
|
|
192
|
+
[&result](string &&message) { result.Resolve(std::move(message)); },
|
|
193
|
+
[&result](string &&message) { result.Reject(winrt::to_hstring(std::move(message)).c_str()); });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
#pragma endregion FileReaderTurboModule
|
|
197
|
+
|
|
139
198
|
/*extern*/ const char *GetFileReaderModuleName() noexcept {
|
|
140
|
-
return
|
|
199
|
+
return s_moduleName;
|
|
141
200
|
}
|
|
142
201
|
|
|
143
202
|
/*extern*/ std::unique_ptr<module::CxxModule> CreateFileReaderModule(
|
|
144
203
|
IInspectable const &inspectableProperties) noexcept {
|
|
145
|
-
auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
146
|
-
auto propBag = ReactPropertyBag{inspectableProperties.try_as<IReactPropertyBag>()};
|
|
204
|
+
auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
205
|
+
auto propBag = msrn::ReactPropertyBag{inspectableProperties.try_as<msrn::IReactPropertyBag>()};
|
|
147
206
|
|
|
148
207
|
if (auto prop = propBag.Get(propId)) {
|
|
149
208
|
auto weakBlobPersistor = prop.Value();
|
|
@@ -154,4 +213,12 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
|
154
213
|
return nullptr;
|
|
155
214
|
}
|
|
156
215
|
|
|
216
|
+
/*extern*/ const wchar_t *GetFileReaderTurboModuleName() noexcept {
|
|
217
|
+
return s_moduleNameW;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/*extern*/ const msrn::ReactModuleProvider &GetFileReaderModuleProvider() noexcept {
|
|
221
|
+
return s_moduleProvider;
|
|
222
|
+
}
|
|
223
|
+
|
|
157
224
|
} // namespace Microsoft::React
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
+
#include <NativeFileReaderModuleSpec.g.h>
|
|
7
|
+
|
|
8
|
+
#include <IFileReaderResource.h>
|
|
9
|
+
#include <NativeModules.h>
|
|
6
10
|
#include "IBlobPersistor.h"
|
|
7
11
|
|
|
8
12
|
// React Native
|
|
@@ -48,7 +52,29 @@ class FileReaderModule : public facebook::xplat::module::CxxModule {
|
|
|
48
52
|
#pragma endregion CxxModule
|
|
49
53
|
|
|
50
54
|
private:
|
|
51
|
-
std::
|
|
55
|
+
std::shared_ptr<IFileReaderResource> m_resource;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
REACT_MODULE(FileReaderTurboModule, L"FileReaderModule")
|
|
59
|
+
struct FileReaderTurboModule {
|
|
60
|
+
using ModuleSpec = ReactNativeSpecs::FileReaderModuleSpec;
|
|
61
|
+
|
|
62
|
+
REACT_INIT(Initialize)
|
|
63
|
+
void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
|
|
64
|
+
|
|
65
|
+
REACT_METHOD(ReadAsDataUrl, L"readAsDataURL")
|
|
66
|
+
void ReadAsDataUrl(
|
|
67
|
+
winrt::Microsoft::ReactNative::JSValue &&data,
|
|
68
|
+
winrt::Microsoft::ReactNative::ReactPromise<winrt::Microsoft::ReactNative::JSValue> &&result) noexcept;
|
|
69
|
+
|
|
70
|
+
REACT_METHOD(ReadAsText, L"readAsText")
|
|
71
|
+
void ReadAsText(
|
|
72
|
+
winrt::Microsoft::ReactNative::JSValue &&data,
|
|
73
|
+
std::string &&encoding,
|
|
74
|
+
winrt::Microsoft::ReactNative::ReactPromise<winrt::Microsoft::ReactNative::JSValue> &&result) noexcept;
|
|
75
|
+
|
|
76
|
+
private:
|
|
77
|
+
std::shared_ptr<IFileReaderResource> m_resource;
|
|
52
78
|
};
|
|
53
79
|
|
|
54
80
|
} // namespace Microsoft::React
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
#include "HttpModule.h"
|
|
7
7
|
|
|
8
|
+
#include <CreateModules.h>
|
|
8
9
|
#include <Modules/CxxModuleUtilities.h>
|
|
9
10
|
#include <ReactPropertyBag.h>
|
|
10
11
|
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
|
|
15
16
|
using facebook::react::Instance;
|
|
16
17
|
using folly::dynamic;
|
|
18
|
+
using std::function;
|
|
17
19
|
using std::shared_ptr;
|
|
18
20
|
using std::string;
|
|
19
21
|
using std::weak_ptr;
|
|
@@ -23,12 +25,15 @@ using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
|
23
25
|
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
24
26
|
using winrt::Windows::Foundation::IInspectable;
|
|
25
27
|
|
|
28
|
+
namespace msrn = winrt::Microsoft::ReactNative;
|
|
29
|
+
|
|
26
30
|
namespace {
|
|
27
31
|
|
|
28
32
|
using Microsoft::React::Modules::SendEvent;
|
|
29
33
|
using Microsoft::React::Networking::IHttpResource;
|
|
30
34
|
|
|
31
|
-
constexpr char
|
|
35
|
+
constexpr char s_moduleName[] = "Networking";
|
|
36
|
+
constexpr wchar_t s_moduleNameW[] = L"Networking";
|
|
32
37
|
|
|
33
38
|
// React event names
|
|
34
39
|
constexpr char completedResponse[] = "didCompleteNetworkResponse";
|
|
@@ -38,6 +43,15 @@ constexpr char receivedIncrementalData[] = "didReceiveNetworkIncrementalData";
|
|
|
38
43
|
constexpr char receivedDataProgress[] = "didReceiveNetworkDataProgress";
|
|
39
44
|
constexpr char receivedData[] = "didReceiveNetworkData";
|
|
40
45
|
|
|
46
|
+
constexpr wchar_t completedResponseW[] = L"didCompleteNetworkResponse";
|
|
47
|
+
constexpr wchar_t receivedResponseW[] = L"didReceiveNetworkResponse";
|
|
48
|
+
constexpr wchar_t sentDataW[] = L"didSendNetworkData";
|
|
49
|
+
constexpr wchar_t receivedIncrementalDataW[] = L"didReceiveNetworkIncrementalData";
|
|
50
|
+
constexpr wchar_t receivedDataProgressW[] = L"didReceiveNetworkDataProgress";
|
|
51
|
+
constexpr wchar_t receivedDataW[] = L"didReceiveNetworkData";
|
|
52
|
+
|
|
53
|
+
msrn::ReactModuleProvider s_moduleProvider = msrn::MakeTurboModuleProvider<Microsoft::React::HttpTurboModule>();
|
|
54
|
+
|
|
41
55
|
static void SetUpHttpResource(
|
|
42
56
|
shared_ptr<IHttpResource> resource,
|
|
43
57
|
weak_ptr<Instance> weakReactInstance,
|
|
@@ -65,10 +79,11 @@ static void SetUpHttpResource(
|
|
|
65
79
|
});
|
|
66
80
|
|
|
67
81
|
// Explicitly declaring function type to avoid type inference ambiguity.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
82
|
+
function<void(int64_t, msrn::JSValueObject &&)> onDataDynamic =
|
|
83
|
+
[weakReactInstance](int64_t requestId, msrn::JSValueObject &&responseData) {
|
|
84
|
+
auto responseDynamic = Microsoft::React::Modules::ToDynamic(msrn::JSValue{std::move(responseData)});
|
|
85
|
+
SendEvent(weakReactInstance, receivedData, dynamic::array(requestId, std::move(responseDynamic)));
|
|
86
|
+
};
|
|
72
87
|
resource->SetOnData(std::move(onDataDynamic));
|
|
73
88
|
|
|
74
89
|
resource->SetOnIncrementalData(
|
|
@@ -101,6 +116,104 @@ static void SetUpHttpResource(
|
|
|
101
116
|
|
|
102
117
|
namespace Microsoft::React {
|
|
103
118
|
|
|
119
|
+
#pragma region HttpTurboModule
|
|
120
|
+
|
|
121
|
+
void HttpTurboModule::Initialize(msrn::ReactContext const &reactContext) noexcept {
|
|
122
|
+
m_context = reactContext;
|
|
123
|
+
m_resource = IHttpResource::Make(m_context.Properties().Handle());
|
|
124
|
+
|
|
125
|
+
m_resource->SetOnRequestSuccess([context = m_context](int64_t requestId) {
|
|
126
|
+
SendEvent(context, completedResponseW, msrn::JSValueArray{requestId});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
m_resource->SetOnResponse([context = m_context](int64_t requestId, IHttpResource::Response &&response) {
|
|
130
|
+
auto headers = msrn::JSValueObject{};
|
|
131
|
+
for (auto &header : response.Headers) {
|
|
132
|
+
headers[header.first] = header.second;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// TODO: Test response content?
|
|
136
|
+
auto args = msrn::JSValueArray{requestId, response.StatusCode, std::move(headers), response.Url};
|
|
137
|
+
|
|
138
|
+
SendEvent(context, receivedResponseW, std::move(args));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
m_resource->SetOnData([context = m_context](int64_t requestId, string &&responseData) {
|
|
142
|
+
SendEvent(context, receivedDataW, msrn::JSValueArray{requestId, std::move(responseData)});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Explicitly declaring function type to avoid type inference ambiguity.
|
|
146
|
+
function<void(int64_t, msrn::JSValueObject &&)> onDataObject =
|
|
147
|
+
[context = m_context](int64_t requestId, msrn::JSValueObject &&responseData) {
|
|
148
|
+
SendEvent(context, receivedDataW, msrn::JSValueArray{requestId, std::move(responseData)});
|
|
149
|
+
};
|
|
150
|
+
m_resource->SetOnData(std::move(onDataObject));
|
|
151
|
+
|
|
152
|
+
m_resource->SetOnIncrementalData(
|
|
153
|
+
[context = m_context](int64_t requestId, string &&responseData, int64_t progress, int64_t total) {
|
|
154
|
+
SendEvent(
|
|
155
|
+
context, receivedIncrementalDataW, msrn::JSValueArray{requestId, std::move(responseData), progress, total});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
m_resource->SetOnDataProgress([context = m_context](int64_t requestId, int64_t progress, int64_t total) {
|
|
159
|
+
SendEvent(context, receivedDataProgressW, msrn::JSValueArray{requestId, progress, total});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
m_resource->SetOnResponseComplete([context = m_context](int64_t requestId) {
|
|
163
|
+
SendEvent(context, completedResponseW, msrn::JSValueArray{requestId});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
m_resource->SetOnError([context = m_context](int64_t requestId, string &&message, bool isTimeout) {
|
|
167
|
+
auto args = msrn::JSValueArray{requestId, std::move(message)};
|
|
168
|
+
if (isTimeout) {
|
|
169
|
+
args.push_back(true);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
SendEvent(context, completedResponseW, std::move(args));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
void HttpTurboModule::SendRequest(
|
|
177
|
+
ReactNativeSpecs::NetworkingIOSSpec_sendRequest_query &&query,
|
|
178
|
+
function<void(double)> const &callback) noexcept {
|
|
179
|
+
m_requestId++;
|
|
180
|
+
auto &headersObj = query.headers.AsObject();
|
|
181
|
+
IHttpResource::Headers headers;
|
|
182
|
+
for (auto &entry : headersObj) {
|
|
183
|
+
headers.emplace(entry.first, entry.second.AsString());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
m_resource->SendRequest(
|
|
187
|
+
std::move(query.method),
|
|
188
|
+
std::move(query.url),
|
|
189
|
+
m_requestId,
|
|
190
|
+
std::move(headers),
|
|
191
|
+
query.data.MoveObject(),
|
|
192
|
+
std::move(query.responseType),
|
|
193
|
+
query.incrementalUpdates,
|
|
194
|
+
static_cast<int64_t>(query.timeout),
|
|
195
|
+
query.withCredentials,
|
|
196
|
+
[&callback](int64_t requestId) { callback({static_cast<double>(requestId)}); });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
void HttpTurboModule::AbortRequest(double requestId) noexcept {
|
|
200
|
+
m_resource->AbortRequest(static_cast<int64_t>(requestId));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
void HttpTurboModule::ClearCookies(function<void(bool)> const &callback) noexcept {
|
|
204
|
+
m_resource->ClearCookies();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void HttpTurboModule::AddListener(string &&eventName) noexcept { /*NOOP*/
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
void HttpTurboModule::RemoveListeners(double count) noexcept { /*NOOP*/
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
#pragma endregion HttpTurboModule
|
|
214
|
+
|
|
215
|
+
#pragma region HttpModule
|
|
216
|
+
|
|
104
217
|
HttpModule::HttpModule(IInspectable const &inspectableProperties) noexcept
|
|
105
218
|
: m_holder{std::make_shared<ModuleHolder>()},
|
|
106
219
|
m_inspectableProperties{inspectableProperties},
|
|
@@ -115,7 +228,7 @@ HttpModule::~HttpModule() noexcept /*override*/ {
|
|
|
115
228
|
#pragma region CxxModule
|
|
116
229
|
|
|
117
230
|
string HttpModule::getName() /*override*/ {
|
|
118
|
-
return
|
|
231
|
+
return s_moduleName;
|
|
119
232
|
}
|
|
120
233
|
|
|
121
234
|
std::map<string, dynamic> HttpModule::getConstants() {
|
|
@@ -124,6 +237,8 @@ std::map<string, dynamic> HttpModule::getConstants() {
|
|
|
124
237
|
|
|
125
238
|
// clang-format off
|
|
126
239
|
std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods() {
|
|
240
|
+
// See CxxNativeModule::lazyInit()
|
|
241
|
+
SetUpHttpResource(m_resource, getInstance(), m_inspectableProperties);
|
|
127
242
|
|
|
128
243
|
return
|
|
129
244
|
{
|
|
@@ -136,12 +251,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
136
251
|
return;
|
|
137
252
|
}
|
|
138
253
|
|
|
139
|
-
|
|
140
|
-
if (!holder->Module->m_isResourceSetup)
|
|
141
|
-
{
|
|
142
|
-
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
143
|
-
holder->Module->m_isResourceSetup = true;
|
|
144
|
-
}
|
|
254
|
+
holder->Module->m_requestId++;
|
|
145
255
|
|
|
146
256
|
auto params = facebook::xplat::jsArgAsObject(args, 0);
|
|
147
257
|
IHttpResource::Headers headers;
|
|
@@ -149,12 +259,12 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
149
259
|
headers.emplace(header.first.getString(), header.second.getString());
|
|
150
260
|
}
|
|
151
261
|
|
|
152
|
-
|
|
262
|
+
holder->Module->m_resource->SendRequest(
|
|
153
263
|
params["method"].asString(),
|
|
154
264
|
params["url"].asString(),
|
|
155
|
-
|
|
265
|
+
holder->Module->m_requestId,
|
|
156
266
|
std::move(headers),
|
|
157
|
-
|
|
267
|
+
Modules::ToJSValue(params["data"]).MoveObject(),
|
|
158
268
|
params["responseType"].asString(),
|
|
159
269
|
params["incrementalUpdates"].asBool(),
|
|
160
270
|
static_cast<int64_t>(params["timeout"].asDouble()),
|
|
@@ -175,14 +285,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
175
285
|
return;
|
|
176
286
|
}
|
|
177
287
|
|
|
178
|
-
|
|
179
|
-
if (!holder->Module->m_isResourceSetup)
|
|
180
|
-
{
|
|
181
|
-
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
182
|
-
holder->Module->m_isResourceSetup = true;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
288
|
+
holder->Module->m_resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
186
289
|
}
|
|
187
290
|
},
|
|
188
291
|
{
|
|
@@ -195,14 +298,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
195
298
|
return;
|
|
196
299
|
}
|
|
197
300
|
|
|
198
|
-
|
|
199
|
-
if (!holder->Module->m_isResourceSetup)
|
|
200
|
-
{
|
|
201
|
-
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
202
|
-
holder->Module->m_isResourceSetup = true;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
resource->ClearCookies();
|
|
301
|
+
holder->Module->m_resource->ClearCookies();
|
|
206
302
|
}
|
|
207
303
|
}
|
|
208
304
|
};
|
|
@@ -211,8 +307,23 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
211
307
|
|
|
212
308
|
#pragma endregion CxxModule
|
|
213
309
|
|
|
310
|
+
#pragma endregion HttpModule
|
|
311
|
+
|
|
214
312
|
/*extern*/ const char *GetHttpModuleName() noexcept {
|
|
215
|
-
return
|
|
313
|
+
return s_moduleName;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateHttpModule(
|
|
317
|
+
IInspectable const &inspectableProperties) noexcept {
|
|
318
|
+
return std::make_unique<HttpModule>(inspectableProperties);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/*extern*/ const wchar_t *GetHttpTurboModuleName() noexcept {
|
|
322
|
+
return s_moduleNameW;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/*extern*/ const msrn::ReactModuleProvider &GetHttpModuleProvider() noexcept {
|
|
326
|
+
return s_moduleProvider;
|
|
216
327
|
}
|
|
217
328
|
|
|
218
329
|
} // namespace Microsoft::React
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
+
#include <NativeNetworkingIOSSpec.g.h>
|
|
7
|
+
#include <NativeModules.h>
|
|
6
8
|
#include <Networking/IHttpResource.h>
|
|
7
9
|
|
|
8
10
|
// React Native
|
|
@@ -13,6 +15,36 @@
|
|
|
13
15
|
|
|
14
16
|
namespace Microsoft::React {
|
|
15
17
|
|
|
18
|
+
REACT_MODULE(HttpTurboModule, L"Networking")
|
|
19
|
+
struct HttpTurboModule {
|
|
20
|
+
using ModuleSpec = ReactNativeSpecs::NetworkingIOSSpec;
|
|
21
|
+
|
|
22
|
+
REACT_INIT(Initialize)
|
|
23
|
+
void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
|
|
24
|
+
|
|
25
|
+
REACT_METHOD(SendRequest, L"sendRequest")
|
|
26
|
+
void SendRequest(
|
|
27
|
+
ReactNativeSpecs::NetworkingIOSSpec_sendRequest_query &&query,
|
|
28
|
+
std::function<void(double)> const &callback) noexcept;
|
|
29
|
+
|
|
30
|
+
REACT_METHOD(AbortRequest, L"abortRequest")
|
|
31
|
+
void AbortRequest(double requestId) noexcept;
|
|
32
|
+
|
|
33
|
+
REACT_METHOD(ClearCookies, L"clearCookies")
|
|
34
|
+
void ClearCookies(std::function<void(bool)> const &callback) noexcept;
|
|
35
|
+
|
|
36
|
+
REACT_METHOD(AddListener, L"addListener")
|
|
37
|
+
void AddListener(std::string &&eventName) noexcept;
|
|
38
|
+
|
|
39
|
+
REACT_METHOD(RemoveListeners, L"removeListeners")
|
|
40
|
+
void RemoveListeners(double count) noexcept;
|
|
41
|
+
|
|
42
|
+
private:
|
|
43
|
+
std::shared_ptr<Networking::IHttpResource> m_resource;
|
|
44
|
+
winrt::Microsoft::ReactNative::ReactContext m_context;
|
|
45
|
+
int64_t m_requestId{0};
|
|
46
|
+
};
|
|
47
|
+
|
|
16
48
|
///
|
|
17
49
|
/// Realizes <c>NativeModules</c> projection.
|
|
18
50
|
/// <remarks>See src\Libraries\Network\RCTNetworking.windows.js</remarks>
|
|
@@ -52,7 +84,7 @@ class HttpModule : public facebook::xplat::module::CxxModule {
|
|
|
52
84
|
|
|
53
85
|
std::shared_ptr<Networking::IHttpResource> m_resource;
|
|
54
86
|
std::shared_ptr<ModuleHolder> m_holder;
|
|
55
|
-
|
|
87
|
+
int64_t m_requestId{0};
|
|
56
88
|
|
|
57
89
|
// Property bag high level reference.
|
|
58
90
|
winrt::Windows::Foundation::IInspectable m_inspectableProperties;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
#include <
|
|
6
|
+
// React Native Windows
|
|
7
|
+
#include <JSValue.h>
|
|
8
8
|
|
|
9
9
|
// Standard Library
|
|
10
10
|
#include <string>
|
|
@@ -26,7 +26,7 @@ struct IRequestBodyHandler {
|
|
|
26
26
|
/// true - <paramref name="data" /> contains a blob reference.
|
|
27
27
|
/// false - <paramref name="data" /> does not contain a blob reference.
|
|
28
28
|
/// </returns>
|
|
29
|
-
virtual bool Supports(
|
|
29
|
+
virtual bool Supports(winrt::Microsoft::ReactNative::JSValueObject &data) = 0;
|
|
30
30
|
|
|
31
31
|
/// <summary>
|
|
32
32
|
/// Returns the {@link RequestBody} for the JS body payload.
|
|
@@ -46,7 +46,9 @@ struct IRequestBodyHandler {
|
|
|
46
46
|
/// "bytes" - Raw body content
|
|
47
47
|
/// NOTE: This is an arbitrary key. Pending non-folly structured object to model request body.
|
|
48
48
|
/// </returns>
|
|
49
|
-
virtual
|
|
49
|
+
virtual winrt::Microsoft::ReactNative::JSValueObject ToRequestBody(
|
|
50
|
+
winrt::Microsoft::ReactNative::JSValueObject &data,
|
|
51
|
+
std::string &contentType) = 0;
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
} // namespace Microsoft::React
|