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.
Files changed (55) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Network/RCTNetworking.windows.js +10 -16
  3. package/Microsoft.ReactNative/Fabric/ImageRequest.cpp +11 -14
  4. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +1 -1
  5. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -3
  6. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -7
  7. package/Microsoft.ReactNative/Modules/LinkingManagerModule.cpp +1 -1
  8. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +11 -10
  9. package/Microsoft.ReactNative.Managed/packages.lock.json +2 -71
  10. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  11. package/PropertySheets/React.Cpp.props +2 -3
  12. package/Shared/BaseFileReaderResource.cpp +95 -0
  13. package/Shared/BaseFileReaderResource.h +41 -0
  14. package/Shared/CreateModules.h +27 -5
  15. package/Shared/IFileReaderResource.h +36 -0
  16. package/Shared/Modules/BlobModule.cpp +93 -297
  17. package/Shared/Modules/BlobModule.h +25 -87
  18. package/Shared/Modules/CxxModuleUtilities.cpp +32 -0
  19. package/Shared/Modules/CxxModuleUtilities.h +17 -0
  20. package/Shared/Modules/FileReaderModule.cpp +118 -51
  21. package/Shared/Modules/FileReaderModule.h +27 -1
  22. package/Shared/Modules/HttpModule.cpp +133 -9
  23. package/Shared/Modules/HttpModule.h +33 -0
  24. package/Shared/Modules/IRequestBodyHandler.h +6 -4
  25. package/Shared/Modules/IResponseHandler.h +3 -3
  26. package/Shared/Modules/IUriHandler.h +3 -3
  27. package/Shared/Modules/IWebSocketModuleContentHandler.h +6 -4
  28. package/Shared/Modules/WebSocketModule.cpp +190 -7
  29. package/Shared/Modules/WebSocketTurboModule.h +52 -0
  30. package/Shared/Networking/DefaultBlobResource.cpp +323 -0
  31. package/Shared/Networking/DefaultBlobResource.h +133 -0
  32. package/Shared/Networking/IBlobResource.h +56 -0
  33. package/Shared/Networking/IHttpResource.h +6 -5
  34. package/Shared/Networking/WinRTHttpResource.cpp +40 -32
  35. package/Shared/Networking/WinRTHttpResource.h +4 -3
  36. package/Shared/Networking/WinRTTypes.h +3 -3
  37. package/Shared/Shared.vcxitems +8 -1
  38. package/Shared/Shared.vcxitems.filters +24 -3
  39. package/package.json +11 -11
  40. package/types/experimental.d.ts +101 -0
  41. package/types/index.d.ts +216 -0
  42. package/types/modules/BatchedBridge.d.ts +32 -0
  43. package/types/modules/Codegen.d.ts +74 -0
  44. package/types/modules/Devtools.d.ts +31 -0
  45. package/types/modules/LaunchScreen.d.ts +18 -0
  46. package/types/modules/globals.d.ts +579 -0
  47. package/types/private/TimerMixin.d.ts +19 -0
  48. package/types/private/Utilities.d.ts +10 -0
  49. package/types/public/DeprecatedPropertiesAlias.d.ts +185 -0
  50. package/types/public/Insets.d.ts +15 -0
  51. package/types/public/ReactNativeRenderer.d.ts +144 -0
  52. package/types/public/ReactNativeTypes.d.ts +143 -0
  53. package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +0 -44
  54. package/Microsoft.ReactNative/Base/CoreNativeModules.h +0 -30
  55. /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 std::scoped_lock;
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 fs = std::filesystem;
20
+ namespace msrn = winrt::Microsoft::ReactNative;
42
21
 
43
22
  namespace {
44
- constexpr char moduleName[] = "BlobModule";
45
- constexpr char blobKey[] = "blob";
46
- constexpr char blobIdKey[] = "blobId";
47
- constexpr char offsetKey[] = "offset";
48
- constexpr char sizeKey[] = "size";
49
- constexpr char typeKey[] = "type";
50
- 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
+
51
30
  } // namespace
52
31
 
53
32
  namespace Microsoft::React {
54
33
 
55
- #pragma region BlobModule
34
+ #pragma region BlobTurboModule
56
35
 
57
- BlobModule::BlobModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept
58
- : m_sharedState{std::make_shared<SharedState>()},
59
- m_blobPersistor{std::make_shared<MemoryBlobPersistor>()},
60
- m_contentHandler{std::make_shared<BlobWebSocketModuleContentHandler>(m_blobPersistor)},
61
- m_requestBodyHandler{std::make_shared<BlobModuleRequestBodyHandler>(m_blobPersistor)},
62
- m_responseHandler{std::make_shared<BlobModuleResponseHandler>(m_blobPersistor)},
63
- m_inspectableProperties{inspectableProperties} {
64
- auto propBag = ReactPropertyBag{m_inspectableProperties.try_as<IReactPropertyBag>()};
65
-
66
- auto contentHandlerPropId =
67
- ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{L"BlobModule.ContentHandler"};
68
- auto contentHandler = weak_ptr<IWebSocketModuleContentHandler>{m_contentHandler};
69
- propBag.Set(contentHandlerPropId, std::move(contentHandler));
70
-
71
- auto blobPersistorPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
72
- auto blobPersistor = weak_ptr<IBlobPersistor>{m_blobPersistor};
73
- propBag.Set(blobPersistorPropId, std::move(blobPersistor));
74
-
75
- 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;
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
- BlobModule::~BlobModule() noexcept /*override*/ {
79
- m_sharedState->Module = nullptr;
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 moduleName;
89
+ return s_moduleName;
86
90
  }
87
91
 
88
92
  std::map<string, dynamic> BlobModule::getConstants() {
89
- return {{"BLOB_URI_SCHEME", blobKey}, {"BLOB_URI_HOST", {}}};
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
- [contentHandler = m_contentHandler](dynamic args) {
106
+ [resource = m_resource](dynamic args) {
111
107
  auto id = jsArgAsInt(args, 0);
112
108
 
113
- contentHandler->Register(id);
109
+ resource->AddWebSocketHandler(id);
114
110
  }},
115
111
 
116
112
  {"removeWebSocketHandler",
117
- [contentHandler = m_contentHandler](dynamic args) {
113
+ [resource = m_resource](dynamic args) {
118
114
  auto id = jsArgAsInt(args, 0);
119
115
 
120
- contentHandler->Unregister(id);
116
+ resource->RemoveWebSocketHandler(id);
121
117
  }},
122
118
 
123
119
  {"sendOverSocket",
124
- [weakState = weak_ptr<SharedState>(m_sharedState),
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[blobIdKey].getString();
138
- auto offset = blob[offsetKey].getInt();
139
- auto size = blob[sizeKey].getInt();
140
- auto socketID = jsArgAsInt(args, 1);
141
-
142
- winrt::array_view<uint8_t const> data;
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
- // As of React Native 0.67, instance is set AFTER CxxModule::getMethods() is invoked.
161
- // Use getInstance() directly once
162
- // https://github.com/facebook/react-native/commit/1d45b20b6c6ba66df0485cdb9be36463d96cf182 becomes available.
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
- vector<uint8_t> buffer{};
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
- [persistor = m_blobPersistor](dynamic args) // blobId: string
140
+ [resource = m_resource](dynamic args) // blobId: string
204
141
  {
205
142
  auto blobId = jsArgAsString(args, 0);
206
143
 
207
- persistor->RemoveMessage(std::move(blobId));
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 &params) /*override*/ {
273
- params[dataKey] = std::move(message);
274
- }
275
-
276
- void BlobWebSocketModuleContentHandler::ProcessMessage(vector<uint8_t> &&message, dynamic &params) /*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 moduleName;
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 <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>
@@ -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
- 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 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 &params) override;
55
-
56
- void ProcessMessage(std::vector<uint8_t> &&message, folly::dynamic &params) 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
- void Unregister(int64_t socketID) noexcept;
63
- };
26
+ REACT_INIT(Initialize)
27
+ void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
64
28
 
65
- class BlobModuleRequestBodyHandler final : public IRequestBodyHandler {
66
- std::shared_ptr<IBlobPersistor> m_blobPersistor;
29
+ REACT_GET_CONSTANTS(GetConstants)
30
+ ReactNativeSpecs::BlobModuleSpec_Constants GetConstants() noexcept;
67
31
 
68
- public:
69
- BlobModuleRequestBodyHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
32
+ REACT_METHOD(AddNetworkingHandler, L"addNetworkingHandler")
33
+ void AddNetworkingHandler() noexcept;
70
34
 
71
- #pragma region IRequestBodyHandler
35
+ REACT_METHOD(AddWebSocketHandler, L"addWebSocketHandler")
36
+ void AddWebSocketHandler(double id) noexcept;
72
37
 
73
- bool Supports(folly::dynamic &data) override;
38
+ REACT_METHOD(RemoveWebSocketHandler, L"removeWebSocketHandler")
39
+ void RemoveWebSocketHandler(double id) noexcept;
74
40
 
75
- folly::dynamic ToRequestBody(folly::dynamic &data, std::string &contentType) override;
41
+ REACT_METHOD(SendOverSocket, L"sendOverSocket")
42
+ void SendOverSocket(winrt::Microsoft::ReactNative::JSValue &&blob, double socketID) noexcept;
76
43
 
77
- #pragma endregion IRequestBodyHandler
78
- };
44
+ REACT_METHOD(CreateFromParts, L"createFromParts")
45
+ void CreateFromParts(std::vector<winrt::Microsoft::ReactNative::JSValue> &&parts, std::string &&withId) noexcept;
79
46
 
80
- class BlobModuleResponseHandler final : public IResponseHandler {
81
- std::shared_ptr<IBlobPersistor> m_blobPersistor;
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
- #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
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<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;
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