react-native-windows 0.69.0-preview.3 → 0.69.0-preview.4

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 (58) hide show
  1. package/Directory.Build.props +4 -0
  2. package/Folly/Folly.vcxproj +4 -5
  3. package/Libraries/Network/RCTNetworkingWinShared.js +7 -0
  4. package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +3 -1
  5. package/Microsoft.ReactNative/IReactContext.cpp +17 -0
  6. package/Microsoft.ReactNative/IReactContext.h +2 -0
  7. package/Microsoft.ReactNative/IReactContext.idl +27 -0
  8. package/Microsoft.ReactNative/JsiApi.cpp +9 -0
  9. package/Microsoft.ReactNative/JsiApi.h +1 -0
  10. package/Microsoft.ReactNative/JsiApi.idl +1 -0
  11. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +3 -5
  12. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +1 -1
  13. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +31 -9
  14. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +48 -0
  15. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +1 -1
  16. package/Microsoft.ReactNative.Managed/packages.lock.json +57 -2
  17. package/PropertySheets/Generated/PackageVersion.g.props +1 -1
  18. package/PropertySheets/JSEngine.props +2 -2
  19. package/Shared/CreateModules.h +17 -2
  20. package/Shared/InspectorPackagerConnection.cpp +6 -7
  21. package/Shared/InspectorPackagerConnection.h +1 -1
  22. package/Shared/JSI/ChakraRuntime.cpp +5 -0
  23. package/Shared/JSI/ChakraRuntime.h +1 -0
  24. package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +72 -2
  25. package/Shared/JSI/NapiJsiV8RuntimeHolder.h +2 -0
  26. package/Shared/Modules/BlobModule.cpp +376 -0
  27. package/Shared/Modules/BlobModule.h +153 -0
  28. package/Shared/Modules/CxxModuleUtilities.cpp +19 -0
  29. package/Shared/Modules/CxxModuleUtilities.h +23 -0
  30. package/Shared/Modules/FileReaderModule.cpp +156 -0
  31. package/Shared/Modules/FileReaderModule.h +54 -0
  32. package/Shared/Modules/HttpModule.cpp +72 -69
  33. package/Shared/Modules/HttpModule.h +8 -1
  34. package/Shared/Modules/IBlobPersistor.h +30 -0
  35. package/Shared/Modules/IHttpModuleProxy.h +30 -0
  36. package/Shared/Modules/IRequestBodyHandler.h +52 -0
  37. package/Shared/Modules/IResponseHandler.h +27 -0
  38. package/Shared/Modules/IUriHandler.h +37 -0
  39. package/Shared/Modules/IWebSocketModuleContentHandler.h +26 -0
  40. package/Shared/Modules/IWebSocketModuleProxy.h +22 -0
  41. package/Shared/Modules/NetworkingModule.cpp +1 -1
  42. package/Shared/Modules/WebSocketModule.cpp +92 -22
  43. package/Shared/Modules/WebSocketModule.h +27 -1
  44. package/Shared/Networking/IHttpResource.h +50 -2
  45. package/Shared/Networking/WinRTHttpResource.cpp +169 -51
  46. package/Shared/Networking/WinRTHttpResource.h +27 -8
  47. package/Shared/Networking/WinRTTypes.h +5 -2
  48. package/Shared/OInstance.cpp +22 -5
  49. package/Shared/OInstance.h +8 -4
  50. package/Shared/RuntimeOptions.cpp +6 -3
  51. package/Shared/RuntimeOptions.h +14 -3
  52. package/Shared/Shared.vcxitems +13 -0
  53. package/Shared/Shared.vcxitems.filters +40 -1
  54. package/fmt/fmt.vcxproj +4 -5
  55. package/package.json +1 -1
  56. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/JSCRuntime.cpp +0 -1480
  57. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h +0 -753
  58. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h +0 -1331
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ // Standard Library
7
+ #include <memory>
8
+ #include <string>
9
+
10
+ namespace Microsoft::React {
11
+
12
+ /// <summary>
13
+ /// Provides partial access to WebSocketModule methods directly to other native modules
14
+ /// without switching to the JavaScript queue thread.
15
+ /// </summary>
16
+ struct IWebSocketModuleProxy {
17
+ virtual ~IWebSocketModuleProxy() noexcept {}
18
+
19
+ virtual void SendBinary(std::string &&base64String, int64_t id) noexcept = 0;
20
+ };
21
+
22
+ } // namespace Microsoft::React
@@ -261,7 +261,7 @@ void NetworkingModule::NetworkingHelper::SendRequest(
261
261
  int64_t requestId = ++s_lastRequestId;
262
262
 
263
263
  // Enforce supported args
264
- assert(responseType == "text" || responseType == "base64");
264
+ assert(responseType == "text" || responseType == "base64" || responseType == "blob");
265
265
 
266
266
  // Callback with the requestId
267
267
  cb({requestId});
@@ -5,10 +5,16 @@
5
5
 
6
6
  #include <Modules/WebSocketModule.h>
7
7
 
8
- #include <Utils.h>
8
+ #include <Modules/CxxModuleUtilities.h>
9
+ #include <Modules/IWebSocketModuleContentHandler.h>
10
+ #include <ReactPropertyBag.h>
11
+
12
+ // React Native
9
13
  #include <cxxreact/Instance.h>
10
14
  #include <cxxreact/JsArgumentHelpers.h>
11
- #include "Unicode.h"
15
+
16
+ // Windows API
17
+ #include <winrt/Windows.Security.Cryptography.h>
12
18
 
13
19
  // Standard Libriary
14
20
  #include <iomanip>
@@ -18,25 +24,26 @@ using namespace facebook::xplat;
18
24
  using facebook::react::Instance;
19
25
  using folly::dynamic;
20
26
 
21
- using Microsoft::Common::Unicode::Utf16ToUtf8;
22
- using Microsoft::Common::Unicode::Utf8ToUtf16;
23
-
24
27
  using std::shared_ptr;
25
28
  using std::string;
26
29
  using std::weak_ptr;
27
30
 
31
+ using winrt::Microsoft::ReactNative::IReactPropertyBag;
32
+ using winrt::Microsoft::ReactNative::ReactNonAbiValue;
33
+ using winrt::Microsoft::ReactNative::ReactPropertyBag;
34
+ using winrt::Microsoft::ReactNative::ReactPropertyId;
35
+
36
+ using winrt::Windows::Foundation::IInspectable;
37
+ using winrt::Windows::Security::Cryptography::CryptographicBuffer;
38
+
28
39
  namespace {
40
+ using Microsoft::React::IWebSocketModuleProxy;
29
41
  using Microsoft::React::WebSocketModule;
42
+ using Microsoft::React::Modules::SendEvent;
30
43
  using Microsoft::React::Networking::IWebSocketResource;
31
44
 
32
45
  constexpr char moduleName[] = "WebSocketModule";
33
46
 
34
- static void SendEvent(weak_ptr<Instance> weakInstance, string &&eventName, dynamic &&args) {
35
- if (auto instance = weakInstance.lock()) {
36
- instance->callJSFunction("RCTDeviceEventEmitter", "emit", dynamic::array(std::move(eventName), std::move(args)));
37
- }
38
- }
39
-
40
47
  static shared_ptr<IWebSocketResource>
41
48
  GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedState> weakState) {
42
49
  auto state = weakState.lock();
@@ -91,14 +98,37 @@ GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedS
91
98
  auto args = dynamic::object("id", id);
92
99
  SendEvent(weakInstance, "websocketOpen", std::move(args));
93
100
  });
94
- ws->SetOnMessage([id, weakInstance](size_t length, const string &message, bool isBinary) {
95
- auto strongInstance = weakInstance.lock();
96
- if (!strongInstance)
97
- return;
101
+ ws->SetOnMessage(
102
+ [id, weakInstance, propBag = ReactPropertyBag{state->InspectableProps.try_as<IReactPropertyBag>()}](
103
+ size_t length, const string &message, bool isBinary) {
104
+ auto strongInstance = weakInstance.lock();
105
+ if (!strongInstance)
106
+ return;
107
+
108
+ dynamic args = dynamic::object("id", id)("type", isBinary ? "binary" : "text");
109
+ shared_ptr<Microsoft::React::IWebSocketModuleContentHandler> contentHandler;
110
+ auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<Microsoft::React::IWebSocketModuleContentHandler>>>{
111
+ L"BlobModule.ContentHandler"};
112
+ if (auto prop = propBag.Get(propId))
113
+ contentHandler = prop.Value().lock();
114
+
115
+ if (contentHandler) {
116
+ if (isBinary) {
117
+ auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(message));
118
+ winrt::com_array<uint8_t> arr;
119
+ CryptographicBuffer::CopyToByteArray(buffer, arr);
120
+ auto data = std::vector<uint8_t>(arr.begin(), arr.end());
121
+
122
+ contentHandler->ProcessMessage(std::move(data), args);
123
+ } else {
124
+ contentHandler->ProcessMessage(string{message}, args);
125
+ }
126
+ } else {
127
+ args["data"] = message;
128
+ }
98
129
 
99
- auto args = dynamic::object("id", id)("data", message)("type", isBinary ? "binary" : "text");
100
- SendEvent(weakInstance, "websocketMessage", std::move(args));
101
- });
130
+ SendEvent(weakInstance, "websocketMessage", std::move(args));
131
+ });
102
132
  ws->SetOnClose([id, weakInstance](IWebSocketResource::CloseCode code, const string &reason) {
103
133
  auto strongInstance = weakInstance.lock();
104
134
  if (!strongInstance)
@@ -119,9 +149,24 @@ GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedS
119
149
 
120
150
  namespace Microsoft::React {
121
151
 
122
- WebSocketModule::WebSocketModule() : m_sharedState{std::make_shared<SharedState>()} {
152
+ #pragma region WebSocketModule
153
+
154
+ WebSocketModule::WebSocketModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties)
155
+ : m_sharedState{std::make_shared<SharedState>()},
156
+ m_proxy{std::make_shared<WebSocketModuleProxy>(inspectableProperties)} {
123
157
  m_sharedState->ResourceFactory = [](string &&url) { return IWebSocketResource::Make(); };
124
158
  m_sharedState->Module = this;
159
+ m_sharedState->InspectableProps = inspectableProperties;
160
+
161
+ auto propBag = ReactPropertyBag{m_sharedState->InspectableProps.try_as<IReactPropertyBag>()};
162
+
163
+ auto proxyPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{L"WebSocketModule.Proxy"};
164
+ auto proxy = weak_ptr<IWebSocketModuleProxy>{m_proxy};
165
+ propBag.Set(proxyPropId, std::move(proxy));
166
+
167
+ auto statePropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<SharedState>>>{L"WebSocketModule.SharedState"};
168
+ auto state = weak_ptr<SharedState>{m_sharedState};
169
+ propBag.Set(statePropId, std::move(state));
125
170
  }
126
171
 
127
172
  WebSocketModule::~WebSocketModule() noexcept /*override*/ {
@@ -167,7 +212,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
167
212
  const auto& headersDynamic = optionsDynamic["headers"];
168
213
  for (const auto& header : headersDynamic.items())
169
214
  {
170
- options.emplace(Utf8ToUtf16(header.first.getString()), header.second.getString());
215
+ options.emplace(winrt::to_hstring(header.first.getString()), header.second.getString());
171
216
  }
172
217
  }
173
218
 
@@ -246,12 +291,37 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
246
291
  } // getMethods
247
292
  // clang-format on
248
293
 
294
+ #pragma endregion WebSocketModule
295
+
296
+ #pragma region WebSocketModuleProxy
297
+
298
+ WebSocketModuleProxy::WebSocketModuleProxy(IInspectable const &inspectableProperties) noexcept
299
+ : m_inspectableProps{inspectableProperties} {}
300
+
301
+ void WebSocketModuleProxy::SendBinary(std::string &&base64String, int64_t id) noexcept /*override*/ {
302
+ auto propBag = ReactPropertyBag{m_inspectableProps.try_as<IReactPropertyBag>()};
303
+ auto sharedPropId =
304
+ ReactPropertyId<ReactNonAbiValue<weak_ptr<WebSocketModule::SharedState>>>{L"WebSocketModule.SharedState"};
305
+ auto state = propBag.Get(sharedPropId).Value();
306
+
307
+ weak_ptr weakWs = GetOrCreateWebSocket(id, {}, std::move(state));
308
+ if (auto sharedWs = weakWs.lock()) {
309
+ sharedWs->SendBinary(std::move(base64String));
310
+ }
311
+ }
312
+
313
+ #pragma endregion WebSocketModuleProxy
314
+
249
315
  /*extern*/ const char *GetWebSocketModuleName() noexcept {
250
316
  return moduleName;
251
317
  }
252
318
 
253
- /*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateWebSocketModule() noexcept {
254
- return std::make_unique<WebSocketModule>();
319
+ /*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateWebSocketModule(
320
+ IInspectable const &inspectableProperties) noexcept {
321
+ if (auto properties = inspectableProperties.try_as<IReactPropertyBag>())
322
+ return std::make_unique<WebSocketModule>(properties);
323
+
324
+ return nullptr;
255
325
  }
256
326
 
257
327
  } // namespace Microsoft::React
@@ -3,13 +3,31 @@
3
3
 
4
4
  #pragma once
5
5
 
6
+ #include <Modules/IWebSocketModuleProxy.h>
6
7
  #include <Networking/IWebSocketResource.h>
7
8
 
8
9
  // React Native
9
10
  #include <cxxreact/CxxModule.h>
10
11
 
12
+ // Windows API
13
+ #include <winrt/Windows.Foundation.h>
14
+
11
15
  namespace Microsoft::React {
12
16
 
17
+ class WebSocketModuleProxy final : public IWebSocketModuleProxy {
18
+ // Property bag high level reference.
19
+ winrt::Windows::Foundation::IInspectable m_inspectableProps;
20
+
21
+ public:
22
+ WebSocketModuleProxy(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept;
23
+
24
+ #pragma region IWebSocketModuleProxy
25
+
26
+ void SendBinary(std::string &&base64String, int64_t id) noexcept override;
27
+
28
+ #pragma endregion
29
+ };
30
+
13
31
  ///
14
32
  /// Realizes <c>NativeModules</c> projection.
15
33
  /// <remarks>See react-native/Libraries/WebSocket/WebSocket.js</remarks>
@@ -18,7 +36,7 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
18
36
  public:
19
37
  enum MethodId { Connect = 0, Close = 1, Send = 2, SendBinary = 3, Ping = 4, SIZE = 5 };
20
38
 
21
- WebSocketModule();
39
+ WebSocketModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties);
22
40
 
23
41
  ~WebSocketModule() noexcept override;
24
42
 
@@ -38,6 +56,9 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
38
56
  /// Keeps a raw reference to the module object to lazily retrieve the React Instance as needed.
39
57
  /// </summary>
40
58
  CxxModule *Module{nullptr};
59
+
60
+ // Property bag high level reference.
61
+ winrt::Windows::Foundation::IInspectable InspectableProps;
41
62
  };
42
63
 
43
64
  #pragma region CxxModule overrides
@@ -74,6 +95,11 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
74
95
  /// Keeps members that can be accessed threads other than this module's owner accessible.
75
96
  /// </summary>
76
97
  std::shared_ptr<SharedState> m_sharedState;
98
+
99
+ /// <summary>
100
+ /// Exposes a subset of the module's methods.
101
+ /// </summary>
102
+ std::shared_ptr<IWebSocketModuleProxy> m_proxy;
77
103
  };
78
104
 
79
105
  } // namespace Microsoft::React
@@ -3,6 +3,12 @@
3
3
 
4
4
  #pragma once
5
5
 
6
+ // Folly
7
+ #include <folly/dynamic.h>
8
+
9
+ // Windows API
10
+ #include <winrt/Windows.Foundation.h>
11
+
6
12
  // Standard Library
7
13
  #include <functional>
8
14
  #include <memory>
@@ -14,6 +20,7 @@ namespace Microsoft::React::Networking {
14
20
  struct IHttpResource {
15
21
  typedef std::unordered_map<std::string, std::string> Headers;
16
22
 
23
+ // TODO: Implement Form data
17
24
  struct BodyData {
18
25
  enum class Type : size_t { Empty, String, Base64, Uri, Form } Type = Type::Empty;
19
26
  std::string Data;
@@ -27,13 +34,53 @@ struct IHttpResource {
27
34
 
28
35
  static std::shared_ptr<IHttpResource> Make() noexcept;
29
36
 
37
+ static std::shared_ptr<IHttpResource> Make(
38
+ winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept;
39
+
30
40
  virtual ~IHttpResource() noexcept {}
31
41
 
42
+ /// <summary>
43
+ /// Initiates an HTTP request.
44
+ /// </summary>
45
+ /// <param name="method">
46
+ /// HTTP verb to send in de request.
47
+ /// GET | POST | PUT | DELETE | OPTIONS
48
+ /// </param>
49
+ /// <param name="url">
50
+ /// Server/service remote endpoint to send the request to.
51
+ /// </param>
52
+ /// <param name="requestId">
53
+ /// Request unique identifier.
54
+ /// </param>
55
+ /// <param name="headers">
56
+ /// HTTP request header map.
57
+ /// </param>
58
+ /// <param name="data">
59
+ /// Dynamic map containing request payload.
60
+ /// The payload may be an empty request body or one of the following:
61
+ /// "string" - UTF-8 string payload
62
+ /// "base64" - Base64-encoded data string
63
+ /// "uri" - URI data reference
64
+ /// "form" - Form-encoded data
65
+ /// </param>
66
+ /// <param name="responseType">
67
+ /// text | binary | blob
68
+ /// </param>
69
+ /// <param name="useIncrementalUpdates">
70
+ /// Response body to be retrieved in several iterations.
71
+ /// </param>
72
+ /// <param name="timeout">
73
+ /// Request timeout in miliseconds.
74
+ /// </param>
75
+ /// <param name="withCredentials">
76
+ /// Allow including credentials in request.
77
+ /// </param>
32
78
  virtual void SendRequest(
33
79
  std::string &&method,
34
80
  std::string &&url,
81
+ int64_t requestId,
35
82
  Headers &&headers,
36
- BodyData &&bodyData,
83
+ folly::dynamic &&data,
37
84
  std::string &&responseType,
38
85
  bool useIncrementalUpdates,
39
86
  int64_t timeout,
@@ -43,9 +90,10 @@ struct IHttpResource {
43
90
 
44
91
  virtual void ClearCookies() noexcept = 0;
45
92
 
46
- virtual void SetOnRequest(std::function<void(int64_t requestId)> &&handler) noexcept = 0;
93
+ virtual void SetOnRequestSuccess(std::function<void(int64_t requestId)> &&handler) noexcept = 0;
47
94
  virtual void SetOnResponse(std::function<void(int64_t requestId, Response &&response)> &&handler) noexcept = 0;
48
95
  virtual void SetOnData(std::function<void(int64_t requestId, std::string &&responseData)> &&handler) noexcept = 0;
96
+ virtual void SetOnData(std::function<void(int64_t requestId, folly::dynamic &&responseData)> &&handler) noexcept = 0;
49
97
  virtual void SetOnError(
50
98
  std::function<void(int64_t requestId, std::string &&errorMessage /*, bool isTimeout*/)> &&handler) noexcept = 0;
51
99
  };