react-native-windows 0.80.0-preview.7 → 0.80.0-preview.8

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.
@@ -31,13 +31,6 @@ namespace Microsoft.ReactNative.Composition.Experimental
31
31
  SwitchThumb,
32
32
  };
33
33
 
34
- enum SnapAlignment
35
- {
36
- Start,
37
- Center,
38
- End,
39
- };
40
-
41
34
  [webhosthidden]
42
35
  [uuid("172def51-9e1a-4e3c-841a-e5a470065acc")] // uuid needed for empty interfaces
43
36
  [version(0)]
@@ -118,6 +111,8 @@ namespace Microsoft.ReactNative.Composition.Experimental
118
111
  event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollPositionChanged;
119
112
  event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollBeginDrag;
120
113
  event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollEndDrag;
114
+ event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollMomentumBegin;
115
+ event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollMomentumEnd;
121
116
  void ContentSize(Windows.Foundation.Numerics.Vector2 size);
122
117
  Windows.Foundation.Numerics.Vector3 ScrollPosition { get; };
123
118
  void ScrollBy(Windows.Foundation.Numerics.Vector3 offset, Boolean animate);
@@ -127,7 +122,7 @@ namespace Microsoft.ReactNative.Composition.Experimental
127
122
  void SetMaximumZoomScale(Single maximumZoomScale);
128
123
  void SetMinimumZoomScale(Single minimumZoomScale);
129
124
  Boolean Horizontal;
130
- void SetSnapPoints(Boolean snapToStart, Boolean snapToEnd, Windows.Foundation.Collections.IVectorView<Single> offsets, SnapAlignment snapToAlignment);
125
+ void SetSnapPoints(Boolean snapToStart, Boolean snapToEnd, Windows.Foundation.Collections.IVectorView<Single> offsets);
131
126
  }
132
127
 
133
128
  [webhosthidden]
@@ -27,8 +27,6 @@
27
27
 
28
28
  namespace Microsoft::ReactNative::Composition::Experimental {
29
29
 
30
- using namespace winrt::Microsoft::ReactNative::Composition::Experimental;
31
-
32
30
  template <typename TSpriteVisual>
33
31
  struct CompositionTypeTraits {};
34
32
 
@@ -711,8 +709,23 @@ struct CompScrollerVisual : winrt::implements<
711
709
  void IdleStateEntered(
712
710
  typename TTypeRedirects::InteractionTracker sender,
713
711
  typename TTypeRedirects::InteractionTrackerIdleStateEnteredArgs args) noexcept {
712
+ // If we were in inertia and are now idle, momentum has ended
713
+ if (m_outer->m_inertia) {
714
+ m_outer->FireScrollMomentumEnd({sender.Position().x, sender.Position().y});
715
+ }
716
+
717
+ // If we were interacting but never entered inertia (Interacting -> Idle),
718
+ // and the interaction was user-driven (requestId == 0), fire end-drag here.
719
+ // Note: if the interactionRequestId was non-zero it was caused by a Try* call
720
+ // (programmatic), so we should not fire onScrollEndDrag.
721
+ if (m_outer->m_interacting && args.RequestId() == 0) {
722
+ m_outer->FireScrollEndDrag({sender.Position().x, sender.Position().y});
723
+ }
724
+
725
+ // Clear state flags
714
726
  m_outer->m_custom = false;
715
727
  m_outer->m_inertia = false;
728
+ m_outer->m_interacting = false;
716
729
  }
717
730
  void InertiaStateEntered(
718
731
  typename TTypeRedirects::InteractionTracker sender,
@@ -720,15 +733,26 @@ struct CompScrollerVisual : winrt::implements<
720
733
  m_outer->m_custom = false;
721
734
  m_outer->m_inertia = true;
722
735
  m_outer->m_currentPosition = args.NaturalRestingPosition();
723
- // When the user stops interacting with the object, tracker can go into two paths:
724
- // 1. tracker goes into idle state immediately
725
- // 2. tracker has just started gliding into Inertia state
726
- // Fire ScrollEndDrag
727
- m_outer->FireScrollEndDrag({args.NaturalRestingPosition().x, args.NaturalRestingPosition().y});
736
+
737
+ if (!m_outer->m_interacting && args.RequestId() == 0) {
738
+ m_outer->FireScrollBeginDrag({args.NaturalRestingPosition().x, args.NaturalRestingPosition().y});
739
+ }
740
+
741
+ // If interaction was user-driven (requestId == 0),
742
+ // fire ScrollEndDrag here (Interacting -> Inertia caused by user lift).
743
+ if (m_outer->m_interacting && args.RequestId() == 0) {
744
+ m_outer->FireScrollEndDrag({args.NaturalRestingPosition().x, args.NaturalRestingPosition().y});
745
+ }
746
+
747
+ // Fire momentum scroll begin when we enter inertia (user or programmatic)
748
+ m_outer->FireScrollMomentumBegin({args.NaturalRestingPosition().x, args.NaturalRestingPosition().y});
728
749
  }
729
750
  void InteractingStateEntered(
730
751
  typename TTypeRedirects::InteractionTracker sender,
731
752
  typename TTypeRedirects::InteractionTrackerInteractingStateEnteredArgs args) noexcept {
753
+ // Mark that we're now interacting and remember the requestId (user manipulations => 0)
754
+ m_outer->m_interacting = true;
755
+
732
756
  // Fire when the user starts dragging the object
733
757
  m_outer->FireScrollBeginDrag({sender.Position().x, sender.Position().y});
734
758
  }
@@ -738,6 +762,10 @@ struct CompScrollerVisual : winrt::implements<
738
762
  void ValuesChanged(
739
763
  typename TTypeRedirects::InteractionTracker sender,
740
764
  typename TTypeRedirects::InteractionTrackerValuesChangedArgs args) noexcept {
765
+ if (!m_outer->m_interacting && args.RequestId() == 0) {
766
+ m_outer->FireScrollBeginDrag({args.Position().x, args.Position().y});
767
+ }
768
+ m_outer->m_interacting = true;
741
769
  m_outer->m_currentPosition = args.Position();
742
770
  m_outer->FireScrollPositionChanged({args.Position().x, args.Position().y});
743
771
  }
@@ -873,11 +901,9 @@ struct CompScrollerVisual : winrt::implements<
873
901
  void SetSnapPoints(
874
902
  bool snapToStart,
875
903
  bool snapToEnd,
876
- winrt::Windows::Foundation::Collections::IVectorView<float> const &offsets,
877
- SnapAlignment snapToAlignment) noexcept {
904
+ winrt::Windows::Foundation::Collections::IVectorView<float> const &offsets) noexcept {
878
905
  m_snapToStart = snapToStart;
879
906
  m_snapToEnd = snapToEnd;
880
- m_snapToAlignment = snapToAlignment;
881
907
  m_snapToOffsets.clear();
882
908
  if (offsets) {
883
909
  for (auto const &offset : offsets) {
@@ -985,6 +1011,20 @@ struct CompScrollerVisual : winrt::implements<
985
1011
  return m_scrollEndDragEvent.add(handler);
986
1012
  }
987
1013
 
1014
+ winrt::event_token ScrollMomentumBegin(
1015
+ winrt::Windows::Foundation::EventHandler<
1016
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs> const
1017
+ &handler) noexcept {
1018
+ return m_scrollMomentumBeginEvent.add(handler);
1019
+ }
1020
+
1021
+ winrt::event_token ScrollMomentumEnd(
1022
+ winrt::Windows::Foundation::EventHandler<
1023
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs> const
1024
+ &handler) noexcept {
1025
+ return m_scrollMomentumEndEvent.add(handler);
1026
+ }
1027
+
988
1028
  void ScrollPositionChanged(winrt::event_token const &token) noexcept {
989
1029
  m_scrollPositionChangedEvent.remove(token);
990
1030
  }
@@ -997,6 +1037,14 @@ struct CompScrollerVisual : winrt::implements<
997
1037
  m_scrollEndDragEvent.remove(token);
998
1038
  }
999
1039
 
1040
+ void ScrollMomentumBegin(winrt::event_token const &token) noexcept {
1041
+ m_scrollMomentumBeginEvent.remove(token);
1042
+ }
1043
+
1044
+ void ScrollMomentumEnd(winrt::event_token const &token) noexcept {
1045
+ m_scrollMomentumEndEvent.remove(token);
1046
+ }
1047
+
1000
1048
  void ContentSize(winrt::Windows::Foundation::Numerics::float2 const &size) noexcept {
1001
1049
  m_contentSize = size;
1002
1050
  m_contentVisual.Size(size);
@@ -1075,6 +1123,14 @@ struct CompScrollerVisual : winrt::implements<
1075
1123
  m_scrollEndDragEvent(*this, winrt::make<CompScrollPositionChangedArgs>(position));
1076
1124
  }
1077
1125
 
1126
+ void FireScrollMomentumBegin(winrt::Windows::Foundation::Numerics::float2 position) noexcept {
1127
+ m_scrollMomentumBeginEvent(*this, winrt::make<CompScrollPositionChangedArgs>(position));
1128
+ }
1129
+
1130
+ void FireScrollMomentumEnd(winrt::Windows::Foundation::Numerics::float2 position) noexcept {
1131
+ m_scrollMomentumEndEvent(*this, winrt::make<CompScrollPositionChangedArgs>(position));
1132
+ }
1133
+
1078
1134
  void UpdateMaxPosition() noexcept {
1079
1135
  m_interactionTracker.MaxPosition(
1080
1136
  {std::max<float>(m_contentSize.x - m_visualSize.x, 0),
@@ -1104,22 +1160,6 @@ struct CompScrollerVisual : winrt::implements<
1104
1160
  }
1105
1161
 
1106
1162
  snapPositions.insert(snapPositions.end(), m_snapToOffsets.begin(), m_snapToOffsets.end());
1107
-
1108
- // Adjust snap positions based on alignment
1109
- const float viewportSize = m_horizontal ? visualSize.x : visualSize.y;
1110
- if (m_snapToAlignment == SnapAlignment::Center) {
1111
- // For center alignment, offset snap positions by half the viewport size
1112
- for (auto &position : snapPositions) {
1113
- position = std::max(0.0f, position - viewportSize / 2.0f);
1114
- }
1115
- } else if (m_snapToAlignment == SnapAlignment::End) {
1116
- // For end alignment, offset snap positions by the full viewport size
1117
- for (auto &position : snapPositions) {
1118
- position = std::max(0.0f, position - viewportSize);
1119
- }
1120
- }
1121
- // For Start alignment, no adjustment needed
1122
-
1123
1163
  std::sort(snapPositions.begin(), snapPositions.end());
1124
1164
  snapPositions.erase(std::unique(snapPositions.begin(), snapPositions.end()), snapPositions.end());
1125
1165
 
@@ -1247,9 +1287,9 @@ struct CompScrollerVisual : winrt::implements<
1247
1287
  bool m_snapToStart{true};
1248
1288
  bool m_snapToEnd{true};
1249
1289
  std::vector<float> m_snapToOffsets;
1250
- SnapAlignment m_snapToAlignment{SnapAlignment::Start};
1251
1290
  bool m_inertia{false};
1252
1291
  bool m_custom{false};
1292
+ bool m_interacting{false};
1253
1293
  winrt::Windows::Foundation::Numerics::float3 m_targetPosition;
1254
1294
  winrt::Windows::Foundation::Numerics::float3 m_currentPosition;
1255
1295
  winrt::Windows::Foundation::Numerics::float2 m_contentSize{0};
@@ -1263,6 +1303,12 @@ struct CompScrollerVisual : winrt::implements<
1263
1303
  winrt::event<winrt::Windows::Foundation::EventHandler<
1264
1304
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs>>
1265
1305
  m_scrollEndDragEvent;
1306
+ winrt::event<winrt::Windows::Foundation::EventHandler<
1307
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs>>
1308
+ m_scrollMomentumBeginEvent;
1309
+ winrt::event<winrt::Windows::Foundation::EventHandler<
1310
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs>>
1311
+ m_scrollMomentumEndEvent;
1266
1312
  typename TTypeRedirects::SpriteVisual m_visual{nullptr};
1267
1313
  typename TTypeRedirects::SpriteVisual m_contentVisual{nullptr};
1268
1314
  typename TTypeRedirects::InteractionTracker m_interactionTracker{nullptr};
@@ -27,7 +27,6 @@
27
27
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
28
28
 
29
29
  constexpr float c_scrollerLineDelta = 16.0f;
30
- constexpr auto c_maxSnapPoints = 1000;
31
30
 
32
31
  enum class ScrollbarHitRegion : int {
33
32
  Unknown = -1,
@@ -741,15 +740,6 @@ void ScrollViewComponentView::updateBackgroundColor(const facebook::react::Share
741
740
  }
742
741
  }
743
742
 
744
- winrt::Windows::Foundation::Collections::IVector<float> ScrollViewComponentView::CreateSnapToOffsets(
745
- const std::vector<float> &offsets) {
746
- auto snapToOffsets = winrt::single_threaded_vector<float>();
747
- for (const auto &offset : offsets) {
748
- snapToOffsets.Append(offset);
749
- }
750
- return snapToOffsets;
751
- }
752
-
753
743
  void ScrollViewComponentView::updateProps(
754
744
  facebook::react::Props::Shared const &props,
755
745
  facebook::react::Props::Shared const &oldProps) noexcept {
@@ -818,13 +808,11 @@ void ScrollViewComponentView::updateProps(
818
808
 
819
809
  if (oldViewProps.snapToStart != newViewProps.snapToStart || oldViewProps.snapToEnd != newViewProps.snapToEnd ||
820
810
  oldViewProps.snapToOffsets != newViewProps.snapToOffsets) {
821
- if (oldViewProps.snapToInterval != newViewProps.snapToInterval) {
822
- updateSnapPoints();
823
- } else {
824
- const auto snapToOffsets = CreateSnapToOffsets(newViewProps.snapToOffsets);
825
- m_scrollVisual.SetSnapPoints(
826
- newViewProps.snapToStart, newViewProps.snapToEnd, snapToOffsets.GetView(), SnapAlignment::Center);
811
+ const auto snapToOffsets = winrt::single_threaded_vector<float>();
812
+ for (const auto &offset : newViewProps.snapToOffsets) {
813
+ snapToOffsets.Append(static_cast<float>(offset));
827
814
  }
815
+ m_scrollVisual.SetSnapPoints(newViewProps.snapToStart, newViewProps.snapToEnd, snapToOffsets.GetView());
828
816
  }
829
817
  }
830
818
 
@@ -875,9 +863,6 @@ void ScrollViewComponentView::updateContentVisualSize() noexcept {
875
863
  m_verticalScrollbarComponent->ContentSize(contentSize);
876
864
  m_horizontalScrollbarComponent->ContentSize(contentSize);
877
865
  m_scrollVisual.ContentSize(contentSize);
878
-
879
- // Update snap points if snapToInterval is being used, as content size affects the number of snap points
880
- updateSnapPoints();
881
866
  }
882
867
 
883
868
  void ScrollViewComponentView::prepareForRecycle() noexcept {}
@@ -1354,6 +1339,32 @@ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ScrollViewComp
1354
1339
  }
1355
1340
  });
1356
1341
 
1342
+ m_scrollMomentumBeginRevoker = m_scrollVisual.ScrollMomentumBegin(
1343
+ winrt::auto_revoke,
1344
+ [this](
1345
+ winrt::IInspectable const & /*sender*/,
1346
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) {
1347
+ auto eventEmitter = GetEventEmitter();
1348
+ if (eventEmitter) {
1349
+ auto scrollMetrics = getScrollMetrics(eventEmitter, args);
1350
+ std::static_pointer_cast<facebook::react::ScrollViewEventEmitter const>(eventEmitter)
1351
+ ->onMomentumScrollBegin(scrollMetrics);
1352
+ }
1353
+ });
1354
+
1355
+ m_scrollMomentumEndRevoker = m_scrollVisual.ScrollMomentumEnd(
1356
+ winrt::auto_revoke,
1357
+ [this](
1358
+ winrt::IInspectable const & /*sender*/,
1359
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) {
1360
+ auto eventEmitter = GetEventEmitter();
1361
+ if (eventEmitter) {
1362
+ auto scrollMetrics = getScrollMetrics(eventEmitter, args);
1363
+ std::static_pointer_cast<facebook::react::ScrollViewEventEmitter const>(eventEmitter)
1364
+ ->onMomentumScrollEnd(scrollMetrics);
1365
+ }
1366
+ });
1367
+
1357
1368
  return visual;
1358
1369
  }
1359
1370
 
@@ -1450,50 +1461,4 @@ void ScrollViewComponentView::updateShowsVerticalScrollIndicator(bool value) noe
1450
1461
  void ScrollViewComponentView::updateDecelerationRate(float value) noexcept {
1451
1462
  m_scrollVisual.SetDecelerationRate({value, value, value});
1452
1463
  }
1453
-
1454
- SnapAlignment ScrollViewComponentView::convertSnapToAlignment(
1455
- facebook::react::ScrollViewSnapToAlignment alignment) noexcept {
1456
- switch (alignment) {
1457
- case facebook::react::ScrollViewSnapToAlignment::Center:
1458
- return SnapAlignment::Center;
1459
- case facebook::react::ScrollViewSnapToAlignment::End:
1460
- return SnapAlignment::End;
1461
- case facebook::react::ScrollViewSnapToAlignment::Start:
1462
- default:
1463
- return SnapAlignment::Start;
1464
- }
1465
- }
1466
-
1467
- void ScrollViewComponentView::updateSnapPoints() noexcept {
1468
- const auto &viewProps = *std::static_pointer_cast<const facebook::react::ScrollViewProps>(this->viewProps());
1469
- const auto snapToOffsets = CreateSnapToOffsets(viewProps.snapToOffsets);
1470
- // Typically used in combination with snapToAlignment and decelerationRate="fast"
1471
- auto snapAlignment = SnapAlignment::Center;
1472
- auto decelerationRate = viewProps.decelerationRate;
1473
-
1474
- // snapToOffsets has priority over snapToInterval (matches React Native behavior)
1475
- if (viewProps.snapToInterval > 0 && decelerationRate >= 0.99) {
1476
- snapAlignment = convertSnapToAlignment(viewProps.snapToAlignment);
1477
- // Generate snap points based on interval
1478
- // Calculate the content size to determine how many intervals to create
1479
- float contentLength = viewProps.horizontal
1480
- ? std::max(m_contentSize.width, m_layoutMetrics.frame.size.width) * m_layoutMetrics.pointScaleFactor
1481
- : std::max(m_contentSize.height, m_layoutMetrics.frame.size.height) * m_layoutMetrics.pointScaleFactor;
1482
-
1483
- float interval = static_cast<float>(viewProps.snapToInterval) * m_layoutMetrics.pointScaleFactor;
1484
-
1485
- // Ensure we have a reasonable minimum interval to avoid infinite loops or excessive memory usage
1486
- if (interval >= 1.0f && contentLength > 0) {
1487
- // Generate offsets at each interval, but limit the number of snap points to avoid excessive memory usage
1488
- int snapPointCount = 0;
1489
-
1490
- for (float offset = 0; offset <= contentLength && snapPointCount < c_maxSnapPoints; offset += interval) {
1491
- snapToOffsets.Append(offset);
1492
- snapPointCount++;
1493
- }
1494
- }
1495
- }
1496
-
1497
- m_scrollVisual.SetSnapPoints(viewProps.snapToStart, viewProps.snapToEnd, snapToOffsets.GetView(), snapAlignment);
1498
- }
1499
1464
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -18,8 +18,6 @@
18
18
 
19
19
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
20
20
 
21
- using namespace Microsoft::ReactNative::Composition::Experimental;
22
-
23
21
  struct ScrollBarComponent;
24
22
 
25
23
  struct ScrollViewComponentView : ScrollViewComponentViewT<ScrollViewComponentView, ViewComponentView> {
@@ -123,7 +121,6 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
123
121
  private:
124
122
  void updateDecelerationRate(float value) noexcept;
125
123
  void updateContentVisualSize() noexcept;
126
- void updateSnapPoints() noexcept;
127
124
  bool scrollToEnd(bool animate) noexcept;
128
125
  bool scrollToStart(bool animate) noexcept;
129
126
  bool scrollDown(float delta, bool animate) noexcept;
@@ -137,8 +134,6 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
137
134
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) noexcept;
138
135
  void updateShowsHorizontalScrollIndicator(bool value) noexcept;
139
136
  void updateShowsVerticalScrollIndicator(bool value) noexcept;
140
- SnapAlignment convertSnapToAlignment(facebook::react::ScrollViewSnapToAlignment alignment) noexcept;
141
- winrt::Windows::Foundation::Collections::IVector<float> CreateSnapToOffsets(const std::vector<float> &offsets);
142
137
 
143
138
  facebook::react::Size m_contentSize;
144
139
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual m_scrollVisual{nullptr};
@@ -148,9 +143,12 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
148
143
  m_scrollPositionChangedRevoker{};
149
144
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollBeginDrag_revoker
150
145
  m_scrollBeginDragRevoker{};
151
-
152
146
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollEndDrag_revoker
153
147
  m_scrollEndDragRevoker{};
148
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollMomentumBegin_revoker
149
+ m_scrollMomentumBeginRevoker{};
150
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollMomentumEnd_revoker
151
+ m_scrollMomentumEndRevoker{};
154
152
 
155
153
  float m_zoomFactor{1.0f};
156
154
  bool m_isScrollingFromInertia = false;
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.80.0-preview.7</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.80.0-preview.8</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>80</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>853633ac26bff5e85654ac5de4d34f37cfbfb529</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>e7d4d2707ed8c8070b8ce0d2ebef5700ad9de61c</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.80.0-preview.7",
3
+ "version": "0.80.0-preview.8",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",