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