react-native-windows 0.0.0-canary.485 → 0.0.0-canary.486

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/.flowconfig CHANGED
@@ -118,4 +118,4 @@ untyped-import
118
118
  untyped-type-import
119
119
 
120
120
  [version]
121
- ^0.175.0
121
+ ^0.175.1
@@ -46,20 +46,23 @@ function createInterpolation(
46
46
  }
47
47
 
48
48
  const outputRange: Array<number> = (config.outputRange: any);
49
- checkInfiniteRange('outputRange', outputRange);
50
49
 
51
50
  const inputRange = config.inputRange;
52
- checkInfiniteRange('inputRange', inputRange);
53
- checkValidInputRange(inputRange);
54
51
 
55
- invariant(
56
- inputRange.length === outputRange.length,
57
- 'inputRange (' +
58
- inputRange.length +
59
- ') and outputRange (' +
60
- outputRange.length +
61
- ') must have the same length',
62
- );
52
+ if (__DEV__) {
53
+ checkInfiniteRange('outputRange', outputRange);
54
+ checkInfiniteRange('inputRange', inputRange);
55
+ checkValidInputRange(inputRange);
56
+
57
+ invariant(
58
+ inputRange.length === outputRange.length,
59
+ 'inputRange (' +
60
+ inputRange.length +
61
+ ') and outputRange (' +
62
+ outputRange.length +
63
+ ') must have the same length',
64
+ );
65
+ }
63
66
 
64
67
  const easing = config.easing || linear;
65
68
 
@@ -276,16 +279,10 @@ function findRange(input: number, inputRange: $ReadOnlyArray<number>) {
276
279
 
277
280
  function checkValidInputRange(arr: $ReadOnlyArray<number>) {
278
281
  invariant(arr.length >= 2, 'inputRange must have at least 2 elements');
282
+ const message =
283
+ 'inputRange must be monotonically non-decreasing ' + String(arr);
279
284
  for (let i = 1; i < arr.length; ++i) {
280
- invariant(
281
- arr[i] >= arr[i - 1],
282
- /* $FlowFixMe[incompatible-type] (>=0.13.0) - In the addition expression
283
- * below this comment, one or both of the operands may be something that
284
- * doesn't cleanly convert to a string, like undefined, null, and object,
285
- * etc. If you really mean this implicit string conversion, you can do
286
- * something like String(myThing) */
287
- 'inputRange must be monotonically non-decreasing ' + arr,
288
- );
285
+ invariant(arr[i] >= arr[i - 1], message);
289
286
  }
290
287
  }
291
288
 
@@ -14,6 +14,7 @@ import type {
14
14
  BlurEvent,
15
15
  FocusEvent,
16
16
  MouseEvent,
17
+ PointerEvent,
17
18
  PressEvent,
18
19
  Layout,
19
20
  LayoutEvent,
@@ -84,8 +85,28 @@ type DirectEventProps = $ReadOnly<{|
84
85
  |}>;
85
86
 
86
87
  type MouseEventProps = $ReadOnly<{|
87
- onMouseEnter?: (event: MouseEvent) => void,
88
- onMouseLeave?: (event: MouseEvent) => void,
88
+ onMouseEnter?: ?(event: MouseEvent) => void,
89
+ onMouseLeave?: ?(event: MouseEvent) => void,
90
+ |}>;
91
+
92
+ type PointerEventProps = $ReadOnly<{|
93
+ onPointerEnter?: ?(event: PointerEvent) => void,
94
+ onPointerLeave?: ?(event: PointerEvent) => void,
95
+ onPointerMove?: ?(event: PointerEvent) => void,
96
+ onPointerCancel?: ?(e: PointerEvent) => void,
97
+ onPointerCancelCapture?: ?(e: PointerEvent) => void,
98
+ onPointerDown?: ?(e: PointerEvent) => void,
99
+ onPointerDownCapture?: ?(e: PointerEvent) => void,
100
+ onPointerUp?: ?(e: PointerEvent) => void,
101
+ onPointerUpCapture?: ?(e: PointerEvent) => void,
102
+
103
+ // FIXME: these events are temporary while we converge pointer event handling
104
+ onPointerEnter2?: ?(e: PointerEvent) => void,
105
+ onPointerEnter2Capture?: ?(e: PointerEvent) => void,
106
+ onPointerLeave2?: ?(e: PointerEvent) => void,
107
+ onPointerLeave2Capture?: ?(e: PointerEvent) => void,
108
+ onPointerMove2?: ?(e: PointerEvent) => void,
109
+ onPointerMove2Capture?: ?(e: PointerEvent) => void,
89
110
  |}>;
90
111
 
91
112
  type TouchEventProps = $ReadOnly<{|
@@ -99,20 +120,6 @@ type TouchEventProps = $ReadOnly<{|
99
120
  onTouchStartCapture?: ?(e: PressEvent) => void,
100
121
  |}>;
101
122
 
102
- type PointerEventCallbackProps = $ReadOnly<{|
103
- onPointerCancel?: ?(e: PointerEvent) => void,
104
- onPointerCancelCapture?: ?(e: PointerEvent) => void,
105
- onPointerDown?: ?(e: PointerEvent) => void,
106
- onPointerDownCapture?: ?(e: PointerEvent) => void,
107
- onPointerEnter2?: ?(e: PointerEvent) => void,
108
- onPointerLeave2?: ?(e: PointerEvent) => void,
109
- onPointerEnter2Capture?: ?(e: PointerEvent) => void,
110
- onPointerLeave2Capture?: ?(e: PointerEvent) => void,
111
- onPointerMove2Capture?: ?(e: PointerEvent) => void,
112
- onPointerUp?: ?(e: PointerEvent) => void,
113
- onPointerUpCapture?: ?(e: PointerEvent) => void,
114
- |}>;
115
-
116
123
  /**
117
124
  * For most touch interactions, you'll simply want to wrap your component in
118
125
  * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`,
@@ -395,8 +402,8 @@ export type ViewProps = $ReadOnly<{|
395
402
  ...DirectEventProps,
396
403
  ...GestureResponderEventProps,
397
404
  ...MouseEventProps,
405
+ ...PointerEventProps,
398
406
  ...TouchEventProps,
399
- ...PointerEventCallbackProps,
400
407
  ...AndroidViewProps,
401
408
  ...IOSViewProps,
402
409
 
@@ -14,6 +14,7 @@ import type {
14
14
  BlurEvent,
15
15
  FocusEvent,
16
16
  MouseEvent,
17
+ PointerEvent,
17
18
  PressEvent,
18
19
  Layout,
19
20
  LayoutEvent,
@@ -85,8 +86,28 @@ type DirectEventProps = $ReadOnly<{|
85
86
  |}>;
86
87
 
87
88
  type MouseEventProps = $ReadOnly<{|
88
- onMouseEnter?: (event: MouseEvent) => void,
89
- onMouseLeave?: (event: MouseEvent) => void,
89
+ onMouseEnter?: ?(event: MouseEvent) => void,
90
+ onMouseLeave?: ?(event: MouseEvent) => void,
91
+ |}>;
92
+
93
+ type PointerEventProps = $ReadOnly<{|
94
+ onPointerEnter?: ?(event: PointerEvent) => void,
95
+ onPointerLeave?: ?(event: PointerEvent) => void,
96
+ onPointerMove?: ?(event: PointerEvent) => void,
97
+ onPointerCancel?: ?(e: PointerEvent) => void,
98
+ onPointerCancelCapture?: ?(e: PointerEvent) => void,
99
+ onPointerDown?: ?(e: PointerEvent) => void,
100
+ onPointerDownCapture?: ?(e: PointerEvent) => void,
101
+ onPointerUp?: ?(e: PointerEvent) => void,
102
+ onPointerUpCapture?: ?(e: PointerEvent) => void,
103
+
104
+ // FIXME: these events are temporary while we converge pointer event handling
105
+ onPointerEnter2?: ?(e: PointerEvent) => void,
106
+ onPointerEnter2Capture?: ?(e: PointerEvent) => void,
107
+ onPointerLeave2?: ?(e: PointerEvent) => void,
108
+ onPointerLeave2Capture?: ?(e: PointerEvent) => void,
109
+ onPointerMove2?: ?(e: PointerEvent) => void,
110
+ onPointerMove2Capture?: ?(e: PointerEvent) => void,
90
111
  |}>;
91
112
 
92
113
  type TouchEventProps = $ReadOnly<{|
@@ -100,20 +121,6 @@ type TouchEventProps = $ReadOnly<{|
100
121
  onTouchStartCapture?: ?(e: PressEvent) => void,
101
122
  |}>;
102
123
 
103
- type PointerEventCallbackProps = $ReadOnly<{|
104
- onPointerCancel?: ?(e: PointerEvent) => void,
105
- onPointerCancelCapture?: ?(e: PointerEvent) => void,
106
- onPointerDown?: ?(e: PointerEvent) => void,
107
- onPointerDownCapture?: ?(e: PointerEvent) => void,
108
- onPointerEnter2?: ?(e: PointerEvent) => void,
109
- onPointerLeave2?: ?(e: PointerEvent) => void,
110
- onPointerEnter2Capture?: ?(e: PointerEvent) => void,
111
- onPointerLeave2Capture?: ?(e: PointerEvent) => void,
112
- onPointerMove2Capture?: ?(e: PointerEvent) => void,
113
- onPointerUp?: ?(e: PointerEvent) => void,
114
- onPointerUpCapture?: ?(e: PointerEvent) => void,
115
- |}>;
116
-
117
124
  /**
118
125
  * For most touch interactions, you'll simply want to wrap your component in
119
126
  * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`,
@@ -443,8 +450,8 @@ export type ViewProps = $ReadOnly<{|
443
450
  ...DirectEventProps,
444
451
  ...GestureResponderEventProps,
445
452
  ...MouseEventProps,
453
+ ...PointerEventProps,
446
454
  ...TouchEventProps,
447
- ...PointerEventCallbackProps,
448
455
  ...AndroidViewProps,
449
456
  ...IOSViewProps,
450
457
  ...WindowsViewProps, // [Windows]
@@ -13,5 +13,5 @@ exports.version = {
13
13
  major: 0,
14
14
  minor: 0,
15
15
  patch: 0,
16
- prerelease: '20220404-2009-d5da70e17',
16
+ prerelease: '20220411-2010-f503b2120',
17
17
  };
@@ -363,6 +363,32 @@ const PlatformBaseViewConfig: PartialViewConfigWithoutName =
363
363
  captured: 'onTouchEndCapture',
364
364
  },
365
365
  },
366
+
367
+ // Pointer Events
368
+ topPointerCancel: {
369
+ phasedRegistrationNames: {
370
+ captured: 'onPointerCancelCapture',
371
+ bubbled: 'onPointerCancel',
372
+ },
373
+ },
374
+ topPointerDown: {
375
+ phasedRegistrationNames: {
376
+ captured: 'onPointerDownCapture',
377
+ bubbled: 'onPointerDown',
378
+ },
379
+ },
380
+ topPointerMove2: {
381
+ phasedRegistrationNames: {
382
+ captured: 'onPointerMove2Capture',
383
+ bubbled: 'onPointerMove2',
384
+ },
385
+ },
386
+ topPointerUp: {
387
+ phasedRegistrationNames: {
388
+ captured: 'onPointerUpCapture',
389
+ bubbled: 'onPointerUp',
390
+ },
391
+ },
366
392
  },
367
393
  directEventTypes: {
368
394
  topAccessibilityAction: {
@@ -12,6 +12,7 @@
12
12
 
13
13
  import type {
14
14
  LayoutEvent,
15
+ PointerEvent,
15
16
  PressEvent,
16
17
  TextLayoutEvent,
17
18
  } from '../Types/CoreEventTypes';
@@ -31,10 +32,18 @@ export type PressRetentionOffset = $ReadOnly<{|
31
32
  right: number,
32
33
  |}>;
33
34
 
35
+ type PointerEventProps = $ReadOnly<{|
36
+ onPointerEnter?: (event: PointerEvent) => void,
37
+ onPointerLeave?: (event: PointerEvent) => void,
38
+ onPointerMove?: (event: PointerEvent) => void,
39
+ |}>;
40
+
34
41
  /**
35
42
  * @see https://reactnative.dev/docs/text#reference
36
43
  */
37
44
  export type TextProps = $ReadOnly<{|
45
+ ...PointerEventProps,
46
+
38
47
  /**
39
48
  * Indicates whether the view is an accessibility element.
40
49
  *
@@ -91,12 +91,4 @@ module.exports = {
91
91
  addChangeListener(listener: AppearanceListener): EventSubscription {
92
92
  return eventEmitter.addListener('change', listener);
93
93
  },
94
-
95
- /**
96
- * @deprecated Use `remove` on the EventSubscription from `addEventListener`.
97
- */
98
- removeChangeListener(listener: AppearanceListener): void {
99
- // NOTE: This will report a deprecation notice via `console.error`.
100
- eventEmitter.removeListener('change', listener);
101
- },
102
94
  };
@@ -292,7 +292,7 @@ function registerBundleEntryPoints(client) {
292
292
 
293
293
  function flushEarlyLogs(client) {
294
294
  try {
295
- pendingLogs.forEach(([level: LogLevel, data: Array<mixed>]) => {
295
+ pendingLogs.forEach(([level, data]) => {
296
296
  HMRClient.log(level, data);
297
297
  });
298
298
  } finally {
@@ -1,6 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
3
 
4
+ #include <utility>
4
5
  #include "dispatchQueue/dispatchQueue.h"
5
6
  #include "queueService.h"
6
7
 
@@ -29,6 +30,13 @@ struct ThreadPoolSchedulerWin : Mso::UnknownObject<IDispatchQueueScheduler> {
29
30
  void Shutdown() noexcept override;
30
31
  void AwaitTermination() noexcept override;
31
32
 
33
+ public: // Used by test APIs
34
+ static void EnableThreadPoolWorkTracking(bool enable) noexcept;
35
+ static void WaitForThreadPoolWorkCompletion() noexcept;
36
+
37
+ private: // Used by test APIs
38
+ static void TrackThreadPoolWork(const std::shared_ptr<TP_WORK> &work) noexcept;
39
+
32
40
  private:
33
41
  struct ThreadAccessGuard {
34
42
  ThreadAccessGuard(ThreadPoolSchedulerWin *scheduler) noexcept;
@@ -42,12 +50,29 @@ struct ThreadPoolSchedulerWin : Mso::UnknownObject<IDispatchQueueScheduler> {
42
50
  };
43
51
 
44
52
  private:
45
- std::unique_ptr<TP_WORK, ThreadPoolWorkDeleter> m_threadPoolWork;
53
+ std::shared_ptr<TP_WORK> m_threadPoolWork;
46
54
  Mso::WeakPtr<IDispatchQueueService> m_queue;
47
55
  const uint32_t m_maxThreads{1};
48
56
  std::atomic<uint32_t> m_usedThreads{0};
49
57
 
50
58
  constexpr static uint32_t MaxConcurrentThreads{64};
59
+
60
+ private:
61
+ static std::mutex s_threadPoolWorkMutex;
62
+ static bool s_enableThreadPoolWorkTracking;
63
+ static std::vector<std::shared_ptr<TP_WORK>> s_trackedThreadPoolWork;
64
+ };
65
+
66
+ // Track the ThreadPoolSchedulerWin instance used by current thread.
67
+ // We use it to avoid a deadlock on queue shutdown.
68
+ struct ThreadPoolSchedulerWinContext {
69
+ ThreadPoolSchedulerWinContext(ThreadPoolSchedulerWin *scheduler) noexcept;
70
+ ~ThreadPoolSchedulerWinContext() noexcept;
71
+ static ThreadPoolSchedulerWin *CurrentScheduler() noexcept;
72
+
73
+ private:
74
+ static thread_local ThreadPoolSchedulerWin *tls_scheduler;
75
+ ThreadPoolSchedulerWin *m_prevScheduler{nullptr};
51
76
  };
52
77
 
53
78
  //=============================================================================
@@ -64,9 +89,15 @@ void ThreadPoolWorkDeleter::operator()(TP_WORK *tpWork) noexcept {
64
89
  // ThreadPoolSchedulerWin implementation
65
90
  //=============================================================================
66
91
 
92
+ std::mutex ThreadPoolSchedulerWin::s_threadPoolWorkMutex;
93
+ bool ThreadPoolSchedulerWin::s_enableThreadPoolWorkTracking{false};
94
+ std::vector<std::shared_ptr<TP_WORK>> ThreadPoolSchedulerWin::s_trackedThreadPoolWork;
95
+
67
96
  ThreadPoolSchedulerWin::ThreadPoolSchedulerWin(uint32_t maxThreads) noexcept
68
- : m_threadPoolWork{::CreateThreadpoolWork(WorkCallback, this, nullptr)},
69
- m_maxThreads{maxThreads == 0 ? MaxConcurrentThreads : maxThreads} {}
97
+ : m_threadPoolWork{::CreateThreadpoolWork(WorkCallback, this, nullptr), ThreadPoolWorkDeleter{}},
98
+ m_maxThreads{maxThreads == 0 ? MaxConcurrentThreads : maxThreads} {
99
+ TrackThreadPoolWork(m_threadPoolWork);
100
+ }
70
101
 
71
102
  ThreadPoolSchedulerWin::~ThreadPoolSchedulerWin() noexcept {
72
103
  AwaitTermination();
@@ -78,6 +109,7 @@ ThreadPoolSchedulerWin::~ThreadPoolSchedulerWin() noexcept {
78
109
  _Inout_ PTP_WORK /*work*/) {
79
110
  // The ThreadPoolSchedulerWin is alive here because m_threadPoolWork must be completed before it is destroyed.
80
111
  ThreadPoolSchedulerWin *self = static_cast<ThreadPoolSchedulerWin *>(context);
112
+ ThreadPoolSchedulerWinContext schedulerContext(self);
81
113
 
82
114
  if (auto queue = self->m_queue.GetStrongPtr()) {
83
115
  auto endTime = std::chrono::steady_clock::now() + 100ms;
@@ -129,7 +161,38 @@ void ThreadPoolSchedulerWin::Shutdown() noexcept {
129
161
  }
130
162
 
131
163
  void ThreadPoolSchedulerWin::AwaitTermination() noexcept {
132
- ::WaitForThreadpoolWorkCallbacks(m_threadPoolWork.get(), false);
164
+ // Avoid deadlock when the dispatch queue and ThreadPoolSchedulerWin are released from inside of a task.
165
+ if (ThreadPoolSchedulerWinContext::CurrentScheduler() != this) {
166
+ ::WaitForThreadpoolWorkCallbacks(m_threadPoolWork.get(), false);
167
+ }
168
+ }
169
+
170
+ void ThreadPoolSchedulerWin::EnableThreadPoolWorkTracking(bool enable) noexcept {
171
+ std::vector<std::shared_ptr<TP_WORK>> tpWorkToStopTracking;
172
+ {
173
+ std::scoped_lock lock{s_threadPoolWorkMutex};
174
+ s_enableThreadPoolWorkTracking = enable;
175
+ // Reset all previously tracked work
176
+ tpWorkToStopTracking = std::move(s_trackedThreadPoolWork);
177
+ }
178
+ }
179
+
180
+ void ThreadPoolSchedulerWin::WaitForThreadPoolWorkCompletion() noexcept {
181
+ std::vector<std::shared_ptr<TP_WORK>> tpWorkToTrack;
182
+ {
183
+ std::scoped_lock lock{s_threadPoolWorkMutex};
184
+ tpWorkToTrack = std::move(s_trackedThreadPoolWork);
185
+ }
186
+ for (std::shared_ptr<TP_WORK> &tpWork : tpWorkToTrack) {
187
+ ::WaitForThreadpoolWorkCallbacks(tpWork.get(), false);
188
+ }
189
+ }
190
+
191
+ void ThreadPoolSchedulerWin::TrackThreadPoolWork(const std::shared_ptr<TP_WORK> &tpWork) noexcept {
192
+ std::scoped_lock lock{s_threadPoolWorkMutex};
193
+ if (s_enableThreadPoolWorkTracking) {
194
+ s_trackedThreadPoolWork.push_back(tpWork);
195
+ }
133
196
  }
134
197
 
135
198
  //=============================================================================
@@ -151,6 +214,23 @@ ThreadPoolSchedulerWin::ThreadAccessGuard::~ThreadAccessGuard() noexcept {
151
214
  return tls_scheduler == scheduler;
152
215
  }
153
216
 
217
+ //=============================================================================
218
+ // ThreadPoolSchedulerWinContext implementation
219
+ //=============================================================================
220
+
221
+ thread_local ThreadPoolSchedulerWin *ThreadPoolSchedulerWinContext::tls_scheduler{nullptr};
222
+
223
+ ThreadPoolSchedulerWinContext::ThreadPoolSchedulerWinContext(ThreadPoolSchedulerWin *scheduler) noexcept
224
+ : m_prevScheduler(std::exchange(tls_scheduler, scheduler)) {}
225
+
226
+ ThreadPoolSchedulerWinContext::~ThreadPoolSchedulerWinContext() noexcept {
227
+ std::exchange(tls_scheduler, m_prevScheduler);
228
+ }
229
+
230
+ ThreadPoolSchedulerWin *ThreadPoolSchedulerWinContext::CurrentScheduler() noexcept {
231
+ return tls_scheduler;
232
+ }
233
+
154
234
  //=============================================================================
155
235
  // DispatchQueueStatic::MakeThreadPoolScheduler implementation
156
236
  //=============================================================================
@@ -160,4 +240,16 @@ ThreadPoolSchedulerWin::ThreadAccessGuard::~ThreadAccessGuard() noexcept {
160
240
  return Mso::Make<ThreadPoolSchedulerWin, IDispatchQueueScheduler>(maxThreads);
161
241
  }
162
242
 
243
+ //=============================================================================
244
+ // Test specific functions
245
+ //=============================================================================
246
+
247
+ void Test_ThreadPoolSchedulerWin_EnableThreadPoolWorkTracking(bool enable) noexcept {
248
+ ThreadPoolSchedulerWin::EnableThreadPoolWorkTracking(enable);
249
+ }
250
+
251
+ void Test_ThreadPoolSchedulerWin_WaitForThreadPoolWorkCompletion() noexcept {
252
+ ThreadPoolSchedulerWin::WaitForThreadPoolWorkCompletion();
253
+ }
254
+
163
255
  } // namespace Mso
@@ -10,7 +10,7 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.0.0-canary.485</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.0.0-canary.486</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>0</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
@@ -33,6 +33,7 @@
33
33
  #pragma warning(pop)
34
34
 
35
35
  #include <future>
36
+ #include <mutex>
36
37
 
37
38
  #include <AppModel.h>
38
39
 
@@ -239,37 +240,32 @@ void DevSupportManager::StopPollingLiveReload() {
239
240
  m_cancellation_token = true;
240
241
  }
241
242
 
242
- void DevSupportManager::StartInspector(
243
+ void DevSupportManager::EnsureHermesInspector(
243
244
  [[maybe_unused]] const std::string &packagerHost,
244
245
  [[maybe_unused]] const uint16_t packagerPort) noexcept {
245
246
  #ifdef HERMES_ENABLE_DEBUGGER
246
- std::string packageName("RNW");
247
- wchar_t fullName[PACKAGE_FULL_NAME_MAX_LENGTH]{};
248
- UINT32 size = ARRAYSIZE(fullName);
249
- if (SUCCEEDED(GetCurrentPackageFullName(&size, fullName))) {
250
- // we are in an unpackaged app
251
- packageName = winrt::to_string(fullName);
252
- }
247
+ static std::once_flag once;
248
+ std::call_once(once, [this, &packagerHost, packagerPort]() {
249
+ std::string packageName("RNW");
250
+ wchar_t fullName[PACKAGE_FULL_NAME_MAX_LENGTH]{};
251
+ UINT32 size = ARRAYSIZE(fullName);
252
+ if (SUCCEEDED(GetCurrentPackageFullName(&size, fullName))) {
253
+ // we are in an unpackaged app
254
+ packageName = winrt::to_string(fullName);
255
+ }
253
256
 
254
- std::string deviceName("RNWHost");
255
- auto hostNames = winrt::Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
256
- if (hostNames && hostNames.First() && hostNames.First().Current()) {
257
- deviceName = winrt::to_string(hostNames.First().Current().DisplayName());
258
- }
257
+ std::string deviceName("RNWHost");
258
+ auto hostNames = winrt::Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
259
+ if (hostNames && hostNames.First() && hostNames.First().Current()) {
260
+ deviceName = winrt::to_string(hostNames.First().Current().DisplayName());
261
+ }
259
262
 
260
- m_inspectorPackagerConnection = std::make_shared<InspectorPackagerConnection>(
261
- facebook::react::DevServerHelper::get_InspectorDeviceUrl(packagerHost, packagerPort, deviceName, packageName),
262
- m_BundleStatusProvider);
263
- m_inspectorPackagerConnection->connectAsync();
264
- #endif
265
- }
263
+ m_inspectorPackagerConnection = std::make_shared<InspectorPackagerConnection>(
264
+ facebook::react::DevServerHelper::get_InspectorDeviceUrl(packagerHost, packagerPort, deviceName, packageName),
265
+ m_BundleStatusProvider);
266
+ m_inspectorPackagerConnection->connectAsync();
267
+ });
266
268
 
267
- void DevSupportManager::StopInspector() noexcept {
268
- #ifdef HERMES_ENABLE_DEBUGGER
269
- if (m_inspectorPackagerConnection) {
270
- m_inspectorPackagerConnection->disconnectAsync();
271
- m_inspectorPackagerConnection = nullptr;
272
- }
273
269
  #endif
274
270
  }
275
271
 
@@ -50,8 +50,7 @@ class DevSupportManager final : public facebook::react::IDevSupportManager {
50
50
  std::function<void()> onChangeCallback) override;
51
51
  virtual void StopPollingLiveReload() override;
52
52
 
53
- virtual void StartInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept override;
54
- virtual void StopInspector() noexcept override;
53
+ virtual void EnsureHermesInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept override;
55
54
  virtual void UpdateBundleStatus(bool isLastDownloadSucess, int64_t updateTimestamp) noexcept override;
56
55
 
57
56
  private:
@@ -74,7 +74,15 @@ class HermesExecutorRuntimeAdapter final : public facebook::hermes::inspector::R
74
74
  } // namespace
75
75
 
76
76
  void HermesRuntimeHolder::crashHandler(int fileDescriptor) noexcept {
77
- HermesShim::hermesCrashHandler(static_cast<facebook::hermes::HermesRuntime &>(*m_runtime), fileDescriptor);
77
+ HermesShim::hermesCrashHandler(*m_hermesRuntime, fileDescriptor);
78
+ }
79
+
80
+ void HermesRuntimeHolder::teardown() noexcept {
81
+ #ifdef HERMES_ENABLE_DEBUGGER
82
+ if (auto devSettings = m_weakDevSettings.lock(); devSettings && devSettings->useDirectDebugger) {
83
+ facebook::hermes::inspector::chrome::disableDebugging(*m_hermesRuntime);
84
+ }
85
+ #endif
78
86
  }
79
87
 
80
88
  facebook::react::JSIEngineOverride HermesRuntimeHolder::getRuntimeType() noexcept {
@@ -84,43 +92,44 @@ facebook::react::JSIEngineOverride HermesRuntimeHolder::getRuntimeType() noexcep
84
92
  std::shared_ptr<jsi::Runtime> HermesRuntimeHolder::getRuntime() noexcept {
85
93
  std::call_once(m_once_flag, [this]() { initRuntime(); });
86
94
 
87
- if (!m_runtime)
95
+ if (!m_hermesRuntime)
88
96
  std::terminate();
89
97
 
90
98
  // Make sure that the runtime instance is not consumed from multiple threads.
91
99
  if (m_own_thread_id != std::this_thread::get_id())
92
100
  std::terminate();
93
101
 
94
- return m_runtime;
102
+ return m_hermesRuntime;
95
103
  }
96
104
 
97
105
  HermesRuntimeHolder::HermesRuntimeHolder(
98
106
  std::shared_ptr<facebook::react::DevSettings> devSettings,
99
107
  std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept
100
- : m_devSettings(std::move(devSettings)), m_jsQueue(std::move(jsQueue)) {}
108
+ : m_weakDevSettings(devSettings), m_jsQueue(std::move(jsQueue)) {}
101
109
 
102
110
  void HermesRuntimeHolder::initRuntime() noexcept {
103
- auto hermesRuntime = makeHermesRuntimeSystraced(m_devSettings->enableDefaultCrashHandler);
104
-
105
- facebook::hermes::HermesRuntime &hermesRuntimeRef = *hermesRuntime;
111
+ auto devSettings = m_weakDevSettings.lock();
112
+ if (!devSettings)
113
+ std::terminate();
106
114
 
107
- m_runtime = std::move(hermesRuntime);
115
+ m_hermesRuntime = makeHermesRuntimeSystraced(devSettings->enableDefaultCrashHandler);
108
116
  m_own_thread_id = std::this_thread::get_id();
109
117
 
110
118
  #ifdef HERMES_ENABLE_DEBUGGER
111
- if (m_devSettings->useDirectDebugger) {
112
- auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(m_runtime, hermesRuntimeRef, m_jsQueue);
119
+ if (devSettings->useDirectDebugger) {
120
+ auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(m_hermesRuntime, *m_hermesRuntime, m_jsQueue);
113
121
  facebook::hermes::inspector::chrome::enableDebugging(
114
122
  std::move(adapter),
115
- m_devSettings->debuggerRuntimeName.empty() ? "Hermes React Native" : m_devSettings->debuggerRuntimeName);
123
+ devSettings->debuggerRuntimeName.empty() ? "Hermes React Native" : devSettings->debuggerRuntimeName);
116
124
  }
117
125
  #endif
118
126
 
119
127
  // Add js engine information to Error.prototype so in error reporting we
120
128
  // can send this information.
121
- auto errorPrototype =
122
- m_runtime->global().getPropertyAsObject(*m_runtime, "Error").getPropertyAsObject(*m_runtime, "prototype");
123
- errorPrototype.setProperty(*m_runtime, "jsEngine", "hermes");
129
+ auto errorPrototype = m_hermesRuntime->global()
130
+ .getPropertyAsObject(*m_hermesRuntime, "Error")
131
+ .getPropertyAsObject(*m_hermesRuntime, "prototype");
132
+ errorPrototype.setProperty(*m_hermesRuntime, "jsEngine", "hermes");
124
133
  }
125
134
 
126
135
  } // namespace react
@@ -9,6 +9,10 @@
9
9
 
10
10
  #include <DevSettings.h>
11
11
 
12
+ namespace facebook::hermes {
13
+ class HermesRuntime;
14
+ }
15
+
12
16
  namespace facebook {
13
17
  namespace react {
14
18
 
@@ -19,18 +23,20 @@ class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
19
23
 
20
24
  void crashHandler(int fileDescriptor) noexcept override;
21
25
 
26
+ void teardown() noexcept override;
27
+
22
28
  HermesRuntimeHolder(
23
29
  std::shared_ptr<facebook::react::DevSettings> devSettings,
24
30
  std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept;
25
31
 
26
32
  private:
27
33
  void initRuntime() noexcept;
28
- std::shared_ptr<facebook::jsi::Runtime> m_runtime;
34
+ std::shared_ptr<facebook::hermes::HermesRuntime> m_hermesRuntime;
29
35
 
30
36
  std::once_flag m_once_flag;
31
37
  std::thread::id m_own_thread_id;
32
38
 
33
- std::shared_ptr<facebook::react::DevSettings> m_devSettings;
39
+ std::weak_ptr<facebook::react::DevSettings> m_weakDevSettings;
34
40
  std::shared_ptr<facebook::react::MessageQueueThread> m_jsQueue;
35
41
  };
36
42
 
@@ -22,8 +22,7 @@ struct IDevSupportManager {
22
22
  std::function<void()> onChangeCallback) = 0;
23
23
  virtual void StopPollingLiveReload() = 0;
24
24
 
25
- virtual void StartInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept = 0;
26
- virtual void StopInspector() noexcept = 0;
25
+ virtual void EnsureHermesInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept = 0;
27
26
  virtual void UpdateBundleStatus(bool isLastDownloadSucess, int64_t updateTimestamp) noexcept = 0;
28
27
  };
29
28
 
@@ -18,6 +18,8 @@ struct RuntimeHolderLazyInit {
18
18
  virtual std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept = 0;
19
19
  virtual facebook::react::JSIEngineOverride getRuntimeType() noexcept = 0;
20
20
 
21
+ virtual void teardown() noexcept {};
22
+
21
23
  // You can call this when a crash happens to attempt recording additional data
22
24
  // The fd supplied is a raw file stream an implementation might write JSON to
23
25
  virtual void crashHandler(int fileDescriptor) noexcept {};
@@ -254,7 +254,7 @@ InstanceImpl::InstanceImpl(
254
254
  #endif
255
255
 
256
256
  if (shouldStartHermesInspector(*m_devSettings)) {
257
- m_devManager->StartInspector(m_devSettings->sourceBundleHost, m_devSettings->sourceBundlePort);
257
+ m_devManager->EnsureHermesInspector(m_devSettings->sourceBundleHost, m_devSettings->sourceBundlePort);
258
258
  }
259
259
 
260
260
  // Default (common) NativeModules
@@ -532,8 +532,8 @@ void InstanceImpl::loadBundleInternal(std::string &&jsBundleRelativePath, bool s
532
532
  }
533
533
 
534
534
  InstanceImpl::~InstanceImpl() {
535
- if (shouldStartHermesInspector(*m_devSettings)) {
536
- m_devManager->StopInspector();
535
+ if (shouldStartHermesInspector(*m_devSettings) && m_devSettings->jsiRuntimeHolder) {
536
+ m_devSettings->jsiRuntimeHolder->teardown();
537
537
  }
538
538
  m_nativeQueue->quitSynchronous();
539
539
  }
@@ -30,7 +30,7 @@ babelRegisterOnly([]);
30
30
 
31
31
  const transformer = require('metro-react-native-babel-transformer');
32
32
  module.exports = {
33
- process(src /*: string */, file /*: string */) /*: string */ {
33
+ process(src /*: string */, file /*: string */) /*: {code: string, ...} */ {
34
34
  if (nodeFiles.test(file)) {
35
35
  // node specific transforms only
36
36
  return babelTransformSync(src, {
@@ -38,7 +38,7 @@ module.exports = {
38
38
  sourceType: 'script',
39
39
  ...nodeOptions,
40
40
  ast: false,
41
- }).code;
41
+ });
42
42
  }
43
43
 
44
44
  const {ast} = transformer.transform({
@@ -111,7 +111,7 @@ module.exports = {
111
111
  sourceMaps: true,
112
112
  },
113
113
  src,
114
- ).code;
114
+ );
115
115
  },
116
116
 
117
117
  getCacheKey: (createCacheKeyFunction([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.0.0-canary.485",
3
+ "version": "0.0.0-canary.486",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,7 +27,7 @@
27
27
  "@react-native-community/cli-platform-android": "^7.0.1",
28
28
  "@react-native-community/cli-platform-ios": "^7.0.1",
29
29
  "@react-native-windows/cli": "0.0.0-canary.125",
30
- "@react-native-windows/virtualized-list": "0.0.0-canary.38",
30
+ "@react-native-windows/virtualized-list": "0.0.0-canary.39",
31
31
  "@react-native/assets": "1.0.0",
32
32
  "@react-native/normalize-color": "2.0.0",
33
33
  "@react-native/polyfills": "2.0.0",
@@ -39,22 +39,22 @@
39
39
  "invariant": "^2.2.4",
40
40
  "jsc-android": "^250230.2.1",
41
41
  "memoize-one": "^5.0.0",
42
- "metro-react-native-babel-transformer": "0.70.0",
43
- "metro-runtime": "0.70.0",
44
- "metro-source-map": "0.70.0",
42
+ "metro-react-native-babel-transformer": "0.70.1",
43
+ "metro-runtime": "0.70.1",
44
+ "metro-source-map": "0.70.1",
45
45
  "nullthrows": "^1.1.1",
46
46
  "pretty-format": "^26.5.2",
47
47
  "promise": "^8.0.3",
48
48
  "react-devtools-core": "4.24.0",
49
49
  "react-native-codegen": "^0.0.14",
50
- "react-native-gradle-plugin": "^0.0.5",
50
+ "react-native-gradle-plugin": "^0.0.6",
51
51
  "react-refresh": "^0.4.0",
52
52
  "react-shallow-renderer": "16.14.1",
53
53
  "regenerator-runtime": "^0.13.2",
54
54
  "scheduler": "^0.20.2",
55
55
  "source-map-support": "^0.5.19",
56
56
  "stacktrace-parser": "^0.1.3",
57
- "use-subscription": "^1.0.0",
57
+ "use-subscription": ">=1.0.0 <1.6.0",
58
58
  "whatwg-fetch": "^3.0.0",
59
59
  "ws": "^6.1.4"
60
60
  },
@@ -69,13 +69,13 @@
69
69
  "@types/react-native": "^0.66.17",
70
70
  "eslint": "^7.32.0",
71
71
  "eslint-plugin-prettier": "^4.0.0",
72
- "flow-bin": "^0.175.0",
72
+ "flow-bin": "^0.175.1",
73
73
  "jscodeshift": "^0.13.1",
74
74
  "just-scripts": "^1.3.3",
75
75
  "metro-config": "^0.67.0",
76
76
  "prettier": "^2.4.1",
77
77
  "react": "17.0.2",
78
- "react-native": "0.0.0-20220404-2009-d5da70e17",
78
+ "react-native": "0.0.0-20220411-2010-f503b2120",
79
79
  "react-native-platform-override": "^1.6.9",
80
80
  "react-refresh": "^0.4.0",
81
81
  "react-shallow-renderer": "16.14.1",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "peerDependencies": {
85
85
  "react": "17.0.2",
86
- "react-native": "0.0.0-20220404-2009-d5da70e17"
86
+ "react-native": "0.0.0-20220411-2010-f503b2120"
87
87
  },
88
88
  "beachball": {
89
89
  "defaultNpmTag": "canary",