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.
Files changed (77) hide show
  1. package/Directory.Build.props +5 -0
  2. package/Libraries/Network/RCTNetworking.windows.js +10 -16
  3. package/Microsoft.ReactNative/IReactDispatcher.cpp +4 -0
  4. package/Microsoft.ReactNative/IReactDispatcher.h +1 -0
  5. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +3 -7
  6. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -7
  7. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +43 -21
  8. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +0 -2
  9. package/Microsoft.ReactNative/Views/DevMenu.cpp +3 -3
  10. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiLoader.cpp +16 -0
  11. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +43 -12
  12. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +17 -6
  13. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
  14. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
  15. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +1 -1
  16. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  17. package/PropertySheets/JSEngine.props +4 -4
  18. package/PropertySheets/React.Cpp.props +3 -3
  19. package/PropertySheets/Warnings.props +6 -0
  20. package/ReactCommon/ReactCommon.vcxproj +53 -1
  21. package/ReactCommon/cgmanifest.json +15 -0
  22. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +36 -0
  23. package/Shared/BaseFileReaderResource.cpp +95 -0
  24. package/Shared/BaseFileReaderResource.h +41 -0
  25. package/Shared/CreateModules.h +27 -5
  26. package/Shared/DevSupportManager.cpp +2 -9
  27. package/Shared/DevSupportManager.h +2 -6
  28. package/Shared/HermesRuntimeHolder.cpp +344 -84
  29. package/Shared/HermesRuntimeHolder.h +32 -21
  30. package/Shared/HermesSamplingProfiler.cpp +66 -14
  31. package/Shared/HermesSamplingProfiler.h +5 -3
  32. package/Shared/IFileReaderResource.h +36 -0
  33. package/Shared/InspectorPackagerConnection.cpp +62 -108
  34. package/Shared/InspectorPackagerConnection.h +9 -21
  35. package/Shared/JSI/RuntimeHolder.h +2 -2
  36. package/Shared/JSI/ScriptStore.h +18 -20
  37. package/Shared/JSI/V8RuntimeHolder.cpp +260 -0
  38. package/Shared/JSI/V8RuntimeHolder.h +37 -0
  39. package/Shared/Modules/BlobModule.cpp +93 -298
  40. package/Shared/Modules/BlobModule.h +25 -91
  41. package/Shared/Modules/CxxModuleUtilities.cpp +32 -0
  42. package/Shared/Modules/CxxModuleUtilities.h +17 -0
  43. package/Shared/Modules/FileReaderModule.cpp +118 -51
  44. package/Shared/Modules/FileReaderModule.h +27 -1
  45. package/Shared/Modules/HttpModule.cpp +133 -9
  46. package/Shared/Modules/HttpModule.h +33 -0
  47. package/Shared/Modules/IRequestBodyHandler.h +6 -4
  48. package/Shared/Modules/IResponseHandler.h +3 -3
  49. package/Shared/Modules/IUriHandler.h +3 -3
  50. package/Shared/Modules/IWebSocketModuleContentHandler.h +6 -4
  51. package/Shared/Modules/WebSocketModule.cpp +190 -7
  52. package/Shared/Modules/WebSocketTurboModule.h +52 -0
  53. package/Shared/Networking/DefaultBlobResource.cpp +323 -0
  54. package/Shared/Networking/DefaultBlobResource.h +133 -0
  55. package/Shared/Networking/IBlobResource.h +56 -0
  56. package/Shared/Networking/IHttpResource.h +6 -5
  57. package/Shared/Networking/WinRTHttpResource.cpp +40 -32
  58. package/Shared/Networking/WinRTHttpResource.h +4 -3
  59. package/Shared/Networking/WinRTTypes.h +3 -3
  60. package/Shared/OInstance.cpp +17 -33
  61. package/Shared/SafeLoadLibrary.cpp +41 -0
  62. package/Shared/SafeLoadLibrary.h +15 -0
  63. package/Shared/Shared.vcxitems +27 -9
  64. package/Shared/Shared.vcxitems.filters +47 -33
  65. package/package.json +2 -2
  66. package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +1 -1
  67. package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +0 -59
  68. package/Microsoft.ReactNative/Base/CoreNativeModules.h +0 -30
  69. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +0 -2103
  70. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +0 -73
  71. package/Shared/HermesShim.cpp +0 -118
  72. package/Shared/HermesShim.h +0 -21
  73. package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +0 -209
  74. package/Shared/JSI/NapiJsiV8RuntimeHolder.h +0 -44
  75. package/Shared/V8JSIRuntimeHolder.cpp +0 -70
  76. package/Shared/V8JSIRuntimeHolder.h +0 -53
  77. /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 std::scoped_lock;
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 fs = std::filesystem;
20
+ namespace msrn = winrt::Microsoft::ReactNative;
44
21
 
45
22
  namespace {
46
- constexpr char moduleName[] = "BlobModule";
47
- constexpr char blobKey[] = "blob";
48
- constexpr char blobIdKey[] = "blobId";
49
- constexpr char offsetKey[] = "offset";
50
- constexpr char sizeKey[] = "size";
51
- constexpr char typeKey[] = "type";
52
- constexpr char dataKey[] = "data";
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 BlobModule
34
+ #pragma region BlobTurboModule
58
35
 
59
- BlobModule::BlobModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept
60
- : m_sharedState{std::make_shared<SharedState>()},
61
- m_blobPersistor{std::make_shared<MemoryBlobPersistor>()},
62
- m_contentHandler{std::make_shared<BlobWebSocketModuleContentHandler>(m_blobPersistor)},
63
- m_requestBodyHandler{std::make_shared<BlobModuleRequestBodyHandler>(m_blobPersistor)},
64
- m_responseHandler{std::make_shared<BlobModuleResponseHandler>(m_blobPersistor)},
65
- m_inspectableProperties{inspectableProperties} {
66
- auto propBag = ReactPropertyBag{m_inspectableProperties.try_as<IReactPropertyBag>()};
67
-
68
- auto contentHandlerPropId =
69
- ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{L"BlobModule.ContentHandler"};
70
- auto contentHandler = weak_ptr<IWebSocketModuleContentHandler>{m_contentHandler};
71
- propBag.Set(contentHandlerPropId, std::move(contentHandler));
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
- BlobModule::~BlobModule() noexcept /*override*/ {
81
- m_sharedState->Module = nullptr;
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 moduleName;
89
+ return s_moduleName;
88
90
  }
89
91
 
90
92
  std::map<string, dynamic> BlobModule::getConstants() {
91
- return {{"BLOB_URI_SCHEME", blobKey}, {"BLOB_URI_HOST", {}}};
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
- [contentHandler = m_contentHandler](dynamic args) {
106
+ [resource = m_resource](dynamic args) {
113
107
  auto id = jsArgAsInt(args, 0);
114
108
 
115
- contentHandler->Register(id);
109
+ resource->AddWebSocketHandler(id);
116
110
  }},
117
111
 
118
112
  {"removeWebSocketHandler",
119
- [contentHandler = m_contentHandler](dynamic args) {
113
+ [resource = m_resource](dynamic args) {
120
114
  auto id = jsArgAsInt(args, 0);
121
115
 
122
- contentHandler->Unregister(id);
116
+ resource->RemoveWebSocketHandler(id);
123
117
  }},
124
118
 
125
119
  {"sendOverSocket",
126
- [weakState = weak_ptr<SharedState>(m_sharedState),
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[blobIdKey].getString();
140
- auto offset = blob[offsetKey].getInt();
141
- auto size = blob[sizeKey].getInt();
142
- auto socketID = jsArgAsInt(args, 1);
143
-
144
- winrt::array_view<uint8_t const> data;
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
- // As of React Native 0.67, instance is set AFTER CxxModule::getMethods() is invoked.
163
- // Use getInstance() directly once
164
- // https://github.com/facebook/react-native/commit/1d45b20b6c6ba66df0485cdb9be36463d96cf182 becomes available.
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
- vector<uint8_t> buffer{};
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
- [persistor = m_blobPersistor](dynamic args) // blobId: string
140
+ [resource = m_resource](dynamic args) // blobId: string
206
141
  {
207
142
  auto blobId = jsArgAsString(args, 0);
208
143
 
209
- persistor->RemoveMessage(std::move(blobId));
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 &params) /*override*/ {
274
- params[dataKey] = std::move(message);
275
- }
276
-
277
- void BlobWebSocketModuleContentHandler::ProcessMessage(vector<uint8_t> &&message, dynamic &params) /*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 moduleName;
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 <Modules/IBlobPersistor.h>
7
- #include <Modules/IRequestBodyHandler.h>
8
- #include <Modules/IResponseHandler.h>
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
- class MemoryBlobPersistor final : public IBlobPersistor {
30
- std::unordered_map<std::string, std::vector<uint8_t>> m_blobs;
31
- std::mutex m_mutex;
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
- void ProcessMessage(std::string &&message, folly::dynamic &params) override;
26
+ REACT_INIT(Initialize)
27
+ void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
59
28
 
60
- void ProcessMessage(std::vector<uint8_t> &&message, folly::dynamic &params) override;
29
+ REACT_GET_CONSTANTS(GetConstants)
30
+ ReactNativeSpecs::BlobModuleSpec_Constants GetConstants() noexcept;
61
31
 
62
- #pragma endregion IWebSocketModuleContentHandler
32
+ REACT_METHOD(AddNetworkingHandler, L"addNetworkingHandler")
33
+ void AddNetworkingHandler() noexcept;
63
34
 
64
- void Register(int64_t socketID) noexcept;
35
+ REACT_METHOD(AddWebSocketHandler, L"addWebSocketHandler")
36
+ void AddWebSocketHandler(double id) noexcept;
65
37
 
66
- void Unregister(int64_t socketID) noexcept;
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
- #pragma region IRequestBodyHandler
41
+ REACT_METHOD(SendOverSocket, L"sendOverSocket")
42
+ void SendOverSocket(winrt::Microsoft::ReactNative::JSValue &&blob, double socketID) noexcept;
76
43
 
77
- bool Supports(folly::dynamic &data) override;
44
+ REACT_METHOD(CreateFromParts, L"createFromParts")
45
+ void CreateFromParts(std::vector<winrt::Microsoft::ReactNative::JSValue> &&parts, std::string &&withId) noexcept;
78
46
 
79
- folly::dynamic ToRequestBody(folly::dynamic &data, std::string &contentType) override;
47
+ REACT_METHOD(Release, L"release")
48
+ void Release(std::string &&blobId) noexcept;
80
49
 
81
- #pragma endregion IRequestBodyHandler
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<MemoryBlobPersistor> m_blobPersistor;
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