react-native-windows 0.71.24 → 0.71.25
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/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 +133 -9
- package/Shared/Modules/HttpModule.h +33 -0
- 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 +323 -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 +40 -32
- package/Shared/Networking/WinRTHttpResource.h +4 -3
- package/Shared/Networking/WinRTTypes.h +3 -3
- package/Shared/OInstance.cpp +17 -33
- 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
|
@@ -3,210 +3,145 @@
|
|
|
3
3
|
|
|
4
4
|
#include "BlobModule.h"
|
|
5
5
|
|
|
6
|
+
#include <CreateModules.h>
|
|
6
7
|
#include <Modules/CxxModuleUtilities.h>
|
|
7
|
-
#include <Modules/IHttpModuleProxy.h>
|
|
8
|
-
#include <Modules/IWebSocketModuleProxy.h>
|
|
9
|
-
#include <ReactPropertyBag.h>
|
|
10
|
-
#include <unicode.h>
|
|
11
8
|
|
|
12
9
|
// React Native
|
|
13
10
|
#include <cxxreact/JsArgumentHelpers.h>
|
|
14
11
|
|
|
15
|
-
// Boost Libriaries
|
|
16
|
-
#include <boost/uuid/uuid_io.hpp>
|
|
17
|
-
|
|
18
|
-
// Windows API
|
|
19
|
-
#include <winrt/Windows.Foundation.h>
|
|
20
|
-
#include <winrt/Windows.Security.Cryptography.h>
|
|
21
|
-
|
|
22
|
-
// Standard Library
|
|
23
|
-
#include <chrono>
|
|
24
|
-
#include <filesystem>
|
|
25
|
-
#include <fstream>
|
|
26
|
-
|
|
27
12
|
using namespace facebook::xplat;
|
|
28
13
|
|
|
29
14
|
using folly::dynamic;
|
|
30
|
-
using
|
|
31
|
-
using std::shared_ptr;
|
|
15
|
+
using Microsoft::React::Networking::IBlobResource;
|
|
32
16
|
using std::string;
|
|
33
17
|
using std::vector;
|
|
34
|
-
using std::weak_ptr;
|
|
35
|
-
using winrt::Microsoft::ReactNative::IReactPropertyBag;
|
|
36
|
-
using winrt::Microsoft::ReactNative::ReactNonAbiValue;
|
|
37
|
-
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
38
|
-
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
39
18
|
using winrt::Windows::Foundation::IInspectable;
|
|
40
|
-
using winrt::Windows::Foundation::Uri;
|
|
41
|
-
using winrt::Windows::Security::Cryptography::CryptographicBuffer;
|
|
42
19
|
|
|
43
|
-
namespace
|
|
20
|
+
namespace msrn = winrt::Microsoft::ReactNative;
|
|
44
21
|
|
|
45
22
|
namespace {
|
|
46
|
-
constexpr char
|
|
47
|
-
constexpr
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
23
|
+
constexpr char s_moduleName[] = "BlobModule";
|
|
24
|
+
constexpr wchar_t s_moduleNameW[] = L"BlobModule";
|
|
25
|
+
|
|
26
|
+
const auto &blobKeys = IBlobResource::FieldNames();
|
|
27
|
+
|
|
28
|
+
msrn::ReactModuleProvider s_moduleProvider = msrn::MakeTurboModuleProvider<Microsoft::React::BlobTurboModule>();
|
|
29
|
+
|
|
53
30
|
} // namespace
|
|
54
31
|
|
|
55
32
|
namespace Microsoft::React {
|
|
56
33
|
|
|
57
|
-
#pragma region
|
|
34
|
+
#pragma region BlobTurboModule
|
|
58
35
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
auto blobPersistorPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
74
|
-
auto blobPersistor = weak_ptr<IBlobPersistor>{m_blobPersistor};
|
|
75
|
-
propBag.Set(blobPersistorPropId, std::move(blobPersistor));
|
|
76
|
-
|
|
77
|
-
m_sharedState->Module = this;
|
|
36
|
+
void BlobTurboModule::Initialize(msrn::ReactContext const &reactContext) noexcept {
|
|
37
|
+
m_resource = IBlobResource::Make(reactContext.Properties().Handle());
|
|
38
|
+
m_resource->Callbacks().OnError = [&reactContext](string &&errorText) {
|
|
39
|
+
Modules::SendEvent(reactContext, L"blobFailed", {errorText});
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ReactNativeSpecs::BlobModuleSpec_Constants BlobTurboModule::GetConstants() noexcept {
|
|
44
|
+
ReactNativeSpecs::BlobModuleSpec_Constants result;
|
|
45
|
+
result.BLOB_URI_SCHEME = blobKeys.Blob;
|
|
46
|
+
result.BLOB_URI_HOST = {};
|
|
47
|
+
|
|
48
|
+
return result;
|
|
78
49
|
}
|
|
79
50
|
|
|
80
|
-
|
|
81
|
-
|
|
51
|
+
void BlobTurboModule::AddNetworkingHandler() noexcept {
|
|
52
|
+
m_resource->AddNetworkingHandler();
|
|
82
53
|
}
|
|
83
54
|
|
|
55
|
+
void BlobTurboModule::AddWebSocketHandler(double id) noexcept {
|
|
56
|
+
m_resource->AddWebSocketHandler(static_cast<int64_t>(id));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void BlobTurboModule::RemoveWebSocketHandler(double id) noexcept {
|
|
60
|
+
m_resource->RemoveWebSocketHandler(static_cast<int64_t>(id));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void BlobTurboModule::SendOverSocket(msrn::JSValue &&blob, double socketID) noexcept {
|
|
64
|
+
m_resource->SendOverSocket(
|
|
65
|
+
blob[blobKeys.BlobId].AsString(),
|
|
66
|
+
blob[blobKeys.Offset].AsInt64(),
|
|
67
|
+
blob[blobKeys.Size].AsInt64(),
|
|
68
|
+
static_cast<int64_t>(socketID));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void BlobTurboModule::CreateFromParts(vector<msrn::JSValue> &&parts, string &&withId) noexcept {
|
|
72
|
+
m_resource->CreateFromParts(std::move(parts), std::move(withId));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void BlobTurboModule::Release(string &&blobId) noexcept {
|
|
76
|
+
m_resource->Release(std::move(blobId));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
#pragma endregion BlobTurboModule
|
|
80
|
+
|
|
81
|
+
#pragma region BlobModule
|
|
82
|
+
|
|
83
|
+
BlobModule::BlobModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept
|
|
84
|
+
: m_resource{IBlobResource::Make(inspectableProperties)} {}
|
|
85
|
+
|
|
84
86
|
#pragma region CxxModule
|
|
85
87
|
|
|
86
88
|
string BlobModule::getName() {
|
|
87
|
-
return
|
|
89
|
+
return s_moduleName;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
std::map<string, dynamic> BlobModule::getConstants() {
|
|
91
|
-
return {{"BLOB_URI_SCHEME",
|
|
93
|
+
return {{"BLOB_URI_SCHEME", blobKeys.Blob}, {"BLOB_URI_HOST", {}}};
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
vector<module::CxxModule::Method> BlobModule::getMethods() {
|
|
97
|
+
// See CxxNativeModule::lazyInit()
|
|
98
|
+
m_resource->Callbacks().OnError = [weakInstance = getInstance()](string &&errorText) {
|
|
99
|
+
Modules::SendEvent(weakInstance, "blobFailed", std::move(errorText));
|
|
100
|
+
};
|
|
101
|
+
|
|
95
102
|
return {
|
|
96
|
-
{"addNetworkingHandler",
|
|
97
|
-
[propBag = ReactPropertyBag{m_inspectableProperties.try_as<IReactPropertyBag>()},
|
|
98
|
-
requestBodyHandler = m_requestBodyHandler,
|
|
99
|
-
responseHandler = m_responseHandler](dynamic args) {
|
|
100
|
-
auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IHttpModuleProxy>>>{L"HttpModule.Proxy"};
|
|
101
|
-
|
|
102
|
-
if (auto prop = propBag.Get(propId)) {
|
|
103
|
-
if (auto httpHandler = prop.Value().lock()) {
|
|
104
|
-
httpHandler->AddRequestBodyHandler(requestBodyHandler);
|
|
105
|
-
httpHandler->AddResponseHandler(responseHandler);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// TODO: else emit error?
|
|
109
|
-
}},
|
|
103
|
+
{"addNetworkingHandler", [resource = m_resource](dynamic /*args*/) { resource->AddNetworkingHandler(); }},
|
|
110
104
|
|
|
111
105
|
{"addWebSocketHandler",
|
|
112
|
-
[
|
|
106
|
+
[resource = m_resource](dynamic args) {
|
|
113
107
|
auto id = jsArgAsInt(args, 0);
|
|
114
108
|
|
|
115
|
-
|
|
109
|
+
resource->AddWebSocketHandler(id);
|
|
116
110
|
}},
|
|
117
111
|
|
|
118
112
|
{"removeWebSocketHandler",
|
|
119
|
-
[
|
|
113
|
+
[resource = m_resource](dynamic args) {
|
|
120
114
|
auto id = jsArgAsInt(args, 0);
|
|
121
115
|
|
|
122
|
-
|
|
116
|
+
resource->RemoveWebSocketHandler(id);
|
|
123
117
|
}},
|
|
124
118
|
|
|
125
119
|
{"sendOverSocket",
|
|
126
|
-
[
|
|
127
|
-
persistor = m_blobPersistor,
|
|
128
|
-
propBag = ReactPropertyBag{m_inspectableProperties.try_as<IReactPropertyBag>()}](dynamic args) {
|
|
129
|
-
auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{L"WebSocketModule.Proxy"};
|
|
130
|
-
shared_ptr<IWebSocketModuleProxy> wsProxy;
|
|
131
|
-
if (auto prop = propBag.Get(propId)) {
|
|
132
|
-
wsProxy = prop.Value().lock();
|
|
133
|
-
}
|
|
134
|
-
if (!wsProxy) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
120
|
+
[resource = m_resource](dynamic args) {
|
|
138
121
|
auto blob = jsArgAsObject(args, 0);
|
|
139
|
-
auto blobId = blob[
|
|
140
|
-
auto offset = blob[
|
|
141
|
-
auto size = blob[
|
|
142
|
-
auto
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
data = persistor->ResolveMessage(std::move(blobId), offset, size);
|
|
147
|
-
} catch (const std::exception &e) {
|
|
148
|
-
if (auto sharedState = weakState.lock()) {
|
|
149
|
-
Modules::SendEvent(sharedState->Module->getInstance(), "blobFailed", e.what());
|
|
150
|
-
}
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
auto buffer = CryptographicBuffer::CreateFromByteArray(data);
|
|
155
|
-
auto winrtString = CryptographicBuffer::EncodeToBase64String(std::move(buffer));
|
|
156
|
-
auto base64String = Common::Unicode::Utf16ToUtf8(std::move(winrtString));
|
|
157
|
-
|
|
158
|
-
wsProxy->SendBinary(std::move(base64String), socketID);
|
|
122
|
+
auto blobId = blob[blobKeys.BlobId].getString();
|
|
123
|
+
auto offset = blob[blobKeys.Offset].getInt();
|
|
124
|
+
auto size = blob[blobKeys.Size].getInt();
|
|
125
|
+
auto socketId = jsArgAsInt(args, 1);
|
|
126
|
+
|
|
127
|
+
resource->SendOverSocket(std::move(blobId), offset, size, socketId);
|
|
159
128
|
}},
|
|
160
129
|
|
|
161
130
|
{"createFromParts",
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
[persistor = m_blobPersistor, weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) {
|
|
166
|
-
auto parts = jsArgAsArray(args, 0); // Array<Object>
|
|
131
|
+
[resource = m_resource](dynamic args) {
|
|
132
|
+
auto dynamicParts = jsArgAsArray(args, 0); // Array<Object>
|
|
133
|
+
auto parts = Modules::ToJSValue(dynamicParts);
|
|
167
134
|
auto blobId = jsArgAsString(args, 1);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
for (const auto &part : parts) {
|
|
171
|
-
auto type = part[typeKey].asString();
|
|
172
|
-
if (blobKey == type) {
|
|
173
|
-
auto blob = part[dataKey];
|
|
174
|
-
winrt::array_view<uint8_t const> bufferPart;
|
|
175
|
-
try {
|
|
176
|
-
bufferPart = persistor->ResolveMessage(
|
|
177
|
-
blob[blobIdKey].asString(), blob[offsetKey].asInt(), blob[sizeKey].asInt());
|
|
178
|
-
} catch (const std::exception &e) {
|
|
179
|
-
if (auto sharedState = weakState.lock()) {
|
|
180
|
-
Modules::SendEvent(sharedState->Module->getInstance(), "blobFailed", e.what());
|
|
181
|
-
}
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
buffer.reserve(buffer.size() + bufferPart.size());
|
|
186
|
-
buffer.insert(buffer.end(), bufferPart.begin(), bufferPart.end());
|
|
187
|
-
} else if ("string" == type) {
|
|
188
|
-
auto data = part[dataKey].asString();
|
|
189
|
-
|
|
190
|
-
buffer.reserve(buffer.size() + data.size());
|
|
191
|
-
buffer.insert(buffer.end(), data.begin(), data.end());
|
|
192
|
-
} else {
|
|
193
|
-
if (auto state = weakState.lock()) {
|
|
194
|
-
auto message = "Invalid type for blob: " + type;
|
|
195
|
-
Modules::SendEvent(state->Module->getInstance(), "blobFailed", std::move(message));
|
|
196
|
-
}
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
persistor->StoreMessage(std::move(buffer), std::move(blobId));
|
|
135
|
+
|
|
136
|
+
resource->CreateFromParts(parts.MoveArray(), std::move(blobId));
|
|
202
137
|
}},
|
|
203
138
|
|
|
204
139
|
{"release",
|
|
205
|
-
[
|
|
140
|
+
[resource = m_resource](dynamic args) // blobId: string
|
|
206
141
|
{
|
|
207
142
|
auto blobId = jsArgAsString(args, 0);
|
|
208
143
|
|
|
209
|
-
|
|
144
|
+
resource->Release(std::move(blobId));
|
|
210
145
|
}}};
|
|
211
146
|
}
|
|
212
147
|
|
|
@@ -214,164 +149,24 @@ vector<module::CxxModule::Method> BlobModule::getMethods() {
|
|
|
214
149
|
|
|
215
150
|
#pragma endregion BlobModule
|
|
216
151
|
|
|
217
|
-
#pragma region MemoryBlobPersistor
|
|
218
|
-
|
|
219
|
-
#pragma region IBlobPersistor
|
|
220
|
-
|
|
221
|
-
winrt::array_view<uint8_t const> MemoryBlobPersistor::ResolveMessage(string &&blobId, int64_t offset, int64_t size) {
|
|
222
|
-
if (size < 1)
|
|
223
|
-
return {};
|
|
224
|
-
|
|
225
|
-
scoped_lock lock{m_mutex};
|
|
226
|
-
|
|
227
|
-
auto dataItr = m_blobs.find(std::move(blobId));
|
|
228
|
-
// Not found.
|
|
229
|
-
if (dataItr == m_blobs.cend())
|
|
230
|
-
throw std::invalid_argument("Blob object not found");
|
|
231
|
-
|
|
232
|
-
auto &bytes = (*dataItr).second;
|
|
233
|
-
auto endBound = static_cast<size_t>(offset + size);
|
|
234
|
-
// Out of bounds.
|
|
235
|
-
if (endBound > bytes.size() || offset >= static_cast<int64_t>(bytes.size()) || offset < 0)
|
|
236
|
-
throw std::out_of_range("Offset or size out of range");
|
|
237
|
-
|
|
238
|
-
return winrt::array_view<uint8_t const>(bytes.data() + offset, bytes.data() + endBound);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
void MemoryBlobPersistor::RemoveMessage(string &&blobId) noexcept {
|
|
242
|
-
scoped_lock lock{m_mutex};
|
|
243
|
-
|
|
244
|
-
m_blobs.erase(std::move(blobId));
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
void MemoryBlobPersistor::StoreMessage(vector<uint8_t> &&message, string &&blobId) noexcept {
|
|
248
|
-
scoped_lock lock{m_mutex};
|
|
249
|
-
|
|
250
|
-
m_blobs.insert_or_assign(std::move(blobId), std::move(message));
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
string MemoryBlobPersistor::StoreMessage(vector<uint8_t> &&message) noexcept {
|
|
254
|
-
auto blobId = boost::uuids::to_string(m_guidGenerator());
|
|
255
|
-
|
|
256
|
-
scoped_lock lock{m_mutex};
|
|
257
|
-
m_blobs.insert_or_assign(blobId, std::move(message));
|
|
258
|
-
|
|
259
|
-
return blobId;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
#pragma endregion IBlobPersistor
|
|
263
|
-
|
|
264
|
-
#pragma endregion MemoryBlobPersistor
|
|
265
|
-
|
|
266
|
-
#pragma region BlobWebSocketModuleContentHandler
|
|
267
|
-
|
|
268
|
-
BlobWebSocketModuleContentHandler::BlobWebSocketModuleContentHandler(shared_ptr<IBlobPersistor> blobPersistor) noexcept
|
|
269
|
-
: m_blobPersistor{blobPersistor} {}
|
|
270
|
-
|
|
271
|
-
#pragma region IWebSocketModuleContentHandler
|
|
272
|
-
|
|
273
|
-
void BlobWebSocketModuleContentHandler::ProcessMessage(string &&message, dynamic ¶ms) /*override*/ {
|
|
274
|
-
params[dataKey] = std::move(message);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
void BlobWebSocketModuleContentHandler::ProcessMessage(vector<uint8_t> &&message, dynamic ¶ms) /*override*/ {
|
|
278
|
-
auto blob = dynamic::object();
|
|
279
|
-
blob(offsetKey, 0);
|
|
280
|
-
blob(sizeKey, message.size());
|
|
281
|
-
blob(blobIdKey, m_blobPersistor->StoreMessage(std::move(message)));
|
|
282
|
-
|
|
283
|
-
params[dataKey] = std::move(blob);
|
|
284
|
-
params[typeKey] = blobKey;
|
|
285
|
-
}
|
|
286
|
-
#pragma endregion IWebSocketModuleContentHandler
|
|
287
|
-
|
|
288
|
-
void BlobWebSocketModuleContentHandler::Register(int64_t socketID) noexcept {
|
|
289
|
-
scoped_lock lock{m_mutex};
|
|
290
|
-
m_socketIds.insert(socketID);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
void BlobWebSocketModuleContentHandler::Unregister(int64_t socketID) noexcept {
|
|
294
|
-
scoped_lock lock{m_mutex};
|
|
295
|
-
|
|
296
|
-
auto itr = m_socketIds.find(socketID);
|
|
297
|
-
if (itr != m_socketIds.end())
|
|
298
|
-
m_socketIds.erase(itr);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
#pragma endregion BlobWebSocketModuleContentHandler
|
|
302
|
-
|
|
303
|
-
#pragma region BlobModuleRequestBodyHandler
|
|
304
|
-
|
|
305
|
-
BlobModuleRequestBodyHandler::BlobModuleRequestBodyHandler(shared_ptr<IBlobPersistor> blobPersistor) noexcept
|
|
306
|
-
: m_blobPersistor{blobPersistor} {}
|
|
307
|
-
|
|
308
|
-
#pragma region IRequestBodyHandler
|
|
309
|
-
|
|
310
|
-
bool BlobModuleRequestBodyHandler::Supports(dynamic &data) /*override*/ {
|
|
311
|
-
auto itr = data.find(blobKey);
|
|
312
|
-
|
|
313
|
-
return itr != data.items().end() && !(*itr).second.empty();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
dynamic BlobModuleRequestBodyHandler::ToRequestBody(dynamic &data, string &contentType) /*override*/ {
|
|
317
|
-
auto type = contentType;
|
|
318
|
-
if (!data[typeKey].isNull() && !data[typeKey].asString().empty()) {
|
|
319
|
-
type = data[typeKey].asString();
|
|
320
|
-
}
|
|
321
|
-
if (type.empty()) {
|
|
322
|
-
type = "application/octet-stream";
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
auto blob = data[blobKey];
|
|
326
|
-
auto blobId = blob[blobIdKey].asString();
|
|
327
|
-
auto bytes = m_blobPersistor->ResolveMessage(std::move(blobId), blob[offsetKey].asInt(), blob[sizeKey].asInt());
|
|
328
|
-
|
|
329
|
-
auto result = dynamic::object();
|
|
330
|
-
result(typeKey, type);
|
|
331
|
-
result(sizeKey, bytes.size());
|
|
332
|
-
result("bytes", dynamic(bytes.cbegin(), bytes.cend()));
|
|
333
|
-
|
|
334
|
-
return result;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
#pragma endregion IRequestBodyHandler
|
|
338
|
-
|
|
339
|
-
#pragma endregion BlobModuleRequestBodyHandler
|
|
340
|
-
|
|
341
|
-
#pragma region BlobModuleResponseHandler
|
|
342
|
-
|
|
343
|
-
BlobModuleResponseHandler::BlobModuleResponseHandler(shared_ptr<IBlobPersistor> blobPersistor) noexcept
|
|
344
|
-
: m_blobPersistor{blobPersistor} {}
|
|
345
|
-
|
|
346
|
-
#pragma region IResponseHandler
|
|
347
|
-
|
|
348
|
-
bool BlobModuleResponseHandler::Supports(string &responseType) /*override*/ {
|
|
349
|
-
return blobKey == responseType;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
dynamic BlobModuleResponseHandler::ToResponseData(vector<uint8_t> &&content) /*override*/ {
|
|
353
|
-
auto blob = dynamic::object();
|
|
354
|
-
blob(offsetKey, 0);
|
|
355
|
-
blob(sizeKey, content.size());
|
|
356
|
-
blob(blobIdKey, m_blobPersistor->StoreMessage(std::move(content)));
|
|
357
|
-
|
|
358
|
-
return blob;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
#pragma endregion IResponseHandler
|
|
362
|
-
|
|
363
|
-
#pragma endregion BlobModuleResponseHandler
|
|
364
|
-
|
|
365
152
|
/*extern*/ const char *GetBlobModuleName() noexcept {
|
|
366
|
-
return
|
|
153
|
+
return s_moduleName;
|
|
367
154
|
}
|
|
368
155
|
|
|
369
156
|
/*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateBlobModule(
|
|
370
157
|
IInspectable const &inspectableProperties) noexcept {
|
|
371
|
-
if (auto properties = inspectableProperties.try_as<IReactPropertyBag>())
|
|
158
|
+
if (auto properties = inspectableProperties.try_as<msrn::IReactPropertyBag>())
|
|
372
159
|
return std::make_unique<BlobModule>(properties);
|
|
373
160
|
|
|
374
161
|
return nullptr;
|
|
375
162
|
}
|
|
376
163
|
|
|
164
|
+
/*extern*/ const wchar_t *GetBlobTurboModuleName() noexcept {
|
|
165
|
+
return s_moduleNameW;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/*extern*/ const msrn::ReactModuleProvider &GetBlobModuleProvider() noexcept {
|
|
169
|
+
return s_moduleProvider;
|
|
170
|
+
}
|
|
171
|
+
|
|
377
172
|
} // namespace Microsoft::React
|
|
@@ -3,107 +3,56 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
-
#include <
|
|
7
|
-
|
|
8
|
-
#include <
|
|
9
|
-
#include <Modules/IWebSocketModuleContentHandler.h>
|
|
6
|
+
#include <NativeBlobModuleSpec.g.h>
|
|
7
|
+
|
|
8
|
+
#include <Networking/IBlobResource.h>
|
|
10
9
|
|
|
11
10
|
// React Native
|
|
12
11
|
#include <cxxreact/CxxModule.h>
|
|
13
12
|
|
|
14
|
-
// Boost Libraries
|
|
15
|
-
#include <boost/uuid/uuid_generators.hpp>
|
|
16
|
-
|
|
17
13
|
// Windows API
|
|
18
14
|
#include <winrt/base.h>
|
|
19
15
|
|
|
20
16
|
// Standard Library
|
|
21
|
-
#include <mutex>
|
|
22
17
|
#include <string>
|
|
23
|
-
#include <unordered_map>
|
|
24
|
-
#include <unordered_set>
|
|
25
18
|
#include <vector>
|
|
26
19
|
|
|
27
20
|
namespace Microsoft::React {
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
boost::uuids::random_generator m_guidGenerator;
|
|
33
|
-
|
|
34
|
-
public:
|
|
35
|
-
#pragma region IBlobPersistor
|
|
36
|
-
|
|
37
|
-
winrt::array_view<uint8_t const> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) override;
|
|
38
|
-
|
|
39
|
-
void RemoveMessage(std::string &&blobId) noexcept override;
|
|
40
|
-
|
|
41
|
-
void StoreMessage(std::vector<uint8_t> &&message, std::string &&blobId) noexcept override;
|
|
42
|
-
|
|
43
|
-
std::string StoreMessage(std::vector<uint8_t> &&message) noexcept override;
|
|
44
|
-
|
|
45
|
-
#pragma endregion IBlobPersistor
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
class BlobWebSocketModuleContentHandler final : public IWebSocketModuleContentHandler {
|
|
49
|
-
std::unordered_set<int64_t> m_socketIds;
|
|
50
|
-
std::mutex m_mutex;
|
|
51
|
-
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
52
|
-
|
|
53
|
-
public:
|
|
54
|
-
BlobWebSocketModuleContentHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
55
|
-
|
|
56
|
-
#pragma region IWebSocketModuleContentHandler
|
|
22
|
+
REACT_MODULE(BlobTurboModule, L"BlobModule")
|
|
23
|
+
struct BlobTurboModule {
|
|
24
|
+
using ModuleSpec = ReactNativeSpecs::BlobModuleSpec;
|
|
57
25
|
|
|
58
|
-
|
|
26
|
+
REACT_INIT(Initialize)
|
|
27
|
+
void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
|
|
59
28
|
|
|
60
|
-
|
|
29
|
+
REACT_GET_CONSTANTS(GetConstants)
|
|
30
|
+
ReactNativeSpecs::BlobModuleSpec_Constants GetConstants() noexcept;
|
|
61
31
|
|
|
62
|
-
|
|
32
|
+
REACT_METHOD(AddNetworkingHandler, L"addNetworkingHandler")
|
|
33
|
+
void AddNetworkingHandler() noexcept;
|
|
63
34
|
|
|
64
|
-
|
|
35
|
+
REACT_METHOD(AddWebSocketHandler, L"addWebSocketHandler")
|
|
36
|
+
void AddWebSocketHandler(double id) noexcept;
|
|
65
37
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class BlobModuleRequestBodyHandler final : public IRequestBodyHandler {
|
|
70
|
-
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
71
|
-
|
|
72
|
-
public:
|
|
73
|
-
BlobModuleRequestBodyHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
38
|
+
REACT_METHOD(RemoveWebSocketHandler, L"removeWebSocketHandler")
|
|
39
|
+
void RemoveWebSocketHandler(double id) noexcept;
|
|
74
40
|
|
|
75
|
-
|
|
41
|
+
REACT_METHOD(SendOverSocket, L"sendOverSocket")
|
|
42
|
+
void SendOverSocket(winrt::Microsoft::ReactNative::JSValue &&blob, double socketID) noexcept;
|
|
76
43
|
|
|
77
|
-
|
|
44
|
+
REACT_METHOD(CreateFromParts, L"createFromParts")
|
|
45
|
+
void CreateFromParts(std::vector<winrt::Microsoft::ReactNative::JSValue> &&parts, std::string &&withId) noexcept;
|
|
78
46
|
|
|
79
|
-
|
|
47
|
+
REACT_METHOD(Release, L"release")
|
|
48
|
+
void Release(std::string &&blobId) noexcept;
|
|
80
49
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class BlobModuleResponseHandler final : public IResponseHandler {
|
|
85
|
-
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
86
|
-
|
|
87
|
-
public:
|
|
88
|
-
BlobModuleResponseHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
89
|
-
|
|
90
|
-
#pragma region IResponseHandler
|
|
91
|
-
|
|
92
|
-
bool Supports(std::string &responseType) override;
|
|
93
|
-
|
|
94
|
-
folly::dynamic ToResponseData(std::vector<uint8_t> &&content) override;
|
|
95
|
-
|
|
96
|
-
#pragma endregion IResponseHandler
|
|
50
|
+
private:
|
|
51
|
+
std::shared_ptr<Networking::IBlobResource> m_resource;
|
|
97
52
|
};
|
|
98
53
|
|
|
99
54
|
class BlobModule : public facebook::xplat::module::CxxModule {
|
|
100
|
-
std::shared_ptr<
|
|
101
|
-
std::shared_ptr<BlobWebSocketModuleContentHandler> m_contentHandler;
|
|
102
|
-
std::shared_ptr<BlobModuleRequestBodyHandler> m_requestBodyHandler;
|
|
103
|
-
std::shared_ptr<BlobModuleResponseHandler> m_responseHandler;
|
|
104
|
-
|
|
105
|
-
// Property bag high level reference.
|
|
106
|
-
winrt::Windows::Foundation::IInspectable m_inspectableProperties;
|
|
55
|
+
std::shared_ptr<Networking::IBlobResource> m_resource;
|
|
107
56
|
|
|
108
57
|
public:
|
|
109
58
|
enum class MethodId {
|
|
@@ -118,15 +67,6 @@ class BlobModule : public facebook::xplat::module::CxxModule {
|
|
|
118
67
|
|
|
119
68
|
BlobModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept;
|
|
120
69
|
|
|
121
|
-
~BlobModule() noexcept override;
|
|
122
|
-
|
|
123
|
-
struct SharedState {
|
|
124
|
-
/// <summary>
|
|
125
|
-
/// Keeps a raw reference to the module object to lazily retrieve the React Instance as needed.
|
|
126
|
-
/// </summary>
|
|
127
|
-
CxxModule *Module{nullptr};
|
|
128
|
-
};
|
|
129
|
-
|
|
130
70
|
#pragma region CxxModule
|
|
131
71
|
|
|
132
72
|
/// <summary>
|
|
@@ -146,12 +86,6 @@ class BlobModule : public facebook::xplat::module::CxxModule {
|
|
|
146
86
|
std::vector<Method> getMethods() override;
|
|
147
87
|
|
|
148
88
|
#pragma endregion CxxModule
|
|
149
|
-
|
|
150
|
-
private:
|
|
151
|
-
/// <summary>
|
|
152
|
-
/// Keeps members that can be accessed threads other than this module's owner accessible.
|
|
153
|
-
/// </summary>
|
|
154
|
-
std::shared_ptr<SharedState> m_sharedState;
|
|
155
89
|
};
|
|
156
90
|
|
|
157
91
|
} // namespace Microsoft::React
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
4
|
#include "CxxModuleUtilities.h"
|
|
5
|
+
#include <DynamicReader.h>
|
|
6
|
+
#include <DynamicWriter.h>
|
|
7
|
+
|
|
8
|
+
namespace msrn = winrt::Microsoft::ReactNative;
|
|
5
9
|
|
|
6
10
|
using facebook::react::Instance;
|
|
7
11
|
using folly::dynamic;
|
|
@@ -16,4 +20,32 @@ void SendEvent(weak_ptr<Instance> weakReactInstance, string &&eventName, dynamic
|
|
|
16
20
|
}
|
|
17
21
|
}
|
|
18
22
|
|
|
23
|
+
void SendEvent(
|
|
24
|
+
msrn::ReactContext const &reactContext,
|
|
25
|
+
std::wstring_view &&eventName,
|
|
26
|
+
msrn::JSValueObject &&args) noexcept {
|
|
27
|
+
reactContext.EmitJSEvent(L"RCTDeviceEventEmitter", std::move(eventName), std::move(args));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void SendEvent(
|
|
31
|
+
msrn::ReactContext const &reactContext,
|
|
32
|
+
std::wstring_view &&eventName,
|
|
33
|
+
msrn::JSValueArray &&args) noexcept {
|
|
34
|
+
reactContext.EmitJSEvent(L"RCTDeviceEventEmitter", std::move(eventName), std::move(args));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
msrn::JSValue ToJSValue(dynamic &value) noexcept {
|
|
38
|
+
auto reader = winrt::make<msrn::DynamicReader>(value);
|
|
39
|
+
auto result = msrn::JSValue::ReadFrom(reader);
|
|
40
|
+
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
dynamic ToDynamic(const msrn::JSValue &value) noexcept {
|
|
45
|
+
auto argWriter = msrn::MakeJSValueArgWriter(value);
|
|
46
|
+
auto result = msrn::DynamicWriter::ToDynamic(argWriter)[0];
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
19
51
|
} // namespace Microsoft::React::Modules
|