react-native-windows 0.66.5 → 0.66.9

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/CHANGELOG.json CHANGED
@@ -2,7 +2,67 @@
2
2
  "name": "react-native-windows",
3
3
  "entries": [
4
4
  {
5
- "date": "Mon, 22 Nov 2021 16:09:45 GMT",
5
+ "date": "Mon, 31 Jan 2022 16:12:08 GMT",
6
+ "tag": "react-native-windows_v0.66.9",
7
+ "version": "0.66.9",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "comment": "Better reporting of failures to load the bundle file",
12
+ "author": "30809111+acoates-ms@users.noreply.github.com",
13
+ "commit": "0951f3da2e746f1feb0bd7e96d3dd8d5d936d6fb",
14
+ "package": "react-native-windows"
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Mon, 24 Jan 2022 16:11:33 GMT",
21
+ "tag": "react-native-windows_v0.66.8",
22
+ "version": "0.66.8",
23
+ "comments": {
24
+ "patch": [
25
+ {
26
+ "comment": "Promote 0.66 to legacy",
27
+ "author": "ngerlem@microsoft.com",
28
+ "commit": "919d91a3e9845f9a60417fb8e47a36d7caedbc28",
29
+ "package": "react-native-windows"
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "date": "Mon, 17 Jan 2022 16:12:35 GMT",
36
+ "tag": "react-native-windows_v0.66.7",
37
+ "version": "0.66.7",
38
+ "comments": {
39
+ "patch": [
40
+ {
41
+ "comment": "Fork HoverState.js to allow hover events on Pressable",
42
+ "author": "saadnajmi2@gmail.com",
43
+ "commit": "1a70a3b499a0e695597e8669439b856d41096170",
44
+ "package": "react-native-windows"
45
+ }
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "date": "Mon, 03 Jan 2022 16:10:55 GMT",
51
+ "tag": "react-native-windows_v0.66.6",
52
+ "version": "0.66.6",
53
+ "comments": {
54
+ "patch": [
55
+ {
56
+ "comment": "[0.66] Avoid capturing raw this pointer in WebSocket module",
57
+ "author": "julio.rocha@microsoft.com",
58
+ "commit": "1a0cec7754fdff58dad91fb15c483e884ef70aee",
59
+ "package": "react-native-windows"
60
+ }
61
+ ]
62
+ }
63
+ },
64
+ {
65
+ "date": "Mon, 22 Nov 2021 16:09:58 GMT",
6
66
  "tag": "react-native-windows_v0.66.5",
7
67
  "version": "0.66.5",
8
68
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,17 +1,49 @@
1
1
  # Change Log - react-native-windows
2
2
 
3
- This log was last generated on Mon, 22 Nov 2021 16:09:45 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 31 Jan 2022 16:12:08 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## 0.66.5
7
+ ## 0.66.9
8
8
 
9
- Mon, 22 Nov 2021 16:09:45 GMT
9
+ Mon, 31 Jan 2022 16:12:08 GMT
10
10
 
11
11
  ### Patches
12
12
 
13
- - Fix C# Module Event invocation (vmorozov@microsoft.com)
13
+ - Better reporting of failures to load the bundle file (30809111+acoates-ms@users.noreply.github.com)
14
14
 
15
+ ## 0.66.8
16
+
17
+ Mon, 24 Jan 2022 16:11:33 GMT
18
+
19
+ ### Patches
20
+
21
+ - Promote 0.66 to legacy (ngerlem@microsoft.com)
22
+
23
+ ## 0.66.7
24
+
25
+ Mon, 17 Jan 2022 16:12:35 GMT
26
+
27
+ ### Patches
28
+
29
+ - Fork HoverState.js to allow hover events on Pressable (saadnajmi2@gmail.com)
30
+
31
+ ## 0.66.6
32
+
33
+ Mon, 03 Jan 2022 16:10:55 GMT
34
+
35
+ ### Patches
36
+
37
+ - [0.66] Avoid capturing raw this pointer in WebSocket module (julio.rocha@microsoft.com)
38
+
39
+ ## 0.66.5
40
+
41
+ Mon, 22 Nov 2021 16:09:58 GMT
42
+
43
+ ### Patches
44
+
45
+ - Fix C# Module Event invocation (vmorozov@microsoft.com)
46
+
15
47
  ## 0.66.4
16
48
 
17
49
  Mon, 15 Nov 2021 16:09:53 GMT
@@ -25,6 +25,7 @@ import usePressability from '../../Pressability/usePressability';
25
25
  import {normalizeRect, type RectOrSize} from '../../StyleSheet/Rect';
26
26
  import type {
27
27
  LayoutEvent,
28
+ MouseEvent,
28
29
  PressEvent,
29
30
  // [Windows
30
31
  BlurEvent,
@@ -72,6 +73,16 @@ type Props = $ReadOnly<{|
72
73
  */
73
74
  children: React.Node | ((state: StateCallbackType) => React.Node),
74
75
 
76
+ /**
77
+ * Duration to wait after hover in before calling `onHoverIn`.
78
+ */
79
+ delayHoverIn?: ?number,
80
+
81
+ /**
82
+ * Duration to wait after hover out before calling `onHoverOut`.
83
+ */
84
+ delayHoverOut?: ?number,
85
+
75
86
  /**
76
87
  * Duration (in milliseconds) from `onPressIn` before `onLongPress` is called.
77
88
  */
@@ -98,6 +109,16 @@ type Props = $ReadOnly<{|
98
109
  */
99
110
  onLayout?: ?(event: LayoutEvent) => mixed,
100
111
 
112
+ /**
113
+ * Called when the hover is activated to provide visual feedback.
114
+ */
115
+ onHoverIn?: ?(event: MouseEvent) => mixed,
116
+
117
+ /**
118
+ * Called when the hover is deactivated to undo visual feedback.
119
+ */
120
+ onHoverOut?: ?(event: MouseEvent) => mixed,
121
+
101
122
  /**
102
123
  * Called when a long-tap gesture is detected.
103
124
  */
@@ -201,9 +222,13 @@ function Pressable(props: Props, forwardedRef): React.Node {
201
222
  android_ripple,
202
223
  cancelable,
203
224
  children,
225
+ delayHoverIn,
226
+ delayHoverOut,
204
227
  delayLongPress,
205
228
  disabled,
206
229
  focusable,
230
+ onHoverIn,
231
+ onHoverOut,
207
232
  onLongPress,
208
233
  onPress,
209
234
  onPressIn,
@@ -267,8 +292,12 @@ function Pressable(props: Props, forwardedRef): React.Node {
267
292
  hitSlop,
268
293
  pressRectOffset: pressRetentionOffset,
269
294
  android_disableSound,
295
+ delayHoverIn,
296
+ delayHoverOut,
270
297
  delayLongPress,
271
298
  delayPressIn: unstable_pressDelay,
299
+ onHoverIn,
300
+ onHoverOut,
272
301
  onLongPress,
273
302
  onPress,
274
303
  onPressIn(event: PressEvent): void {
@@ -301,9 +330,13 @@ function Pressable(props: Props, forwardedRef): React.Node {
301
330
  android_disableSound,
302
331
  android_rippleConfig,
303
332
  cancelable,
333
+ delayHoverIn,
334
+ delayHoverOut,
304
335
  delayLongPress,
305
336
  disabled,
306
337
  hitSlop,
338
+ onHoverIn,
339
+ onHoverOut,
307
340
  onLongPress,
308
341
  onPress,
309
342
  onPressIn,
@@ -49,6 +49,10 @@ if (Platform.OS === 'web') {
49
49
  document.addEventListener('touchmove', disableHover, true);
50
50
  document.addEventListener('mousemove', enableHover, true);
51
51
  }
52
+ // [Windows
53
+ } else if (Platform.OS === 'windows') {
54
+ isEnabled = true;
55
+ // Windows]
52
56
  }
53
57
 
54
58
  export function isHoverEnabled(): boolean {
@@ -19,9 +19,9 @@ using winrt::Microsoft::ReactNative::implementation::QuirkSettings;
19
19
 
20
20
  namespace Microsoft::React {
21
21
 
22
- std::shared_ptr<IWebSocketResource> IWebSocketResource::Make(std::string &&urlString) {
22
+ std::shared_ptr<IWebSocketResource> IWebSocketResource::Make() {
23
23
  std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> certExceptions;
24
- return std::make_shared<WinRTWebSocketResource>(std::move(urlString), std::move(certExceptions));
24
+ return std::make_shared<WinRTWebSocketResource>(std::move(certExceptions));
25
25
  }
26
26
 
27
27
  } // namespace Microsoft::React
@@ -139,14 +139,9 @@ struct ReactViewInstance : public Mso::UnknownObject<Mso::RefCountStrategy::Weak
139
139
  inline Mso::Future<void> PostInUIQueue(winrt::delegate<ReactNative::IReactViewInstance> const &action) noexcept {
140
140
  Mso::Promise<void> promise;
141
141
 
142
- // ReactViewInstance has shorter lifetime than ReactRootControl. Thus, we capture this WeakPtr.
143
- m_uiDispatcher.Post([weakThis = Mso::WeakPtr{this}, promise, action{std::move(action)}]() mutable noexcept {
144
- if (auto strongThis = weakThis.GetStrongPtr()) {
145
- action(strongThis->m_rootControl);
146
- promise.SetValue();
147
- } else {
148
- promise.TryCancel();
149
- }
142
+ m_uiDispatcher.Post([control = m_rootControl, promise, action{std::move(action)}]() mutable noexcept {
143
+ action(control);
144
+ promise.SetValue();
150
145
  });
151
146
  return promise.AsFuture();
152
147
  }
@@ -159,9 +154,7 @@ winrt::Windows::Foundation::IAsyncAction ReactViewHost::AttachViewInstance(
159
154
  }
160
155
 
161
156
  winrt::Windows::Foundation::IAsyncAction ReactViewHost::DetachViewInstance() noexcept {
162
- Mso::Promise<void> promise;
163
- promise.SetValue();
164
- return make<Mso::AsyncActionFutureAdapter>(promise.AsFuture());
157
+ return make<Mso::AsyncActionFutureAdapter>(m_viewHost->DetachViewInstance());
165
158
  }
166
159
 
167
160
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -379,8 +379,13 @@ Mso::Future<void> ReactHost::LoadInQueue(ReactOptions &&options) noexcept {
379
379
  }
380
380
  }
381
381
 
382
- return whenLoaded.AsFuture().Then(m_executor, [this](Mso::Maybe<void> && /*value*/) noexcept {
382
+ return whenLoaded.AsFuture().Then(m_executor, [this](Mso::Maybe<void> &&value) noexcept {
383
383
  std::vector<Mso::Future<void>> loadCompletionList;
384
+
385
+ if (value.IsError()) {
386
+ return Mso::MakeFailedFuture<void>(std::move(value.TakeError()));
387
+ }
388
+
384
389
  ForEachViewHost([&loadCompletionList](auto &viewHost) noexcept {
385
390
  loadCompletionList.push_back(viewHost.UpdateViewInstanceInQueue());
386
391
  });
@@ -224,9 +224,11 @@ ReactInstanceWin::ReactInstanceWin(
224
224
  m_whenLoaded.AsFuture()
225
225
  .Then<Mso::Executors::Inline>(
226
226
  [onLoaded = m_options.OnInstanceLoaded, reactContext = m_reactContext](Mso::Maybe<void> &&value) noexcept {
227
+ auto errCode = value.IsError() ? value.TakeError() : Mso::ErrorCode();
227
228
  if (onLoaded) {
228
- onLoaded.Get()->Invoke(reactContext, value.IsError() ? value.TakeError() : Mso::ErrorCode());
229
+ onLoaded.Get()->Invoke(reactContext, errCode);
229
230
  }
231
+ return Mso::Maybe<void>(errCode);
230
232
  })
231
233
  .Then(Queue(), [whenLoaded = std::move(whenLoaded)](Mso::Maybe<void> &&value) noexcept {
232
234
  whenLoaded.SetValue(std::move(value));
@@ -468,7 +470,7 @@ void ReactInstanceWin::Initialize() noexcept {
468
470
  m_options.TurboModuleProvider,
469
471
  std::make_unique<BridgeUIBatchInstanceCallback>(weakThis),
470
472
  m_jsMessageThread.Load(),
471
- Mso::Copy(m_batchingUIThread),
473
+ m_nativeMessageThread.Load(),
472
474
  std::move(devSettings));
473
475
 
474
476
  m_instanceWrapper.Exchange(std::move(instanceWrapper));
@@ -483,6 +485,16 @@ void ReactInstanceWin::Initialize() noexcept {
483
485
  }
484
486
  #endif
485
487
 
488
+ // The InstanceCreated event can be used to augment the JS environment for all JS code. So it needs to be
489
+ // triggered before any platform JS code is run. Using m_jsMessageThread instead of jsDispatchQueue avoids
490
+ // waiting for the JSCaller which can delay the event until after certain JS code has already run
491
+ m_jsMessageThread.Load()->runOnQueue(
492
+ [onCreated = m_options.OnInstanceCreated, reactContext = m_reactContext]() noexcept {
493
+ if (onCreated) {
494
+ onCreated.Get()->Invoke(reactContext);
495
+ }
496
+ });
497
+
486
498
  LoadJSBundles();
487
499
 
488
500
  if (UseDeveloperSupport() && State() != ReactInstanceState::HasError) {
@@ -558,7 +570,9 @@ void ReactInstanceWin::LoadJSBundles() noexcept {
558
570
 
559
571
  try {
560
572
  instanceWrapper->loadBundleSync(Mso::Copy(strongThis->JavaScriptBundleFile()));
561
- strongThis->OnReactInstanceLoaded(Mso::ErrorCode{});
573
+ if (strongThis->State() != ReactInstanceState::HasError) {
574
+ strongThis->OnReactInstanceLoaded(Mso::ErrorCode{});
575
+ }
562
576
  } catch (...) {
563
577
  strongThis->OnReactInstanceLoaded(Mso::ExceptionErrorProvider().MakeErrorCode(std::current_exception()));
564
578
  }
@@ -629,13 +643,6 @@ void ReactInstanceWin::InitJSMessageThread() noexcept {
629
643
  Mso::Copy(m_whenDestroyed));
630
644
  auto jsDispatchQueue = Mso::DispatchQueue::MakeCustomQueue(Mso::CntPtr(scheduler));
631
645
 
632
- // This work item will be processed as a first item in JS queue when the react instance is created.
633
- jsDispatchQueue.Post([onCreated = m_options.OnInstanceCreated, reactContext = m_reactContext]() noexcept {
634
- if (onCreated) {
635
- onCreated.Get()->Invoke(reactContext);
636
- }
637
- });
638
-
639
646
  auto jsDispatcher =
640
647
  winrt::make<winrt::Microsoft::ReactNative::implementation::ReactDispatcher>(Mso::Copy(jsDispatchQueue));
641
648
  m_options.Properties.Set(ReactDispatcherHelper::JSDispatcherProperty(), jsDispatcher);
@@ -27,18 +27,20 @@ struct AsyncActionFutureAdapter : winrt::implements<
27
27
  if (strongThis->m_status == AsyncStatus::Started) {
28
28
  if (result.IsValue()) {
29
29
  strongThis->m_status = AsyncStatus::Completed;
30
- if (strongThis->m_completedAssigned) {
31
- handler = std::move(strongThis->m_completed);
32
- }
33
30
  } else {
34
- strongThis->m_status = AsyncStatus::Error;
35
31
  strongThis->m_error = result.GetError();
32
+ strongThis->m_status = Mso::CancellationErrorProvider().TryGetErrorInfo(strongThis->m_error, false)
33
+ ? AsyncStatus::Canceled
34
+ : AsyncStatus::Error;
35
+ }
36
+ if (strongThis->m_completedAssigned) {
37
+ handler = std::move(strongThis->m_completed);
36
38
  }
37
39
  }
38
40
  }
39
41
 
40
42
  if (handler) {
41
- invoke(handler, *strongThis, AsyncStatus::Completed);
43
+ invoke(handler, *strongThis, strongThis->m_status);
42
44
  }
43
45
  }
44
46
  });
@@ -79,17 +79,17 @@ struct IWebSocketResource {
79
79
  /// <summary>
80
80
  /// Creates an <c>IWebSocketResource</c> instance.
81
81
  /// </summary>
82
- /// <param name="url">
83
- /// WebSocket URL address the instance will connect to.
84
- /// The address's scheme can be either ws:// or wss://.
85
- /// </param>
86
- static std::shared_ptr<IWebSocketResource> Make(std::string &&url);
82
+ static std::shared_ptr<IWebSocketResource> Make();
87
83
 
88
84
  virtual ~IWebSocketResource() noexcept {}
89
85
 
90
86
  /// <summary>
91
87
  /// Establishes a continuous connection with the remote endpoint.
92
88
  /// </summary>
89
+ /// <param name="url">
90
+ /// WebSocket URL address the instance will connect to.
91
+ /// The address's scheme can be either ws:// or wss://.
92
+ /// </param>
93
93
  /// <param name="protocols">
94
94
  /// Currently unused
95
95
  /// </param>
@@ -97,7 +97,7 @@ struct IWebSocketResource {
97
97
  /// HTTP header fields passed by the remote endpoint, to be used in the
98
98
  /// handshake process.
99
99
  /// </param>
100
- virtual void Connect(const Protocols &protocols = {}, const Options &options = {}) noexcept = 0;
100
+ virtual void Connect(std::string &&url, const Protocols &protocols = {}, const Options &options = {}) noexcept = 0;
101
101
 
102
102
  /// <summary>
103
103
  /// Sends a ping frame to the remote endpoint.
@@ -204,8 +204,7 @@ winrt::fire_and_forget InspectorPackagerConnection::connectAsync() {
204
204
  co_await winrt::resume_background();
205
205
 
206
206
  std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> certExceptions;
207
- m_packagerWebSocketConnection =
208
- std::make_shared<Microsoft::React::WinRTWebSocketResource>(m_url, std::move(certExceptions));
207
+ m_packagerWebSocketConnection = std::make_shared<Microsoft::React::WinRTWebSocketResource>(std::move(certExceptions));
209
208
 
210
209
  m_packagerWebSocketConnection->SetOnError([](const Microsoft::React::IWebSocketResource::Error &err) {
211
210
  facebook::react::tracing::error(err.Message.c_str());
@@ -270,7 +269,7 @@ winrt::fire_and_forget InspectorPackagerConnection::connectAsync() {
270
269
 
271
270
  Microsoft::React::IWebSocketResource::Protocols protocols;
272
271
  Microsoft::React::IWebSocketResource::Options options;
273
- m_packagerWebSocketConnection->Connect(protocols, options);
272
+ m_packagerWebSocketConnection->Connect(std::string{m_url}, protocols, options);
274
273
 
275
274
  co_return;
276
275
  }
@@ -14,7 +14,9 @@
14
14
  #include <iomanip>
15
15
 
16
16
  using namespace facebook::xplat;
17
- using namespace folly;
17
+
18
+ using facebook::react::Instance;
19
+ using folly::dynamic;
18
20
 
19
21
  using Microsoft::Common::Unicode::Utf16ToUtf8;
20
22
  using Microsoft::Common::Unicode::Utf8ToUtf16;
@@ -24,17 +26,111 @@ using std::string;
24
26
  using std::weak_ptr;
25
27
 
26
28
  namespace {
29
+ using Microsoft::React::IWebSocketResource;
30
+ using Microsoft::React::WebSocketModule;
31
+
27
32
  constexpr char moduleName[] = "WebSocketModule";
33
+
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
+ static shared_ptr<IWebSocketResource>
41
+ GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedState> weakState) {
42
+ auto state = weakState.lock();
43
+ if (!state) {
44
+ return nullptr;
45
+ }
46
+
47
+ auto itr = state->ResourceMap.find(id);
48
+ if (itr == state->ResourceMap.end()) {
49
+ if (!state->Module) {
50
+ return nullptr;
51
+ }
52
+ auto weakInstance = state->Module->getInstance();
53
+
54
+ shared_ptr<IWebSocketResource> ws;
55
+ try {
56
+ ws = state->ResourceFactory(std::move(url));
57
+ } catch (const winrt::hresult_error &e) {
58
+ std::stringstream ss;
59
+ ss << "[" << std::hex << std::showbase << std::setw(8) << static_cast<uint32_t>(e.code()) << "] "
60
+ << winrt::to_string(e.message());
61
+
62
+ SendEvent(weakInstance, "webSocketFailed", dynamic::object("id", id)("message", std::move(ss.str())));
63
+
64
+ return nullptr;
65
+ } catch (const std::exception &e) {
66
+ SendEvent(weakInstance, "webSocketFailed", dynamic::object("id", id)("message", e.what()));
67
+
68
+ return nullptr;
69
+ } catch (...) {
70
+ SendEvent(
71
+ weakInstance,
72
+ "webSocketFailed",
73
+ dynamic::object("id", id)("message", "Unidentified error creating IWebSocketResource"));
74
+
75
+ return nullptr;
76
+ }
77
+
78
+ ws->SetOnError([id, weakInstance](const IWebSocketResource::Error &err) {
79
+ auto strongInstance = weakInstance.lock();
80
+ if (!strongInstance)
81
+ return;
82
+
83
+ auto errorObj = dynamic::object("id", id)("message", err.Message);
84
+ SendEvent(weakInstance, "websocketFailed", std::move(errorObj));
85
+ });
86
+ ws->SetOnConnect([id, weakInstance]() {
87
+ auto strongInstance = weakInstance.lock();
88
+ if (!strongInstance)
89
+ return;
90
+
91
+ auto args = dynamic::object("id", id);
92
+ SendEvent(weakInstance, "websocketOpen", std::move(args));
93
+ });
94
+ ws->SetOnMessage([id, weakInstance](size_t length, const string &message, bool isBinary) {
95
+ auto strongInstance = weakInstance.lock();
96
+ if (!strongInstance)
97
+ return;
98
+
99
+ auto args = dynamic::object("id", id)("data", message)("type", isBinary ? "binary" : "text");
100
+ SendEvent(weakInstance, "websocketMessage", std::move(args));
101
+ });
102
+ ws->SetOnClose([id, weakInstance](IWebSocketResource::CloseCode code, const string &reason) {
103
+ auto strongInstance = weakInstance.lock();
104
+ if (!strongInstance)
105
+ return;
106
+
107
+ auto args = dynamic::object("id", id)("code", static_cast<uint16_t>(code))("reason", reason);
108
+ SendEvent(weakInstance, "websocketClosed", std::move(args));
109
+ });
110
+
111
+ state->ResourceMap.emplace(id, ws);
112
+ return ws;
113
+ }
114
+
115
+ return itr->second;
116
+ }
117
+
28
118
  } // anonymous namespace
29
119
 
30
120
  namespace Microsoft::React {
31
121
 
32
- WebSocketModule::WebSocketModule()
33
- : m_resourceFactory{[](string &&url) { return IWebSocketResource::Make(std::move(url)); }} {}
122
+ WebSocketModule::WebSocketModule() : m_sharedState{std::make_shared<SharedState>()} {
123
+ m_sharedState->ResourceFactory = [](string &&url) { return IWebSocketResource::Make(); };
124
+ m_sharedState->Module = this;
125
+ }
126
+
127
+ WebSocketModule::~WebSocketModule() noexcept /*override*/ {
128
+ m_sharedState->Module = nullptr;
129
+ }
34
130
 
35
131
  void WebSocketModule::SetResourceFactory(
36
132
  std::function<shared_ptr<IWebSocketResource>(const string &)> &&resourceFactory) {
37
- m_resourceFactory = std::move(resourceFactory);
133
+ m_sharedState->ResourceFactory = std::move(resourceFactory);
38
134
  }
39
135
 
40
136
  string WebSocketModule::getName() {
@@ -50,9 +146,9 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
50
146
  {
51
147
  return
52
148
  {
53
- Method(
149
+ {
54
150
  "connect",
55
- [this](dynamic args) // const string& url, dynamic protocols, dynamic options, int64_t id
151
+ [weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // const string& url, dynamic protocols, dynamic options, int64_t id
56
152
  {
57
153
  IWebSocketResource::Protocols protocols;
58
154
  dynamic protocolsDynamic = jsArgAsDynamic(args, 1);
@@ -75,20 +171,21 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
75
171
  }
76
172
  }
77
173
 
78
- weak_ptr weakWs = this->GetOrCreateWebSocket(jsArgAsInt(args, 3), jsArgAsString(args, 0));
174
+ weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 3), jsArgAsString(args, 0), weakState);
79
175
  if (auto sharedWs = weakWs.lock())
80
176
  {
81
- sharedWs->Connect(protocols, options);
177
+ sharedWs->Connect(jsArgAsString(args, 0), protocols, options);
82
178
  }
83
- }),
84
- Method(
179
+ }
180
+ },
181
+ {
85
182
  "close",
86
- [this](dynamic args) // [int64_t code, string reason,] int64_t id
183
+ [weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // [int64_t code, string reason,] int64_t id
87
184
  {
88
185
  // See react-native\Libraries\WebSocket\WebSocket.js:_close
89
186
  if (args.size() == 3) // WebSocketModule.close(statusCode, closeReason, this._socketId);
90
187
  {
91
- weak_ptr weakWs = this->GetOrCreateWebSocket(jsArgAsInt(args, 2));
188
+ weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 2), {}, weakState);
92
189
  if (auto sharedWs = weakWs.lock())
93
190
  {
94
191
  sharedWs->Close(static_cast<IWebSocketResource::CloseCode>(jsArgAsInt(args, 0)), jsArgAsString(args, 1));
@@ -96,7 +193,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
96
193
  }
97
194
  else if (args.size() == 1) // WebSocketModule.close(this._socketId);
98
195
  {
99
- weak_ptr weakWs = this->GetOrCreateWebSocket(jsArgAsInt(args, 0));
196
+ weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 0), {}, weakState);
100
197
  if (auto sharedWs = weakWs.lock())
101
198
  {
102
199
  sharedWs->Close(IWebSocketResource::CloseCode::Normal, {});
@@ -104,137 +201,53 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
104
201
  }
105
202
  else
106
203
  {
107
- auto errorObj = dynamic::object("id", -1)("message", "Incorrect number of parameters");
108
- this->SendEvent("websocketFailed", std::move(errorObj));
204
+ auto state = weakState.lock();
205
+ if (state && state->Module) {
206
+ auto errorObj = dynamic::object("id", -1)("message", "Incorrect number of parameters");
207
+ SendEvent(state->Module->getInstance(), "websocketFailed", std::move(errorObj));
208
+ }
109
209
  }
110
- }),
111
- Method(
210
+ }
211
+ },
212
+ {
112
213
  "send",
113
- [this](dynamic args) // const string& message, int64_t id
214
+ [weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // const string& message, int64_t id
114
215
  {
115
- weak_ptr weakWs = this->GetOrCreateWebSocket(jsArgAsInt(args, 1));
216
+ weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 1), {}, weakState);
116
217
  if (auto sharedWs = weakWs.lock())
117
218
  {
118
219
  sharedWs->Send(jsArgAsString(args, 0));
119
220
  }
120
- }),
121
- Method(
221
+ }
222
+ },
223
+ {
122
224
  "sendBinary",
123
- [this](dynamic args) // const string& base64String, int64_t id
225
+ [weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // const string& base64String, int64_t id
124
226
  {
125
- weak_ptr weakWs = this->GetOrCreateWebSocket(jsArgAsInt(args, 1));
227
+ weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 1), {}, weakState);
126
228
  if (auto sharedWs = weakWs.lock())
127
229
  {
128
230
  sharedWs->SendBinary(jsArgAsString(args, 0));
129
231
  }
130
- }),
131
- Method(
232
+ }
233
+ },
234
+ {
132
235
  "ping",
133
- [this](dynamic args) // int64_t id
236
+ [weakState = weak_ptr<SharedState>(m_sharedState)](dynamic args) // int64_t id
134
237
  {
135
- weak_ptr weakWs = this->GetOrCreateWebSocket(jsArgAsInt(args, 0));
238
+ weak_ptr weakWs = GetOrCreateWebSocket(jsArgAsInt(args, 0), {}, weakState);
136
239
  if (auto sharedWs = weakWs.lock())
137
240
  {
138
241
  sharedWs->Ping();
139
242
  }
140
- })
243
+ }
244
+ }
141
245
  };
142
246
  } // getMethods
143
247
  // clang-format on
144
248
 
145
- #pragma region private members
146
-
147
- void WebSocketModule::SendEvent(string &&eventName, dynamic &&args) {
148
- auto weakInstance = this->getInstance();
149
- if (auto instance = weakInstance.lock()) {
150
- instance->callJSFunction("RCTDeviceEventEmitter", "emit", dynamic::array(std::move(eventName), std::move(args)));
151
- }
152
- }
153
-
154
- // clang-format off
155
- shared_ptr<IWebSocketResource> WebSocketModule::GetOrCreateWebSocket(int64_t id, string&& url)
156
- {
157
- auto itr = m_webSockets.find(id);
158
- if (itr == m_webSockets.end())
159
- {
160
- shared_ptr<IWebSocketResource> ws;
161
- try
162
- {
163
- ws = m_resourceFactory(std::move(url));
164
- }
165
- catch (const winrt::hresult_error& e)
166
- {
167
- std::stringstream ss;
168
- ss << "[" << std::hex << std::showbase << std::setw(8) << static_cast<uint32_t>(e.code()) << "] " <<
169
- winrt::to_string(e.message());
170
-
171
- SendEvent("webSocketFailed", dynamic::object("id", id)("message", std::move(ss.str())));
172
-
173
- return nullptr;
174
- }
175
- catch (const std::exception& e)
176
- {
177
- SendEvent("webSocketFailed", dynamic::object("id", id)("message", e.what()));
178
-
179
- return nullptr;
180
- }
181
- catch (...)
182
- {
183
- SendEvent("webSocketFailed", dynamic::object("id", id)("message", "Unidentified error creating IWebSocketResource"));
184
-
185
- return nullptr;
186
- }
187
-
188
- auto weakInstance = this->getInstance();
189
- ws->SetOnError([this, id, weakInstance](const IWebSocketResource::Error& err)
190
- {
191
- auto strongInstance = weakInstance.lock();
192
- if (!strongInstance)
193
- return;
194
-
195
- auto errorObj = dynamic::object("id", id)("message", err.Message);
196
- this->SendEvent("websocketFailed", std::move(errorObj));
197
- });
198
- ws->SetOnConnect([this, id, weakInstance]()
199
- {
200
- auto strongInstance = weakInstance.lock();
201
- if (!strongInstance)
202
- return;
203
-
204
- auto args = dynamic::object("id", id);
205
- this->SendEvent("websocketOpen", std::move(args));
206
- });
207
- ws->SetOnMessage([this, id, weakInstance](size_t length, const string& message, bool isBinary)
208
- {
209
- auto strongInstance = weakInstance.lock();
210
- if (!strongInstance)
211
- return;
212
-
213
- auto args = dynamic::object("id", id)("data", message)("type", isBinary ? "binary" : "text");
214
- this->SendEvent("websocketMessage", std::move(args));
215
- });
216
- ws->SetOnClose([this, id, weakInstance](IWebSocketResource::CloseCode code, const string& reason)
217
- {
218
- auto strongInstance = weakInstance.lock();
219
- if (!strongInstance)
220
- return;
221
-
222
- auto args = dynamic::object("id", id)("code", static_cast<uint16_t>(code))("reason", reason);
223
- this->SendEvent("websocketClosed", std::move(args));
224
- });
225
-
226
- m_webSockets.emplace(id, ws);
227
- return ws;
228
- }
229
-
230
- return itr->second;
231
- }
232
- // clang-format on
233
-
234
- #pragma endregion private members
235
-
236
249
  /*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateWebSocketModule() noexcept {
237
- return make_unique<WebSocketModule>();
250
+ return std::make_unique<WebSocketModule>();
238
251
  }
239
252
 
240
253
  } // namespace Microsoft::React
@@ -18,6 +18,26 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
18
18
 
19
19
  WebSocketModule();
20
20
 
21
+ ~WebSocketModule() noexcept override;
22
+
23
+ struct SharedState {
24
+ /// <summary>
25
+ /// Keeps <c>IWebSocketResource</c> instances identified by <c>id</c>.
26
+ /// As defined in WebSocket.js.
27
+ /// </summary>
28
+ std::map<int64_t, std::shared_ptr<IWebSocketResource>> ResourceMap{};
29
+
30
+ /// <summary>
31
+ /// Generates IWebSocketResource instances, defaulting to IWebSocketResource::Make.
32
+ /// </summary>
33
+ std::function<std::shared_ptr<IWebSocketResource>(std::string &&)> ResourceFactory;
34
+
35
+ /// <summary>
36
+ /// Keeps a raw reference to the module object to lazily retrieve the React Instance as needed.
37
+ /// </summary>
38
+ CxxModule *Module{nullptr};
39
+ };
40
+
21
41
  #pragma region CxxModule overrides
22
42
 
23
43
  /// <summary>
@@ -41,16 +61,6 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
41
61
  void SetResourceFactory(std::function<std::shared_ptr<IWebSocketResource>(const std::string &)> &&resourceFactory);
42
62
 
43
63
  private:
44
- /// <summary>
45
- /// Notifies an event to the current React Instance.
46
- /// </summary>
47
- void SendEvent(std::string &&eventName, folly::dynamic &&parameters);
48
-
49
- /// <summary>
50
- /// Creates or retrieves a raw <c>IWebSocketResource</c> pointer.
51
- /// </summary>
52
- std::shared_ptr<IWebSocketResource> GetOrCreateWebSocket(std::int64_t id, std::string &&url = {});
53
-
54
64
  /// <summary>
55
65
  /// Keeps <c>IWebSocketResource</c> instances identified by <c>id</c>.
56
66
  /// As defined in WebSocket.js.
@@ -58,9 +68,9 @@ class WebSocketModule : public facebook::xplat::module::CxxModule {
58
68
  std::map<int64_t, std::shared_ptr<IWebSocketResource>> m_webSockets;
59
69
 
60
70
  /// <summary>
61
- /// Generates IWebSocketResource instances, defaulting to IWebSocketResource::Make.
71
+ /// Keeps members that can be accessed threads other than this module's owner accessible.
62
72
  /// </summary>
63
- std::function<std::shared_ptr<IWebSocketResource>(std::string &&)> m_resourceFactory;
73
+ std::shared_ptr<SharedState> m_sharedState;
64
74
  };
65
75
 
66
76
  } // namespace Microsoft::React
@@ -61,86 +61,6 @@
61
61
  #include <tracing/tracing.h>
62
62
  namespace fs = std::filesystem;
63
63
 
64
- namespace {
65
-
66
- #if (defined(_MSC_VER) && !defined(WINRT))
67
-
68
- std::string GetJSBundleDirectory(
69
- const std::string &jsBundleBasePath,
70
- const std::string &jsBundleRelativePath) noexcept {
71
- // If there is a base path, use that to calculate the absolute path.
72
- if (jsBundleBasePath.length() > 0) {
73
- std::string jsBundleDirectory = jsBundleBasePath;
74
- if (jsBundleDirectory.back() != '\\')
75
- jsBundleDirectory += '\\';
76
-
77
- return jsBundleDirectory += jsBundleRelativePath;
78
- } else if (!PathIsRelativeA(jsBundleRelativePath.c_str())) {
79
- // If the given path is an absolute path, return it as-is
80
- return jsBundleRelativePath;
81
- }
82
- // Otherwise use the path of the executable file to construct the absolute
83
- // path.
84
- else {
85
- wchar_t modulePath[MAX_PATH];
86
-
87
- auto len = GetModuleFileNameW(nullptr, modulePath, _countof(modulePath));
88
-
89
- if (len == 0 || (len == _countof(modulePath) && GetLastError() == ERROR_INSUFFICIENT_BUFFER))
90
- return jsBundleRelativePath;
91
-
92
- // remove the trailing filename as we are interested in only the path
93
- auto succeeded = PathRemoveFileSpecW(modulePath);
94
- if (!succeeded)
95
- return jsBundleRelativePath;
96
-
97
- std::string jsBundlePath = Microsoft::Common::Unicode::Utf16ToUtf8(modulePath, wcslen(modulePath));
98
- if (!jsBundlePath.empty() && jsBundlePath.back() != '\\')
99
- jsBundlePath += '\\';
100
-
101
- return jsBundlePath += jsBundleRelativePath;
102
- }
103
- }
104
-
105
- std::string GetJSBundleFilePath(const std::string &jsBundleBasePath, const std::string &jsBundleRelativePath) {
106
- auto jsBundleFilePath = GetJSBundleDirectory(jsBundleBasePath, jsBundleRelativePath);
107
-
108
- // Usually, the module name: "module name" + "." + "platform name", for
109
- // example "lpc.win32". If we can not find the the bundle.js file under the
110
- // normal folder, we are trying to find it under the folder without the dot
111
- // (e.g. "lpcwin32"). VSO:1997035 remove this code after we have better name
112
- // convension
113
- if (PathFileExistsA((jsBundleFilePath + "\\bundle.js").c_str())) {
114
- jsBundleFilePath += "\\bundle.js";
115
- } else {
116
- // remove the dot only if is belongs to the bundle file name.
117
- size_t lastDotPosition = jsBundleFilePath.find_last_of('.');
118
- size_t bundleFilePosition = jsBundleFilePath.find_last_of('\\');
119
- if (lastDotPosition != std::string::npos &&
120
- (bundleFilePosition == std::string::npos || lastDotPosition > bundleFilePosition)) {
121
- jsBundleFilePath.erase(lastDotPosition, 1);
122
- }
123
-
124
- jsBundleFilePath += "\\bundle.js";
125
-
126
- // Back before we have base path plumbed through, we made win32 force a
127
- // seperate folder for each bundle by appending bundle.js Now that we have
128
- // base path, we can handle multiple SDXs with the same index name so we
129
- // should switch to using the same scheme as all the other platforms (and
130
- // the bundle server)
131
- // TODO: We should remove all the previous logic and use the same names as
132
- // the other platforms...
133
- if (!PathFileExistsA(jsBundleFilePath.c_str())) {
134
- jsBundleFilePath = GetJSBundleDirectory(jsBundleBasePath, jsBundleRelativePath) + ".bundle";
135
- }
136
- }
137
-
138
- return jsBundleFilePath;
139
- }
140
- #endif
141
-
142
- } // namespace
143
-
144
64
  using namespace facebook;
145
65
  using namespace Microsoft::JSI;
146
66
 
@@ -560,22 +480,13 @@ void InstanceImpl::loadBundleInternal(std::string &&jsBundleRelativePath, bool s
560
480
  }
561
481
  } else {
562
482
  #if (defined(_MSC_VER) && !defined(WINRT))
563
- auto fullBundleFilePath = GetJSBundleFilePath(m_jsBundleBasePath, jsBundleRelativePath);
564
-
565
- // If fullBundleFilePath exists, load User bundle.
566
- // Otherwise all bundles (User and Platform) are loaded through
567
- // platformBundles.
568
- if (PathFileExistsA(fullBundleFilePath.c_str())) {
569
- auto bundleString = FileMappingBigString::fromPath(fullBundleFilePath);
570
- m_innerInstance->loadScriptFromString(std::move(bundleString), std::move(fullBundleFilePath), synchronously);
571
- }
572
-
483
+ std::string bundlePath = (fs::path(m_devSettings->bundleRootPath) / jsBundleRelativePath).string();
484
+ auto bundleString = FileMappingBigString::fromPath(bundlePath);
573
485
  #else
574
486
  std::string bundlePath = (fs::path(m_devSettings->bundleRootPath) / (jsBundleRelativePath + ".bundle")).string();
575
-
576
487
  auto bundleString = std::make_unique<::Microsoft::ReactNative::StorageFileBigString>(bundlePath);
577
- m_innerInstance->loadScriptFromString(std::move(bundleString), jsBundleRelativePath, synchronously);
578
488
  #endif
489
+ m_innerInstance->loadScriptFromString(std::move(bundleString), std::move(jsBundleRelativePath), synchronously);
579
490
  }
580
491
  } catch (const std::exception &e) {
581
492
  m_devSettings->errorCallback(e.what());
@@ -90,29 +90,21 @@ namespace Microsoft::React {
90
90
  // private
91
91
  WinRTWebSocketResource::WinRTWebSocketResource(
92
92
  IMessageWebSocket &&socket,
93
- Uri &&uri,
94
93
  vector<ChainValidationResult> &&certExceptions)
95
- : WinRTWebSocketResource(
96
- std::move(socket),
97
- DataWriter{socket.OutputStream()},
98
- std::move(uri),
99
- std::move(certExceptions)) {}
94
+ : WinRTWebSocketResource(std::move(socket), DataWriter{socket.OutputStream()}, std::move(certExceptions)) {}
100
95
 
101
96
  WinRTWebSocketResource::WinRTWebSocketResource(
102
97
  IMessageWebSocket &&socket,
103
98
  IDataWriter &&writer,
104
- Uri &&uri,
105
99
  vector<ChainValidationResult> &&certExceptions)
106
- : m_uri{std::move(uri)}, m_socket{std::move(socket)}, m_writer{std::move(writer)} {
107
- m_socket.MessageReceived({this, &WinRTWebSocketResource::OnMessageReceived});
108
-
100
+ : m_socket{std::move(socket)}, m_writer{std::move(writer)} {
109
101
  for (const auto &certException : certExceptions) {
110
102
  m_socket.Control().IgnorableServerCertificateErrors().Append(certException);
111
103
  }
112
104
  }
113
105
 
114
- WinRTWebSocketResource::WinRTWebSocketResource(const string &urlString, vector<ChainValidationResult> &&certExceptions)
115
- : WinRTWebSocketResource(MessageWebSocket{}, Uri{winrt::to_hstring(urlString)}, std::move(certExceptions)) {}
106
+ WinRTWebSocketResource::WinRTWebSocketResource(vector<ChainValidationResult> &&certExceptions)
107
+ : WinRTWebSocketResource(MessageWebSocket{}, std::move(certExceptions)) {}
116
108
 
117
109
  WinRTWebSocketResource::~WinRTWebSocketResource() noexcept /*override*/
118
110
  {
@@ -123,13 +115,14 @@ WinRTWebSocketResource::~WinRTWebSocketResource() noexcept /*override*/
123
115
 
124
116
  #pragma region Private members
125
117
 
126
- IAsyncAction WinRTWebSocketResource::PerformConnect() noexcept {
118
+ IAsyncAction WinRTWebSocketResource::PerformConnect(Uri &&uri) noexcept {
127
119
  auto self = shared_from_this();
120
+ auto coUri = std::move(uri);
128
121
 
129
122
  co_await resume_background();
130
123
 
131
124
  try {
132
- auto async = self->m_socket.ConnectAsync(self->m_uri);
125
+ auto async = self->m_socket.ConnectAsync(coUri);
133
126
 
134
127
  co_await lessthrow_await_adapter<IAsyncAction>{async};
135
128
 
@@ -293,36 +286,6 @@ fire_and_forget WinRTWebSocketResource::PerformClose() noexcept {
293
286
  m_closePerformed.Set();
294
287
  }
295
288
 
296
- void WinRTWebSocketResource::OnMessageReceived(
297
- IWebSocket const &sender,
298
- IMessageWebSocketMessageReceivedEventArgs const &args) {
299
- try {
300
- string response;
301
- IDataReader reader = args.GetDataReader();
302
- auto len = reader.UnconsumedBufferLength();
303
- if (args.MessageType() == SocketMessageType::Utf8) {
304
- reader.UnicodeEncoding(UnicodeEncoding::Utf8);
305
- vector<uint8_t> data(len);
306
- reader.ReadBytes(data);
307
-
308
- response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
309
- } else {
310
- auto buffer = reader.ReadBuffer(len);
311
- winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
312
-
313
- response = winrt::to_string(std::wstring_view(data));
314
- }
315
-
316
- if (m_readHandler) {
317
- m_readHandler(response.length(), response, args.MessageType() == SocketMessageType::Binary);
318
- }
319
- } catch (hresult_error const &e) {
320
- if (m_errorHandler) {
321
- m_errorHandler({HResultToString(e), ErrorType::Receive});
322
- }
323
- }
324
- }
325
-
326
289
  void WinRTWebSocketResource::Synchronize() noexcept {
327
290
  // Ensure sequence of other operations
328
291
  if (m_connectRequested) {
@@ -334,7 +297,36 @@ void WinRTWebSocketResource::Synchronize() noexcept {
334
297
 
335
298
  #pragma region IWebSocketResource
336
299
 
337
- void WinRTWebSocketResource::Connect(const Protocols &protocols, const Options &options) noexcept {
300
+ void WinRTWebSocketResource::Connect(string &&url, const Protocols &protocols, const Options &options) noexcept {
301
+ m_socket.MessageReceived(
302
+ [self = shared_from_this()](IWebSocket const &sender, IMessageWebSocketMessageReceivedEventArgs const &args) {
303
+ try {
304
+ string response;
305
+ IDataReader reader = args.GetDataReader();
306
+ auto len = reader.UnconsumedBufferLength();
307
+ if (args.MessageType() == SocketMessageType::Utf8) {
308
+ reader.UnicodeEncoding(UnicodeEncoding::Utf8);
309
+ vector<uint8_t> data(len);
310
+ reader.ReadBytes(data);
311
+
312
+ response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
313
+ } else {
314
+ auto buffer = reader.ReadBuffer(len);
315
+ winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
316
+
317
+ response = winrt::to_string(std::wstring_view(data));
318
+ }
319
+
320
+ if (self->m_readHandler) {
321
+ self->m_readHandler(response.length(), response, args.MessageType() == SocketMessageType::Binary);
322
+ }
323
+ } catch (hresult_error const &e) {
324
+ if (self->m_errorHandler) {
325
+ self->m_errorHandler({HResultToString(e), ErrorType::Receive});
326
+ }
327
+ }
328
+ });
329
+
338
330
  m_readyState = ReadyState::Connecting;
339
331
 
340
332
  for (const auto &header : options) {
@@ -348,7 +340,24 @@ void WinRTWebSocketResource::Connect(const Protocols &protocols, const Options &
348
340
  }
349
341
 
350
342
  m_connectRequested = true;
351
- PerformConnect();
343
+
344
+ Uri uri{nullptr};
345
+ try {
346
+ uri = Uri{winrt::to_hstring(url)};
347
+ } catch (hresult_error const &e) {
348
+ if (m_errorHandler) {
349
+ m_errorHandler({HResultToString(e), ErrorType::Connection});
350
+ }
351
+
352
+ // Abort - Mark connection as concluded.
353
+ SetEvent(m_connectPerformed.get());
354
+ m_connectPerformedPromise.set_value();
355
+ m_connectRequested = false;
356
+
357
+ return;
358
+ }
359
+
360
+ PerformConnect(std::move(uri));
352
361
  }
353
362
 
354
363
  void WinRTWebSocketResource::Ping() noexcept {
@@ -17,7 +17,6 @@
17
17
  namespace Microsoft::React {
18
18
 
19
19
  class WinRTWebSocketResource : public IWebSocketResource, public std::enable_shared_from_this<WinRTWebSocketResource> {
20
- winrt::Windows::Foundation::Uri m_uri;
21
20
  winrt::Windows::Networking::Sockets::IMessageWebSocket m_socket;
22
21
  // TODO: Use or remove.
23
22
  winrt::Windows::Networking::Sockets::IMessageWebSocket::MessageReceived_revoker m_revoker;
@@ -45,28 +44,22 @@ class WinRTWebSocketResource : public IWebSocketResource, public std::enable_sha
45
44
 
46
45
  WinRTWebSocketResource(
47
46
  winrt::Windows::Networking::Sockets::IMessageWebSocket &&socket,
48
- winrt::Windows::Foundation::Uri &&uri,
49
47
  std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> &&certExceptions);
50
48
 
51
- winrt::Windows::Foundation::IAsyncAction PerformConnect() noexcept;
49
+ winrt::Windows::Foundation::IAsyncAction PerformConnect(winrt::Windows::Foundation::Uri &&uri) noexcept;
52
50
  winrt::fire_and_forget PerformPing() noexcept;
53
51
  winrt::fire_and_forget PerformWrite(std::string &&message, bool isBinary) noexcept;
54
52
  winrt::fire_and_forget PerformClose() noexcept;
55
53
 
56
- void OnMessageReceived(
57
- winrt::Windows::Networking::Sockets::IWebSocket const &sender,
58
- winrt::Windows::Networking::Sockets::IMessageWebSocketMessageReceivedEventArgs const &args);
59
54
  void Synchronize() noexcept;
60
55
 
61
56
  public:
62
57
  WinRTWebSocketResource(
63
58
  winrt::Windows::Networking::Sockets::IMessageWebSocket &&socket,
64
59
  winrt::Windows::Storage::Streams::IDataWriter &&writer,
65
- winrt::Windows::Foundation::Uri &&uri,
66
60
  std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> &&certExceptions);
67
61
 
68
62
  WinRTWebSocketResource(
69
- const std::string &urlString,
70
63
  std::vector<winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult> &&certExceptions);
71
64
 
72
65
  ~WinRTWebSocketResource() noexcept override;
@@ -76,7 +69,7 @@ class WinRTWebSocketResource : public IWebSocketResource, public std::enable_sha
76
69
  /// <summary>
77
70
  /// <see cref="IWebSocketResource::Connect" />
78
71
  /// </summary>
79
- void Connect(const Protocols &protocols, const Options &options) noexcept override;
72
+ void Connect(std::string &&url, const Protocols &protocols, const Options &options) noexcept override;
80
73
 
81
74
  /// <summary>
82
75
  /// <see cref="IWebSocketResource::Ping" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.66.5",
3
+ "version": "0.66.9",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,8 +26,8 @@
26
26
  "@react-native-community/cli": "^6.0.0",
27
27
  "@react-native-community/cli-platform-android": "^6.0.0",
28
28
  "@react-native-community/cli-platform-ios": "^6.0.0",
29
- "@react-native-windows/cli": "0.66.1",
30
- "@react-native-windows/virtualized-list": "0.66.0",
29
+ "@react-native-windows/cli": "0.66.2",
30
+ "@react-native-windows/virtualized-list": "0.66.1",
31
31
  "@react-native/assets": "1.0.0",
32
32
  "@react-native/normalize-color": "1.0.0",
33
33
  "@react-native/polyfills": "2.0.0",
@@ -58,7 +58,7 @@
58
58
  "ws": "^6.1.4"
59
59
  },
60
60
  "devDependencies": {
61
- "@react-native-windows/codegen": "0.66.0",
61
+ "@react-native-windows/codegen": "0.66.1",
62
62
  "@rnw-scripts/eslint-config": "1.1.7",
63
63
  "@rnw-scripts/jest-out-of-tree-snapshot-resolver": "^1.0.1",
64
64
  "@rnx-kit/jest-preset": "^0.1.0",
@@ -84,7 +84,7 @@
84
84
  "react-native": "^0.66.0"
85
85
  },
86
86
  "beachball": {
87
- "defaultNpmTag": "latest",
87
+ "defaultNpmTag": "v0.66-stable",
88
88
  "gitTags": true,
89
89
  "disallowedChangeTypes": [
90
90
  "major",