react-native-windows 0.69.0-preview.2 → 0.69.0-preview.5
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 +4 -0
- package/Folly/Folly.vcxproj +4 -5
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Network/RCTNetworkingWinShared.js +7 -0
- package/Libraries/Utilities/codegenNativeComponent.js +5 -6
- package/Libraries/Utilities/useColorScheme.js +9 -15
- package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +3 -1
- package/Microsoft.ReactNative/IReactContext.cpp +17 -0
- package/Microsoft.ReactNative/IReactContext.h +2 -0
- package/Microsoft.ReactNative/IReactContext.idl +27 -0
- package/Microsoft.ReactNative/JsiApi.cpp +9 -0
- package/Microsoft.ReactNative/JsiApi.h +1 -0
- package/Microsoft.ReactNative/JsiApi.idl +1 -0
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +3 -5
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +31 -9
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +48 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +2 -2
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +1 -1
- package/Microsoft.ReactNative.Managed/packages.lock.json +57 -2
- package/PropertySheets/Generated/PackageVersion.g.props +1 -1
- package/PropertySheets/JSEngine.props +2 -2
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +9 -5
- package/Shared/CreateModules.h +17 -2
- package/Shared/InspectorPackagerConnection.cpp +6 -7
- package/Shared/InspectorPackagerConnection.h +1 -1
- package/Shared/JSI/ChakraRuntime.cpp +5 -0
- package/Shared/JSI/ChakraRuntime.h +1 -0
- package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +72 -2
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +2 -0
- package/Shared/Modules/BlobModule.cpp +376 -0
- package/Shared/Modules/BlobModule.h +153 -0
- package/Shared/Modules/CxxModuleUtilities.cpp +19 -0
- package/Shared/Modules/CxxModuleUtilities.h +23 -0
- package/Shared/Modules/FileReaderModule.cpp +156 -0
- package/Shared/Modules/FileReaderModule.h +54 -0
- package/Shared/Modules/HttpModule.cpp +72 -69
- package/Shared/Modules/HttpModule.h +8 -1
- package/Shared/Modules/IBlobPersistor.h +30 -0
- package/Shared/Modules/IHttpModuleProxy.h +30 -0
- package/Shared/Modules/IRequestBodyHandler.h +52 -0
- package/Shared/Modules/IResponseHandler.h +27 -0
- package/Shared/Modules/IUriHandler.h +37 -0
- package/Shared/Modules/IWebSocketModuleContentHandler.h +26 -0
- package/Shared/Modules/IWebSocketModuleProxy.h +22 -0
- package/Shared/Modules/NetworkingModule.cpp +1 -1
- package/Shared/Modules/WebSocketModule.cpp +92 -22
- package/Shared/Modules/WebSocketModule.h +27 -1
- package/Shared/Networking/IHttpResource.h +50 -2
- package/Shared/Networking/WinRTHttpResource.cpp +169 -51
- package/Shared/Networking/WinRTHttpResource.h +27 -8
- package/Shared/Networking/WinRTTypes.h +5 -2
- package/Shared/OInstance.cpp +22 -5
- package/Shared/OInstance.h +8 -4
- package/Shared/RuntimeOptions.cpp +6 -3
- package/Shared/RuntimeOptions.h +14 -3
- package/Shared/Shared.vcxitems +13 -0
- package/Shared/Shared.vcxitems.filters +40 -1
- package/fmt/fmt.vcxproj +4 -5
- package/package.json +14 -12
- package/template/cs-app-WinAppSDK/proj/NuGet.Config +3 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/JSCRuntime.cpp +0 -1480
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h +0 -753
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h +0 -1331
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <Modules/IBlobPersistor.h>
|
|
7
|
+
#include <Modules/IRequestBodyHandler.h>
|
|
8
|
+
#include <Modules/IResponseHandler.h>
|
|
9
|
+
#include <Modules/IWebSocketModuleContentHandler.h>
|
|
10
|
+
|
|
11
|
+
// React Native
|
|
12
|
+
#include <cxxreact/CxxModule.h>
|
|
13
|
+
|
|
14
|
+
// Windows API
|
|
15
|
+
#include <winrt/base.h>
|
|
16
|
+
|
|
17
|
+
// Standard Library
|
|
18
|
+
#include <mutex>
|
|
19
|
+
#include <string>
|
|
20
|
+
#include <unordered_map>
|
|
21
|
+
#include <unordered_set>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
namespace Microsoft::React {
|
|
25
|
+
|
|
26
|
+
class MemoryBlobPersistor final : public IBlobPersistor {
|
|
27
|
+
std::unordered_map<std::string, std::vector<uint8_t>> m_blobs;
|
|
28
|
+
std::mutex m_mutex;
|
|
29
|
+
|
|
30
|
+
public:
|
|
31
|
+
#pragma region IBlobPersistor
|
|
32
|
+
|
|
33
|
+
winrt::array_view<uint8_t> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) override;
|
|
34
|
+
|
|
35
|
+
void RemoveMessage(std::string &&blobId) noexcept override;
|
|
36
|
+
|
|
37
|
+
void StoreMessage(std::vector<uint8_t> &&message, std::string &&blobId) noexcept override;
|
|
38
|
+
|
|
39
|
+
std::string StoreMessage(std::vector<uint8_t> &&message) noexcept override;
|
|
40
|
+
|
|
41
|
+
#pragma endregion IBlobPersistor
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
class BlobWebSocketModuleContentHandler final : public IWebSocketModuleContentHandler {
|
|
45
|
+
std::unordered_set<int64_t> m_socketIds;
|
|
46
|
+
std::mutex m_mutex;
|
|
47
|
+
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
BlobWebSocketModuleContentHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
51
|
+
|
|
52
|
+
#pragma region IWebSocketModuleContentHandler
|
|
53
|
+
|
|
54
|
+
void ProcessMessage(std::string &&message, folly::dynamic ¶ms) override;
|
|
55
|
+
|
|
56
|
+
void ProcessMessage(std::vector<uint8_t> &&message, folly::dynamic ¶ms) override;
|
|
57
|
+
|
|
58
|
+
#pragma endregion IWebSocketModuleContentHandler
|
|
59
|
+
|
|
60
|
+
void Register(int64_t socketID) noexcept;
|
|
61
|
+
|
|
62
|
+
void Unregister(int64_t socketID) noexcept;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
class BlobModuleRequestBodyHandler final : public IRequestBodyHandler {
|
|
66
|
+
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
67
|
+
|
|
68
|
+
public:
|
|
69
|
+
BlobModuleRequestBodyHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
70
|
+
|
|
71
|
+
#pragma region IRequestBodyHandler
|
|
72
|
+
|
|
73
|
+
bool Supports(folly::dynamic &data) override;
|
|
74
|
+
|
|
75
|
+
folly::dynamic ToRequestBody(folly::dynamic &data, std::string &contentType) override;
|
|
76
|
+
|
|
77
|
+
#pragma endregion IRequestBodyHandler
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
class BlobModuleResponseHandler final : public IResponseHandler {
|
|
81
|
+
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
82
|
+
|
|
83
|
+
public:
|
|
84
|
+
BlobModuleResponseHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
85
|
+
|
|
86
|
+
#pragma region IResponseHandler
|
|
87
|
+
|
|
88
|
+
bool Supports(std::string &responseType) override;
|
|
89
|
+
|
|
90
|
+
folly::dynamic ToResponseData(std::vector<uint8_t> &&content) override;
|
|
91
|
+
|
|
92
|
+
#pragma endregion IResponseHandler
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
class BlobModule : public facebook::xplat::module::CxxModule {
|
|
96
|
+
std::shared_ptr<MemoryBlobPersistor> m_blobPersistor;
|
|
97
|
+
std::shared_ptr<BlobWebSocketModuleContentHandler> m_contentHandler;
|
|
98
|
+
std::shared_ptr<BlobModuleRequestBodyHandler> m_requestBodyHandler;
|
|
99
|
+
std::shared_ptr<BlobModuleResponseHandler> m_responseHandler;
|
|
100
|
+
|
|
101
|
+
// Property bag high level reference.
|
|
102
|
+
winrt::Windows::Foundation::IInspectable m_inspectableProperties;
|
|
103
|
+
|
|
104
|
+
public:
|
|
105
|
+
enum class MethodId {
|
|
106
|
+
AddNetworkingHandler = 0,
|
|
107
|
+
AddWebSocketHandler = 1,
|
|
108
|
+
RemoveWebSocketHandler = 2,
|
|
109
|
+
SendOverSocket = 3,
|
|
110
|
+
CreateFromParts = 4,
|
|
111
|
+
Release = 5,
|
|
112
|
+
SIZE = 6
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
BlobModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept;
|
|
116
|
+
|
|
117
|
+
~BlobModule() noexcept override;
|
|
118
|
+
|
|
119
|
+
struct SharedState {
|
|
120
|
+
/// <summary>
|
|
121
|
+
/// Keeps a raw reference to the module object to lazily retrieve the React Instance as needed.
|
|
122
|
+
/// </summary>
|
|
123
|
+
CxxModule *Module{nullptr};
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
#pragma region CxxModule
|
|
127
|
+
|
|
128
|
+
/// <summary>
|
|
129
|
+
/// <see cref="facebook::xplat::module::CxxModule::getName" />
|
|
130
|
+
/// </summary>
|
|
131
|
+
std::string getName() override;
|
|
132
|
+
|
|
133
|
+
/// <summary>
|
|
134
|
+
/// <see cref="facebook::xplat::module::CxxModule::getConstants" />
|
|
135
|
+
/// </summary>
|
|
136
|
+
std::map<std::string, folly::dynamic> getConstants() override;
|
|
137
|
+
|
|
138
|
+
/// <summary>
|
|
139
|
+
/// <see cref="facebook::xplat::module::CxxModule::getMethods" />
|
|
140
|
+
/// </summary>
|
|
141
|
+
/// <remarks>See See react-native/Libraries/WebSocket/WebSocket.js</remarks>
|
|
142
|
+
std::vector<Method> getMethods() override;
|
|
143
|
+
|
|
144
|
+
#pragma endregion CxxModule
|
|
145
|
+
|
|
146
|
+
private:
|
|
147
|
+
/// <summary>
|
|
148
|
+
/// Keeps members that can be accessed threads other than this module's owner accessible.
|
|
149
|
+
/// </summary>
|
|
150
|
+
std::shared_ptr<SharedState> m_sharedState;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "CxxModuleUtilities.h"
|
|
5
|
+
|
|
6
|
+
using facebook::react::Instance;
|
|
7
|
+
using folly::dynamic;
|
|
8
|
+
using std::string;
|
|
9
|
+
using std::weak_ptr;
|
|
10
|
+
|
|
11
|
+
namespace Microsoft::React::Modules {
|
|
12
|
+
|
|
13
|
+
void SendEvent(weak_ptr<Instance> weakReactInstance, string &&eventName, dynamic &&args) {
|
|
14
|
+
if (auto instance = weakReactInstance.lock()) {
|
|
15
|
+
instance->callJSFunction("RCTDeviceEventEmitter", "emit", dynamic::array(std::move(eventName), std::move(args)));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
} // namespace Microsoft::React::Modules
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
// Folly
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
|
|
9
|
+
// React Native
|
|
10
|
+
#include <cxxreact/Instance.h>
|
|
11
|
+
|
|
12
|
+
// Standard Library
|
|
13
|
+
#include <memory>
|
|
14
|
+
#include <string>
|
|
15
|
+
|
|
16
|
+
namespace Microsoft::React::Modules {
|
|
17
|
+
|
|
18
|
+
void SendEvent(
|
|
19
|
+
std::weak_ptr<facebook::react::Instance> weakReactInstance,
|
|
20
|
+
std::string &&eventName,
|
|
21
|
+
folly::dynamic &&args);
|
|
22
|
+
|
|
23
|
+
} // namespace Microsoft::React::Modules
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "FileReaderModule.h"
|
|
5
|
+
|
|
6
|
+
#include <ReactPropertyBag.h>
|
|
7
|
+
|
|
8
|
+
// Boost Library
|
|
9
|
+
#include <boost/archive/iterators/base64_from_binary.hpp>
|
|
10
|
+
#include <boost/archive/iterators/ostream_iterator.hpp>
|
|
11
|
+
#include <boost/archive/iterators/transform_width.hpp>
|
|
12
|
+
|
|
13
|
+
// React Native
|
|
14
|
+
#include <cxxreact/JsArgumentHelpers.h>
|
|
15
|
+
|
|
16
|
+
// Windows API
|
|
17
|
+
#include <winrt/Windows.Foundation.h>
|
|
18
|
+
|
|
19
|
+
using namespace facebook::xplat;
|
|
20
|
+
|
|
21
|
+
using folly::dynamic;
|
|
22
|
+
using std::string;
|
|
23
|
+
using std::weak_ptr;
|
|
24
|
+
using winrt::Microsoft::ReactNative::IReactPropertyBag;
|
|
25
|
+
using winrt::Microsoft::ReactNative::ReactNonAbiValue;
|
|
26
|
+
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
27
|
+
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
28
|
+
using winrt::Windows::Foundation::IInspectable;
|
|
29
|
+
|
|
30
|
+
namespace {
|
|
31
|
+
constexpr char moduleName[] = "FileReaderModule";
|
|
32
|
+
} // namespace
|
|
33
|
+
|
|
34
|
+
namespace Microsoft::React {
|
|
35
|
+
|
|
36
|
+
#pragma region FileReaderModule
|
|
37
|
+
|
|
38
|
+
FileReaderModule::FileReaderModule(weak_ptr<IBlobPersistor> weakBlobPersistor) noexcept
|
|
39
|
+
: m_weakBlobPersistor{weakBlobPersistor} {}
|
|
40
|
+
|
|
41
|
+
FileReaderModule::~FileReaderModule() noexcept /*override*/
|
|
42
|
+
{}
|
|
43
|
+
|
|
44
|
+
#pragma region CxxModule
|
|
45
|
+
|
|
46
|
+
string FileReaderModule::getName() {
|
|
47
|
+
return moduleName;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
std::map<string, dynamic> FileReaderModule::getConstants() {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
55
|
+
return {
|
|
56
|
+
{///
|
|
57
|
+
/// <param name="args">
|
|
58
|
+
/// Array of arguments passed from the JavaScript layer.
|
|
59
|
+
/// [0] - dynamic blob object { blobId, offset, size[, type] }
|
|
60
|
+
/// </param>
|
|
61
|
+
///
|
|
62
|
+
"readAsDataURL",
|
|
63
|
+
[blobPersistor = m_weakBlobPersistor.lock()](dynamic args, Callback resolve, Callback reject) {
|
|
64
|
+
if (!blobPersistor) {
|
|
65
|
+
return reject({"Could not find Blob persistor"});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
auto blob = jsArgAsObject(args, 0);
|
|
69
|
+
|
|
70
|
+
auto blobId = blob["blobId"].asString();
|
|
71
|
+
auto offset = blob["offset"].asInt();
|
|
72
|
+
auto size = blob["size"].asInt();
|
|
73
|
+
|
|
74
|
+
winrt::array_view<uint8_t> bytes;
|
|
75
|
+
try {
|
|
76
|
+
bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
|
|
77
|
+
} catch (const std::exception &e) {
|
|
78
|
+
return reject({e.what()});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
auto result = string{"data:"};
|
|
82
|
+
auto typeItr = blob.find("type");
|
|
83
|
+
if (typeItr == blob.items().end()) {
|
|
84
|
+
result += "application/octet-stream";
|
|
85
|
+
} else {
|
|
86
|
+
result += (*typeItr).second.asString();
|
|
87
|
+
}
|
|
88
|
+
result += ";base64,";
|
|
89
|
+
|
|
90
|
+
// https://www.boost.org/doc/libs/1_76_0/libs/serialization/doc/dataflow.html
|
|
91
|
+
using namespace boost::archive::iterators;
|
|
92
|
+
typedef base64_from_binary<transform_width<const char *, 6, 8>> encode_base64;
|
|
93
|
+
std::ostringstream oss;
|
|
94
|
+
std::copy(encode_base64(bytes.cbegin()), encode_base64(bytes.cend()), ostream_iterator<char>(oss));
|
|
95
|
+
result += oss.str();
|
|
96
|
+
|
|
97
|
+
resolve({std::move(result)});
|
|
98
|
+
}},
|
|
99
|
+
{///
|
|
100
|
+
/// <param name="args">
|
|
101
|
+
/// Array of arguments passed from the JavaScript layer.
|
|
102
|
+
/// [0] - dynamic blob object { blobId, offset, size }
|
|
103
|
+
/// [1] - string encoding
|
|
104
|
+
/// </param>
|
|
105
|
+
///
|
|
106
|
+
"readAsText",
|
|
107
|
+
[blobPersistor = m_weakBlobPersistor.lock()](dynamic args, Callback resolve, Callback reject) {
|
|
108
|
+
if (!blobPersistor) {
|
|
109
|
+
return reject({"Could not find Blob persistor"});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
auto blob = jsArgAsObject(args, 0);
|
|
113
|
+
auto encoding = jsArgAsString(args, 1); // Default: "UTF-8"
|
|
114
|
+
|
|
115
|
+
auto blobId = blob["blobId"].asString();
|
|
116
|
+
auto offset = blob["offset"].asInt();
|
|
117
|
+
auto size = blob["size"].asInt();
|
|
118
|
+
|
|
119
|
+
winrt::array_view<uint8_t> bytes;
|
|
120
|
+
try {
|
|
121
|
+
bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
|
|
122
|
+
} catch (const std::exception &e) {
|
|
123
|
+
return reject({e.what()});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// #9982 - Handle non-UTF8 encodings
|
|
127
|
+
// See https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/charset/Charset.html
|
|
128
|
+
auto result = string{bytes.cbegin(), bytes.cend()};
|
|
129
|
+
|
|
130
|
+
resolve({std::move(result)});
|
|
131
|
+
}}};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#pragma endregion CxxModule
|
|
135
|
+
|
|
136
|
+
#pragma endregion FileReaderModule
|
|
137
|
+
|
|
138
|
+
/*extern*/ const char *GetFileReaderModuleName() noexcept {
|
|
139
|
+
return moduleName;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/*extern*/ std::unique_ptr<module::CxxModule> CreateFileReaderModule(
|
|
143
|
+
IInspectable const &inspectableProperties) noexcept {
|
|
144
|
+
auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
145
|
+
auto propBag = ReactPropertyBag{inspectableProperties.try_as<IReactPropertyBag>()};
|
|
146
|
+
|
|
147
|
+
if (auto prop = propBag.Get(propId)) {
|
|
148
|
+
auto weakBlobPersistor = prop.Value();
|
|
149
|
+
|
|
150
|
+
return std::make_unique<FileReaderModule>(weakBlobPersistor);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return nullptr;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "IBlobPersistor.h"
|
|
7
|
+
|
|
8
|
+
// React Native
|
|
9
|
+
#include <cxxreact/CxxModule.h>
|
|
10
|
+
|
|
11
|
+
// Folly
|
|
12
|
+
#include <folly/dynamic.h>
|
|
13
|
+
|
|
14
|
+
// Standard Library
|
|
15
|
+
#include <map>
|
|
16
|
+
#include <memory>
|
|
17
|
+
#include <string>
|
|
18
|
+
#include <vector>
|
|
19
|
+
|
|
20
|
+
namespace Microsoft::React {
|
|
21
|
+
|
|
22
|
+
class FileReaderModule : public facebook::xplat::module::CxxModule {
|
|
23
|
+
public:
|
|
24
|
+
enum class MethodId { ReadAsDataURL = 0, ReadAsText = 1, SIZE = 2 };
|
|
25
|
+
|
|
26
|
+
FileReaderModule(std::weak_ptr<IBlobPersistor> weakBlobPersistor) noexcept;
|
|
27
|
+
|
|
28
|
+
~FileReaderModule() noexcept override;
|
|
29
|
+
|
|
30
|
+
#pragma region CxxModule
|
|
31
|
+
|
|
32
|
+
/// <summary>
|
|
33
|
+
/// <see cref="facebook::xplat::module::CxxModule::getName" />
|
|
34
|
+
/// </summary>
|
|
35
|
+
std::string getName() override;
|
|
36
|
+
|
|
37
|
+
/// <summary>
|
|
38
|
+
/// <see cref="facebook::xplat::module::CxxModule::getConstants" />
|
|
39
|
+
/// </summary>
|
|
40
|
+
std::map<std::string, folly::dynamic> getConstants() override;
|
|
41
|
+
|
|
42
|
+
/// <summary>
|
|
43
|
+
/// <see cref="facebook::xplat::module::CxxModule::getMethods" />
|
|
44
|
+
/// </summary>
|
|
45
|
+
/// <remarks>See See react-native/Libraries/WebSocket/WebSocket.js</remarks>
|
|
46
|
+
std::vector<Method> getMethods() override;
|
|
47
|
+
|
|
48
|
+
#pragma endregion CxxModule
|
|
49
|
+
|
|
50
|
+
private:
|
|
51
|
+
std::weak_ptr<IBlobPersistor> m_weakBlobPersistor;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
} // namespace Microsoft::React
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
#include "HttpModule.h"
|
|
7
7
|
|
|
8
|
+
#include <Modules/CxxModuleUtilities.h>
|
|
9
|
+
#include <ReactPropertyBag.h>
|
|
10
|
+
|
|
8
11
|
// React Native
|
|
9
12
|
#include <cxxreact/Instance.h>
|
|
10
13
|
#include <cxxreact/JsArgumentHelpers.h>
|
|
@@ -14,21 +17,34 @@ using folly::dynamic;
|
|
|
14
17
|
using std::shared_ptr;
|
|
15
18
|
using std::string;
|
|
16
19
|
using std::weak_ptr;
|
|
20
|
+
using winrt::Microsoft::ReactNative::IReactPropertyBag;
|
|
21
|
+
using winrt::Microsoft::ReactNative::ReactNonAbiValue;
|
|
22
|
+
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
23
|
+
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
24
|
+
using winrt::Windows::Foundation::IInspectable;
|
|
17
25
|
|
|
18
26
|
namespace {
|
|
19
27
|
|
|
28
|
+
using Microsoft::React::Modules::SendEvent;
|
|
20
29
|
using Microsoft::React::Networking::IHttpResource;
|
|
21
30
|
|
|
22
31
|
constexpr char moduleName[] = "Networking";
|
|
23
32
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
// React event names
|
|
34
|
+
constexpr char completedResponse[] = "didCompleteNetworkResponse";
|
|
35
|
+
constexpr char receivedResponse[] = "didReceiveNetworkResponse";
|
|
36
|
+
constexpr char receivedData[] = "didReceiveNetworkData";
|
|
37
|
+
constexpr char receivedDataProgress[] = "didReceiveNetworkDataProgress";
|
|
29
38
|
|
|
30
|
-
static
|
|
31
|
-
|
|
39
|
+
static void SetUpHttpResource(
|
|
40
|
+
shared_ptr<IHttpResource> resource,
|
|
41
|
+
weak_ptr<Instance> weakReactInstance,
|
|
42
|
+
IInspectable &inspectableProperties) {
|
|
43
|
+
resource->SetOnRequestSuccess([weakReactInstance](int64_t requestId) {
|
|
44
|
+
auto args = dynamic::array(requestId);
|
|
45
|
+
|
|
46
|
+
SendEvent(weakReactInstance, completedResponse, std::move(args));
|
|
47
|
+
});
|
|
32
48
|
|
|
33
49
|
resource->SetOnResponse([weakReactInstance](int64_t requestId, IHttpResource::Response &&response) {
|
|
34
50
|
dynamic headers = dynamic::object();
|
|
@@ -39,33 +55,39 @@ static shared_ptr<IHttpResource> CreateHttpResource(weak_ptr<Instance> weakReact
|
|
|
39
55
|
// TODO: Test response content.
|
|
40
56
|
dynamic args = dynamic::array(requestId, response.StatusCode, headers, response.Url);
|
|
41
57
|
|
|
42
|
-
SendEvent(weakReactInstance,
|
|
58
|
+
SendEvent(weakReactInstance, receivedResponse, std::move(args));
|
|
43
59
|
});
|
|
44
60
|
|
|
45
|
-
resource->SetOnData([weakReactInstance](int64_t requestId,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
SendEvent(weakReactInstance, "didReceiveNetworkData", std::move(args));
|
|
61
|
+
resource->SetOnData([weakReactInstance](int64_t requestId, string &&responseData) {
|
|
62
|
+
SendEvent(weakReactInstance, receivedData, dynamic::array(requestId, std::move(responseData)));
|
|
49
63
|
|
|
50
64
|
// TODO: Move into separate method IF not executed right after onData()
|
|
51
|
-
SendEvent(weakReactInstance,
|
|
65
|
+
SendEvent(weakReactInstance, completedResponse, dynamic::array(requestId));
|
|
52
66
|
});
|
|
53
67
|
|
|
68
|
+
// Explicitly declaring function type to avoid type inference ambiguity.
|
|
69
|
+
std::function<void(int64_t, dynamic &&)> onDataDynamic = [weakReactInstance](
|
|
70
|
+
int64_t requestId, dynamic &&responseData) {
|
|
71
|
+
SendEvent(weakReactInstance, receivedData, dynamic::array(requestId, std::move(responseData)));
|
|
72
|
+
};
|
|
73
|
+
resource->SetOnData(std::move(onDataDynamic));
|
|
74
|
+
|
|
54
75
|
resource->SetOnError([weakReactInstance](int64_t requestId, string &&message) {
|
|
55
76
|
dynamic args = dynamic::array(requestId, std::move(message));
|
|
56
77
|
// TODO: isTimeout errorArgs.push_back(true);
|
|
57
78
|
|
|
58
|
-
SendEvent(weakReactInstance,
|
|
79
|
+
SendEvent(weakReactInstance, completedResponse, std::move(args));
|
|
59
80
|
});
|
|
60
|
-
|
|
61
|
-
return resource;
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
} // namespace
|
|
65
84
|
|
|
66
85
|
namespace Microsoft::React {
|
|
67
86
|
|
|
68
|
-
HttpModule::HttpModule(
|
|
87
|
+
HttpModule::HttpModule(IInspectable const &inspectableProperties) noexcept
|
|
88
|
+
: m_holder{std::make_shared<ModuleHolder>()},
|
|
89
|
+
m_inspectableProperties{inspectableProperties},
|
|
90
|
+
m_resource{IHttpResource::Make(inspectableProperties)} {
|
|
69
91
|
m_holder->Module = this;
|
|
70
92
|
}
|
|
71
93
|
|
|
@@ -86,10 +108,6 @@ std::map<string, dynamic> HttpModule::getConstants() {
|
|
|
86
108
|
// clang-format off
|
|
87
109
|
std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods() {
|
|
88
110
|
|
|
89
|
-
auto weakHolder = weak_ptr<ModuleHolder>(m_holder);
|
|
90
|
-
auto holder = weakHolder.lock();
|
|
91
|
-
auto weakReactInstance = weak_ptr<Instance>(holder->Module->getInstance());
|
|
92
|
-
|
|
93
111
|
return
|
|
94
112
|
{
|
|
95
113
|
{
|
|
@@ -102,53 +120,32 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
102
120
|
}
|
|
103
121
|
|
|
104
122
|
auto resource = holder->Module->m_resource;
|
|
105
|
-
if (
|
|
123
|
+
if (!holder->Module->m_isResourceSetup)
|
|
106
124
|
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
auto stringData = data["string"];
|
|
111
|
-
if (!stringData.empty())
|
|
112
|
-
{
|
|
113
|
-
bodyData = {IHttpResource::BodyData::Type::String, stringData.getString()};
|
|
114
|
-
}
|
|
115
|
-
else
|
|
116
|
-
{
|
|
117
|
-
auto base64Data = data["base64"];
|
|
118
|
-
if (!base64Data.empty())
|
|
119
|
-
{
|
|
120
|
-
bodyData = {IHttpResource::BodyData::Type::Base64, base64Data.getString()};
|
|
121
|
-
}
|
|
122
|
-
else
|
|
123
|
-
{
|
|
124
|
-
auto uriData = data["uri"];
|
|
125
|
-
if (!uriData.empty())
|
|
126
|
-
{
|
|
127
|
-
bodyData = {IHttpResource::BodyData::Type::Uri, uriData.getString()};
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
//TODO: Support FORM data
|
|
125
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
126
|
+
holder->Module->m_isResourceSetup = true;
|
|
127
|
+
}
|
|
132
128
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
129
|
+
auto params = facebook::xplat::jsArgAsObject(args, 0);
|
|
130
|
+
IHttpResource::Headers headers;
|
|
131
|
+
for (auto& header : params["headers"].items()) {
|
|
132
|
+
headers.emplace(header.first.getString(), header.second.getString());
|
|
133
|
+
}
|
|
137
134
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
135
|
+
resource->SendRequest(
|
|
136
|
+
params["method"].asString(),
|
|
137
|
+
params["url"].asString(),
|
|
138
|
+
params["requestId"].asInt(),
|
|
139
|
+
std::move(headers),
|
|
140
|
+
std::move(params["data"]),
|
|
141
|
+
params["responseType"].asString(),
|
|
142
|
+
params["incrementalUpdates"].asBool(),
|
|
143
|
+
static_cast<int64_t>(params["timeout"].asDouble()),
|
|
144
|
+
params["withCredentials"].asBool(),
|
|
145
|
+
[cxxCallback = std::move(cxxCallback)](int64_t requestId) {
|
|
146
|
+
cxxCallback({requestId});
|
|
147
|
+
}
|
|
148
|
+
);
|
|
152
149
|
}
|
|
153
150
|
},
|
|
154
151
|
{
|
|
@@ -162,10 +159,13 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
162
159
|
}
|
|
163
160
|
|
|
164
161
|
auto resource = holder->Module->m_resource;
|
|
165
|
-
if (
|
|
162
|
+
if (!holder->Module->m_isResourceSetup)
|
|
166
163
|
{
|
|
167
|
-
resource->
|
|
164
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
165
|
+
holder->Module->m_isResourceSetup = true;
|
|
168
166
|
}
|
|
167
|
+
|
|
168
|
+
resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
169
169
|
}
|
|
170
170
|
},
|
|
171
171
|
{
|
|
@@ -179,10 +179,13 @@ std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods()
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
auto resource = holder->Module->m_resource;
|
|
182
|
-
if (
|
|
182
|
+
if (!holder->Module->m_isResourceSetup)
|
|
183
183
|
{
|
|
184
|
-
resource->
|
|
184
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
185
|
+
holder->Module->m_isResourceSetup = true;
|
|
185
186
|
}
|
|
187
|
+
|
|
188
|
+
resource->ClearCookies();
|
|
186
189
|
}
|
|
187
190
|
}
|
|
188
191
|
};
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
// React Native
|
|
9
9
|
#include <cxxreact/CxxModule.h>
|
|
10
10
|
|
|
11
|
+
// Windows API
|
|
12
|
+
#include <winrt/Windows.Foundation.h>
|
|
13
|
+
|
|
11
14
|
namespace Microsoft::React {
|
|
12
15
|
|
|
13
16
|
///
|
|
@@ -18,7 +21,7 @@ class HttpModule : public facebook::xplat::module::CxxModule {
|
|
|
18
21
|
public:
|
|
19
22
|
enum MethodId { SendRequest = 0, AbortRequest = 1, ClearCookies = 2, LAST = ClearCookies };
|
|
20
23
|
|
|
21
|
-
HttpModule() noexcept;
|
|
24
|
+
HttpModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept;
|
|
22
25
|
|
|
23
26
|
~HttpModule() noexcept override;
|
|
24
27
|
|
|
@@ -49,5 +52,9 @@ class HttpModule : public facebook::xplat::module::CxxModule {
|
|
|
49
52
|
|
|
50
53
|
std::shared_ptr<Networking::IHttpResource> m_resource;
|
|
51
54
|
std::shared_ptr<ModuleHolder> m_holder;
|
|
55
|
+
bool m_isResourceSetup{false};
|
|
56
|
+
|
|
57
|
+
// Property bag high level reference.
|
|
58
|
+
winrt::Windows::Foundation::IInspectable m_inspectableProperties;
|
|
52
59
|
};
|
|
53
60
|
} // namespace Microsoft::React
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
// Windows API
|
|
7
|
+
#include <winrt/base.h>
|
|
8
|
+
|
|
9
|
+
// Standard Library
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace Microsoft::React {
|
|
14
|
+
|
|
15
|
+
struct IBlobPersistor {
|
|
16
|
+
///
|
|
17
|
+
/// <exception cref="std::invalid_argument">
|
|
18
|
+
/// When an entry for blobId cannot be found.
|
|
19
|
+
/// </exception>
|
|
20
|
+
///
|
|
21
|
+
virtual winrt::array_view<uint8_t> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) = 0;
|
|
22
|
+
|
|
23
|
+
virtual void RemoveMessage(std::string &&blobId) noexcept = 0;
|
|
24
|
+
|
|
25
|
+
virtual void StoreMessage(std::vector<uint8_t> &&message, std::string &&blobId) noexcept = 0;
|
|
26
|
+
|
|
27
|
+
virtual std::string StoreMessage(std::vector<uint8_t> &&message) noexcept = 0;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} // namespace Microsoft::React
|