From 87d9414bf0c4f2a830a83bdbbd1b74762f352a20 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Tue, 31 Oct 2023 04:41:05 -0700 Subject: [PATCH 01/43] Bump target SDK to 34 (#5246) Summary: [android] Bump target SDK to 34 Changelog: Android SDK is now built against SDK 34 Pull Request resolved: https://github.com/facebook/flipper/pull/5246 Test Plan: --- Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/flipper/pull/5246). * https://github.com/facebook/flipper/issues/5252 * https://github.com/facebook/flipper/issues/5247 * __->__ https://github.com/facebook/flipper/issues/5246 * https://github.com/facebook/flipper/issues/5245 Reviewed By: mweststrate Differential Revision: D50599215 Pulled By: passy fbshipit-source-id: a9883fdbab7bdd06a63a2949e1502a7854299752 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 109b8d1bf..1cb548ff4 100644 --- a/build.gradle +++ b/build.gradle @@ -49,8 +49,8 @@ subprojects { ext { minSdkVersion = 15 - targetSdkVersion = 33 - compileSdkVersion = 33 + targetSdkVersion = 34 + compileSdkVersion = 34 buildToolsVersion = "33.0.2" ndkVersion = "25.1.8937393" javaTargetVersion = JavaVersion.VERSION_17 From 6bec2d659e187246d0de3740dbc07e94e8d0ca6f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 31 Oct 2023 04:42:26 -0700 Subject: [PATCH 02/43] Automated: Update Podfile.lock (#5251) Summary: This is an automated PR to update the Podfile.lock. - Make sure that the Podfile.lock contains latest FlipperKit and Flipper pod versions. - Also make sure that all the dependencies are updated to the latest one. - This is auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request) Pull Request resolved: https://github.com/facebook/flipper/pull/5251 Reviewed By: mweststrate Differential Revision: D50793947 Pulled By: passy fbshipit-source-id: be1d4967f825a125c1f8819f1c2eea4b52c9eaba --- Flipper.podspec | 2 +- FlipperKit.podspec | 2 +- docs/getting-started/ios-native.mdx | 2 +- iOS/Sample/Podfile.lock | 46 ++++++------ iOS/SampleSwift/Podfile.lock | 42 +++++------ iOS/Tutorial/Podfile | 2 +- iOS/Tutorial/Podfile.lock | 52 +++++++------- .../ReactNativeFlipperExample/ios/Podfile | 2 +- .../ios/Podfile.lock | 72 +++++++++---------- 9 files changed, 111 insertions(+), 111 deletions(-) diff --git a/Flipper.podspec b/Flipper.podspec index 2040bbef2..b72ab3347 100644 --- a/Flipper.podspec +++ b/Flipper.podspec @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -flipperkit_version = '0.222.0' +flipperkit_version = '0.233.0' Pod::Spec.new do |spec| spec.name = 'Flipper' spec.cocoapods_version = '>= 1.10' diff --git a/FlipperKit.podspec b/FlipperKit.podspec index 8ea9f97b5..227626dba 100644 --- a/FlipperKit.podspec +++ b/FlipperKit.podspec @@ -4,7 +4,7 @@ # LICENSE file in the root directory of this source tree. folly_compiler_flags = '-DDEBUG=1 -DFLIPPER_OSS=1 -DFB_SONARKIT_ENABLED=1 -DFOLLY_HAVE_BACKTRACE=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAVE_LIBGFLAGS=0 -DFOLLY_HAVE_LIBJEMALLOC=0 -DFOLLY_HAVE_PREADV=0 -DFOLLY_HAVE_PWRITEV=0 -DFOLLY_HAVE_TFO=0 -DFOLLY_USE_SYMBOLIZER=0' -flipperkit_version = '0.222.0' +flipperkit_version = '0.233.0' Pod::Spec.new do |spec| spec.name = 'FlipperKit' spec.version = flipperkit_version diff --git a/docs/getting-started/ios-native.mdx b/docs/getting-started/ios-native.mdx index d15b8bdef..e17e9b1e9 100644 --- a/docs/getting-started/ios-native.mdx +++ b/docs/getting-started/ios-native.mdx @@ -19,7 +19,7 @@ The following configuration assumes CocoaPods 1.9+: ```ruby project 'MyApp.xcodeproj' -flipperkit_version = '0.222.0' +flipperkit_version = '0.233.0' target 'MyApp' do platform :ios, '10.0' diff --git a/iOS/Sample/Podfile.lock b/iOS/Sample/Podfile.lock index 8989248a0..6243be7df 100644 --- a/iOS/Sample/Podfile.lock +++ b/iOS/Sample/Podfile.lock @@ -1,6 +1,6 @@ PODS: - CocoaAsyncSocket (7.6.5) - - Flipper (0.222.0): + - Flipper (0.233.0): - Flipper-Folly (~> 2.6) - Flipper-Boost-iOSX (1.76.0.1.11) - Flipper-DoubleConversion (3.2.0.1) @@ -14,50 +14,50 @@ PODS: - OpenSSL-Universal (= 1.1.1100) - Flipper-Glog (0.5.0.5) - Flipper-PeerTalk (0.0.4) - - FlipperKit (0.222.0): - - FlipperKit/Core (= 0.222.0) - - FlipperKit/Core (0.222.0): - - Flipper (~> 0.222.0) + - FlipperKit (0.233.0): + - FlipperKit/Core (= 0.233.0) + - FlipperKit/Core (0.233.0): + - Flipper (~> 0.233.0) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - SocketRocket (~> 0.7.0) - - FlipperKit/CppBridge (0.222.0): - - Flipper (~> 0.222.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.222.0): + - FlipperKit/CppBridge (0.233.0): + - Flipper (~> 0.233.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.233.0): - Flipper-Folly (~> 2.6) - - FlipperKit/FBDefines (0.222.0) - - FlipperKit/FKPortForwarding (0.222.0): + - FlipperKit/FBDefines (0.233.0) + - FlipperKit/FKPortForwarding (0.233.0): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitExamplePlugin (0.222.0): + - FlipperKit/FlipperKitExamplePlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitHighlightOverlay (0.222.0) - - FlipperKit/FlipperKitLayoutHelpers (0.222.0): + - FlipperKit/FlipperKitHighlightOverlay (0.233.0) + - FlipperKit/FlipperKitLayoutHelpers (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutIOSDescriptors (0.222.0): + - FlipperKit/FlipperKitLayoutIOSDescriptors (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - - FlipperKit/FlipperKitLayoutPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - FlipperKit/FlipperKitLayoutIOSDescriptors - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutTextSearchable (0.222.0) - - FlipperKit/FlipperKitNetworkPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutTextSearchable (0.233.0) + - FlipperKit/FlipperKitNetworkPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitReactPlugin (0.222.0): + - FlipperKit/FlipperKitReactPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitUIDebuggerPlugin (0.222.0): + - FlipperKit/FlipperKitUIDebuggerPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.222.0): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.222.0): + - FlipperKit/SKIOSNetworkPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - libevent (2.1.12) @@ -104,14 +104,14 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - Flipper: 2134ddbde14751be413e22c2677d743dffaa9945 + Flipper: 78cb4b9cf280b4ad4230a4f3b5c21ff657f3c147 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - FlipperKit: 347167ea72c9d718edb15757184384cf31a2cf27 + FlipperKit: 825a05d0e628a8533599bff069d8325c0c577b27 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d diff --git a/iOS/SampleSwift/Podfile.lock b/iOS/SampleSwift/Podfile.lock index 2698fb1f0..f11b6e63a 100644 --- a/iOS/SampleSwift/Podfile.lock +++ b/iOS/SampleSwift/Podfile.lock @@ -1,7 +1,7 @@ PODS: - boost-for-react-native (1.63.0) - CocoaAsyncSocket (7.6.5) - - Flipper (0.222.0): + - Flipper (0.233.0): - Flipper-Folly (~> 2.6) - Flipper-Boost-iOSX (1.76.0.1.11) - Flipper-DoubleConversion (3.2.0.1) @@ -15,46 +15,46 @@ PODS: - OpenSSL-Universal (= 1.1.1100) - Flipper-Glog (0.5.0.5) - Flipper-PeerTalk (0.0.4) - - FlipperKit (0.222.0): - - FlipperKit/Core (= 0.222.0) - - FlipperKit/Core (0.222.0): - - Flipper (~> 0.222.0) + - FlipperKit (0.233.0): + - FlipperKit/Core (= 0.233.0) + - FlipperKit/Core (0.233.0): + - Flipper (~> 0.233.0) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - SocketRocket (~> 0.7.0) - - FlipperKit/CppBridge (0.222.0): - - Flipper (~> 0.222.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.222.0): + - FlipperKit/CppBridge (0.233.0): + - Flipper (~> 0.233.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.233.0): - Flipper-Folly (~> 2.6) - - FlipperKit/FBDefines (0.222.0) - - FlipperKit/FKPortForwarding (0.222.0): + - FlipperKit/FBDefines (0.233.0) + - FlipperKit/FKPortForwarding (0.233.0): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitExamplePlugin (0.222.0): + - FlipperKit/FlipperKitExamplePlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitHighlightOverlay (0.222.0) - - FlipperKit/FlipperKitLayoutHelpers (0.222.0): + - FlipperKit/FlipperKitHighlightOverlay (0.233.0) + - FlipperKit/FlipperKitLayoutHelpers (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutIOSDescriptors (0.222.0): + - FlipperKit/FlipperKitLayoutIOSDescriptors (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - - FlipperKit/FlipperKitLayoutPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - FlipperKit/FlipperKitLayoutIOSDescriptors - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutTextSearchable (0.222.0) - - FlipperKit/FlipperKitNetworkPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutTextSearchable (0.233.0) + - FlipperKit/FlipperKitNetworkPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.222.0): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.222.0): + - FlipperKit/SKIOSNetworkPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - libevent (2.1.12) @@ -100,14 +100,14 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - Flipper: 2134ddbde14751be413e22c2677d743dffaa9945 + Flipper: 78cb4b9cf280b4ad4230a4f3b5c21ff657f3c147 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - FlipperKit: 347167ea72c9d718edb15757184384cf31a2cf27 + FlipperKit: 825a05d0e628a8533599bff069d8325c0c577b27 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d diff --git a/iOS/Tutorial/Podfile b/iOS/Tutorial/Podfile index 6341cdebe..65aaa34b7 100644 --- a/iOS/Tutorial/Podfile +++ b/iOS/Tutorial/Podfile @@ -1,6 +1,6 @@ project 'Tutorial.xcodeproj' swift_version = "4.1" -flipperkit_version = '0.222.0' +flipperkit_version = '0.233.0' use_frameworks! target 'Tutorial' do diff --git a/iOS/Tutorial/Podfile.lock b/iOS/Tutorial/Podfile.lock index 7c4133f25..19f15ca9d 100644 --- a/iOS/Tutorial/Podfile.lock +++ b/iOS/Tutorial/Podfile.lock @@ -3,7 +3,7 @@ PODS: - ComponentKit (0.31): - RenderCore (= 0.31) - Yoga (~> 1.14) - - Flipper (0.222.0): + - Flipper (0.233.0): - Flipper-Folly (~> 2.6) - Flipper-Boost-iOSX (1.76.0.1.11) - Flipper-DoubleConversion (3.2.0.1) @@ -17,25 +17,25 @@ PODS: - OpenSSL-Universal (= 1.1.1100) - Flipper-Glog (0.5.0.5) - Flipper-PeerTalk (0.0.4) - - FlipperKit (0.222.0): - - FlipperKit/Core (= 0.222.0) - - FlipperKit/Core (0.222.0): - - Flipper (~> 0.222.0) + - FlipperKit (0.233.0): + - FlipperKit/Core (= 0.233.0) + - FlipperKit/Core (0.233.0): + - Flipper (~> 0.233.0) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - SocketRocket (~> 0.7.0) - - FlipperKit/CppBridge (0.222.0): - - Flipper (~> 0.222.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.222.0): + - FlipperKit/CppBridge (0.233.0): + - Flipper (~> 0.233.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.233.0): - Flipper-Folly (~> 2.6) - - FlipperKit/FBDefines (0.222.0) - - FlipperKit/FKPortForwarding (0.222.0): + - FlipperKit/FBDefines (0.233.0) + - FlipperKit/FKPortForwarding (0.233.0): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitHighlightOverlay (0.222.0) - - FlipperKit/FlipperKitLayoutComponentKitSupport (0.222.0): + - FlipperKit/FlipperKitHighlightOverlay (0.233.0) + - FlipperKit/FlipperKitLayoutComponentKitSupport (0.233.0): - ComponentKit (= 0.31) - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay @@ -43,26 +43,26 @@ PODS: - FlipperKit/FlipperKitLayoutPlugin - FlipperKit/FlipperKitLayoutTextSearchable - RenderCore (= 0.31) - - FlipperKit/FlipperKitLayoutHelpers (0.222.0): + - FlipperKit/FlipperKitLayoutHelpers (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutIOSDescriptors (0.222.0): + - FlipperKit/FlipperKitLayoutIOSDescriptors (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - - FlipperKit/FlipperKitLayoutPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - FlipperKit/FlipperKitLayoutIOSDescriptors - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutTextSearchable (0.222.0) - - FlipperKit/FlipperKitNetworkPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutTextSearchable (0.233.0) + - FlipperKit/FlipperKitNetworkPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.222.0): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.222.0): + - FlipperKit/SKIOSNetworkPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - libevent (2.1.12) @@ -72,10 +72,10 @@ PODS: - Yoga (1.14.0) DEPENDENCIES: - - FlipperKit (~> 0.222.0) - - FlipperKit/FlipperKitLayoutComponentKitSupport (~> 0.222.0) - - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.222.0) - - FlipperKit/SKIOSNetworkPlugin (~> 0.222.0) + - FlipperKit (~> 0.233.0) + - FlipperKit/FlipperKitLayoutComponentKitSupport (~> 0.233.0) + - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.233.0) + - FlipperKit/SKIOSNetworkPlugin (~> 0.233.0) SPEC REPOS: trunk: @@ -98,20 +98,20 @@ SPEC REPOS: SPEC CHECKSUMS: CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 ComponentKit: 7bf7048b9814afc6b6641645a14177f95fd9b9ae - Flipper: 2134ddbde14751be413e22c2677d743dffaa9945 + Flipper: 78cb4b9cf280b4ad4230a4f3b5c21ff657f3c147 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - FlipperKit: 347167ea72c9d718edb15757184384cf31a2cf27 + FlipperKit: 825a05d0e628a8533599bff069d8325c0c577b27 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c RenderCore: 090beb17b5bff80b86929a7ceb49df789923d23a SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: cff67a400f6b74dc38eb0bad4f156673d9aa980c -PODFILE CHECKSUM: 8f946f0af7af514b0220472d59f2b9d79b44d357 +PODFILE CHECKSUM: 21ac489846903706fab579f97b09e3927902f123 COCOAPODS: 1.12.1 diff --git a/react-native/ReactNativeFlipperExample/ios/Podfile b/react-native/ReactNativeFlipperExample/ios/Podfile index 55df1d95c..82c626660 100644 --- a/react-native/ReactNativeFlipperExample/ios/Podfile +++ b/react-native/ReactNativeFlipperExample/ios/Podfile @@ -5,7 +5,7 @@ source 'https://github.com/CocoaPods/Specs' platform :ios, '12.4' # used for automatic bumping -flipperkit_version = '0.222.0' +flipperkit_version = '0.233.0' target 'ReactNativeFlipperExample' do config = use_native_modules! diff --git a/react-native/ReactNativeFlipperExample/ios/Podfile.lock b/react-native/ReactNativeFlipperExample/ios/Podfile.lock index 638414ac5..5e9206c2d 100644 --- a/react-native/ReactNativeFlipperExample/ios/Podfile.lock +++ b/react-native/ReactNativeFlipperExample/ios/Podfile.lock @@ -10,7 +10,7 @@ PODS: - React-Core (= 0.69.7) - React-jsi (= 0.69.7) - ReactCommon/turbomodule/core (= 0.69.7) - - Flipper (0.222.0): + - Flipper (0.233.0): - Flipper-Folly (~> 2.6) - Flipper-Boost-iOSX (1.76.0.1.11) - Flipper-DoubleConversion (3.2.0) @@ -26,46 +26,46 @@ PODS: - Flipper-PeerTalk (0.0.4) - Flipper-RSocket (1.4.3): - Flipper-Folly (~> 2.6) - - FlipperKit (0.222.0): - - FlipperKit/Core (= 0.222.0) - - FlipperKit/Core (0.222.0): - - Flipper (~> 0.222.0) + - FlipperKit (0.233.0): + - FlipperKit/Core (= 0.233.0) + - FlipperKit/Core (0.233.0): + - Flipper (~> 0.233.0) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - SocketRocket (~> 0.7.0) - - FlipperKit/CppBridge (0.222.0): - - Flipper (~> 0.222.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.222.0): + - FlipperKit/CppBridge (0.233.0): + - Flipper (~> 0.233.0) + - FlipperKit/FBCxxFollyDynamicConvert (0.233.0): - Flipper-Folly (~> 2.6) - - FlipperKit/FBDefines (0.222.0) - - FlipperKit/FKPortForwarding (0.222.0): + - FlipperKit/FBDefines (0.233.0) + - FlipperKit/FKPortForwarding (0.233.0): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitHighlightOverlay (0.222.0) - - FlipperKit/FlipperKitLayoutHelpers (0.222.0): + - FlipperKit/FlipperKitHighlightOverlay (0.233.0) + - FlipperKit/FlipperKitLayoutHelpers (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutIOSDescriptors (0.222.0): + - FlipperKit/FlipperKitLayoutIOSDescriptors (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - - FlipperKit/FlipperKitLayoutPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutHelpers - FlipperKit/FlipperKitLayoutIOSDescriptors - FlipperKit/FlipperKitLayoutTextSearchable - - FlipperKit/FlipperKitLayoutTextSearchable (0.222.0) - - FlipperKit/FlipperKitNetworkPlugin (0.222.0): + - FlipperKit/FlipperKitLayoutTextSearchable (0.233.0) + - FlipperKit/FlipperKitNetworkPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitReactPlugin (0.222.0): + - FlipperKit/FlipperKitReactPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.222.0): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.233.0): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.222.0): + - FlipperKit/SKIOSNetworkPlugin (0.233.0): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - fmt (6.2.1) @@ -375,7 +375,7 @@ DEPENDENCIES: - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - - Flipper (= 0.222.0) + - Flipper (= 0.233.0) - Flipper-Boost-iOSX (= 1.76.0.1.11) - Flipper-DoubleConversion (= 3.2.0) - Flipper-Fmt (= 7.1.7) @@ -383,19 +383,19 @@ DEPENDENCIES: - Flipper-Glog (= 0.5.0.3) - Flipper-PeerTalk (= 0.0.4) - Flipper-RSocket (= 1.4.3) - - FlipperKit (= 0.222.0) - - FlipperKit/Core (= 0.222.0) - - FlipperKit/CppBridge (= 0.222.0) - - FlipperKit/FBCxxFollyDynamicConvert (= 0.222.0) - - FlipperKit/FBDefines (= 0.222.0) - - FlipperKit/FKPortForwarding (= 0.222.0) - - FlipperKit/FlipperKitHighlightOverlay (= 0.222.0) - - FlipperKit/FlipperKitLayoutPlugin (= 0.222.0) - - FlipperKit/FlipperKitLayoutTextSearchable (= 0.222.0) - - FlipperKit/FlipperKitNetworkPlugin (= 0.222.0) - - FlipperKit/FlipperKitReactPlugin (= 0.222.0) - - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.222.0) - - FlipperKit/SKIOSNetworkPlugin (= 0.222.0) + - FlipperKit (= 0.233.0) + - FlipperKit/Core (= 0.233.0) + - FlipperKit/CppBridge (= 0.233.0) + - FlipperKit/FBCxxFollyDynamicConvert (= 0.233.0) + - FlipperKit/FBDefines (= 0.233.0) + - FlipperKit/FKPortForwarding (= 0.233.0) + - FlipperKit/FlipperKitHighlightOverlay (= 0.233.0) + - FlipperKit/FlipperKitLayoutPlugin (= 0.233.0) + - FlipperKit/FlipperKitLayoutTextSearchable (= 0.233.0) + - FlipperKit/FlipperKitNetworkPlugin (= 0.233.0) + - FlipperKit/FlipperKitReactPlugin (= 0.233.0) + - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.233.0) + - FlipperKit/SKIOSNetworkPlugin (= 0.233.0) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`) - libevent (~> 2.1.12) @@ -527,7 +527,7 @@ SPEC CHECKSUMS: DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 6b7f5692909b4300d50e7359cdefbcd09dd30faa FBReactNativeSpec: affcf71d996f6b0c01f68883482588297b9d5e6e - Flipper: 2134ddbde14751be413e22c2677d743dffaa9945 + Flipper: 78cb4b9cf280b4ad4230a4f3b5c21ff657f3c147 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 3d3d04a078d4f3a1b6c6916587f159dc11f232c4 Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b @@ -535,7 +535,7 @@ SPEC CHECKSUMS: Flipper-Glog: 7761f5362d23ead28c19afc2dd1d819f00e40df9 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541 - FlipperKit: 347167ea72c9d718edb15757184384cf31a2cf27 + FlipperKit: 825a05d0e628a8533599bff069d8325c0c577b27 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a hermes-engine: 51aaceb1f6dc1aed44b8bbf866f52ec146c00a89 @@ -572,6 +572,6 @@ SPEC CHECKSUMS: SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 0b84a956f7393ef1f37f3bb213c516184e4a689d -PODFILE CHECKSUM: 4e948bc99291e6ee9db9ffa2c78a53e28aab3012 +PODFILE CHECKSUM: 5e5d992e623055876f27684fc962e3d0e2b2fa37 COCOAPODS: 1.12.1 From 560a50485c92c42c7b8b7530f317c849537de77f Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Tue, 31 Oct 2023 04:45:33 -0700 Subject: [PATCH 03/43] Improve offline page Summary: The previous offline page suggested launching Flipper from terminal by running a command. Although this works, guidance can be simplified by just instructing users to launch Flipper from within the Applications folder. Reviewed By: aigoncharov Differential Revision: D50833741 fbshipit-source-id: 5a41090a66ee62c30cfc35edd69de51ed9cbbab9 --- desktop/static/offline.html | 42 +------------------------------- desktop/static/service-worker.js | 2 +- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/desktop/static/offline.html b/desktop/static/offline.html index 975c29049..3792addc6 100644 --- a/desktop/static/offline.html +++ b/desktop/static/offline.html @@ -36,36 +36,6 @@ text-align: center; } - .console { - font-family: 'Fira Mono'; - width: 600px; - height: 250px; - box-sizing: border-box; - margin: auto; - } - - .console header { - border-top-left-radius: 15px; - border-top-right-radius: 15px; - background-color: #9254de; - height: 45px; - line-height: 45px; - text-align: center; - color: white; - } - - .console .consolebody { - border-bottom-left-radius: 15px; - border-bottom-right-radius: 15px; - box-sizing: border-box; - padding: 0px 10px; - height: calc(100% - 40px); - overflow: scroll; - background-color: #000; - color: white; - text-align: left; - } - input[type="submit"] { background-color: #9254de; color: white; @@ -107,17 +77,7 @@

Flipper will automatically reload once the connection is re-established.

-

If is taking a bit longer than it should, you can manually start Flipper.

-

From the terminal, please run:

- -
-
-

shell

-
-
-

> open -a 'Flipper' --args '--server'

-
-
+

Note: if is taking a bit longer than it should, you can manually start Flipper by launching it from the Applications folder.

diff --git a/desktop/static/service-worker.js b/desktop/static/service-worker.js index 7386d13fa..4bad5af54 100644 --- a/desktop/static/service-worker.js +++ b/desktop/static/service-worker.js @@ -8,7 +8,7 @@ // OFFLINE_VERSION is used as an update marker so that on subsequent installations // the newer version of the file gets updated. // eslint-disable-next-line header/header, no-unused-vars -const OFFLINE_VERSION = 1.1; +const OFFLINE_VERSION = 1.2; const CACHE_NAME = 'offline'; const OFFLINE_URL = 'offline.html'; From 57d4e865453145c953855381dab36730c1751542 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Tue, 31 Oct 2023 05:16:21 -0700 Subject: [PATCH 04/43] Additional troubleshoot guidance for idb Summary: Reference: https://fb.workplace.com/groups/flippersupport/permalink/1717333982080586/ The steps added below seem to have fixed the issue. Still need to investigate why these steps are needed. Reviewed By: aigoncharov Differential Revision: D50797561 fbshipit-source-id: a31c71dbedc506344438082846b41ff16b6f459a --- .../src/devices/ios/iOSContainerUtility.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx b/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx index ebec6222d..2ace8bf00 100644 --- a/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx +++ b/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx @@ -16,6 +16,7 @@ import {promisify} from 'util'; import child_process from 'child_process'; import fs from 'fs-extra'; import {recorder} from '../../recorder'; +import {isFBBuild} from '../../fb-stubs/constants'; const exec = promisify(child_process.exec); export type IdbConfig = { @@ -173,8 +174,12 @@ async function queryTargetsWithIdb( const cmd = `${idbPath} list-targets --json`; const description = `Query available devices with idb. idb is aware of the companions that you have manually connected, as well as other iOS targets that do not yet have companions.`; - const troubleshoot = `Either idb is not installed or needs to be reset. + let troubleshoot = `Either idb is not installed or needs to be reset. Run 'idb kill' from terminal.`; + if (isFBBuild) { + troubleshoot += ` If the steps above do not fix the issue, try re-installing idb by running these commands on the terminal 'sudo microdnf remove fb-idb fb-idb-companion' +and 'sudo microdnf install fb-idb fb-idb-companion'.`; + } try { const {stdout} = await unsafeExec(cmd); From 8086816f82d0423e5485fb888441acf53543d234 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Tue, 31 Oct 2023 07:10:30 -0700 Subject: [PATCH 05/43] Upgrade deps Summary: 666 deletions seems just right. Reviewed By: lblasa Differential Revision: D50600098 fbshipit-source-id: 269ce9f1da18ece283492ed7ff29c4dcfc2f78b4 --- js/js-flipper/package.json | 36 +- js/js-flipper/yarn.lock | 1544 +++++++++++++++++++++--------------- 2 files changed, 917 insertions(+), 663 deletions(-) diff --git a/js/js-flipper/package.json b/js/js-flipper/package.json index 1c7dcf4b0..c05e539a8 100644 --- a/js/js-flipper/package.json +++ b/js/js-flipper/package.json @@ -39,34 +39,34 @@ "licenseFilename": "LICENSE", "readmeFilename": "README.md", "devDependencies": { - "@babel/core": "^7.22.10", - "@babel/eslint-parser": "7.22.10", - "@types/jest": "^29.5.3", - "@types/node": "^20.5.0", - "@types/sinon": "^10.0.16", - "@types/ws": "^8.5.5", - "@typescript-eslint/eslint-plugin": "6.4.0", - "@typescript-eslint/parser": "6.4.0", + "@babel/core": "^7.23.2", + "@babel/eslint-parser": "7.22.15", + "@types/jest": "^29.5.6", + "@types/node": "^20.8.8", + "@types/sinon": "^10.0.20", + "@types/ws": "^8.5.8", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "ansi-to-html": "^0.7.2", "cross-env": "^7.0.3", - "eslint": "8.47.0", + "eslint": "8.52.0", "eslint-config-fbjs": "^4.0.0", "eslint-config-prettier": "^9.0.0", - "eslint-import-resolver-typescript": "^3.6.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-babel": "^5.3.0", - "eslint-plugin-ft-flow": "^3.0.0", + "eslint-plugin-ft-flow": "^3.0.1", "eslint-plugin-header": "^3.0.0", - "eslint-plugin-import": "^2.28.0", + "eslint-plugin-import": "^2.29.0", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^5.0.0", + "eslint-plugin-prettier": "^5.0.1", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.5.0", - "jest": "^29.6.2", - "prettier": "^3.0.2", - "sinon": "^15.2.0", + "jest": "^29.7.0", + "prettier": "^3.0.3", + "sinon": "^17.0.0", "ts-jest": "^29.1.0", - "typescript": "^5.1.6", - "ws": "^8.12.1" + "typescript": "^5.2.2", + "ws": "^8.14.2" } } diff --git a/js/js-flipper/yarn.lock b/js/js-flipper/yarn.lock index 3f045604a..d0e51f17e 100644 --- a/js/js-flipper/yarn.lock +++ b/js/js-flipper/yarn.lock @@ -22,21 +22,14 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/code-frame@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" - integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.22.10" + "@babel/highlight" "^7.22.13" chalk "^2.4.2" -"@babel/code-frame@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" - integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== - dependencies: - "@babel/highlight" "^7.22.5" - "@babel/compat-data@^7.20.0": version "7.20.5" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733" @@ -68,31 +61,31 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/core@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.10.tgz#aad442c7bcd1582252cb4576747ace35bc122f35" - integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== +"@babel/core@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" + integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.10" - "@babel/generator" "^7.22.10" - "@babel/helper-compilation-targets" "^7.22.10" - "@babel/helper-module-transforms" "^7.22.9" - "@babel/helpers" "^7.22.10" - "@babel/parser" "^7.22.10" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.10" - "@babel/types" "^7.22.10" - convert-source-map "^1.7.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.0" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.2" + json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.10.tgz#bfdf3d1b32ad573fe7c1c3447e0b485e3a41fd09" - integrity sha512-0J8DNPRXQRLeR9rPaUMM3fA+RbixjnVLe/MRMYCkp3hzgsSuxCHQ8NN8xQG1wIHKJ4a1DTROTvFJdW+B5/eOsg== +"@babel/eslint-parser@7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz#263f059c476e29ca4972481a17b8b660cb025a34" + integrity sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" @@ -107,12 +100,12 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" -"@babel/generator@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" - integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A== +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== dependencies: - "@babel/types" "^7.22.10" + "@babel/types" "^7.23.0" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" @@ -127,13 +120,13 @@ browserslist "^4.21.3" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024" - integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q== +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== dependencies: "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" browserslist "^4.21.9" lru-cache "^5.1.1" semver "^6.3.1" @@ -143,10 +136,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-environment-visitor@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" - integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== "@babel/helper-function-name@^7.19.0": version "7.19.0" @@ -156,13 +149,13 @@ "@babel/template" "^7.18.10" "@babel/types" "^7.19.0" -"@babel/helper-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" - integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== dependencies: - "@babel/template" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" @@ -185,12 +178,12 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-imports@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" - integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== dependencies: - "@babel/types" "^7.22.5" + "@babel/types" "^7.22.15" "@babel/helper-module-transforms@^7.20.2": version "7.20.2" @@ -206,16 +199,16 @@ "@babel/traverse" "^7.20.1" "@babel/types" "^7.20.2" -"@babel/helper-module-transforms@^7.22.9": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" - integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== +"@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" "@babel/helper-simple-access" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.8.0": version "7.18.9" @@ -265,6 +258,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" @@ -275,10 +273,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== -"@babel/helper-validator-option@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" - integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== "@babel/helpers@^7.20.5": version "7.20.6" @@ -289,14 +287,14 @@ "@babel/traverse" "^7.20.5" "@babel/types" "^7.20.5" -"@babel/helpers@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.10.tgz#ae6005c539dfbcb5cd71fb51bfc8a52ba63bc37a" - integrity sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw== +"@babel/helpers@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" + integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== dependencies: - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.10" - "@babel/types" "^7.22.10" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" "@babel/highlight@^7.18.6": version "7.18.6" @@ -307,38 +305,24 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/highlight@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" - integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== dependencies: - "@babel/helper-validator-identifier" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/highlight@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" - integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== - dependencies: - "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.5": version "7.20.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8" integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== -"@babel/parser@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" - integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== - -"@babel/parser@^7.22.5": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" - integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -454,14 +438,14 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/template@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" - integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/parser" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" "@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5": version "7.20.5" @@ -479,19 +463,19 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" - integrity sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig== +"@babel/traverse@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== dependencies: - "@babel/code-frame" "^7.22.10" - "@babel/generator" "^7.22.10" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.22.10" - "@babel/types" "^7.22.10" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" @@ -504,13 +488,13 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@babel/types@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" - integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg== +"@babel/types@^7.22.15", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== dependencies: "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" "@babel/types@^7.22.5": @@ -566,17 +550,17 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@^8.47.0": - version "8.47.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d" - integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== +"@eslint/js@8.52.0": + version "8.52.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.52.0.tgz#78fe5f117840f69dc4a353adf9b9cd926353378c" + integrity sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA== -"@humanwhocodes/config-array@^0.11.10": - version "0.11.10" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" + "@humanwhocodes/object-schema" "^2.0.1" debug "^4.1.1" minimatch "^3.0.5" @@ -585,10 +569,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -606,61 +590,61 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.6.2.tgz#bf1d4101347c23e07c029a1b1ae07d550f5cc541" - integrity sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w== +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.6.2" - jest-util "^29.6.2" + jest-message-util "^29.7.0" + jest-util "^29.7.0" slash "^3.0.0" -"@jest/core@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.6.2.tgz#6f2d1dbe8aa0265fcd4fb8082ae1952f148209c8" - integrity sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg== +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== dependencies: - "@jest/console" "^29.6.2" - "@jest/reporters" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.5.0" - jest-config "^29.6.2" - jest-haste-map "^29.6.2" - jest-message-util "^29.6.2" - jest-regex-util "^29.4.3" - jest-resolve "^29.6.2" - jest-resolve-dependencies "^29.6.2" - jest-runner "^29.6.2" - jest-runtime "^29.6.2" - jest-snapshot "^29.6.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" - jest-watcher "^29.6.2" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" micromatch "^4.0.4" - pretty-format "^29.6.2" + pretty-format "^29.7.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.2.tgz#794c0f769d85e7553439d107d3f43186dc6874a9" - integrity sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q== +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.2" + jest-mock "^29.7.0" "@jest/expect-utils@^29.4.2": version "29.4.2" @@ -669,53 +653,53 @@ dependencies: jest-get-type "^29.4.2" -"@jest/expect-utils@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.2.tgz#1b97f290d0185d264dd9fdec7567a14a38a90534" - integrity sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg== +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== dependencies: - jest-get-type "^29.4.3" + jest-get-type "^29.6.3" -"@jest/expect@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.6.2.tgz#5a2ad58bb345165d9ce0a1845bbf873c480a4b28" - integrity sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg== +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== dependencies: - expect "^29.6.2" - jest-snapshot "^29.6.2" + expect "^29.7.0" + jest-snapshot "^29.7.0" -"@jest/fake-timers@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.2.tgz#fe9d43c5e4b1b901168fe6f46f861b3e652a2df4" - integrity sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA== +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.6.2" - jest-mock "^29.6.2" - jest-util "^29.6.2" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" -"@jest/globals@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.6.2.tgz#74af81b9249122cc46f1eb25793617eec69bf21a" - integrity sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw== +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== dependencies: - "@jest/environment" "^29.6.2" - "@jest/expect" "^29.6.2" - "@jest/types" "^29.6.1" - jest-mock "^29.6.2" + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" -"@jest/reporters@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.6.2.tgz#524afe1d76da33d31309c2c4a2c8062d0c48780a" - integrity sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw== +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@jridgewell/trace-mapping" "^0.3.18" "@types/node" "*" chalk "^4.0.0" @@ -724,13 +708,13 @@ glob "^7.1.3" graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" + istanbul-lib-instrument "^6.0.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.6.2" - jest-util "^29.6.2" - jest-worker "^29.6.2" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" @@ -750,58 +734,58 @@ dependencies: "@sinclair/typebox" "^0.25.16" -"@jest/schemas@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" - integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: "@sinclair/typebox" "^0.27.8" -"@jest/source-map@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" - integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== dependencies: "@jridgewell/trace-mapping" "^0.3.18" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.6.2.tgz#fdd11583cd1608e4db3114e8f0cce277bf7a32ed" - integrity sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw== +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== dependencies: - "@jest/console" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz#585eff07a68dd75225a7eacf319780cb9f6b9bf4" - integrity sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw== +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== dependencies: - "@jest/test-result" "^29.6.2" + "@jest/test-result" "^29.7.0" graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" + jest-haste-map "^29.7.0" slash "^3.0.0" -"@jest/transform@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.6.2.tgz#522901ebbb211af08835bc3bcdf765ab778094e3" - integrity sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg== +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@jridgewell/trace-mapping" "^0.3.18" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" - jest-regex-util "^29.4.3" - jest-util "^29.6.2" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" @@ -831,12 +815,12 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jest/types@^29.6.1": - version "29.6.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" - integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -978,10 +962,10 @@ dependencies: "@sinonjs/commons" "^2.0.0" -"@sinonjs/fake-timers@^10.3.0": - version "10.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" - integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== +"@sinonjs/fake-timers@^11.2.2": + version "11.2.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz#50063cc3574f4a27bd8453180a04171c85cc9699" + integrity sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw== dependencies: "@sinonjs/commons" "^3.0.0" @@ -1058,10 +1042,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.5.3": - version "29.5.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" - integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== +"@types/jest@^29.5.6": + version "29.5.6" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.6.tgz#f4cf7ef1b5b0bfc1aa744e41b24d9cc52533130b" + integrity sha512-/t9NnzkOpXb4Nfvg17ieHE6EeSjDS2SGSpNYfoLbUAeL/EOueU/RSdOWFpfQTXBEM7BguYW1XQ0EbM+6RlIh6w== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -1081,20 +1065,22 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.3.tgz#4e4a95b6fe44014563ceb514b2598b3e623d1c98" integrity sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg== -"@types/node@^20.5.0": - version "20.5.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313" - integrity sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q== +"@types/node@^20.8.8": + version "20.8.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.8.tgz#adee050b422061ad5255fc38ff71b2bb96ea2a0e" + integrity sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ== + dependencies: + undici-types "~5.25.1" "@types/semver@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== -"@types/sinon@^10.0.16": - version "10.0.16" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.16.tgz#4bf10313bd9aa8eef1e50ec9f4decd3dd455b4d3" - integrity sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ== +"@types/sinon@^10.0.20": + version "10.0.20" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.20.tgz#f1585debf4c0d99f9938f4111e5479fb74865146" + integrity sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg== dependencies: "@types/sinonjs__fake-timers" "*" @@ -1108,10 +1094,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/ws@^8.5.5": - version "8.5.5" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" - integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== +"@types/ws@^8.5.8": + version "8.5.8" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" + integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== dependencies: "@types/node" "*" @@ -1127,16 +1113,16 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz#53428b616f7d80fe879f45a08f11cc0f0b62cf13" - integrity sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg== +"@typescript-eslint/eslint-plugin@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz#fdb6f3821c0167e3356e9d89c80e8230b2e401f4" + integrity sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.4.0" - "@typescript-eslint/type-utils" "6.4.0" - "@typescript-eslint/utils" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/scope-manager" "6.9.0" + "@typescript-eslint/type-utils" "6.9.0" + "@typescript-eslint/utils" "6.9.0" + "@typescript-eslint/visitor-keys" "6.9.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -1144,74 +1130,79 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.4.0.tgz#47e7c6e22ff1248e8675d95f488890484de67600" - integrity sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg== +"@typescript-eslint/parser@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.9.0.tgz#2b402cadeadd3f211c25820e5433413347b27391" + integrity sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw== dependencies: - "@typescript-eslint/scope-manager" "6.4.0" - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/typescript-estree" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/scope-manager" "6.9.0" + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/typescript-estree" "6.9.0" + "@typescript-eslint/visitor-keys" "6.9.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz#3048e4262ba3eafa4e2e69b08912d9037ec646ae" - integrity sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig== +"@typescript-eslint/scope-manager@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz#2626e9a7fe0e004c3e25f3b986c75f584431134e" + integrity sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw== dependencies: - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/visitor-keys" "6.9.0" -"@typescript-eslint/type-utils@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz#c8ac92716ed6a9d5443aa3e342910355b0796ba0" - integrity sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg== +"@typescript-eslint/type-utils@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz#23923c8c9677c2ad41457cf8e10a5f2946be1b04" + integrity sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ== dependencies: - "@typescript-eslint/typescript-estree" "6.4.0" - "@typescript-eslint/utils" "6.4.0" + "@typescript-eslint/typescript-estree" "6.9.0" + "@typescript-eslint/utils" "6.9.0" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.4.0.tgz#5b109a59a805f0d8d375895e42d9e5f0037f66ee" - integrity sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg== +"@typescript-eslint/types@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.9.0.tgz#86a0cbe7ac46c0761429f928467ff3d92f841098" + integrity sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw== -"@typescript-eslint/typescript-estree@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz#3c58d20632db93fec3d6ab902acbedf593d37276" - integrity sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA== +"@typescript-eslint/typescript-estree@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz#d0601b245be873d8fe49f3737f93f8662c8693d4" + integrity sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ== dependencies: - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/visitor-keys" "6.4.0" + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/visitor-keys" "6.9.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.4.0.tgz#23e996b693603c5924b1fbb733cc73196256baa5" - integrity sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw== +"@typescript-eslint/utils@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.9.0.tgz#5bdac8604fca4823f090e4268e681c84d3597c9f" + integrity sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.4.0" - "@typescript-eslint/types" "6.4.0" - "@typescript-eslint/typescript-estree" "6.4.0" + "@typescript-eslint/scope-manager" "6.9.0" + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/typescript-estree" "6.9.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz#96a426cdb1add28274abd7a34aefe27f8b7d51ef" - integrity sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA== +"@typescript-eslint/visitor-keys@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz#cc69421c10c4ac997ed34f453027245988164e80" + integrity sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg== dependencies: - "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/types" "6.9.0" eslint-visitor-keys "^3.4.1" +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -1316,30 +1307,41 @@ array-includes@^3.1.5, array-includes@^3.1.6: get-intrinsic "^1.1.3" is-string "^1.0.7" +array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-string "^1.0.7" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.findlastindex@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz#bc229aef98f6bd0533a2bc61ff95209875526c9b" - integrity sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw== +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.1" -array.prototype.flat@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== +array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" array.prototype.flatmap@^1.3.1: @@ -1352,6 +1354,16 @@ array.prototype.flatmap@^1.3.1: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + array.prototype.tosorted@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" @@ -1375,6 +1387,19 @@ arraybuffer.prototype.slice@^1.0.1: is-array-buffer "^3.0.2" is-shared-array-buffer "^1.0.2" +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" @@ -1404,15 +1429,15 @@ axobject-query@^3.1.1: dependencies: deep-equal "^2.0.5" -babel-jest@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.6.2.tgz#cada0a59e07f5acaeb11cbae7e3ba92aec9c1126" - integrity sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A== +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== dependencies: - "@jest/transform" "^29.6.2" + "@jest/transform" "^29.7.0" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.5.0" + babel-preset-jest "^29.6.3" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" @@ -1428,10 +1453,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" - integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1456,12 +1481,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" - integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== dependencies: - babel-plugin-jest-hoist "^29.5.0" + babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -1531,6 +1556,15 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1648,6 +1682,19 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + cross-env@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -1721,6 +1768,15 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -1752,10 +1808,10 @@ diff-sequences@^29.4.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.2.tgz#711fe6bd8a5869fe2539cee4a5152425ff671fda" integrity sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw== -diff-sequences@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" - integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@^5.1.0: version "5.1.0" @@ -1888,7 +1944,7 @@ es-abstract@^1.20.4: string.prototype.trimstart "^1.0.5" unbox-primitive "^1.0.2" -es-abstract@^1.21.2, es-abstract@^1.21.3: +es-abstract@^1.21.3: version "1.22.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== @@ -1933,6 +1989,51 @@ es-abstract@^1.21.2, es-abstract@^1.21.3: unbox-primitive "^1.0.2" which-typed-array "^1.1.10" +es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + es-get-iterator@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" @@ -2019,19 +2120,19 @@ eslint-config-prettier@^9.0.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== -eslint-import-resolver-node@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" - integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" - is-core-module "^2.11.0" - resolve "^1.22.1" + is-core-module "^2.13.0" + resolve "^1.22.4" -eslint-import-resolver-typescript@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.0.tgz#36f93e1eb65a635e688e16cae4bead54552e3bbd" - integrity sha512-QTHR9ddNnn35RTxlaEnx2gCxqFlF2SEN0SE2d17SqwyM7YOSI2GHWRYp5BiRkObTUNYPupC/3Fq2a0PpT+EKpg== +eslint-import-resolver-typescript@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz#7b983680edd3f1c5bce1a5829ae0bc2d57fe9efa" + integrity sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg== dependencies: debug "^4.3.4" enhanced-resolve "^5.12.0" @@ -2070,10 +2171,10 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-ft-flow@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-ft-flow/-/eslint-plugin-ft-flow-3.0.0.tgz#e9cbe4531089c2a85726928baa2d30d24d9af3b5" - integrity sha512-fz5ep5V2jh5aNBHoCKOdq+xxGenxYMfmOq8F6MUnFGyeEncJgV91O7mOWyKTZN0h/ofP+yW1CS7fZq8iEglNxw== +eslint-plugin-ft-flow@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-ft-flow/-/eslint-plugin-ft-flow-3.0.1.tgz#a0f39cc35efff1a369829e5ba1b528ba0524b371" + integrity sha512-SB6gWDisy2hdYFWimK3fXOKOmi16pIC06R9mCGozHFs6jyr5yi9RDMSGiNuZdBJh1mw2YSF+l7a5hd8ykRQ/Gg== dependencies: lodash "^4.17.21" string-natural-compare "^3.0.1" @@ -2083,27 +2184,26 @@ eslint-plugin-header@^3.0.0: resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg== -eslint-plugin-import@^2.28.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz#8d66d6925117b06c4018d491ae84469eb3cb1005" - integrity sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q== +eslint-plugin-import@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" + integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== dependencies: - array-includes "^3.1.6" - array.prototype.findlastindex "^1.2.2" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" + eslint-import-resolver-node "^0.3.9" eslint-module-utils "^2.8.0" - has "^1.0.3" - is-core-module "^2.12.1" + hasown "^2.0.0" + is-core-module "^2.13.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.fromentries "^2.0.6" - object.groupby "^1.0.0" - object.values "^1.1.6" - resolve "^1.22.3" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" semver "^6.3.1" tsconfig-paths "^3.14.2" @@ -2141,10 +2241,10 @@ eslint-plugin-node@^11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-prettier@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a" - integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== +eslint-plugin-prettier@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz#a3b399f04378f79f066379f544e42d6b73f11515" + integrity sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg== dependencies: prettier-linter-helpers "^1.0.0" synckit "^0.8.5" @@ -2224,18 +2324,19 @@ eslint-visitor-keys@^3.4.3: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@8.47.0: - version "8.47.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.47.0.tgz#c95f9b935463fb4fad7005e626c7621052e90806" - integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q== +eslint@8.52.0: + version "8.52.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" + integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "^8.47.0" - "@humanwhocodes/config-array" "^0.11.10" + "@eslint/js" "8.52.0" + "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2341,17 +2442,16 @@ expect@^29.0.0: jest-message-util "^29.4.2" jest-util "^29.4.2" -expect@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.2.tgz#7b08e83eba18ddc4a2cf62b5f2d1918f5cd84521" - integrity sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA== +expect@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== dependencies: - "@jest/expect-utils" "^29.6.2" - "@types/node" "*" - jest-get-type "^29.4.3" - jest-matcher-utils "^29.6.2" - jest-message-util "^29.6.2" - jest-util "^29.6.2" + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" @@ -2474,6 +2574,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + function.prototype.name@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" @@ -2484,6 +2589,16 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" @@ -2518,6 +2633,16 @@ get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: has-proto "^1.0.1" has-symbols "^1.0.3" +get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -2671,6 +2796,13 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -2817,13 +2949,20 @@ is-core-module@^2.11.0: dependencies: has "^1.0.3" -is-core-module@^2.12.1, is-core-module@^2.13.0: +is-core-module@^2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" +is-core-module@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + is-core-module@^2.9.0: version "2.10.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" @@ -2956,7 +3095,7 @@ is-typed-array@^1.1.10: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typed-array@^1.1.9: +is-typed-array@^1.1.12, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== @@ -3010,7 +3149,7 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: +istanbul-lib-instrument@^5.0.4: version "5.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== @@ -3021,6 +3160,17 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" +istanbul-lib-instrument@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz#71e87707e8041428732518c6fb5211761753fbdf" + integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + istanbul-lib-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" @@ -3058,83 +3208,83 @@ iterator.prototype@^1.1.0: has-tostringtag "^1.0.0" reflect.getprototypeof "^1.0.3" -jest-changed-files@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" - integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== dependencies: execa "^5.0.0" + jest-util "^29.7.0" p-limit "^3.1.0" -jest-circus@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.6.2.tgz#1e6ffca60151ac66cad63fce34f443f6b5bb4258" - integrity sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw== +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== dependencies: - "@jest/environment" "^29.6.2" - "@jest/expect" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^1.0.0" is-generator-fn "^2.0.0" - jest-each "^29.6.2" - jest-matcher-utils "^29.6.2" - jest-message-util "^29.6.2" - jest-runtime "^29.6.2" - jest-snapshot "^29.6.2" - jest-util "^29.6.2" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" p-limit "^3.1.0" - pretty-format "^29.6.2" + pretty-format "^29.7.0" pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.6.2.tgz#edb381763398d1a292cd1b636a98bfa5644b8fda" - integrity sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q== +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== dependencies: - "@jest/core" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" chalk "^4.0.0" + create-jest "^29.7.0" exit "^0.1.2" - graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.6.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" - prompts "^2.0.1" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" yargs "^17.3.1" -jest-config@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.6.2.tgz#c68723f06b31ca5e63030686e604727d406cd7c3" - integrity sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw== +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.6.2" - "@jest/types" "^29.6.1" - babel-jest "^29.6.2" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.6.2" - jest-environment-node "^29.6.2" - jest-get-type "^29.4.3" - jest-regex-util "^29.4.3" - jest-resolve "^29.6.2" - jest-runner "^29.6.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.6.2" + pretty-format "^29.7.0" slash "^3.0.0" strip-json-comments "^3.1.1" @@ -3148,82 +3298,82 @@ jest-diff@^29.4.2: jest-get-type "^29.4.2" pretty-format "^29.4.2" -jest-diff@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.2.tgz#c36001e5543e82a0805051d3ceac32e6825c1c46" - integrity sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA== +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== dependencies: chalk "^4.0.0" - diff-sequences "^29.4.3" - jest-get-type "^29.4.3" - pretty-format "^29.6.2" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" -jest-docblock@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" - integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== dependencies: detect-newline "^3.0.0" -jest-each@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.6.2.tgz#c9e4b340bcbe838c73adf46b76817b15712d02ce" - integrity sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw== +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" chalk "^4.0.0" - jest-get-type "^29.4.3" - jest-util "^29.6.2" - pretty-format "^29.6.2" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" -jest-environment-node@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.2.tgz#a9ea2cabff39b08eca14ccb32c8ceb924c8bb1ad" - integrity sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ== +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: - "@jest/environment" "^29.6.2" - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.2" - jest-util "^29.6.2" + jest-mock "^29.7.0" + jest-util "^29.7.0" jest-get-type@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.2.tgz#7cb63f154bca8d8f57364d01614477d466fa43fe" integrity sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg== -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-haste-map@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.6.2.tgz#298c25ea5255cfad8b723179d4295cf3a50a70d1" - integrity sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA== +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^29.4.3" - jest-util "^29.6.2" - jest-worker "^29.6.2" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz#e2b307fee78cab091c37858a98c7e1d73cdf5b38" - integrity sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ== +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== dependencies: - jest-get-type "^29.4.3" - pretty-format "^29.6.2" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" jest-matcher-utils@^29.4.2: version "29.4.2" @@ -3235,15 +3385,15 @@ jest-matcher-utils@^29.4.2: jest-get-type "^29.4.2" pretty-format "^29.4.2" -jest-matcher-utils@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz#39de0be2baca7a64eacb27291f0bd834fea3a535" - integrity sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ== +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== dependencies: chalk "^4.0.0" - jest-diff "^29.6.2" - jest-get-type "^29.4.3" - pretty-format "^29.6.2" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" jest-message-util@^29.4.2: version "29.4.2" @@ -3260,142 +3410,142 @@ jest-message-util@^29.4.2: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" - integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.6.2" + pretty-format "^29.7.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.2.tgz#ef9c9b4d38c34a2ad61010a021866dad41ce5e00" - integrity sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg== +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-util "^29.6.2" + jest-util "^29.7.0" jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" - integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== -jest-resolve-dependencies@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz#36435269b6672c256bcc85fb384872c134cc4cf2" - integrity sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w== +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== dependencies: - jest-regex-util "^29.4.3" - jest-snapshot "^29.6.2" + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" -jest-resolve@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.6.2.tgz#f18405fe4b50159b7b6d85e81f6a524d22afb838" - integrity sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw== +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" + jest-haste-map "^29.7.0" jest-pnp-resolver "^1.2.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" resolve "^1.20.0" resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.6.2.tgz#89e8e32a8fef24781a7c4c49cd1cb6358ac7fc01" - integrity sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w== +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== dependencies: - "@jest/console" "^29.6.2" - "@jest/environment" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.4.3" - jest-environment-node "^29.6.2" - jest-haste-map "^29.6.2" - jest-leak-detector "^29.6.2" - jest-message-util "^29.6.2" - jest-resolve "^29.6.2" - jest-runtime "^29.6.2" - jest-util "^29.6.2" - jest-watcher "^29.6.2" - jest-worker "^29.6.2" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.6.2.tgz#692f25e387f982e89ab83270e684a9786248e545" - integrity sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg== +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== dependencies: - "@jest/environment" "^29.6.2" - "@jest/fake-timers" "^29.6.2" - "@jest/globals" "^29.6.2" - "@jest/source-map" "^29.6.0" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" - jest-message-util "^29.6.2" - jest-mock "^29.6.2" - jest-regex-util "^29.4.3" - jest-resolve "^29.6.2" - jest-snapshot "^29.6.2" - jest-util "^29.6.2" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.6.2.tgz#9b431b561a83f2bdfe041e1cab8a6becdb01af9c" - integrity sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA== +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.6.2" + expect "^29.7.0" graceful-fs "^4.2.9" - jest-diff "^29.6.2" - jest-get-type "^29.4.3" - jest-matcher-utils "^29.6.2" - jest-message-util "^29.6.2" - jest-util "^29.6.2" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" natural-compare "^1.4.0" - pretty-format "^29.6.2" + pretty-format "^29.7.0" semver "^7.5.3" jest-util@^29.0.0, jest-util@^29.4.2: @@ -3410,63 +3560,63 @@ jest-util@^29.0.0, jest-util@^29.4.2: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" - integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082" - integrity sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg== +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: - "@jest/types" "^29.6.1" + "@jest/types" "^29.6.3" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.4.3" + jest-get-type "^29.6.3" leven "^3.1.0" - pretty-format "^29.6.2" + pretty-format "^29.7.0" -jest-watcher@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.6.2.tgz#77c224674f0620d9f6643c4cfca186d8893ca088" - integrity sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA== +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== dependencies: - "@jest/test-result" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.6.2" + jest-util "^29.7.0" string-length "^4.0.1" -jest-worker@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.6.2.tgz#682fbc4b6856ad0aa122a5403c6d048b83f3fb44" - integrity sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ== +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" - jest-util "^29.6.2" + jest-util "^29.7.0" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.6.2.tgz#3bd55b9fd46a161b2edbdf5f1d1bd0d1eab76c42" - integrity sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg== +jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== dependencies: - "@jest/core" "^29.6.2" - "@jest/types" "^29.6.1" + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" import-local "^3.0.2" - jest-cli "^29.6.2" + jest-cli "^29.7.0" "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -3515,7 +3665,7 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: +json5@^2.2.1, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -3697,10 +3847,10 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -nise@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.4.tgz#491ce7e7307d4ec546f5a659b2efe94a18b4bbc0" - integrity sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg== +nise@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.5.tgz#f2aef9536280b6c18940e32ba1fbdc770b8964ee" + integrity sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw== dependencies: "@sinonjs/commons" "^2.0.0" "@sinonjs/fake-timers" "^10.0.2" @@ -3750,6 +3900,11 @@ object-inspect@^1.12.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -3791,14 +3946,23 @@ object.fromentries@^2.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" -object.groupby@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.0.tgz#cb29259cf90f37e7bac6437686c1ea8c916d12a9" - integrity sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw== +object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== dependencies: call-bind "^1.0.2" define-properties "^1.2.0" - es-abstract "^1.21.2" + es-abstract "^1.22.1" + +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" get-intrinsic "^1.2.1" object.hasown@^1.1.2: @@ -3818,6 +3982,15 @@ object.values@^1.1.6: define-properties "^1.1.4" es-abstract "^1.20.4" +object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -3969,10 +4142,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.2.tgz#78fcecd6d870551aa5547437cdae39d4701dca5b" - integrity sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ== +prettier@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== pretty-format@^29.0.0, pretty-format@^29.4.2: version "29.4.2" @@ -3983,12 +4156,12 @@ pretty-format@^29.0.0, pretty-format@^29.4.2: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" - integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== +pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: - "@jest/schemas" "^29.6.0" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -4069,6 +4242,15 @@ regexp.prototype.flags@^1.5.0: define-properties "^1.2.0" functions-have-names "^1.2.3" +regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + regexpp@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -4101,7 +4283,7 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e" integrity sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg== -resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.1: +resolve@^1.10.1, resolve@^1.20.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -4110,10 +4292,10 @@ resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.22.3: - version "1.22.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" - integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== +resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" path-parse "^1.0.7" @@ -4157,6 +4339,16 @@ safe-array-concat@^1.0.0: has-symbols "^1.0.3" isarray "^2.0.5" +safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -4195,6 +4387,25 @@ semver@^7.5.4: dependencies: lru-cache "^6.0.0" +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +set-function-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -4221,16 +4432,16 @@ signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -sinon@^15.2.0: - version "15.2.0" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-15.2.0.tgz#5e44d4bc5a9b5d993871137fd3560bebfac27565" - integrity sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw== +sinon@^17.0.0: + version "17.0.0" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-17.0.0.tgz#626fde5d903c16dba16fd52afdb9917508dd26ae" + integrity sha512-p4lJiYKBoOEVUxxVIC9H1MM2znG1/c8gud++I2BauJA5hsz7hHsst35eurNWXTusBsIq66FzOQbZ/uMdpvbPIQ== dependencies: "@sinonjs/commons" "^3.0.0" - "@sinonjs/fake-timers" "^10.3.0" + "@sinonjs/fake-timers" "^11.2.2" "@sinonjs/samsam" "^8.0.0" diff "^5.1.0" - nise "^5.1.4" + nise "^5.1.5" supports-color "^7.2.0" sisteransi@^1.0.5: @@ -4320,6 +4531,15 @@ string.prototype.trim@^1.2.7: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + string.prototype.trimend@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" @@ -4338,6 +4558,15 @@ string.prototype.trimend@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + string.prototype.trimstart@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" @@ -4356,6 +4585,15 @@ string.prototype.trimstart@^1.0.6: define-properties "^1.1.4" es-abstract "^1.20.4" +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -4561,10 +4799,10 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== unbox-primitive@^1.0.2: version "1.0.2" @@ -4576,6 +4814,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici-types@~5.25.1: + version "5.25.3" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" + integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== + update-browserslist-db@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" @@ -4665,6 +4908,17 @@ which-typed-array@^1.1.10, which-typed-array@^1.1.11: gopd "^1.0.1" has-tostringtag "^1.0.0" +which-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + which-typed-array@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" @@ -4706,10 +4960,10 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^8.12.1: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== +ws@^8.14.2: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== y18n@^5.0.5: version "5.0.8" From 3706be8b2f54af7b00d7303f88bd44974bea287d Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Tue, 31 Oct 2023 09:51:13 -0700 Subject: [PATCH 06/43] Fix power search metrics Summary: Move them from programmatic API that is barely used to a central place that handles state updates Reviewed By: lblasa Differential Revision: D50841152 fbshipit-source-id: 7938ae08629ba05736cb7acba5ca2014e2827acc --- .../flipper-plugin/src/ui/data-table/DataTableManager.tsx | 8 +++++--- .../src/ui/data-table/DataTableWithPowerSearchManager.tsx | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/desktop/flipper-plugin/src/ui/data-table/DataTableManager.tsx b/desktop/flipper-plugin/src/ui/data-table/DataTableManager.tsx index 7c659c7c5..55d23cd77 100644 --- a/desktop/flipper-plugin/src/ui/data-table/DataTableManager.tsx +++ b/desktop/flipper-plugin/src/ui/data-table/DataTableManager.tsx @@ -223,6 +223,7 @@ export const dataTableManagerReducer = produce< break; } case 'setSearchValue': { + getFlipperLib().logger.track('usage', 'data-table:filter:search'); draft.searchValue = action.value; draft.previousSearchValue = ''; draft.filterExceptions = undefined; @@ -240,6 +241,7 @@ export const dataTableManagerReducer = produce< break; } case 'toggleSearchValue': { + getFlipperLib().logger.track('usage', 'data-table:filter:toggle-search'); draft.filterExceptions = undefined; if (draft.searchValue) { draft.previousSearchValue = draft.searchValue; @@ -297,6 +299,7 @@ export const dataTableManagerReducer = produce< break; } case 'addColumnFilter': { + getFlipperLib().logger.track('usage', 'data-table:filter:add-column'); draft.filterExceptions = undefined; addColumnFilter( draft.columns, @@ -307,6 +310,7 @@ export const dataTableManagerReducer = produce< break; } case 'removeColumnFilter': { + getFlipperLib().logger.track('usage', 'data-table:filter:remove-column'); draft.filterExceptions = undefined; const column = draft.columns.find((c) => c.key === action.column)!; const index = @@ -321,6 +325,7 @@ export const dataTableManagerReducer = produce< break; } case 'toggleColumnFilter': { + getFlipperLib().logger.track('usage', 'data-table:filter:toggle-column'); draft.filterExceptions = undefined; const column = draft.columns.find((c) => c.key === action.column)!; const index = @@ -486,7 +491,6 @@ export function createDataTableManager( dispatch({type: 'sortColumn', column, direction}); }, setSearchValue(value, addToHistory = false) { - getFlipperLib().logger.track('usage', 'data-table:filter:search'); dispatch({type: 'setSearchValue', value, addToHistory}); }, toggleSearchValue() { @@ -508,11 +512,9 @@ export function createDataTableManager( dispatch({type: 'setShowNumberedHistory', showNumberedHistory}); }, addColumnFilter(column, value, options = {}) { - getFlipperLib().logger.track('usage', 'data-table:filter:add-column'); dispatch({type: 'addColumnFilter', column, value, options}); }, removeColumnFilter(column, label) { - getFlipperLib().logger.track('usage', 'data-table:filter:remove-column'); dispatch({type: 'removeColumnFilter', column, label}); }, setFilterExceptions(exceptions: string[] | undefined) { diff --git a/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx b/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx index 76421bf86..897d02d0f 100644 --- a/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx +++ b/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx @@ -303,7 +303,6 @@ export function createDataTableManager( dispatch({type: 'sortColumn', column, direction}); }, setSearchExpression(searchExpression) { - getFlipperLib().logger.track('usage', 'data-table:power-search:search'); dispatch({type: 'setSearchExpression', searchExpression}); }, toggleSideBySide() { From 43530e3bbf2be123cb4831388e3a7b28eee9a0ca Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Wed, 1 Nov 2023 03:38:11 -0700 Subject: [PATCH 07/43] Upgrade compose deps (#5247) Summary: [android][sample] Upgrade compose deps Was dependent on SDK 34. Pull Request resolved: https://github.com/facebook/flipper/pull/5247 Test Plan: --- Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/flipper/pull/5247). * __->__ https://github.com/facebook/flipper/issues/5247 * https://github.com/facebook/flipper/issues/5246 * https://github.com/facebook/flipper/issues/5245 Reviewed By: lblasa Differential Revision: D50599220 Pulled By: passy fbshipit-source-id: 54038274ba894264c4027e48799ce6d0ceda4e82 --- android/sample/build.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/android/sample/build.gradle b/android/sample/build.gradle index 073924107..dadc3b5fc 100644 --- a/android/sample/build.gradle +++ b/android/sample/build.gradle @@ -75,13 +75,13 @@ dependencies { // Compose implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.activity:activity-ktx:1.7.2' - implementation 'androidx.compose.runtime:runtime:1.4.3' - implementation 'androidx.activity:activity-compose:1.7.2' - implementation 'androidx.compose.ui:ui:1.4.3' - implementation 'androidx.compose.material3:material3:1.1.1' - implementation 'androidx.compose.ui:ui-tooling:1.4.3' - implementation 'androidx.compose.ui:ui-tooling-preview:1.4.3' + implementation 'androidx.activity:activity-ktx:1.8.0' + implementation 'androidx.compose.runtime:runtime:1.5.4' + implementation 'androidx.activity:activity-compose:1.8.0' + implementation 'androidx.compose.ui:ui:1.5.4' + implementation 'androidx.compose.material3:material3:1.1.2' + implementation 'androidx.compose.ui:ui-tooling:1.5.4' + implementation 'androidx.compose.ui:ui-tooling-preview:1.5.4' // Third-party implementation deps.soloader From 6dd1fcd5691fd5776d0be6071435550da2358402 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Wed, 1 Nov 2023 04:44:48 -0700 Subject: [PATCH 08/43] Set x64 default architecture and .pkg target for RN-only builds Summary: These are local changes required to make an installer for the last RN-only Electron distribution of Flipper. Instead of just throwing this away, let's keep it in the history of the repository, just in case. Reviewed By: passy Differential Revision: D50838207 fbshipit-source-id: 4966e046161e24a616c04d5cf57fee2512f06525 --- desktop/scripts/build-release.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/desktop/scripts/build-release.tsx b/desktop/scripts/build-release.tsx index 8bdafe38f..8e79ee791 100755 --- a/desktop/scripts/build-release.tsx +++ b/desktop/scripts/build-release.tsx @@ -211,15 +211,20 @@ async function buildDist(buildFolder: string) { const postBuildCallbacks: (() => void)[] = []; if (argv.mac || argv['mac-dmg']) { - targetsRaw.push(Platform.MAC.createTarget(['dir'])); - // You can build mac apps on Linux but can't build dmgs, so we separate those. - if (argv['mac-dmg']) { - targetsRaw.push(Platform.MAC.createTarget(['dmg'])); - } - const macPath = path.join( + let macPath = path.join( distDir, process.arch === 'arm64' ? 'mac-arm64' : 'mac', ); + if (argv['react-native-only']) { + targetsRaw.push(Platform.MAC.createTarget(['pkg'], Arch.x64)); + macPath = path.join(distDir, 'mac'); + } else { + targetsRaw.push(Platform.MAC.createTarget(['dir'])); + // You can build mac apps on Linux but can't build dmgs, so we separate those. + if (argv['mac-dmg']) { + targetsRaw.push(Platform.MAC.createTarget(['dmg'])); + } + } postBuildCallbacks.push(() => spawn('zip', ['-qyr9', '../Flipper-mac.zip', 'Flipper.app'], { cwd: macPath, From 7bbc386d715464fe33b24613244122de2852db57 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005306973 Date: Wed, 1 Nov 2023 05:11:58 -0700 Subject: [PATCH 09/43] Flipper Release: v0.234.0 Summary: Releasing version 0.234.0 Reviewed By: aigoncharov Differential Revision: D50878230 fbshipit-source-id: 79a2a01b4e881ae6b97e3616057e759fd4f73c64 --- desktop/package.json | 2 +- desktop/plugins/public/layout/docs/setup.mdx | 2 +- desktop/plugins/public/leak_canary/docs/setup.mdx | 2 +- desktop/plugins/public/network/docs/setup.mdx | 2 +- desktop/static/CHANGELOG.md | 6 ++++++ docs/getting-started/android-native.mdx | 4 ++-- docs/getting-started/react-native-ios.mdx | 2 +- docs/getting-started/react-native.mdx | 4 ++-- gradle.properties | 2 +- js/js-flipper/package.json | 2 +- react-native/react-native-flipper/package.json | 2 +- 11 files changed, 18 insertions(+), 12 deletions(-) diff --git a/desktop/package.json b/desktop/package.json index 5c7d49f02..eebe66ef3 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -170,7 +170,7 @@ "npm": "use yarn instead", "yarn": "^1.16" }, - "version": "0.233.0", + "version": "0.234.0", "workspaces": { "packages": [ "scripts", diff --git a/desktop/plugins/public/layout/docs/setup.mdx b/desktop/plugins/public/layout/docs/setup.mdx index 4113641eb..215a2c471 100644 --- a/desktop/plugins/public/layout/docs/setup.mdx +++ b/desktop/plugins/public/layout/docs/setup.mdx @@ -27,7 +27,7 @@ You also need to compile in the `litho-annotations` package, as Flipper reflects ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-litho-plugin:0.233.0' + debugImplementation 'com.facebook.flipper:flipper-litho-plugin:0.234.0' debugImplementation 'com.facebook.litho:litho-annotations:0.19.0' // ... } diff --git a/desktop/plugins/public/leak_canary/docs/setup.mdx b/desktop/plugins/public/leak_canary/docs/setup.mdx index 6cdc3ba7a..0ddd787ca 100644 --- a/desktop/plugins/public/leak_canary/docs/setup.mdx +++ b/desktop/plugins/public/leak_canary/docs/setup.mdx @@ -8,7 +8,7 @@ To setup the LeakCan ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-leakcanary2-plugin:0.233.0' + debugImplementation 'com.facebook.flipper:flipper-leakcanary2-plugin:0.234.0' debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' } ``` diff --git a/desktop/plugins/public/network/docs/setup.mdx b/desktop/plugins/public/network/docs/setup.mdx index 7f81f9b11..15595c108 100644 --- a/desktop/plugins/public/network/docs/setup.mdx +++ b/desktop/plugins/public/network/docs/setup.mdx @@ -12,7 +12,7 @@ The network plugin is shipped as a separate Maven artifact, as follows: ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.233.0' + debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.234.0' } ``` diff --git a/desktop/static/CHANGELOG.md b/desktop/static/CHANGELOG.md index 01c2da1f3..93ffb478a 100644 --- a/desktop/static/CHANGELOG.md +++ b/desktop/static/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.234.0 (1/11/2023) + + * [D50595987](https://github.com/facebook/flipper/search?q=D50595987&type=Commits) - UIDebugger, new sidebar design + * [D50599215](https://github.com/facebook/flipper/search?q=D50599215&type=Commits) - Android SDK is now built against SDK 34 + + # 0.223.0 (2/10/2023) * [D49704398](https://github.com/facebook/flipper/search?q=D49704398&type=Commits) - UIDebugger: improvements to iOS Accessibility mode diff --git a/docs/getting-started/android-native.mdx b/docs/getting-started/android-native.mdx index 64af14c22..8c682d141 100644 --- a/docs/getting-started/android-native.mdx +++ b/docs/getting-started/android-native.mdx @@ -24,10 +24,10 @@ repositories { } dependencies { - debugImplementation 'com.facebook.flipper:flipper:0.233.0' + debugImplementation 'com.facebook.flipper:flipper:0.234.0' debugImplementation 'com.facebook.soloader:soloader:0.10.5' - releaseImplementation 'com.facebook.flipper:flipper-noop:0.233.0' + releaseImplementation 'com.facebook.flipper:flipper-noop:0.234.0' } ``` diff --git a/docs/getting-started/react-native-ios.mdx b/docs/getting-started/react-native-ios.mdx index 83ff1232e..06aedb907 100644 --- a/docs/getting-started/react-native-ios.mdx +++ b/docs/getting-started/react-native-ios.mdx @@ -51,7 +51,7 @@ Add all of the code below to your `ios/Podfile`: platform :ios, '9.0' def flipper_pods() - flipperkit_version = '0.233.0' # should match the version of your Flipper client app + flipperkit_version = '0.234.0' # should match the version of your Flipper client app pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug' diff --git a/docs/getting-started/react-native.mdx b/docs/getting-started/react-native.mdx index 79f3de193..fbb6403bd 100644 --- a/docs/getting-started/react-native.mdx +++ b/docs/getting-started/react-native.mdx @@ -34,7 +34,7 @@ Latest version of Flipper requires react-native 0.69+! If you use react-native < Android: -1. Bump the `FLIPPER_VERSION` variable in `android/gradle.properties`, for example: `FLIPPER_VERSION=0.233.0`. +1. Bump the `FLIPPER_VERSION` variable in `android/gradle.properties`, for example: `FLIPPER_VERSION=0.234.0`. 2. Run `./gradlew clean` in the `android` directory. iOS: @@ -44,7 +44,7 @@ react-native version => 0.69.0 2. Run `pod install --repo-update` in the `ios` directory. react-native version < 0.69.0 -1. Call `use_flipper` with a specific version in `ios/Podfile`, for example: `use_flipper!({ 'Flipper' => '0.233.0' })`. +1. Call `use_flipper` with a specific version in `ios/Podfile`, for example: `use_flipper!({ 'Flipper' => '0.234.0' })`. 2. Run `pod install --repo-update` in the `ios` directory. ## Manual Setup diff --git a/gradle.properties b/gradle.properties index 15ff2bb5b..3ca0fa5c5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # POM publishing constants -VERSION_NAME=0.233.1-SNAPSHOT +VERSION_NAME=0.234.0 GROUP=com.facebook.flipper SONATYPE_STAGING_PROFILE=comfacebook POM_URL=https://github.com/facebook/flipper diff --git a/js/js-flipper/package.json b/js/js-flipper/package.json index c05e539a8..24e99e831 100644 --- a/js/js-flipper/package.json +++ b/js/js-flipper/package.json @@ -1,7 +1,7 @@ { "name": "js-flipper", "title": "JS Flipper Bindings for Web-Socket based clients", - "version": "0.233.0", + "version": "0.234.0", "main": "lib/index.js", "browser": { "os": false diff --git a/react-native/react-native-flipper/package.json b/react-native/react-native-flipper/package.json index 27428c3c0..641564766 100644 --- a/react-native/react-native-flipper/package.json +++ b/react-native/react-native-flipper/package.json @@ -1,7 +1,7 @@ { "name": "react-native-flipper", "title": "React Native Flipper Bindings", - "version": "0.233.0", + "version": "0.234.0", "description": "Flipper bindings for React Native", "main": "index.js", "types": "index.d.ts", From 0f3f4de25e528c06bf461dde9b55561c2f50105b Mon Sep 17 00:00:00 2001 From: generatedunixname89002005306973 Date: Wed, 1 Nov 2023 05:11:58 -0700 Subject: [PATCH 10/43] Flipper Snapshot Bump: v0.234.1-SNAPSHOT Summary: Releasing snapshot version 0.234.1-SNAPSHOT Reviewed By: aigoncharov Differential Revision: D50878229 fbshipit-source-id: 93f70c9b4109746edcedf2f06d4113ca4a776c10 --- docs/getting-started/android-native.mdx | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/android-native.mdx b/docs/getting-started/android-native.mdx index 8c682d141..f9e7e051a 100644 --- a/docs/getting-started/android-native.mdx +++ b/docs/getting-started/android-native.mdx @@ -124,10 +124,10 @@ repositories { } dependencies { - debugImplementation 'com.facebook.flipper:flipper:0.233.1-SNAPSHOT' + debugImplementation 'com.facebook.flipper:flipper:0.234.1-SNAPSHOT' debugImplementation 'com.facebook.soloader:soloader:0.10.5' - releaseImplementation 'com.facebook.flipper:flipper-noop:0.233.1-SNAPSHOT' + releaseImplementation 'com.facebook.flipper:flipper-noop:0.234.1-SNAPSHOT' } ``` diff --git a/gradle.properties b/gradle.properties index 3ca0fa5c5..0004d29b0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # POM publishing constants -VERSION_NAME=0.234.0 +VERSION_NAME=0.234.1-SNAPSHOT GROUP=com.facebook.flipper SONATYPE_STAGING_PROFILE=comfacebook POM_URL=https://github.com/facebook/flipper From 254110bf0278c1e8e68fa1517aa3ab6a0754eee3 Mon Sep 17 00:00:00 2001 From: Brett Lavalla Date: Wed, 1 Nov 2023 05:46:53 -0700 Subject: [PATCH 11/43] Make 'none' AccessibilityRole return the class for View Summary: This changes the default behavior for a "NONE" accessibility role to match Googles implementation in ExploreByTouchHelper (https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/com/android/internal/widget/ExploreByTouchHelper.java;drc=c7585d0e2f27f00c47802a78422228a81cf2c939;l=56?q=ExploreByTouchHelper). This also matches ReactNative's default behavior here as well: https://www.internalfb.com/code/fbsource/[199b5d1c47b224f2891b8cba33da90c5c8714a81]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java?lines=291 A role of "View" is a no-op behind the scenes for accessibility services, but making this a valid string rather than `null` will prevent potential crashed from systems expecting a string value to always exist from the "getClassName" method. For context on how large of a potential problem this is, see this post: https://fb.workplace.com/groups/sbteng/posts/1396301817590446 Reviewed By: ikenwoo Differential Revision: D50864782 fbshipit-source-id: 8b176ed9427f62a1d039b012d10ea889df4777e3 --- .../inspector/descriptors/utils/AccessibilityRoleUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java b/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java index 4ad9ce960..64e75c430 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java +++ b/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java @@ -34,7 +34,7 @@ public class AccessibilityRoleUtil { *

https://github.com/google/talkback/blob/master/compositor/src/main/res/raw/compositor.json */ public enum AccessibilityRole { - NONE(null, ""), + NONE("android.view.View", ""), BUTTON("android.widget.Button", "Button"), CHECK_BOX("android.widget.CompoundButton", "Check box"), DROP_DOWN_LIST("android.widget.Spinner", "Drop down list"), From 620b41b691e281321e627a723e579b0b996c4bbf Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Wed, 1 Nov 2023 06:41:55 -0700 Subject: [PATCH 12/43] Fix npe crash in visibility check Summary: https://fb.workplace.com/groups/443457641253219/permalink/1716178925529425/ we had this stack trace which i belive is because we are accessing the litho view after its been unmounted, this is possible as the attributes fetching is async. To fix we move this part to be sync on the main thread ui-debugger] Client error during traversal: {\n \"nodeName\": \"DeferredProcessing\",\n \"errorType\": \"NullPointerException\",\n \"errorMessage\": \"Attempt to invoke virtual method 'com.facebook.rendercore.extensions.ExtensionState com.facebook.litho.LithoHostListenerCoordinator.getVisibilityExtensionState()' on a null object reference\",\n \"stack\": \"java.lang.NullPointerException: Attempt to invoke virtual method 'com.facebook.rendercore.extensions.ExtensionState com.facebook.litho.LithoHostListenerCoordinator.getVisibilityExtensionState()' on a null object reference\\n\\tat com.facebook.litho.LithoView.getVisibilityExtensionState(LithoView.java:710)\\n\\tat com.facebook.litho.DebugComponent$Companion.isVisible(DebugComponent.kt:406)\\n\\tat com.facebook.flipper.plugins.uidebugger.litho.descriptors.DebugComponentDescriptor.getMountingData(DebugComponentDescriptor.kt:182)\\n\\tat com.facebook.flipper.plugins.uidebugger.litho.descriptors.DebugComponentDescriptor.access$getMountingData(DebugComponentDescriptor.kt:32)\\n\\tat com.facebook.flipper.plugins.uidebugger.litho.descriptors.Debug Reviewed By: adityasharat Differential Revision: D50843793 fbshipit-source-id: 8c1df8b291371fd379cb819df33ed933f36026a6 --- .../litho/descriptors/DebugComponentDescriptor.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt index 6de5e232d..75b114d74 100644 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.uidebugger.litho.descriptors -import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister import com.facebook.flipper.plugins.uidebugger.descriptors.Id import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister @@ -102,10 +101,13 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto override fun getAttributes( node: DebugComponent ): MaybeDeferred> { + + // this accesses the litho view so do this on the main thread + val mountingData = getMountingData(node) + return Deferred { val attributeSections = mutableMapOf() - val mountingData = getMountingData(node) attributeSections[MountingDataId] = InspectableObject(mountingData) val layoutProps = LayoutPropExtractor.getProps(node) @@ -138,9 +140,7 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto } return tags } - - override fun getSnapshot(node: DebugComponent, bitmap: Bitmap?): Bitmap? = null - + override fun getInlineAttributes(node: DebugComponent): Map { val attributes = mutableMapOf() val key = node.key From 9f78eb3f00cc8bf2de8ff2317c152fe1033013fe Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Wed, 1 Nov 2023 06:41:55 -0700 Subject: [PATCH 13/43] Fix NPE in text descriptor Summary: Apparantly this can be null, we have received traversal errors with this in the stacktrace Reviewed By: adityasharat Differential Revision: D50839760 fbshipit-source-id: 8e43f35b2adfa91358924b1e162c53c50b0d855d --- .../uidebugger/litho/descriptors/TextDrawableDescriptor.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt index 0ec132b6e..f131029a9 100644 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/TextDrawableDescriptor.kt @@ -31,7 +31,8 @@ object TextDrawableDescriptor : ChainedDescriptor() { attributeSections: MutableMap ) { val props = - mapOf(TextAttributeId to InspectableValue.Text(node.text.toString())) + mapOf( + TextAttributeId to InspectableValue.Text(node.text?.toString() ?: "null")) attributeSections[SectionId] = InspectableObject(props) } From 6d3ff9d5d9ea8de74875ebe679c08f4a8f7f6bae Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Wed, 1 Nov 2023 07:47:09 -0700 Subject: [PATCH 14/43] Bump Fresco to 3.1.3 (#5252) Summary: [android] Bump Fresco to 3.1.3 --- Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/flipper/pull/5252). * __->__ https://github.com/facebook/flipper/issues/5252 * https://github.com/facebook/flipper/issues/5247 * https://github.com/facebook/flipper/issues/5246 * https://github.com/facebook/flipper/issues/5245 Pull Request resolved: https://github.com/facebook/flipper/pull/5252 Reviewed By: lblasa Differential Revision: D50737888 Pulled By: passy fbshipit-source-id: 18eba6b140abf24ae9b1c4440938b19432b2e620 --- build.gradle | 16 ++++++++-------- gradle.properties | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 1cb548ff4..48fc54c05 100644 --- a/build.gradle +++ b/build.gradle @@ -113,12 +113,12 @@ ext.deps = [ testCore : 'androidx.test:core:1.4.0', testRules : 'androidx.test:rules:1.5.0', // Plugin dependencies - flipperFrescoPlugin: 'com.facebook.fresco:flipper-fresco-plugin:3.1.0', - frescoFlipper : 'com.facebook.fresco:flipper:3.1.0', - frescoStetho : 'com.facebook.fresco:stetho:3.1.0', - fresco : 'com.facebook.fresco:fresco:3.1.0', - frescoUiCommon : 'com.facebook.fresco:ui-common:3.1.0', - frescoVito : 'com.facebook.fresco:vito:3.1.0', - frescoVitoCore : 'com.facebook.fresco:vito-core:3.1.0', - frescoVitoLitho : 'com.facebook.fresco:vito-litho:3.1.0', + flipperFrescoPlugin: "com.facebook.fresco:flipper-fresco-plugin:$FRESCO_VERSION", + frescoFlipper : "com.facebook.fresco:flipper:$FRESCO_VERSION", + frescoStetho : "com.facebook.fresco:stetho:$FRESCO_VERSION", + fresco : "com.facebook.fresco:fresco:$FRESCO_VERSION", + frescoUiCommon : "com.facebook.fresco:ui-common:$FRESCO_VERSION", + frescoVito : "com.facebook.fresco:vito:$FRESCO_VERSION", + frescoVitoCore : "com.facebook.fresco:vito-core:$FRESCO_VERSION", + frescoVitoLitho : "com.facebook.fresco:vito-litho:$FRESCO_VERSION", ] diff --git a/gradle.properties b/gradle.properties index 0004d29b0..0355d5737 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,6 +18,7 @@ POM_DEVELOPER_NAME=facebook POM_ISSUES_URL=https://github.com/facebook/flipper/issues/ # Shared version numbers LITHO_VERSION=0.48.0 +FRESCO_VERSION=3.1.3 ANDROIDX_VERSION=1.3.0 KOTLIN_VERSION=1.8.20 FBJNI_VERSION=0.3.0 From b4f77da11aeb335f2b316852ba9b22c4aaa07e10 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Wed, 1 Nov 2023 07:55:57 -0700 Subject: [PATCH 15/43] Fix unexpected unkown options recognition Summary: #thanks LukeDefeo for helping to debug power search Before: https://pxl.cl/3JFqq Reviewed By: LukeDefeo, lblasa Differential Revision: D50884084 fbshipit-source-id: 4cf76a73704cda3627b3bb5ab170d6e76df977cf --- .../ui/PowerSearch/PowerSearchTermFinder.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx b/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx index c8cc37f7c..208e80fbc 100644 --- a/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx +++ b/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx @@ -65,20 +65,20 @@ export const PowerSearchTermFinder = React.forwardRef< onChange={setSearchTermFinderValue} onBlur={() => { setSearchTermFinderValue(null); - }} - onInputKeyDown={(event) => { - if (event.key === 'Enter') { - if (searchTermFinderValue && onConfirmUnknownOption) { - onConfirmUnknownOption(searchTermFinderValue); - } - setSearchTermFinderValue(null); - } - if (event.key === 'Backspace' && !searchTermFinderValue) { - onBackspacePressWhileEmpty(); - } }}> { + if (event.key === 'Enter') { + if (searchTermFinderValue && onConfirmUnknownOption) { + onConfirmUnknownOption(searchTermFinderValue); + } + setSearchTermFinderValue(null); + } + if (event.key === 'Backspace' && !searchTermFinderValue) { + onBackspacePressWhileEmpty(); + } + }} onPasteCapture={(event) => { const text = event.clipboardData.getData('text/plain'); From 7a6f95d1202287a2a95c5f262d4e99f33d80cbad Mon Sep 17 00:00:00 2001 From: generatedunixname89002005306973 Date: Wed, 1 Nov 2023 10:11:43 -0700 Subject: [PATCH 16/43] Flipper Release: v0.235.0 Summary: Releasing version 0.235.0 Reviewed By: aigoncharov Differential Revision: D50885746 fbshipit-source-id: 582d6c6373ffcd96572ae59f11709bb2d2741c67 --- desktop/package.json | 2 +- desktop/plugins/public/layout/docs/setup.mdx | 2 +- desktop/plugins/public/leak_canary/docs/setup.mdx | 2 +- desktop/plugins/public/network/docs/setup.mdx | 2 +- docs/getting-started/android-native.mdx | 4 ++-- docs/getting-started/react-native-ios.mdx | 2 +- docs/getting-started/react-native.mdx | 4 ++-- gradle.properties | 2 +- js/js-flipper/package.json | 2 +- react-native/react-native-flipper/package.json | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/desktop/package.json b/desktop/package.json index eebe66ef3..7bda8730d 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -170,7 +170,7 @@ "npm": "use yarn instead", "yarn": "^1.16" }, - "version": "0.234.0", + "version": "0.235.0", "workspaces": { "packages": [ "scripts", diff --git a/desktop/plugins/public/layout/docs/setup.mdx b/desktop/plugins/public/layout/docs/setup.mdx index 215a2c471..6952b86b1 100644 --- a/desktop/plugins/public/layout/docs/setup.mdx +++ b/desktop/plugins/public/layout/docs/setup.mdx @@ -27,7 +27,7 @@ You also need to compile in the `litho-annotations` package, as Flipper reflects ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-litho-plugin:0.234.0' + debugImplementation 'com.facebook.flipper:flipper-litho-plugin:0.235.0' debugImplementation 'com.facebook.litho:litho-annotations:0.19.0' // ... } diff --git a/desktop/plugins/public/leak_canary/docs/setup.mdx b/desktop/plugins/public/leak_canary/docs/setup.mdx index 0ddd787ca..4d673f419 100644 --- a/desktop/plugins/public/leak_canary/docs/setup.mdx +++ b/desktop/plugins/public/leak_canary/docs/setup.mdx @@ -8,7 +8,7 @@ To setup the LeakCan ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-leakcanary2-plugin:0.234.0' + debugImplementation 'com.facebook.flipper:flipper-leakcanary2-plugin:0.235.0' debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' } ``` diff --git a/desktop/plugins/public/network/docs/setup.mdx b/desktop/plugins/public/network/docs/setup.mdx index 15595c108..f9f355a37 100644 --- a/desktop/plugins/public/network/docs/setup.mdx +++ b/desktop/plugins/public/network/docs/setup.mdx @@ -12,7 +12,7 @@ The network plugin is shipped as a separate Maven artifact, as follows: ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.234.0' + debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.235.0' } ``` diff --git a/docs/getting-started/android-native.mdx b/docs/getting-started/android-native.mdx index f9e7e051a..be04ef47a 100644 --- a/docs/getting-started/android-native.mdx +++ b/docs/getting-started/android-native.mdx @@ -24,10 +24,10 @@ repositories { } dependencies { - debugImplementation 'com.facebook.flipper:flipper:0.234.0' + debugImplementation 'com.facebook.flipper:flipper:0.235.0' debugImplementation 'com.facebook.soloader:soloader:0.10.5' - releaseImplementation 'com.facebook.flipper:flipper-noop:0.234.0' + releaseImplementation 'com.facebook.flipper:flipper-noop:0.235.0' } ``` diff --git a/docs/getting-started/react-native-ios.mdx b/docs/getting-started/react-native-ios.mdx index 06aedb907..a968f4da9 100644 --- a/docs/getting-started/react-native-ios.mdx +++ b/docs/getting-started/react-native-ios.mdx @@ -51,7 +51,7 @@ Add all of the code below to your `ios/Podfile`: platform :ios, '9.0' def flipper_pods() - flipperkit_version = '0.234.0' # should match the version of your Flipper client app + flipperkit_version = '0.235.0' # should match the version of your Flipper client app pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug' diff --git a/docs/getting-started/react-native.mdx b/docs/getting-started/react-native.mdx index fbb6403bd..8dbb900ec 100644 --- a/docs/getting-started/react-native.mdx +++ b/docs/getting-started/react-native.mdx @@ -34,7 +34,7 @@ Latest version of Flipper requires react-native 0.69+! If you use react-native < Android: -1. Bump the `FLIPPER_VERSION` variable in `android/gradle.properties`, for example: `FLIPPER_VERSION=0.234.0`. +1. Bump the `FLIPPER_VERSION` variable in `android/gradle.properties`, for example: `FLIPPER_VERSION=0.235.0`. 2. Run `./gradlew clean` in the `android` directory. iOS: @@ -44,7 +44,7 @@ react-native version => 0.69.0 2. Run `pod install --repo-update` in the `ios` directory. react-native version < 0.69.0 -1. Call `use_flipper` with a specific version in `ios/Podfile`, for example: `use_flipper!({ 'Flipper' => '0.234.0' })`. +1. Call `use_flipper` with a specific version in `ios/Podfile`, for example: `use_flipper!({ 'Flipper' => '0.235.0' })`. 2. Run `pod install --repo-update` in the `ios` directory. ## Manual Setup diff --git a/gradle.properties b/gradle.properties index 0355d5737..81d5e24bc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # POM publishing constants -VERSION_NAME=0.234.1-SNAPSHOT +VERSION_NAME=0.235.0 GROUP=com.facebook.flipper SONATYPE_STAGING_PROFILE=comfacebook POM_URL=https://github.com/facebook/flipper diff --git a/js/js-flipper/package.json b/js/js-flipper/package.json index 24e99e831..153db6da1 100644 --- a/js/js-flipper/package.json +++ b/js/js-flipper/package.json @@ -1,7 +1,7 @@ { "name": "js-flipper", "title": "JS Flipper Bindings for Web-Socket based clients", - "version": "0.234.0", + "version": "0.235.0", "main": "lib/index.js", "browser": { "os": false diff --git a/react-native/react-native-flipper/package.json b/react-native/react-native-flipper/package.json index 641564766..80a69c62a 100644 --- a/react-native/react-native-flipper/package.json +++ b/react-native/react-native-flipper/package.json @@ -1,7 +1,7 @@ { "name": "react-native-flipper", "title": "React Native Flipper Bindings", - "version": "0.234.0", + "version": "0.235.0", "description": "Flipper bindings for React Native", "main": "index.js", "types": "index.d.ts", From 368dfc90f6b0942ffcb1423630e26421f88998ce Mon Sep 17 00:00:00 2001 From: generatedunixname89002005306973 Date: Wed, 1 Nov 2023 10:11:43 -0700 Subject: [PATCH 17/43] Flipper Snapshot Bump: v0.235.1-SNAPSHOT Summary: Releasing snapshot version 0.235.1-SNAPSHOT Reviewed By: aigoncharov Differential Revision: D50885747 fbshipit-source-id: a586315fd281e643298ea22c15758550d49ec845 --- docs/getting-started/android-native.mdx | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/android-native.mdx b/docs/getting-started/android-native.mdx index be04ef47a..cc01bee33 100644 --- a/docs/getting-started/android-native.mdx +++ b/docs/getting-started/android-native.mdx @@ -124,10 +124,10 @@ repositories { } dependencies { - debugImplementation 'com.facebook.flipper:flipper:0.234.1-SNAPSHOT' + debugImplementation 'com.facebook.flipper:flipper:0.235.1-SNAPSHOT' debugImplementation 'com.facebook.soloader:soloader:0.10.5' - releaseImplementation 'com.facebook.flipper:flipper-noop:0.234.1-SNAPSHOT' + releaseImplementation 'com.facebook.flipper:flipper-noop:0.235.1-SNAPSHOT' } ``` diff --git a/gradle.properties b/gradle.properties index 81d5e24bc..22aa4764e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # POM publishing constants -VERSION_NAME=0.235.0 +VERSION_NAME=0.235.1-SNAPSHOT GROUP=com.facebook.flipper SONATYPE_STAGING_PROFILE=comfacebook POM_URL=https://github.com/facebook/flipper From 08e742ceff138be9d69e5680099e606f55d9158c Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Wed, 1 Nov 2023 11:15:17 -0700 Subject: [PATCH 18/43] Utility to determine if client is PWA Summary: This is currently used in multiple places, let's put it under utils. Reviewed By: aigoncharov Differential Revision: D50883125 fbshipit-source-id: ee161a035cd01ca73a2521f813c4b397aa647037 --- desktop/flipper-ui-core/src/index.tsx | 2 ++ desktop/flipper-ui-core/src/utils/pwa.tsx | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 desktop/flipper-ui-core/src/utils/pwa.tsx diff --git a/desktop/flipper-ui-core/src/index.tsx b/desktop/flipper-ui-core/src/index.tsx index 83369ac66..9fcd909c3 100644 --- a/desktop/flipper-ui-core/src/index.tsx +++ b/desktop/flipper-ui-core/src/index.tsx @@ -12,3 +12,5 @@ export {RenderHost, getRenderHostInstance} from 'flipper-frontend-core'; export {startFlipperDesktop} from './startFlipperDesktop'; export {Icon} from './utils/icons'; + +export {isPWA} from './utils/pwa'; diff --git a/desktop/flipper-ui-core/src/utils/pwa.tsx b/desktop/flipper-ui-core/src/utils/pwa.tsx new file mode 100644 index 000000000..3a0142db7 --- /dev/null +++ b/desktop/flipper-ui-core/src/utils/pwa.tsx @@ -0,0 +1,12 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +export const isPWA = () => { + return window.matchMedia('(display-mode: standalone)').matches; +}; From 1a9803897969bcbcb316bde9448cd611eff491e4 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Wed, 1 Nov 2023 11:15:17 -0700 Subject: [PATCH 19/43] Use isPWA utility function instead Summary: As a follow-up from the utility created on the previous diff Reviewed By: aigoncharov Differential Revision: D50885337 fbshipit-source-id: 6bc0c942b3d96eb020ec15395f34d5794ba2ae15 --- desktop/flipper-ui-browser/src/index.tsx | 3 ++- desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/desktop/flipper-ui-browser/src/index.tsx b/desktop/flipper-ui-browser/src/index.tsx index f7fcc645e..23efa6733 100644 --- a/desktop/flipper-ui-browser/src/index.tsx +++ b/desktop/flipper-ui-browser/src/index.tsx @@ -15,6 +15,7 @@ import { import {init as initLogger} from './fb-stubs/Logger'; import {initializeRenderHost} from './initializeRenderHost'; import {createFlipperServer, FlipperServerState} from 'flipper-server-client'; +import {isPWA} from 'flipper-ui-core'; const loadingContainer = document.getElementById('loading'); if (loadingContainer) { @@ -151,7 +152,7 @@ start().catch((e) => { logger.track('success-rate', 'flipper-ui-browser-started', { value: 0, error: getStringFromErrorLike(e), - pwa: window.matchMedia('(display-mode: standalone)').matches, + pwa: isPWA(), }); window.flipperShowMessage?.('Failed to start UI with error: ' + e); }); diff --git a/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx b/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx index 84ce4f5d2..9e3f648d6 100644 --- a/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx +++ b/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx @@ -12,6 +12,7 @@ import {Image, Modal, Button} from 'antd'; import {getFlipperLib, Layout, _NuxManagerContext} from 'flipper-plugin'; import {getRenderHostInstance} from 'flipper-frontend-core'; import isProduction from '../utils/isProduction'; +import {isPWA} from '../utils/pwa'; type Props = { onHide: () => void; @@ -55,7 +56,7 @@ export function shouldShowPWAInstallationWizard(): boolean { return false; } - if (window.matchMedia('(display-mode: standalone)').matches) { + if (isPWA()) { tracker.track('pwa-installation-wizard-should-show', { show: false, reason: 'Display mode is standalone, seems is already running as PWA', From c8ee1847a22b693a4943fb91f10c73094cfea24d Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 2 Nov 2023 03:31:35 -0700 Subject: [PATCH 20/43] Flipper browser singleton Summary: This will ensure only one instance of Flipper is running at any given point in time. #thanks antonk52 for guidance and advise implementing a single Flipper instance solution which will improve overall Flipper user experience. Reviewed By: antonk52 Differential Revision: D50455446 fbshipit-source-id: 2407c77d43ba28e91d525f6cdb11d7b9db1cfab7 --- desktop/flipper-ui-browser/src/index.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/desktop/flipper-ui-browser/src/index.tsx b/desktop/flipper-ui-browser/src/index.tsx index 23efa6733..126b07f30 100644 --- a/desktop/flipper-ui-browser/src/index.tsx +++ b/desktop/flipper-ui-browser/src/index.tsx @@ -28,6 +28,16 @@ let cachedDeepLinkURL: string | undefined; const logger = initLogger(); async function start() { + /** + * The following is used to ensure only one instance of Flipper is running at a time. + * The event will not be fired for the current tab. + */ + window.addEventListener('storage', function (event) { + if (event.key === 'flipper-kill-window') { + window.close(); + } + }); + // @ts-ignore electronRequire = function (path: string) { console.error( @@ -143,6 +153,12 @@ async function start() { require('flipper-ui-core').startFlipperDesktop(flipperServer); window.flipperHideMessage?.(); + /** + * At this stage, the current client has established a connection with the server. + * So, it is safe to 'set' into local storage so that other clients close. + */ + localStorage.setItem('flipper-kill-window', Date.now().toString()); + getLogger().info('[flipper-client][ui-browser] UI initialised'); logger.track('success-rate', 'flipper-ui-browser-started', {value: 1}); } From e72dcbb28d890f3bd81e2b2d0202ce9cda73f0c0 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005325672 Date: Thu, 2 Nov 2023 03:41:53 -0700 Subject: [PATCH 21/43] Daily `arc lint --take KTFMT` Reviewed By: martintrojer Differential Revision: D50925513 fbshipit-source-id: 1b964b758c53d6d490bd6c7f76d003c0afecfc70 --- .../uidebugger/litho/descriptors/DebugComponentDescriptor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt index 75b114d74..f2f400a04 100644 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/DebugComponentDescriptor.kt @@ -140,7 +140,7 @@ class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescripto } return tags } - + override fun getInlineAttributes(node: DebugComponent): Map { val attributes = mutableMapOf() val key = node.key From fecaa8d9743e6a7bbba34cd0a722b800cb4121e4 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 2 Nov 2023 04:28:14 -0700 Subject: [PATCH 22/43] Back out "Use isPWA utility function instead" Summary: Original commit changeset: 6bc0c942b3d9 Original Phabricator Diff: D50885337 There's an issue with the import, same reason we do: ``` require('flipper-ui-core').startFlipperDesktop(flipperServer); ``` Reviewed By: aigoncharov Differential Revision: D50926125 fbshipit-source-id: 04e1b920bcecab9f245924907637b36dac312f1f --- desktop/flipper-ui-browser/src/index.tsx | 3 +-- desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/desktop/flipper-ui-browser/src/index.tsx b/desktop/flipper-ui-browser/src/index.tsx index 126b07f30..fbbf974e4 100644 --- a/desktop/flipper-ui-browser/src/index.tsx +++ b/desktop/flipper-ui-browser/src/index.tsx @@ -15,7 +15,6 @@ import { import {init as initLogger} from './fb-stubs/Logger'; import {initializeRenderHost} from './initializeRenderHost'; import {createFlipperServer, FlipperServerState} from 'flipper-server-client'; -import {isPWA} from 'flipper-ui-core'; const loadingContainer = document.getElementById('loading'); if (loadingContainer) { @@ -168,7 +167,7 @@ start().catch((e) => { logger.track('success-rate', 'flipper-ui-browser-started', { value: 0, error: getStringFromErrorLike(e), - pwa: isPWA(), + pwa: window.matchMedia('(display-mode: standalone)').matches, }); window.flipperShowMessage?.('Failed to start UI with error: ' + e); }); diff --git a/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx b/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx index 9e3f648d6..84ce4f5d2 100644 --- a/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx +++ b/desktop/flipper-ui-core/src/chrome/PWAppInstallationWizard.tsx @@ -12,7 +12,6 @@ import {Image, Modal, Button} from 'antd'; import {getFlipperLib, Layout, _NuxManagerContext} from 'flipper-plugin'; import {getRenderHostInstance} from 'flipper-frontend-core'; import isProduction from '../utils/isProduction'; -import {isPWA} from '../utils/pwa'; type Props = { onHide: () => void; @@ -56,7 +55,7 @@ export function shouldShowPWAInstallationWizard(): boolean { return false; } - if (isPWA()) { + if (window.matchMedia('(display-mode: standalone)').matches) { tracker.track('pwa-installation-wizard-should-show', { show: false, reason: 'Display mode is standalone, seems is already running as PWA', From 8f1b4ffa1cda4ac00e17765398a4a1852c3254a8 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 2 Nov 2023 10:42:15 -0700 Subject: [PATCH 23/43] Track UI launches Summary: This is currently done by querying the 'console-log' event. Instead, make it type safe and official. Reviewed By: antonk52 Differential Revision: D50927713 fbshipit-source-id: 780c0f158bf8bdaa6d009035a0cee62c7828f479 --- desktop/flipper-server-core/src/tracker.tsx | 1 + desktop/flipper-server/src/index.tsx | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/desktop/flipper-server-core/src/tracker.tsx b/desktop/flipper-server-core/src/tracker.tsx index 4f69560a7..72836c6e1 100644 --- a/desktop/flipper-server-core/src/tracker.tsx +++ b/desktop/flipper-server-core/src/tracker.tsx @@ -47,6 +47,7 @@ type TrackerEvents = { error?: string; }; 'server-socket-already-in-use': {}; + 'server-open-ui': {browser: boolean; hasToken: boolean}; 'browser-connection-created': { successful: boolean; timeMS: number; diff --git a/desktop/flipper-server/src/index.tsx b/desktop/flipper-server/src/index.tsx index 77ad9e066..ed49dadf6 100644 --- a/desktop/flipper-server/src/index.tsx +++ b/desktop/flipper-server/src/index.tsx @@ -313,6 +313,11 @@ async function launch() { console.info(`[flipper-server] Go to: ${chalk.blue(url.toString())}`); open(url.toString(), {app: {name: open.apps.chrome}}); + + tracker.track('server-open-ui', { + browser: true, + hasToken: token?.length != 0, + }); }; if (argv.bundler) { @@ -320,6 +325,10 @@ async function launch() { } else { const path = await findInstallation(); if (path) { + tracker.track('server-open-ui', { + browser: false, + hasToken: token?.length != 0, + }); open(path); } else { await openInBrowser(); From d5a0c206f241b6979f99870642f85665eb91df41 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 2 Nov 2023 10:42:15 -0700 Subject: [PATCH 24/43] Track WS server error Summary: This is currently done by querying the 'console-log' event. Instead, make it type safe and official. Reviewed By: antonk52 Differential Revision: D50927803 fbshipit-source-id: e0488782dd584e36b6f742f9892fc09ffaf62469 --- .../src/app-connectivity/ServerWebSocket.tsx | 7 ++++--- desktop/flipper-server-core/src/tracker.tsx | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/desktop/flipper-server-core/src/app-connectivity/ServerWebSocket.tsx b/desktop/flipper-server-core/src/app-connectivity/ServerWebSocket.tsx index 0e882e26d..100ba2d48 100644 --- a/desktop/flipper-server-core/src/app-connectivity/ServerWebSocket.tsx +++ b/desktop/flipper-server-core/src/app-connectivity/ServerWebSocket.tsx @@ -29,6 +29,7 @@ import {Server} from 'net'; import {serializeError} from 'serialize-error'; import {WSCloseCode} from '../utils/WSCloseCode'; import {recorder} from '../recorder'; +import {tracker} from '../tracker'; export interface ConnectionCtx { clientQuery?: ClientQuery; @@ -63,11 +64,11 @@ class ServerWebSocket extends ServerWebSocketBase { // We do not need to listen to http server's `error` because it is propagated to WS // https://github.com/websockets/ws/blob/a3a22e4ed39c1a3be8e727e9c630dd440edc61dd/lib/websocket-server.js#L109 const onConnectionError = (error: Error) => { + const message = JSON.stringify(serializeError(error)); + tracker.track('server-ws-server-error', {port, error: message}); reject( new Error( - `Unable to start server at port ${port} due to ${JSON.stringify( - serializeError(error), - )}`, + `Unable to start server at port ${port} due to ${message}`, ), ); }; diff --git a/desktop/flipper-server-core/src/tracker.tsx b/desktop/flipper-server-core/src/tracker.tsx index 72836c6e1..e3db6228d 100644 --- a/desktop/flipper-server-core/src/tracker.tsx +++ b/desktop/flipper-server-core/src/tracker.tsx @@ -48,6 +48,7 @@ type TrackerEvents = { }; 'server-socket-already-in-use': {}; 'server-open-ui': {browser: boolean; hasToken: boolean}; + 'server-ws-server-error': {port: number; error: string}; 'browser-connection-created': { successful: boolean; timeMS: number; From afae1bd141406af57fd97934db810ebaa3f600d5 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 2 Nov 2023 10:42:15 -0700 Subject: [PATCH 25/43] Track unable to become ready within timeout Summary: This is currently done by querying the 'console-log' event. Instead, make it type safe and official. Reviewed By: antonk52 Differential Revision: D50927954 fbshipit-source-id: ff767acdc51b942c6deb92ffbfd93288b3367062 --- desktop/flipper-server-core/src/server/startServer.tsx | 1 + desktop/flipper-server-core/src/tracker.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/desktop/flipper-server-core/src/server/startServer.tsx b/desktop/flipper-server-core/src/server/startServer.tsx index 66bcf1f5f..5b7a4420b 100644 --- a/desktop/flipper-server-core/src/server/startServer.tsx +++ b/desktop/flipper-server-core/src/server/startServer.tsx @@ -110,6 +110,7 @@ export async function startServer( }> { setTimeout(() => { if (!isReady && isProduction()) { + tracker.track('server-ready-timeout', {timeout: timeoutSeconds}); console.error( `[flipper-server] Unable to become ready within ${timeoutSeconds} seconds, exit`, ); diff --git a/desktop/flipper-server-core/src/tracker.tsx b/desktop/flipper-server-core/src/tracker.tsx index e3db6228d..dd5ba2067 100644 --- a/desktop/flipper-server-core/src/tracker.tsx +++ b/desktop/flipper-server-core/src/tracker.tsx @@ -49,6 +49,7 @@ type TrackerEvents = { 'server-socket-already-in-use': {}; 'server-open-ui': {browser: boolean; hasToken: boolean}; 'server-ws-server-error': {port: number; error: string}; + 'server-ready-timeout': {timeout: number}; 'browser-connection-created': { successful: boolean; timeMS: number; From 87cb9bd77ab3a9ce78a2e8db02c4f2ab1b87be25 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Thu, 2 Nov 2023 10:42:15 -0700 Subject: [PATCH 26/43] Track state changes Summary: Track server connectivity state changes, queries will follow. Reviewed By: antonk52 Differential Revision: D50928297 fbshipit-source-id: 9f3a3b799481556bab7339d710736448fed6004c --- desktop/flipper-ui-browser/src/index.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/desktop/flipper-ui-browser/src/index.tsx b/desktop/flipper-ui-browser/src/index.tsx index fbbf974e4..d6c4b018e 100644 --- a/desktop/flipper-ui-browser/src/index.tsx +++ b/desktop/flipper-ui-browser/src/index.tsx @@ -97,11 +97,18 @@ async function start() { getLogger().info('[flipper-client][ui-browser] Create WS client'); + let lastStateChangeMS = performance.now(); const flipperServer = await createFlipperServer( location.hostname, parseInt(location.port, 10), tokenProvider, (state: FlipperServerState) => { + const timestamp = performance.now(); + getLogger().track('usage', 'browser-server-state-changed', { + state, + timeElapsedMS: timestamp - lastStateChangeMS, + }); + lastStateChangeMS = timestamp; switch (state) { case FlipperServerState.CONNECTING: getLogger().info('[flipper-client] Connecting to server'); From c93c494ef448cbd50f558bc554a74230cb6cdc66 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 27/43] Refactor android view observation Summary: The previous approach was designed for a world that didnt happen and was extremely confusing and allowed for states that didnt make a lot of sense. E.g it was possible we were snapshotting multiple views. The new model is much simpler. we still depend on the root view resolver to tell us about root decor views but now we just attach a predraw listener to the top most view and push out the updates. This is handled by the new class decor view tracker which is a replacement for all the observer business Additionally we use a conflated chanel in the update queue, this means if the background processing is slow we wont keep adding new frames to the queue, we just keep 1 and the most recent frame Partial layout traversal -> Layout traversal as traversal is now always from top to bottom of the whole application Reviewed By: lblasa Differential Revision: D50791527 fbshipit-source-id: 43640723aefa775aa7b74065f405cc08224ed8b8 --- .../flipper/sample/FlipperInitializer.java | 2 - .../uidebugger/UIDebuggerFlipperPlugin.kt | 7 +- .../plugins/uidebugger/core/ApplicationRef.kt | 3 +- .../uidebugger/core/DecorViewTracker.kt | 114 ++++++++++ .../LayoutTraversal.kt} | 17 +- .../plugins/uidebugger/core/UIDContext.kt | 12 +- .../plugins/uidebugger/core/UpdateQueue.kt | 166 ++++++++++++++ .../plugins/uidebugger/model/Events.kt | 1 - .../observers/ApplicationTreeObserver.kt | 60 ------ .../observers/DecorViewTreeObserver.kt | 91 -------- .../uidebugger/observers/TreeObserver.kt | 115 ---------- .../observers/TreeObserverFactory.kt | 45 ---- .../observers/TreeObserverManager.kt | 203 ------------------ .../uidebugger/scheduler/SharedThrottle.kt | 74 ------- .../plugins/uidebugger/util/StopWatch.kt | 30 +++ .../plugins/uidebugger/util/Throttler.kt | 34 +++ 16 files changed, 359 insertions(+), 615 deletions(-) create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt rename android/src/main/java/com/facebook/flipper/plugins/uidebugger/{traversal/PartialLayoutTraversal.kt => core/LayoutTraversal.kt} (86%) create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt delete mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/ApplicationTreeObserver.kt delete mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/DecorViewTreeObserver.kt delete mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserver.kt delete mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverFactory.kt delete mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverManager.kt delete mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/scheduler/SharedThrottle.kt create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt diff --git a/android/sample/src/debug/java/com/facebook/flipper/sample/FlipperInitializer.java b/android/sample/src/debug/java/com/facebook/flipper/sample/FlipperInitializer.java index 6ac940110..76a8c20f2 100644 --- a/android/sample/src/debug/java/com/facebook/flipper/sample/FlipperInitializer.java +++ b/android/sample/src/debug/java/com/facebook/flipper/sample/FlipperInitializer.java @@ -26,7 +26,6 @@ import com.facebook.flipper.plugins.uidebugger.UIDebuggerFlipperPlugin; import com.facebook.flipper.plugins.uidebugger.core.UIDContext; import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister; import com.facebook.flipper.plugins.uidebugger.litho.UIDebuggerLithoSupport; -import com.facebook.flipper.plugins.uidebugger.observers.TreeObserverFactory; import com.facebook.litho.config.ComponentsConfiguration; import com.facebook.litho.editor.flipper.LithoFlipperDescriptors; import java.util.Arrays; @@ -63,7 +62,6 @@ public final class FlipperInitializer { client.addPlugin(NavigationFlipperPlugin.getInstance()); DescriptorRegister descriptorRegister = DescriptorRegister.Companion.withDefaults(); - TreeObserverFactory treeObserverFactory = TreeObserverFactory.Companion.withDefaults(); UIDContext uidContext = UIDContext.Companion.create((Application) context); UIDebuggerLithoSupport.INSTANCE.enable(uidContext); UIDebuggerComposeSupport.INSTANCE.enable(uidContext); diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/UIDebuggerFlipperPlugin.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/UIDebuggerFlipperPlugin.kt index 003c51d8b..df2c25396 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/UIDebuggerFlipperPlugin.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/UIDebuggerFlipperPlugin.kt @@ -48,7 +48,8 @@ class UIDebuggerFlipperPlugin(val context: UIDContext) : FlipperPlugin { MetadataUpdateEvent.serializer(), MetadataUpdateEvent(MetadataRegister.extractPendingMetadata()))) - context.treeObserverManager.start() + context.updateQueue.start() + context.decorViewTracker.start() context.connectionListeners.forEach { it.onConnect() } } @@ -59,7 +60,9 @@ class UIDebuggerFlipperPlugin(val context: UIDContext) : FlipperPlugin { MetadataRegister.reset() - context.treeObserverManager.stop() + context.decorViewTracker.stop() + context.updateQueue.stop() + context.bitmapPool.recycleAll() context.connectionListeners.forEach { it.onDisconnect() } context.clearFrameworkEvents() diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt index 1886cec59..82663d432 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt @@ -17,7 +17,8 @@ class ApplicationRef(val application: Application) { // the root view resolver will contain all root views 100% It is needed for 2 cases: // 1. In some cases an activity will not be picked up by the activity tracker, - // the root view resolver will at least find the decor view + // the root view resolver will at least find the decor view, this is the case for various + // kinds of custom overlays // 2. Dialog fragments val rootsResolver: RootViewResolver = RootViewResolver() diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt new file mode 100644 index 000000000..c4e98e59e --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt @@ -0,0 +1,114 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.core + +import android.util.Log +import android.view.View +import android.view.ViewTreeObserver +import com.facebook.flipper.plugins.uidebugger.LogTag +import com.facebook.flipper.plugins.uidebugger.common.BitmapPool +import com.facebook.flipper.plugins.uidebugger.descriptors.ViewDescriptor +import com.facebook.flipper.plugins.uidebugger.util.StopWatch +import com.facebook.flipper.plugins.uidebugger.util.Throttler +import com.facebook.flipper.plugins.uidebugger.util.objectIdentity + +/** + * The responsibility of this class is to find the top most decor view and add a pre draw observer + * to it This predraw observer triggers a full traversal of the UI. There should only ever be one + * active predraw listener at once + */ +class DecorViewTracker(val context: UIDContext) { + + private var currentDecorView: View? = null + private var preDrawListener: ViewTreeObserver.OnPreDrawListener? = null + private val mStopWatch = StopWatch() + + fun start() { + Log.i(LogTag, "Subscribing activity / root view changes") + + val applicationRef = context.applicationRef + + val rootViewListener = + object : RootViewResolver.Listener { + override fun onRootViewAdded(rootView: View) {} + + override fun onRootViewRemoved(rootView: View) {} + + override fun onRootViewsChanged(rootViews: List) { + // remove predraw listen from current view as its going away or will be covered + currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener) + + // setup new listener on top most view + val topView = rootViews.lastOrNull() + val throttler = Throttler(500) { currentDecorView?.let { traverseSnapshotAndSend(it) } } + + if (topView != null) { + preDrawListener = + ViewTreeObserver.OnPreDrawListener { + throttler.trigger() + true + } + + topView.viewTreeObserver.addOnPreDrawListener(preDrawListener) + currentDecorView = topView + + Log.i(LogTag, "Added pre draw listener to ${topView.objectIdentity()}") + + // schedule traversal immediately when we detect a new decor view + throttler.trigger() + } else { + Log.i(LogTag, "Stack is empty") + } + } + } + + context.applicationRef.rootsResolver.attachListener(rootViewListener) + // On subscribe, trigger a traversal on whatever roots we have + rootViewListener.onRootViewsChanged(applicationRef.rootsResolver.rootViews()) + + Log.i(LogTag, "${context.applicationRef.rootsResolver.rootViews().size} root views") + Log.i(LogTag, "${context.applicationRef.activitiesStack.size} activities") + } + + fun stop() { + context.applicationRef.rootsResolver.attachListener(null) + currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener) + currentDecorView = null + preDrawListener = null + } + + private fun traverseSnapshotAndSend(decorView: View) { + + val startTimestamp = System.currentTimeMillis() + val (nodes, traversalTime) = + StopWatch.time { context.layoutTraversal.traverse(context.applicationRef) } + + mStopWatch.start() + var snapshotBitmap: BitmapPool.ReusableBitmap? = null + if (decorView.width > 0 && decorView.height > 0) { + snapshotBitmap = context.bitmapPool.getBitmap(decorView.width, decorView.height) + context.bitmapPool.getBitmap(decorView.width, decorView.height) + Log.i( + LogTag, + "Snapshotting view ${ViewDescriptor.getId(decorView)}", + ) + ViewDescriptor.getSnapshot(decorView, snapshotBitmap.bitmap) + } + val snapshotTime = mStopWatch.stop() + + context.updateQueue.enqueueUpdate( + Update( + ViewDescriptor.getId(decorView), + nodes, + startTimestamp, + traversalTime, + snapshotTime, + System.currentTimeMillis(), + snapshotBitmap)) + } +} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/traversal/PartialLayoutTraversal.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt similarity index 86% rename from android/src/main/java/com/facebook/flipper/plugins/uidebugger/traversal/PartialLayoutTraversal.kt rename to android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt index fd724ee57..2f228bab3 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/traversal/PartialLayoutTraversal.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/LayoutTraversal.kt @@ -5,11 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.flipper.plugins.uidebugger.traversal +package com.facebook.flipper.plugins.uidebugger.core import android.util.Log import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.core.UIDContext import com.facebook.flipper.plugins.uidebugger.descriptors.Id import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor import com.facebook.flipper.plugins.uidebugger.model.Node @@ -23,21 +22,20 @@ import com.facebook.flipper.plugins.uidebugger.util.MaybeDeferred * - The first item in the pair is the visited nodes. * - The second item are any observable roots discovered. */ -class PartialLayoutTraversal( +class LayoutTraversal( private val context: UIDContext, ) { @Suppress("unchecked_cast") private fun NodeDescriptor<*>.asAny(): NodeDescriptor = this as NodeDescriptor - fun traverse(root: Any, parentId: Id?): Pair>, List>> { + fun traverse(root: Any): MutableList> { val visited = mutableListOf>() - val observableRoots = mutableListOf>() // cur and parent Id val stack = mutableListOf>() - stack.add(Pair(root, parentId)) + stack.add(Pair(root, null)) val shallow = mutableSetOf() @@ -45,11 +43,6 @@ class PartialLayoutTraversal( val (node, parentId) = stack.removeLast() try { - // If we encounter a node that has it own observer, don't traverse - if (node != root && context.observerFactory.hasObserverFor(node)) { - observableRoots.add((node to parentId)) - continue - } val descriptor = context.descriptorRegister.descriptorForClassUnsafe(node::class.java).asAny() @@ -126,6 +119,6 @@ class PartialLayoutTraversal( } } - return Pair(visited, observableRoots) + return visited } } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt index bd2a275d3..6c7680322 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt @@ -14,10 +14,6 @@ import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister import com.facebook.flipper.plugins.uidebugger.model.FrameworkEvent import com.facebook.flipper.plugins.uidebugger.model.FrameworkEventMetadata import com.facebook.flipper.plugins.uidebugger.model.TraversalError -import com.facebook.flipper.plugins.uidebugger.observers.TreeObserverFactory -import com.facebook.flipper.plugins.uidebugger.observers.TreeObserverManager -import com.facebook.flipper.plugins.uidebugger.scheduler.SharedThrottle -import com.facebook.flipper.plugins.uidebugger.traversal.PartialLayoutTraversal import kotlinx.serialization.json.Json interface ConnectionListener { @@ -30,16 +26,15 @@ class UIDContext( val applicationRef: ApplicationRef, val connectionRef: ConnectionRef, val descriptorRegister: DescriptorRegister, - val observerFactory: TreeObserverFactory, val frameworkEventMetadata: MutableList, val connectionListeners: MutableList, private val pendingFrameworkEvents: MutableList ) { - val layoutTraversal: PartialLayoutTraversal = PartialLayoutTraversal(this) + val decorViewTracker = DecorViewTracker(this) + val updateQueue = UpdateQueue(this) + val layoutTraversal: LayoutTraversal = LayoutTraversal(this) - val treeObserverManager = TreeObserverManager(this) - val sharedThrottle: SharedThrottle = SharedThrottle() val bitmapPool = BitmapPool() fun addFrameworkEvent(frameworkEvent: FrameworkEvent) { @@ -69,7 +64,6 @@ class UIDContext( ApplicationRef(application), ConnectionRef(null), descriptorRegister = DescriptorRegister.withDefaults(), - observerFactory = TreeObserverFactory.withDefaults(), frameworkEventMetadata = mutableListOf(), connectionListeners = mutableListOf(), pendingFrameworkEvents = mutableListOf()) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt new file mode 100644 index 000000000..d768ea4f3 --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt @@ -0,0 +1,166 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.core + +import android.annotation.SuppressLint +import android.graphics.Bitmap +import android.util.Base64 +import android.util.Base64OutputStream +import android.util.Log +import com.facebook.flipper.plugins.uidebugger.LogTag +import com.facebook.flipper.plugins.uidebugger.common.BitmapPool +import com.facebook.flipper.plugins.uidebugger.descriptors.Id +import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister +import com.facebook.flipper.plugins.uidebugger.model.FrameScanEvent +import com.facebook.flipper.plugins.uidebugger.model.MetadataUpdateEvent +import com.facebook.flipper.plugins.uidebugger.model.Node +import com.facebook.flipper.plugins.uidebugger.model.PerfStatsEvent +import com.facebook.flipper.plugins.uidebugger.model.Snapshot +import com.facebook.flipper.plugins.uidebugger.model.TraversalError +import com.facebook.flipper.plugins.uidebugger.util.MaybeDeferred +import com.facebook.flipper.plugins.uidebugger.util.StopWatch +import java.io.ByteArrayOutputStream +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.Channel.Factory.CONFLATED +import kotlinx.serialization.json.Json + +data class Update( + val snapshotNode: Id, + val deferredNodes: List>, + val startTimestamp: Long, + val traversalMS: Long, + val snapshotMS: Long, + val queuedTimestamp: Long, + val snapshotBitmap: BitmapPool.ReusableBitmap? +) + +/** + * Holds an update and manages a coroutine which serially reads from queue and sends to flipper + * desktop + */ +class UpdateQueue(val context: UIDContext) { + + // conflated channel means we only hold 1 item and newer values override older ones, + // there is no point processing frames that the desktop cant keep up with since we only display + // the latest + private val frameChannel = Channel(CONFLATED) + + private var job: Job? = null + private val workerScope = CoroutineScope(Dispatchers.IO) + private val stopWatch = StopWatch() + + fun enqueueUpdate(update: Update) { + frameChannel.trySend(update) + } + + /** + * 1. Sets up the root observer + * 2. Starts worker to listen to channel, which serializers and sends data over connection + */ + @SuppressLint("NewApi") + fun start() { + + job = + workerScope.launch { + while (isActive) { + try { + val update = frameChannel.receive() + sendUpdate(update) + } catch (e: CancellationException) {} catch (e: java.lang.Exception) { + Log.e(LogTag, "Unexpected Error in channel ", e) + } + } + Log.i(LogTag, "Shutting down worker") + } + } + + fun stop() { + job?.cancel() + job = null + // drain channel + frameChannel.tryReceive() + } + + private fun sendUpdate(update: Update) { + + val queuingTimeMs = System.currentTimeMillis() - update.queuedTimestamp + + stopWatch.start() + val nodes = + try { + update.deferredNodes.map { it.value() } + } catch (exception: Exception) { + context.onError( + TraversalError( + "DeferredProcessing", + exception.javaClass.simpleName, + exception.message ?: "", + exception.stackTraceToString())) + return + } + + val deferredComputationEndTimestamp = stopWatch.stop() + + val frameworkEvents = context.extractPendingFrameworkEvents() + + var snapshot: Snapshot? = null + if (update.snapshotBitmap != null) { + val stream = ByteArrayOutputStream() + val base64Stream = Base64OutputStream(stream, Base64.DEFAULT) + update.snapshotBitmap.bitmap?.compress(Bitmap.CompressFormat.PNG, 100, base64Stream) + snapshot = Snapshot(update.snapshotNode, stream.toString()) + update.snapshotBitmap.readyForReuse() + } + + // it is important this comes after deferred processing since the deferred processing can create + // metadata + sendMetadata() + + val (serialized, serializationTimeMs) = + StopWatch.time { + Json.encodeToString( + FrameScanEvent.serializer(), + FrameScanEvent(update.startTimestamp, nodes, snapshot, frameworkEvents)) + } + + val (_, sendTimeMs) = + StopWatch.time { context.connectionRef.connection?.send(FrameScanEvent.name, serialized) } + + Log.i(LogTag, "Sent frame with nodes ${nodes.size}") + + // Note about payload size: + // Payload size is an approximation as it assumes all characters + // are ASCII encodable, this should be true for most of the payload content. + // So, assume each character will at most occupy one byte. + val perfStats = + PerfStatsEvent( + txId = update.startTimestamp, + nodesCount = nodes.size, + start = update.startTimestamp, + traversalMS = update.traversalMS, + snapshotMS = update.snapshotMS, + queuingMS = queuingTimeMs, + deferredComputationMS = deferredComputationEndTimestamp, + serializationMS = serializationTimeMs, + socketMS = sendTimeMs, + payloadSize = serialized.length) + + context.connectionRef.connection?.send( + PerfStatsEvent.name, Json.encodeToString(PerfStatsEvent.serializer(), perfStats)) + } + + private fun sendMetadata() { + val metadata = MetadataRegister.extractPendingMetadata() + if (metadata.isNotEmpty()) { + context.connectionRef.connection?.send( + MetadataUpdateEvent.name, + Json.encodeToString(MetadataUpdateEvent.serializer(), MetadataUpdateEvent(metadata))) + } + } +} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Events.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Events.kt index def4febe7..742699500 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Events.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/model/Events.kt @@ -53,7 +53,6 @@ class TraversalError( @kotlinx.serialization.Serializable class PerfStatsEvent( val txId: Long, - val observerType: String, val nodesCount: Int, val start: Long, val traversalMS: Long, diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/ApplicationTreeObserver.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/ApplicationTreeObserver.kt deleted file mode 100644 index 0eafaf3ef..000000000 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/ApplicationTreeObserver.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.flipper.plugins.uidebugger.observers - -import android.util.Log -import android.view.View -import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef -import com.facebook.flipper.plugins.uidebugger.core.RootViewResolver -import com.facebook.flipper.plugins.uidebugger.core.UIDContext -import com.facebook.flipper.plugins.uidebugger.descriptors.Id -import com.facebook.flipper.plugins.uidebugger.util.objectIdentity - -/** - * Responsible for observing the activity stack and managing the subscription to the top most - * content view (decor view) - */ -class ApplicationTreeObserver(val context: UIDContext) : TreeObserver() { - - override val type = "Application" - - override fun subscribe(node: Any, parentId: Id?) { - Log.i(LogTag, "Subscribing activity / root view changes") - - val applicationRef = node as ApplicationRef - - val rootViewListener = - object : RootViewResolver.Listener { - override fun onRootViewAdded(rootView: View) {} - - override fun onRootViewRemoved(rootView: View) {} - - override fun onRootViewsChanged(rootViews: List) { - Log.i(LogTag, "Root views updated, num ${rootViews.size}") - context.sharedThrottle.trigger() - } - } - - context.sharedThrottle.registerCallback(this.objectIdentity()) { - traverseAndSend(null, context, applicationRef) - } - - context.applicationRef.rootsResolver.attachListener(rootViewListener) - // On subscribe, trigger a traversal on whatever roots we have - rootViewListener.onRootViewsChanged(applicationRef.rootsResolver.rootViews()) - - Log.i(LogTag, "${context.applicationRef.rootsResolver.rootViews().size} root views") - Log.i(LogTag, "${context.applicationRef.activitiesStack.size} activities") - } - - override fun unsubscribe() { - context.applicationRef.rootsResolver.attachListener(null) - context.sharedThrottle.deregisterCallback(this.objectIdentity()) - } -} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/DecorViewTreeObserver.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/DecorViewTreeObserver.kt deleted file mode 100644 index 003fe4f1d..000000000 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/DecorViewTreeObserver.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.flipper.plugins.uidebugger.observers - -import android.util.Log -import android.view.View -import android.view.ViewTreeObserver -import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool -import com.facebook.flipper.plugins.uidebugger.core.UIDContext -import com.facebook.flipper.plugins.uidebugger.descriptors.Id -import com.facebook.flipper.plugins.uidebugger.util.objectIdentity -import java.lang.ref.WeakReference - -typealias DecorView = View - -/** Responsible for subscribing to updates to the content view of an activity */ -class DecorViewObserver(val context: UIDContext) : TreeObserver() { - - private var nodeRef: WeakReference? = null - private var preDrawListener: ViewTreeObserver.OnPreDrawListener? = null - - override val type = "DecorView" - - override fun subscribe(node: Any, parentId: Id?) { - node as View - nodeRef = WeakReference(node) - - Log.i(LogTag, "Subscribing to decor view changes") - - context.sharedThrottle.registerCallback(this.objectIdentity()) { - nodeRef?.get()?.let { traverseAndSendWithSnapshot(parentId) } - } - - preDrawListener = - ViewTreeObserver.OnPreDrawListener { - context.sharedThrottle.trigger() - true - } - - node.viewTreeObserver.addOnPreDrawListener(preDrawListener) - - // It can be the case that the DecorView the current observer owns has already - // drawn. In this case, manually trigger an update. - traverseAndSendWithSnapshot(parentId) - } - - private fun traverseAndSendWithSnapshot(parentId: Id?) { - nodeRef?.get()?.let { view -> - var snapshotBitmap: BitmapPool.ReusableBitmap? = null - if (view.width > 0 && view.height > 0) { - snapshotBitmap = context.bitmapPool.getBitmap(view.width, view.height) - } - traverseAndSend( - parentId, - context, - view, - snapshotBitmap, - ) - } - } - - override fun unsubscribe() { - Log.i(LogTag, "Unsubscribing from decor view changes") - - preDrawListener.let { - nodeRef?.get()?.viewTreeObserver?.removeOnPreDrawListener(it) - preDrawListener = null - } - - context.sharedThrottle.deregisterCallback(this.objectIdentity()) - nodeRef?.clear() - nodeRef = null - } -} - -object DecorViewTreeObserverBuilder : TreeObserverBuilder { - override fun canBuildFor(node: Any): Boolean { - return node.javaClass.simpleName.contains("DecorView") - } - - override fun build(context: UIDContext): TreeObserver { - Log.i(LogTag, "Building DecorView observer") - return DecorViewObserver(context) - } -} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserver.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserver.kt deleted file mode 100644 index 7e23a9b2d..000000000 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserver.kt +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.flipper.plugins.uidebugger.observers - -import android.util.Log -import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool -import com.facebook.flipper.plugins.uidebugger.core.UIDContext -import com.facebook.flipper.plugins.uidebugger.descriptors.Id -import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor -import com.facebook.flipper.plugins.uidebugger.model.FrameworkEvent -import com.facebook.flipper.plugins.uidebugger.util.objectIdentity - -/* - * Represents a stateful observer that manages some subtree in the UI Hierarchy. - * It is responsible for: - * 1. Listening to the relevant framework events - * 2. Traversing the hierarchy of the managed nodes - * 3. Diffing to previous state (optional) - * 4. Pushing out updates for its entire set of managed nodes - * - * If while traversing it encounters a node type which has its own TreeObserver, it - * does not traverse that, instead it sets up a Tree observer responsible for that subtree - * - * The parent is responsible for detecting when a child observer needs to be cleaned up. - */ -abstract class TreeObserver { - - protected val children: MutableMap> = mutableMapOf() - - abstract val type: String - - abstract fun subscribe(node: Any, parentId: Id?) - - abstract fun unsubscribe() - - /** Traverses the layout hierarchy while managing any encountered child observers. */ - fun traverseAndSend( - parentId: Id?, - context: UIDContext, - root: Any, - snapshotBitmap: BitmapPool.ReusableBitmap? = null, - frameworkEvents: List? = null - ) { - val traversalStartTimestamp = System.currentTimeMillis() - val (visitedNodes, observableRoots) = context.layoutTraversal.traverse(root, parentId) - - // Add any new observers - observableRoots.forEach { (observable, parentId) -> - if (!children.containsKey(observable.objectIdentity())) { - context.observerFactory.createObserver(observable, context)?.let { observer -> - Log.d( - LogTag, - "Observer ${this.type} discovered new child of type ${observer.type} Node ID ${observable.objectIdentity()}") - observer.subscribe(observable, parentId) - children[observable.objectIdentity()] = observer - } - } - } - - // Remove any old observers - val observableRootsIdentifiers = - observableRoots.map { (observable, _) -> observable.objectIdentity() } - val removables = mutableListOf() - children.keys.forEach { key -> - if (!observableRootsIdentifiers.contains(key)) { - children[key]?.let { observer -> - Log.d( - LogTag, - "Observer ${this.type} cleaning up child of type ${observer.type} Node ID $key") - - observer.cleanUpRecursive() - } - removables.add(key) - } - } - removables.forEach { key -> children.remove(key) } - - val traversalEndTimestamp = System.currentTimeMillis() - - if (snapshotBitmap != null) { - @Suppress("unchecked_cast") - val descriptor = - context.descriptorRegister.descriptorForClassUnsafe(root::class.java) - as NodeDescriptor - descriptor.getSnapshot(root, snapshotBitmap.bitmap) - } - - val snapshotEndTimestamp = System.currentTimeMillis() - - context.treeObserverManager.enqueueUpdate( - SubtreeUpdate( - type, - root.objectIdentity(), - visitedNodes, - traversalStartTimestamp, - snapshotEndTimestamp, - (traversalEndTimestamp - traversalStartTimestamp), - (snapshotEndTimestamp - traversalEndTimestamp), - frameworkEvents, - snapshotBitmap)) - } - - fun cleanUpRecursive() { - Log.i(LogTag, "Cleaning up observer $this") - children.values.forEach { it.cleanUpRecursive() } - unsubscribe() - children.clear() - } -} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverFactory.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverFactory.kt deleted file mode 100644 index 33f480156..000000000 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverFactory.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.flipper.plugins.uidebugger.observers - -import com.facebook.flipper.plugins.uidebugger.core.UIDContext - -interface TreeObserverBuilder { - fun canBuildFor(node: Any): Boolean - - fun build(context: UIDContext): TreeObserver -} - -class TreeObserverFactory { - - private val builders = mutableListOf>() - - fun register(builder: TreeObserverBuilder) { - builders.add(builder) - } - - // TODO: Not very efficient, need to cache this. Builders cannot be removed - fun hasObserverFor(node: Any): Boolean { - return builders.any { it.canBuildFor(node) } - } - - // TODO: Not very efficient, need to cache this. Builders cannot be removed. - fun createObserver(node: Any, context: UIDContext): TreeObserver<*>? { - return builders.find { it.canBuildFor(node) }?.build(context) - } - - companion object { - fun withDefaults(): TreeObserverFactory { - val factory = TreeObserverFactory() - // TODO: Only builder for DecorView, maybe more are needed. - factory.register(DecorViewTreeObserverBuilder) - - return factory - } - } -} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverManager.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverManager.kt deleted file mode 100644 index 7abd8db7b..000000000 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/observers/TreeObserverManager.kt +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.flipper.plugins.uidebugger.observers - -import android.annotation.SuppressLint -import android.graphics.Bitmap -import android.os.Looper -import android.util.Base64 -import android.util.Base64OutputStream -import android.util.Log -import android.view.Choreographer -import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool -import com.facebook.flipper.plugins.uidebugger.core.UIDContext -import com.facebook.flipper.plugins.uidebugger.descriptors.Id -import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister -import com.facebook.flipper.plugins.uidebugger.model.FrameScanEvent -import com.facebook.flipper.plugins.uidebugger.model.FrameworkEvent -import com.facebook.flipper.plugins.uidebugger.model.MetadataUpdateEvent -import com.facebook.flipper.plugins.uidebugger.model.Node -import com.facebook.flipper.plugins.uidebugger.model.PerfStatsEvent -import com.facebook.flipper.plugins.uidebugger.model.Snapshot -import com.facebook.flipper.plugins.uidebugger.model.TraversalError -import com.facebook.flipper.plugins.uidebugger.util.MaybeDeferred -import java.io.ByteArrayOutputStream -import java.util.concurrent.atomic.AtomicInteger -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.serialization.json.Json - -data class SubtreeUpdate( - val observerType: String, - val rootId: Id, - val deferredNodes: List>, - val timestamp: Long, - val queuedTimestamp: Long, - val traversalMS: Long, - val snapshotMS: Long, - val frameworkEvents: List?, - val snapshot: BitmapPool.ReusableBitmap? -) - -data class BatchedUpdate(val updates: List, val frameTimeMs: Long) - -/** Holds the root observer and manages sending updates to desktop */ -class TreeObserverManager(val context: UIDContext) { - - private val rootObserver = ApplicationTreeObserver(context) - private lateinit var batchedUpdates: Channel - - private val subtreeUpdateBuffer = SubtreeUpdateBuffer(this::enqueueBatch) - - private var job: Job? = null - private val workerScope = CoroutineScope(Dispatchers.IO) - private val mainScope = CoroutineScope(Dispatchers.Main) - private val txId = AtomicInteger() - - fun enqueueUpdate(update: SubtreeUpdate) { - subtreeUpdateBuffer.bufferUpdate(update) - } - - private fun enqueueBatch(batchedUpdate: BatchedUpdate) { - batchedUpdates.trySend(batchedUpdate) - } - - /** - * 1. Sets up the root observer - * 2. Starts worker to listen to channel, which serializers and sends data over connection - */ - @SuppressLint("NewApi") - fun start() { - - if (Looper.myLooper() != Looper.getMainLooper()) { - mainScope.launch { start() } - } - batchedUpdates = Channel(Channel.UNLIMITED) - rootObserver.subscribe(context.applicationRef, null) - - job = - workerScope.launch { - while (isActive) { - try { - val update = batchedUpdates.receive() - sendBatchedUpdate(update) - } catch (e: CancellationException) {} catch (e: java.lang.Exception) { - Log.e(LogTag, "Unexpected Error in channel ", e) - } - } - Log.i(LogTag, "Shutting down worker") - } - } - - fun stop() { - rootObserver.cleanUpRecursive() - job?.cancel() - batchedUpdates.cancel() - } - - private fun sendBatchedUpdate(batchedUpdate: BatchedUpdate) { - Log.i( - LogTag, - "Got update from ${batchedUpdate.updates.size} observers at time ${batchedUpdate.frameTimeMs}") - - val workerThreadStartTimestamp = System.currentTimeMillis() - - val nodes = - try { - batchedUpdate.updates.flatMap { it.deferredNodes.map { it.value() } } - } catch (exception: Exception) { - context.onError( - TraversalError( - "DeferredProcessing", - exception.javaClass.simpleName, - exception.message ?: "", - exception.stackTraceToString())) - return - } - - val frameworkEvents = context.extractPendingFrameworkEvents() - val snapshotUpdate = batchedUpdate.updates.find { it.snapshot != null } - val deferredComputationEndTimestamp = System.currentTimeMillis() - - var snapshot: Snapshot? = null - if (snapshotUpdate?.snapshot != null) { - val stream = ByteArrayOutputStream() - val base64Stream = Base64OutputStream(stream, Base64.DEFAULT) - snapshotUpdate.snapshot.bitmap?.compress(Bitmap.CompressFormat.PNG, 100, base64Stream) - snapshot = Snapshot(snapshotUpdate.rootId, stream.toString()) - snapshotUpdate.snapshot.readyForReuse() - } - - // it is important this comes after deferred processing since the deferred processing can create - // metadata - sendMetadata() - - val serialized = - Json.encodeToString( - FrameScanEvent.serializer(), - FrameScanEvent(batchedUpdate.frameTimeMs, nodes, snapshot, frameworkEvents)) - - val serialisationEndTimestamp = System.currentTimeMillis() - - context.connectionRef.connection?.send(FrameScanEvent.name, serialized) - - val socketEndTimestamp = System.currentTimeMillis() - Log.i(LogTag, "Sent event for batched subtree update with nodes with ${nodes.size}") - - // Note about payload size: - // Payload size is an approximation as it assumes all characters - // are ASCII encodable, this should be true for most of the payload content. - // So, assume each character will at most occupy one byte. - val perfStats = - PerfStatsEvent( - txId = batchedUpdate.frameTimeMs, - observerType = "batched", - nodesCount = nodes.size, - start = batchedUpdate.updates.minOf { it.timestamp }, - traversalMS = batchedUpdate.updates.maxOf { it.traversalMS }, - snapshotMS = batchedUpdate.updates.maxOf { it.snapshotMS }, - queuingMS = - workerThreadStartTimestamp - batchedUpdate.updates.minOf { it.queuedTimestamp }, - deferredComputationMS = (deferredComputationEndTimestamp - workerThreadStartTimestamp), - serializationMS = (serialisationEndTimestamp - deferredComputationEndTimestamp), - socketMS = (socketEndTimestamp - serialisationEndTimestamp), - payloadSize = serialized.length) - - context.connectionRef.connection?.send( - PerfStatsEvent.name, Json.encodeToString(PerfStatsEvent.serializer(), perfStats)) - } - - private fun sendMetadata() { - val metadata = MetadataRegister.extractPendingMetadata() - if (metadata.isNotEmpty()) { - context.connectionRef.connection?.send( - MetadataUpdateEvent.name, - Json.encodeToString(MetadataUpdateEvent.serializer(), MetadataUpdateEvent(metadata))) - } - } -} - -/** Buffers up subtree updates until the frame is complete, should only be called on main thread */ -private class SubtreeUpdateBuffer(private val onBatchReady: (BatchedUpdate) -> Unit) { - - private val bufferedSubtreeUpdates = mutableListOf() - - fun bufferUpdate(update: SubtreeUpdate) { - if (bufferedSubtreeUpdates.isEmpty()) { - - Choreographer.getInstance().postFrameCallback { frameTime -> - val updatesCopy = bufferedSubtreeUpdates.toList() - bufferedSubtreeUpdates.clear() - - onBatchReady(BatchedUpdate(updatesCopy, frameTime / 1000000)) - } - } - bufferedSubtreeUpdates.add(update) - } -} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/scheduler/SharedThrottle.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/scheduler/SharedThrottle.kt deleted file mode 100644 index 795f3b0d9..000000000 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/scheduler/SharedThrottle.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.flipper.plugins.uidebugger.scheduler - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch - -/** - * The class makes the following guarantees - * 1. All registered callbacks will be called on the same frame at the same time - * 2. The callbacks will never be called more often than the min interval - * 3. If it has been > min interval since the callbacks was last called we will call the callbacks - * immediately - * 4. If an event comes in within the min interval of the last firing we will schedule another - * firing at the next possible moment - * - * The reason we need this is because with an independent throttle per observer you end up with - * updates occurring across different frames, - * - * WARNING: Not thread safe, should only be called on main thread. Also It is important to - * deregister to avoid leaks - */ -class SharedThrottle( - private val executionScope: CoroutineScope = CoroutineScope(Dispatchers.Main) -) { - - private var job: Job? = null - private val callbacks = mutableMapOf Unit>() - private var latestInvocationId: Long = 0 - - fun registerCallback(id: Int, callback: () -> Unit) { - callbacks[id] = callback - } - - fun deregisterCallback(id: Int) { - callbacks.remove(id) - } - - fun trigger() { - latestInvocationId += 1 - - if (job == null || job?.isCompleted == true) { - job = - executionScope.launch { - var i = 0 - do { - val thisInvocationId = latestInvocationId - - callbacks.values.toList().forEach { callback -> callback() } - - val delayTime = exponentialBackOff(base = 250, exp = 1.5, max = 1000, i = i).toLong() - delay(delayTime) - i++ - - // if we haven't received an call since we executed break out and let a new job be - // created which, otherwise we loop which executes again at the next appropriate time - // since we have already waited - } while (thisInvocationId != latestInvocationId) - } - } - } - - private fun exponentialBackOff(base: Long, exp: Double, max: Long, i: Int): Double { - return Math.min(base * Math.pow(exp, i.toDouble()), max.toDouble()) - } -} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt new file mode 100644 index 000000000..12698ebac --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.util + +class StopWatch() { + private var startTime: Long = 0 + + fun start() { + startTime = System.currentTimeMillis() + } + + fun stop(): Long { + return System.currentTimeMillis() - startTime + } + + companion object { + + fun time(fn: () -> T): Pair { + val start = System.currentTimeMillis() + val result = fn() + val elapsed = System.currentTimeMillis() - start + return Pair(result, elapsed) + } + } +} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt new file mode 100644 index 000000000..1069ddd80 --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.util + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +/** + * This class will throttle calls into a callback. E.g if interval is 500ms and you receive triggers + * at t=0, 100, 300 400, the callback will only be triggered at t=500 + */ +class Throttler(private val intervalMs: Long, val callback: () -> T) { + + private val executionScope: CoroutineScope = CoroutineScope(Dispatchers.Main) + private var throttleJob: Job? = null + + fun trigger() { + if (throttleJob == null || throttleJob?.isCompleted == true) { + throttleJob = + executionScope.launch { + delay(intervalMs) + executionScope.launch { callback() } + } + } + } +} From 6bf93347eebe4e64f12eacbd4b9960f5c7480f09 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 28/43] Extracted snapshot out of descriptor Summary: Snapshot never made much sense in the descriptor since we only snapshot the decor views. Additionally in the next diff i will introduce a new way to snapshot so this will make it easier Reviewed By: lblasa Differential Revision: D50845280 fbshipit-source-id: c2eac351b72786e7b66951d0fa09cea52a6dcc69 --- .../descriptors/ComposeInnerViewDescriptor.kt | 8 ---- .../descriptors/ComposeNodeDescriptor.kt | 3 -- .../plugins/uidebugger/common/BitmapPool.kt | 2 +- .../uidebugger/core/DecorViewTracker.kt | 20 ++------- .../plugins/uidebugger/core/Snapshot.kt | 43 +++++++++++++++++++ .../plugins/uidebugger/core/UIDContext.kt | 5 +-- .../descriptors/ChainedDescriptor.kt | 10 ----- .../uidebugger/descriptors/NodeDescriptor.kt | 8 ---- .../descriptors/ObjectDescriptor.kt | 3 -- .../descriptors/OffsetChildDescriptor.kt | 4 -- .../uidebugger/descriptors/ViewDescriptor.kt | 26 ----------- 11 files changed, 50 insertions(+), 82 deletions(-) create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt diff --git a/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeInnerViewDescriptor.kt b/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeInnerViewDescriptor.kt index 8e430d89a..c68a51eda 100644 --- a/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeInnerViewDescriptor.kt +++ b/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeInnerViewDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.jetpackcompose.descriptors -import android.graphics.Bitmap import android.view.ViewGroup import com.facebook.flipper.plugins.jetpackcompose.model.ComposeInnerViewNode import com.facebook.flipper.plugins.uidebugger.descriptors.Id @@ -49,13 +48,6 @@ object ComposeInnerViewDescriptor : NodeDescriptor { return ViewDescriptor.getChildren(node.view) } - override fun getSnapshot(node: ComposeInnerViewNode, bitmap: Bitmap?): Bitmap? { - if (node.view is ViewGroup) { - return ViewGroupDescriptor.getSnapshot(node.view, bitmap) - } - return ViewDescriptor.getSnapshot(node.view, bitmap) - } - override fun getActiveChild(node: ComposeInnerViewNode): Any? { if (node.view is ViewGroup) { return ViewGroupDescriptor.getActiveChild(node.view) diff --git a/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeNodeDescriptor.kt b/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeNodeDescriptor.kt index 22b5e0046..8cc2bb328 100644 --- a/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeNodeDescriptor.kt +++ b/android/plugins/jetpack-compose/src/main/java/com/facebook/flipper/plugins/jetpackcompose/descriptors/ComposeNodeDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.jetpackcompose.descriptors -import android.graphics.Bitmap import com.facebook.flipper.plugins.jetpackcompose.model.ComposeNode import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags import com.facebook.flipper.plugins.uidebugger.descriptors.Id @@ -130,8 +129,6 @@ object ComposeNodeDescriptor : NodeDescriptor { override fun getQualifiedName(node: ComposeNode): String = node.inspectorNode.name - override fun getSnapshot(node: ComposeNode, bitmap: Bitmap?): Bitmap? = null - override fun getActiveChild(node: ComposeNode): Any? = null override fun getTags(node: ComposeNode): Set = setOf(BaseTags.Android, "Compose") diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt index 778fc2e7c..a623fd02b 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt @@ -16,7 +16,7 @@ import kotlinx.coroutines.launch class BitmapPool(private val config: Bitmap.Config = Bitmap.Config.RGB_565) { interface ReusableBitmap { - val bitmap: Bitmap? + val bitmap: Bitmap fun readyForReuse() } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt index c4e98e59e..96f3cf0f6 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt @@ -11,7 +11,6 @@ import android.util.Log import android.view.View import android.view.ViewTreeObserver import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool import com.facebook.flipper.plugins.uidebugger.descriptors.ViewDescriptor import com.facebook.flipper.plugins.uidebugger.util.StopWatch import com.facebook.flipper.plugins.uidebugger.util.Throttler @@ -22,7 +21,7 @@ import com.facebook.flipper.plugins.uidebugger.util.objectIdentity * to it This predraw observer triggers a full traversal of the UI. There should only ever be one * active predraw listener at once */ -class DecorViewTracker(val context: UIDContext) { +class DecorViewTracker(private val context: UIDContext, private val snapshotter: Snapshotter) { private var currentDecorView: View? = null private var preDrawListener: ViewTreeObserver.OnPreDrawListener? = null @@ -88,18 +87,7 @@ class DecorViewTracker(val context: UIDContext) { val (nodes, traversalTime) = StopWatch.time { context.layoutTraversal.traverse(context.applicationRef) } - mStopWatch.start() - var snapshotBitmap: BitmapPool.ReusableBitmap? = null - if (decorView.width > 0 && decorView.height > 0) { - snapshotBitmap = context.bitmapPool.getBitmap(decorView.width, decorView.height) - context.bitmapPool.getBitmap(decorView.width, decorView.height) - Log.i( - LogTag, - "Snapshotting view ${ViewDescriptor.getId(decorView)}", - ) - ViewDescriptor.getSnapshot(decorView, snapshotBitmap.bitmap) - } - val snapshotTime = mStopWatch.stop() + val (reusableBitmap, snapshotMs) = StopWatch.time { snapshotter.takeSnapshot(decorView) } context.updateQueue.enqueueUpdate( Update( @@ -107,8 +95,8 @@ class DecorViewTracker(val context: UIDContext) { nodes, startTimestamp, traversalTime, - snapshotTime, + snapshotMs, System.currentTimeMillis(), - snapshotBitmap)) + reusableBitmap)) } } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt new file mode 100644 index 000000000..4ce9af9c6 --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.core + +import android.graphics.Canvas +import android.util.Log +import android.view.View +import com.facebook.flipper.plugins.uidebugger.LogTag +import com.facebook.flipper.plugins.uidebugger.common.BitmapPool + +interface Snapshotter { + fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? +} + +/** + * Takes a snapshot by redrawing the view into a bitmap backed canvas, Since this is software + * rendering there can be discrepancies between the real image and the snapshot: + * 1. It can be unreliable when snapshotting views that are added directly to window manager + * 2. It doesnt include certain types of content (video / images) + */ +class CanvasSnapshotter(private val bitmapPool: BitmapPool) : Snapshotter { + override fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { + + if (view.width <= 0 || view.height <= 0) { + return null + } + + return try { + val reuseAbleBitmap = bitmapPool.getBitmap(view.width, view.height) + val canvas = Canvas(reuseAbleBitmap.bitmap) + view.draw(canvas) + reuseAbleBitmap + } catch (e: OutOfMemoryError) { + Log.e(LogTag, "OOM when taking snapshot") + null + } + } +} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt index 6c7680322..47dcac79a 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt @@ -31,12 +31,11 @@ class UIDContext( private val pendingFrameworkEvents: MutableList ) { - val decorViewTracker = DecorViewTracker(this) + val bitmapPool = BitmapPool() + val decorViewTracker = DecorViewTracker(this, CanvasSnapshotter(bitmapPool)) val updateQueue = UpdateQueue(this) val layoutTraversal: LayoutTraversal = LayoutTraversal(this) - val bitmapPool = BitmapPool() - fun addFrameworkEvent(frameworkEvent: FrameworkEvent) { synchronized(pendingFrameworkEvents) { pendingFrameworkEvents.add(frameworkEvent) } } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt index ccc9413e6..ba0ef3cba 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ChainedDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.uidebugger.descriptors -import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.MetadataId @@ -133,15 +132,6 @@ abstract class ChainedDescriptor : NodeDescriptor { */ open fun onGetAttributes(node: T, attributeSections: MutableMap) {} - /** Get a snapshot of the node. */ - final override fun getSnapshot(node: T, bitmap: Bitmap?): Bitmap? { - return onGetSnapshot(node, bitmap) ?: mSuper?.onGetSnapshot(node, bitmap) - } - - open fun onGetSnapshot(node: T, bitmap: Bitmap?): Bitmap? { - return null - } - final override fun getInlineAttributes(node: T): Map { val builder = mutableMapOf() diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt index d7b569c9d..7ab6b9e50 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/NodeDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.uidebugger.descriptors -import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.MetadataId @@ -58,13 +57,6 @@ interface NodeDescriptor { /** The children this node exposes in the inspector. */ fun getChildren(node: T): List - /** - * Get a snapshot of the node. Bitmaps are not cheap to create, so accept one as an optional - * parameter. If a bitmap is provided, it will be used by the canvas to draw on it. Otherwise, a - * bitmap will be created. - */ - fun getSnapshot(node: T, bitmap: Bitmap?): Bitmap? = null - /** * If you have overlapping children this indicates which child is active / on top, we will only * listen to / traverse this child. If return null we assume all children are 'active' diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt index f60127995..96bb8169b 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ObjectDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.uidebugger.descriptors -import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.MetadataId @@ -34,6 +33,4 @@ object ObjectDescriptor : NodeDescriptor { override fun getBounds(node: Any): Bounds = Bounds(0, 0, 0, 0) override fun getTags(node: Any): Set = setOf(BaseTags.Unknown) - - override fun getSnapshot(node: Any, bitmap: Bitmap?): Bitmap? = null } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/OffsetChildDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/OffsetChildDescriptor.kt index 2471c86c0..8a9d6a287 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/OffsetChildDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/OffsetChildDescriptor.kt @@ -7,7 +7,6 @@ package com.facebook.flipper.plugins.uidebugger.descriptors -import android.graphics.Bitmap import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.model.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.MetadataId @@ -42,7 +41,4 @@ object OffsetChildDescriptor : NodeDescriptor { node.descriptor.getAttributes(node.child) override fun getTags(node: OffsetChild): Set = node.descriptor.getTags(node.child) - - override fun getSnapshot(node: OffsetChild, bitmap: Bitmap?): Bitmap? = - node.descriptor.getSnapshot(node.child, bitmap) } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt index 0c6a63bf2..5003bb3f2 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt @@ -8,8 +8,6 @@ package com.facebook.flipper.plugins.uidebugger.descriptors import android.annotation.SuppressLint -import android.graphics.Bitmap -import android.graphics.Canvas import android.graphics.Rect import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable @@ -380,30 +378,6 @@ object ViewDescriptor : ChainedDescriptor() { attributes["id"] = value } - override fun onGetSnapshot(node: View, bitmap: Bitmap?): Bitmap? { - if (node.width <= 0 || node.height <= 0) { - return null - } - var workingBitmap = bitmap - - try { - val differentSize = - if (bitmap != null) (node.width != bitmap.width || node.height != bitmap.height) - else false - if (workingBitmap == null || differentSize) { - val viewWidth: Int = node.width - val viewHeight: Int = node.height - - workingBitmap = BitmapPool.createBitmapWithDefaultConfig(viewWidth, viewHeight) - } - - val canvas = Canvas(workingBitmap) - node.draw(canvas) - } catch (e: OutOfMemoryError) {} - - return workingBitmap - } - private fun fromDrawable(d: Drawable?): Inspectable? { return if (d is ColorDrawable) { InspectableValue.Color(Color.fromColor(d.color)) From d85adc030f139e09515e660d28c77dc2e2a4e4e5 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 29/43] Use pixel copy on activities Summary: Pixel copy is a more reliable and consistent way to take a snapshot rather than drawing into a canvas. It accepts either: Surface SurfaceView Window For root views that belong to an activity its easy to get the window so we do that here. In the next diff we solve this for other root views Reviewed By: lblasa Differential Revision: D50845282 fbshipit-source-id: 3968828dedd1e96a854b907e0fd152ad64993d95 --- .../plugins/uidebugger/common/BitmapPool.kt | 3 +- .../plugins/uidebugger/core/Snapshot.kt | 53 +++++++++++++++++++ .../plugins/uidebugger/core/UIDContext.kt | 12 ++++- .../descriptors/ApplicationRefDescriptor.kt | 2 +- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt index a623fd02b..5a779c1a9 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt @@ -10,7 +10,6 @@ package com.facebook.flipper.plugins.uidebugger.common import android.graphics.Bitmap import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch /** BitmapPool is intended to be used on the main thread. In other words, it is not thread-safe. */ class BitmapPool(private val config: Bitmap.Config = Bitmap.Config.RGB_565) { @@ -57,7 +56,7 @@ class BitmapPool(private val config: Bitmap.Config = Bitmap.Config.RGB_565) { override fun readyForReuse() { val key = generateKey(bitmap.width, bitmap.height) - mainScope.launch { + synchronized(this@BitmapPool) { if (isRecycled) { bitmap.recycle() } else { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index 4ce9af9c6..1467d73c9 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -7,9 +7,15 @@ package com.facebook.flipper.plugins.uidebugger.core +import android.app.Activity import android.graphics.Canvas +import android.os.Build +import android.os.Handler +import android.os.Looper import android.util.Log +import android.view.PixelCopy import android.view.View +import androidx.annotation.RequiresApi import com.facebook.flipper.plugins.uidebugger.LogTag import com.facebook.flipper.plugins.uidebugger.common.BitmapPool @@ -41,3 +47,50 @@ class CanvasSnapshotter(private val bitmapPool: BitmapPool) : Snapshotter { } } } + +@RequiresApi(Build.VERSION_CODES.O) +class PixelCopySnapshotter( + private val bitmapPool: BitmapPool, + private val applicationRef: ApplicationRef, + private val fallback: Snapshotter +) : Snapshotter { + + override fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { + + if (view.width <= 0 || view.height <= 0) { + return null + } + + val bitmap = bitmapPool.getBitmap(view.width, view.height) + try { + + val decorViewToActivity: Map = + applicationRef.activitiesStack.toList().associateBy { it.window.decorView } + + val activity = decorViewToActivity[view] + + // if this view belongs to an activity prefer this as it doesn't require private api hacks + if (activity != null) { + PixelCopy.request( + activity.window, + bitmap.bitmap, + { + // no-op this this api is actually synchronous despite how it looks + }, + Handler(Looper.getMainLooper())) + return bitmap + } + } catch (e: OutOfMemoryError) { + Log.e(LogTag, "OOM when taking snapshot") + null + } catch (e: Exception) { + // there was some problem with the pixel copy, fall back to canvas impl + Log.e(LogTag, "Exception when taking snapshot", e) + Log.i(LogTag, "Using fallback snapshot", e) + bitmap.readyForReuse() + fallback.takeSnapshot(view) + } + + return null + } +} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt index 47dcac79a..6741b4ef7 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt @@ -8,6 +8,7 @@ package com.facebook.flipper.plugins.uidebugger.core import android.app.Application +import android.os.Build import com.facebook.flipper.core.FlipperConnection import com.facebook.flipper.plugins.uidebugger.common.BitmapPool import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister @@ -32,7 +33,16 @@ class UIDContext( ) { val bitmapPool = BitmapPool() - val decorViewTracker = DecorViewTracker(this, CanvasSnapshotter(bitmapPool)) + private val canvasSnapshotter = CanvasSnapshotter(bitmapPool) + + val snapshotter = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + PixelCopySnapshotter(bitmapPool, applicationRef, canvasSnapshotter) + } else { + canvasSnapshotter + } + + val decorViewTracker = DecorViewTracker(this, snapshotter) val updateQueue = UpdateQueue(this) val layoutTraversal: LayoutTraversal = LayoutTraversal(this) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt index eea5a20a4..5278561bb 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt @@ -44,7 +44,7 @@ object ApplicationRefDescriptor : ChainedDescriptor() { val activeRoots = node.rootsResolver.rootViews() val decorViewToActivity: Map = - node.activitiesStack.toList().map { it.window.decorView to it }.toMap() + node.activitiesStack.toList().associateBy { it.window.decorView } for (root in activeRoots) { // if there is an activity for this root view use that, From 6e64f530462fdf5892b8633e5329c5ec9239c74d Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 30/43] Support pixel copy on views attached directly to window manager Summary: As mentioned in the previous diff pixel copy only support copying a Window, Surface or SurfaceView, All of these underneath use surface. For views attached to the window manager there is no activity / window so we need another solution There is no official way to get a views underlying surface so we had to do some dirty hacks to get it from the window manager. See the inline comments for details. Additionally it turns out that the pixel copy api was actually made async in Android 34, so to prepare for this the snapshot method was made a suspend function and we wrap the callback based apit with suspendCoroutine. Reviewed By: lblasa Differential Revision: D50845281 fbshipit-source-id: 5ba8ed6f330c1e04549812a6493ae5f4cb629d1f --- .../plugins/uidebugger/core/ApplicationRef.kt | 2 +- .../uidebugger/core/DecorViewTracker.kt | 5 +- .../uidebugger/core/RootViewResolver.kt | 20 ++-- .../plugins/uidebugger/core/Snapshot.kt | 77 ++++++++++----- .../plugins/uidebugger/core/UpdateQueue.kt | 2 +- .../uidebugger/core/WindowManagerUtility.kt | 93 +++++++++++++++++++ .../plugins/uidebugger/util/StopWatch.kt | 8 ++ .../plugins/uidebugger/util/Throttler.kt | 2 +- .../uidebugger/util/WindowManagerCommon.kt | 37 ++++++++ 9 files changed, 205 insertions(+), 41 deletions(-) create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/WindowManagerUtility.kt create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/WindowManagerCommon.kt diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt index 82663d432..69f4e307d 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt @@ -21,7 +21,7 @@ class ApplicationRef(val application: Application) { // kinds of custom overlays // 2. Dialog fragments val rootsResolver: RootViewResolver = RootViewResolver() - + val windowManagerUtility = WindowManagerUtility() val activitiesStack: List get() { return ActivityTracker.activitiesStack diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt index 96f3cf0f6..24720ff89 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt @@ -81,13 +81,14 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: preDrawListener = null } - private fun traverseSnapshotAndSend(decorView: View) { + private suspend fun traverseSnapshotAndSend(decorView: View) { val startTimestamp = System.currentTimeMillis() + val (nodes, traversalTime) = StopWatch.time { context.layoutTraversal.traverse(context.applicationRef) } - val (reusableBitmap, snapshotMs) = StopWatch.time { snapshotter.takeSnapshot(decorView) } + val (reusableBitmap, snapshotMs) = StopWatch.timeSuspend { snapshotter.takeSnapshot(decorView) } context.updateQueue.enqueueUpdate( Update( diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/RootViewResolver.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/RootViewResolver.kt index dc5ea1a2f..653b6ea2e 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/RootViewResolver.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/RootViewResolver.kt @@ -10,12 +10,14 @@ package com.facebook.flipper.plugins.uidebugger.core import android.annotation.SuppressLint import android.os.Build import android.view.View +import com.facebook.flipper.plugins.uidebugger.util.WindowManagerCommon import java.lang.reflect.Field import java.lang.reflect.InvocationTargetException import java.lang.reflect.Modifier /** - * Provides access to all root views in an application. + * Provides access to all root views in an application, as well as the ability to listen to changes + * in root views * * 95% of the time this is unnecessary and we can operate solely on current Activity's root view as * indicated by getWindow().getDecorView(). However in the case of popup windows, menus, and dialogs @@ -67,15 +69,13 @@ class RootViewResolver { private fun initialize() { initialized = true - val accessClass = - if (Build.VERSION.SDK_INT > 16) WINDOW_MANAGER_GLOBAL_CLAZZ else WINDOW_MANAGER_IMPL_CLAZZ - val instanceMethod = if (Build.VERSION.SDK_INT > 16) GET_GLOBAL_INSTANCE else GET_DEFAULT_IMPL try { - val clazz = Class.forName(accessClass) - val getMethod = clazz.getMethod(instanceMethod) - windowManagerObj = getMethod.invoke(null) - val viewsField: Field = clazz.getDeclaredField(VIEWS_FIELD) + val (windowManager, windowManagerClas) = + WindowManagerCommon.getGlobalWindowManager() ?: return + windowManagerObj = windowManager + + val viewsField: Field = windowManagerClas.getDeclaredField(VIEWS_FIELD) viewsField.let { vf -> vf.isAccessible = true @@ -98,11 +98,7 @@ class RootViewResolver { } companion object { - private const val WINDOW_MANAGER_IMPL_CLAZZ = "android.view.WindowManagerImpl" - private const val WINDOW_MANAGER_GLOBAL_CLAZZ = "android.view.WindowManagerGlobal" private const val VIEWS_FIELD = "mViews" - private const val GET_DEFAULT_IMPL = "getDefault" - private const val GET_GLOBAL_INSTANCE = "getInstance" } class ObservableViewArrayList : ArrayList() { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index 1467d73c9..b8335866a 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -11,6 +11,7 @@ import android.app.Activity import android.graphics.Canvas import android.os.Build import android.os.Handler +import android.os.HandlerThread import android.os.Looper import android.util.Log import android.view.PixelCopy @@ -18,19 +19,22 @@ import android.view.View import androidx.annotation.RequiresApi import com.facebook.flipper.plugins.uidebugger.LogTag import com.facebook.flipper.plugins.uidebugger.common.BitmapPool +import kotlin.coroutines.Continuation +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine interface Snapshotter { - fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? + suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? } /** * Takes a snapshot by redrawing the view into a bitmap backed canvas, Since this is software * rendering there can be discrepancies between the real image and the snapshot: * 1. It can be unreliable when snapshotting views that are added directly to window manager - * 2. It doesnt include certain types of content (video / images) + * 2. It doesn't include certain types of content (video / images) */ class CanvasSnapshotter(private val bitmapPool: BitmapPool) : Snapshotter { - override fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { + override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { if (view.width <= 0 || view.height <= 0) { return null @@ -54,8 +58,9 @@ class PixelCopySnapshotter( private val applicationRef: ApplicationRef, private val fallback: Snapshotter ) : Snapshotter { + private var handler = Handler(Looper.getMainLooper()) - override fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { + override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { if (view.width <= 0 || view.height <= 0) { return null @@ -63,34 +68,58 @@ class PixelCopySnapshotter( val bitmap = bitmapPool.getBitmap(view.width, view.height) try { - - val decorViewToActivity: Map = - applicationRef.activitiesStack.toList().associateBy { it.window.decorView } - - val activity = decorViewToActivity[view] - - // if this view belongs to an activity prefer this as it doesn't require private api hacks - if (activity != null) { - PixelCopy.request( - activity.window, - bitmap.bitmap, - { - // no-op this this api is actually synchronous despite how it looks - }, - Handler(Looper.getMainLooper())) + if (tryCopyViaActivityWindow(view, bitmap)) { + // if this view belongs to an activity prefer this as it doesn't require private api hacks + return bitmap + } else if (tryCopyViaInternalSurface(view, bitmap)) { return bitmap } } catch (e: OutOfMemoryError) { Log.e(LogTag, "OOM when taking snapshot") - null } catch (e: Exception) { // there was some problem with the pixel copy, fall back to canvas impl Log.e(LogTag, "Exception when taking snapshot", e) - Log.i(LogTag, "Using fallback snapshot", e) - bitmap.readyForReuse() - fallback.takeSnapshot(view) } - return null + // something went wrong, use fallback + Log.i(LogTag, "Using fallback snapshot method") + bitmap.readyForReuse() + return fallback.takeSnapshot(view) + } + + private suspend fun tryCopyViaActivityWindow( + view: View, + bitmap: BitmapPool.ReusableBitmap + ): Boolean { + + val decorViewToActivity: Map = + applicationRef.activitiesStack.toList().associateBy { it.window.decorView } + + val activityForDecorView = decorViewToActivity[view] ?: return false + + return suspendCoroutine { continuation -> + PixelCopy.request( + activityForDecorView.window, bitmap.bitmap, pixelCopyCallback(continuation), handler) + } + } + + private suspend fun tryCopyViaInternalSurface( + view: View, + bitmap: BitmapPool.ReusableBitmap + ): Boolean { + val surface = applicationRef.windowManagerUtility.surfaceForRootView(view) ?: return false + + return suspendCoroutine { continuation -> + PixelCopy.request(surface, bitmap.bitmap, pixelCopyCallback(continuation), handler) + } + } + + private fun pixelCopyCallback(continuation: Continuation) = { result: Int -> + if (result == PixelCopy.SUCCESS) { + continuation.resume(true) + } else { + Log.w(LogTag, "Pixel copy failed, code $result") + continuation.resume(false) + } } } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt index d768ea4f3..218ff2cd2 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt @@ -113,7 +113,7 @@ class UpdateQueue(val context: UIDContext) { if (update.snapshotBitmap != null) { val stream = ByteArrayOutputStream() val base64Stream = Base64OutputStream(stream, Base64.DEFAULT) - update.snapshotBitmap.bitmap?.compress(Bitmap.CompressFormat.PNG, 100, base64Stream) + update.snapshotBitmap.bitmap.compress(Bitmap.CompressFormat.PNG, 100, base64Stream) snapshot = Snapshot(update.snapshotNode, stream.toString()) update.snapshotBitmap.readyForReuse() } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/WindowManagerUtility.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/WindowManagerUtility.kt new file mode 100644 index 000000000..4f9cab789 --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/WindowManagerUtility.kt @@ -0,0 +1,93 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.core + +import android.annotation.SuppressLint +import android.util.Log +import android.view.Surface +import android.view.View +import com.facebook.flipper.plugins.uidebugger.LogTag +import com.facebook.flipper.plugins.uidebugger.util.WindowManagerCommon +import java.lang.reflect.Field + +/** + * This class is related to root view resolver, it also accesses parts of the global window manager + */ +class WindowManagerUtility { + + private var initialized = false + + // type is RootViewImpl + private var rootsImpls: ArrayList<*>? = null + private var mSurfaceField: Field? = null + private var mViewField: Field? = null + + /** + * Find the surface for a given root view to allow snapshotting with pixelcopy. In the window + * manager there exists 2 arrays that contain similar data + * 1. mViews (this is what we track in the observable array in the root view resolver), these are + * the root decor views + * 2. mRoots - this is an internal class that holds a reference to the decor view as well as other + * internal bits (including the surface). + * + * Therefore we go through the roots and check for a view that matches the target, if it + * matches we return the surface. It is possible for us to observe these 2 arrays slightly out + * of sync with each other which is why we do this equality matching on the view field + * + * The reason we do this and not just grab the last view is because sometimes there is a + * 'empty' root view at the top we need to ignore. The decision to decide which view to + * snapshot is done else where as it needs to be synced with the observation and traversal + */ + fun surfaceForRootView(rootView: View): Surface? { + if (!initialized) { + initialize() + } + + val roots = rootsImpls ?: return null + for (i in roots.size - 1 downTo 0) { + val rootViewImpl = roots[i] + val view = mViewField?.get(rootViewImpl) + if (view == rootView) { + return mSurfaceField?.get(rootViewImpl) as? Surface + } + } + + return null + } + + @SuppressLint("PrivateApi") + private fun initialize() { + + try { + val (windowManager, windowManagerClass) = + WindowManagerCommon.getGlobalWindowManager() ?: return + + val rootsField: Field = windowManagerClass.getDeclaredField(ROOTS_FIELD) + rootsField.isAccessible = true + rootsImpls = rootsField.get(windowManager) as ArrayList<*>? + + val rootViewImplClass = Class.forName(VIEW_ROOT_IMPL_CLAZZ) + mSurfaceField = rootViewImplClass.getDeclaredField(SURFACE_FIELD) + mSurfaceField?.isAccessible = true + + mViewField = rootViewImplClass.getDeclaredField(VIEW_FIELD) + mViewField?.isAccessible = true + + initialized = true + } catch (exception: Exception) { + Log.e(LogTag, "Failed to initialize WindowManagerUtility", exception) + } + } + + companion object { + private const val VIEW_ROOT_IMPL_CLAZZ = "android.view.ViewRootImpl" + private const val SURFACE_FIELD = "mSurface" + private const val VIEW_FIELD = "mView" + private const val ROOTS_FIELD = "mRoots" + } +} diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt index 12698ebac..16fa37c66 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/StopWatch.kt @@ -21,6 +21,14 @@ class StopWatch() { companion object { fun time(fn: () -> T): Pair { + + val start = System.currentTimeMillis() + val result = fn() + val elapsed = System.currentTimeMillis() - start + return Pair(result, elapsed) + } + + suspend fun timeSuspend(fn: suspend () -> T): Pair { val start = System.currentTimeMillis() val result = fn() val elapsed = System.currentTimeMillis() - start diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt index 1069ddd80..7856e95ce 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Throttler.kt @@ -17,7 +17,7 @@ import kotlinx.coroutines.launch * This class will throttle calls into a callback. E.g if interval is 500ms and you receive triggers * at t=0, 100, 300 400, the callback will only be triggered at t=500 */ -class Throttler(private val intervalMs: Long, val callback: () -> T) { +class Throttler(private val intervalMs: Long, val callback: suspend () -> T) { private val executionScope: CoroutineScope = CoroutineScope(Dispatchers.Main) private var throttleJob: Job? = null diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/WindowManagerCommon.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/WindowManagerCommon.kt new file mode 100644 index 000000000..6170be3e2 --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/WindowManagerCommon.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.util + +import android.os.Build +import android.util.Log +import com.facebook.flipper.plugins.uidebugger.LogTag + +object WindowManagerCommon { + + // provides access to + // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/view/WindowManagerGlobal.java + fun getGlobalWindowManager(): Pair>? { + val accessClass = + if (Build.VERSION.SDK_INT > 16) WINDOW_MANAGER_GLOBAL_CLAZZ else WINDOW_MANAGER_IMPL_CLAZZ + val instanceMethod = if (Build.VERSION.SDK_INT > 16) GET_GLOBAL_INSTANCE else GET_DEFAULT_IMPL + + try { + val clazz = Class.forName(accessClass) + val getMethod = clazz.getMethod(instanceMethod) + return Pair(getMethod.invoke(null), clazz) + } catch (exception: Exception) { + Log.e(LogTag, "Unable to get global window manager handle", exception) + return null + } + } + + private const val GET_DEFAULT_IMPL = "getDefault" + private const val GET_GLOBAL_INSTANCE = "getInstance" + private const val WINDOW_MANAGER_IMPL_CLAZZ = "android.view.WindowManagerImpl" + private const val WINDOW_MANAGER_GLOBAL_CLAZZ = "android.view.WindowManagerGlobal" +} From d26612d840dd88e0bd0b43bdbd865d1c75efcf9c Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 31/43] Add modern snapshot approach Summary: Since api level 34 there is a way to snapshot any view, prior to this you needed a window which you can only get from an activity, or a surface which required hacks. The hacks are in place for older verisons of android but ive added modern pixel copy snapshotter for future proofing in case google decide to make any of the previously used hack not work in future version of android Since there was a bunch of common code in each snap shot impl this has been pull into a utility function Reviewed By: lblasa Differential Revision: D50845284 fbshipit-source-id: c7910c45ff51fcf8636adc3d7272198ac3d4aefe --- .../plugins/uidebugger/core/Snapshot.kt | 116 ++++++++++++------ .../plugins/uidebugger/core/UIDContext.kt | 15 ++- 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index b8335866a..814c68793 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -11,7 +11,6 @@ import android.app.Activity import android.graphics.Canvas import android.os.Build import android.os.Handler -import android.os.HandlerThread import android.os.Looper import android.util.Log import android.view.PixelCopy @@ -36,22 +35,47 @@ interface Snapshotter { class CanvasSnapshotter(private val bitmapPool: BitmapPool) : Snapshotter { override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { - if (view.width <= 0 || view.height <= 0) { - return null - } - - return try { - val reuseAbleBitmap = bitmapPool.getBitmap(view.width, view.height) - val canvas = Canvas(reuseAbleBitmap.bitmap) + return SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback = null) { bitmap -> + val canvas = Canvas(bitmap.bitmap) view.draw(canvas) - reuseAbleBitmap - } catch (e: OutOfMemoryError) { - Log.e(LogTag, "OOM when taking snapshot") - null + true } } } +/** + * Uses the new api to snapshot any view regardless whether its attached to a activity or not, + * requires no hacks + */ +@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) +class ModernPixelCopySnapshotter( + private val bitmapPool: BitmapPool, + private val fallback: Snapshotter +) : Snapshotter { + private var handler = Handler(Looper.getMainLooper()) + + override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { + + return SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback) { reusableBitmap + -> + suspendCoroutine { continuation -> + // Since android U this api is actually async + val request = + PixelCopy.Request.Builder.ofWindow(view) + .setDestinationBitmap(reusableBitmap.bitmap) + .build() + PixelCopy.request( + request, { handler.post(it) }, { continuation.resume(it.status == PixelCopy.SUCCESS) }) + } + } + } +} + +/** + * Uses pixel copy api to do a snapshot, this is accurate but prior to android U we have to use a + * bit of hack to get the surface for root views not associated to an activity (added directly to + * the window manager) + */ @RequiresApi(Build.VERSION_CODES.O) class PixelCopySnapshotter( private val bitmapPool: BitmapPool, @@ -62,29 +86,9 @@ class PixelCopySnapshotter( override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { - if (view.width <= 0 || view.height <= 0) { - return null + return SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback) { + tryCopyViaActivityWindow(view, it) || tryCopyViaInternalSurface(view, it) } - - val bitmap = bitmapPool.getBitmap(view.width, view.height) - try { - if (tryCopyViaActivityWindow(view, bitmap)) { - // if this view belongs to an activity prefer this as it doesn't require private api hacks - return bitmap - } else if (tryCopyViaInternalSurface(view, bitmap)) { - return bitmap - } - } catch (e: OutOfMemoryError) { - Log.e(LogTag, "OOM when taking snapshot") - } catch (e: Exception) { - // there was some problem with the pixel copy, fall back to canvas impl - Log.e(LogTag, "Exception when taking snapshot", e) - } - - // something went wrong, use fallback - Log.i(LogTag, "Using fallback snapshot method") - bitmap.readyForReuse() - return fallback.takeSnapshot(view) } private suspend fun tryCopyViaActivityWindow( @@ -114,12 +118,44 @@ class PixelCopySnapshotter( } } - private fun pixelCopyCallback(continuation: Continuation) = { result: Int -> - if (result == PixelCopy.SUCCESS) { - continuation.resume(true) - } else { - Log.w(LogTag, "Pixel copy failed, code $result") - continuation.resume(false) + private fun pixelCopyCallback(continuation: Continuation): (Int) -> Unit = + { result: Int -> + if (result == PixelCopy.SUCCESS) { + continuation.resume(true) + } else { + Log.w(LogTag, "Pixel copy failed, code $result") + continuation.resume(false) + } + } +} + +internal object SnapshotCommon { + + internal suspend fun doSnapshotWithErrorHandling( + bitmapPool: BitmapPool, + view: View, + fallback: Snapshotter?, + snapshotStrategy: suspend (reuseableBitmap: BitmapPool.ReusableBitmap) -> Boolean + ): BitmapPool.ReusableBitmap? { + if (view.width <= 0 || view.height <= 0) { + return null } + var reusableBitmap: BitmapPool.ReusableBitmap? = null + try { + reusableBitmap = bitmapPool.getBitmap(view.width, view.height) + if (snapshotStrategy(reusableBitmap)) { + return reusableBitmap + } + } catch (e: OutOfMemoryError) { + Log.e(LogTag, "OOM when taking snapshot") + } catch (e: Exception) { + // there was some problem with the pixel copy, fall back to canvas impl + Log.e(LogTag, "Exception when taking snapshot", e) + } + + // something went wrong, use fallback, make sure to give bitmap back to pool first + Log.i(LogTag, "Using fallback snapshot method") + reusableBitmap?.readyForReuse() + return fallback?.takeSnapshot(view) } } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt index 6741b4ef7..32737c736 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt @@ -9,7 +9,9 @@ package com.facebook.flipper.plugins.uidebugger.core import android.app.Application import android.os.Build +import android.util.Log import com.facebook.flipper.core.FlipperConnection +import com.facebook.flipper.plugins.uidebugger.LogTag import com.facebook.flipper.plugins.uidebugger.common.BitmapPool import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister import com.facebook.flipper.plugins.uidebugger.model.FrameworkEvent @@ -35,15 +37,20 @@ class UIDContext( val bitmapPool = BitmapPool() private val canvasSnapshotter = CanvasSnapshotter(bitmapPool) - val snapshotter = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + private val snapshotter = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + ModernPixelCopySnapshotter(bitmapPool, canvasSnapshotter) + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { PixelCopySnapshotter(bitmapPool, applicationRef, canvasSnapshotter) } else { + Log.w( + LogTag, + "Using legacy snapshot mode, use device with API level >=26 to for pixel copy snapshot ") canvasSnapshotter } - val decorViewTracker = DecorViewTracker(this, snapshotter) - val updateQueue = UpdateQueue(this) + val decorViewTracker: DecorViewTracker = DecorViewTracker(this, snapshotter) + val updateQueue: UpdateQueue = UpdateQueue(this) val layoutTraversal: LayoutTraversal = LayoutTraversal(this) fun addFrameworkEvent(frameworkEvent: FrameworkEvent) { From 5b89331ea291f346959696f6a8c9979f4ddb8875 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 32/43] Fix case where traversal was out of sync with snapshot Summary: Its was possible for the view tree observer to be observing one root but this can a dead root with no view in it. As a result the snapshot will be empty and the observer will never fire. The layout traversal Applicaiton ref descriptor had logic to handle these dead roots, this logic is now extracted and shared between the descriptor in the traversal and by the decor view tracker so they are in sync Reviewed By: lblasa Differential Revision: D50848155 fbshipit-source-id: ce6da13df40632cbb7a302a59382b4907131d9f5 --- .../uidebugger/core/DecorViewTracker.kt | 31 ++++++++++++----- .../descriptors/ApplicationRefDescriptor.kt | 33 ++++++++++--------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt index 24720ff89..83aef111f 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt @@ -11,15 +11,30 @@ import android.util.Log import android.view.View import android.view.ViewTreeObserver import com.facebook.flipper.plugins.uidebugger.LogTag +import com.facebook.flipper.plugins.uidebugger.descriptors.ApplicationRefDescriptor import com.facebook.flipper.plugins.uidebugger.descriptors.ViewDescriptor import com.facebook.flipper.plugins.uidebugger.util.StopWatch import com.facebook.flipper.plugins.uidebugger.util.Throttler import com.facebook.flipper.plugins.uidebugger.util.objectIdentity /** - * The responsibility of this class is to find the top most decor view and add a pre draw observer - * to it This predraw observer triggers a full traversal of the UI. There should only ever be one - * active predraw listener at once + * The UIDebugger does 3 things: + * 1. Observe changes + * 2. Traverse UI hierarchy, gathering tree + * 3. Generate snapshot + * + * All 3 of these stages need to work on the same view else there will be major inconsistencies + * + * The first responsibility of this class is to track changes to root views, find the top most decor + * view and add a pre draw observer to it. There should only ever be one active predraw listener at + * once. + * + * This pre-draw observer triggers a full traversal of the UI, the traversal of the hierarchy might + * skip some branches (active child) so its essential that both the active child decision and top + * root decision match. + * + * The observer also triggers a snapshot, again its essential the same root view as we do for + * traversal and observation */ class DecorViewTracker(private val context: UIDContext, private val snapshotter: Snapshotter) { @@ -42,11 +57,13 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: // remove predraw listen from current view as its going away or will be covered currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener) - // setup new listener on top most view - val topView = rootViews.lastOrNull() - val throttler = Throttler(500) { currentDecorView?.let { traverseSnapshotAndSend(it) } } + // setup new listener on top most view, that will be the active child in traversal + val topView = rootViews.lastOrNull(ApplicationRefDescriptor::isUsefulRoot) if (topView != null) { + val throttler = + Throttler(500) { currentDecorView?.let { traverseSnapshotAndSend(it) } } + preDrawListener = ViewTreeObserver.OnPreDrawListener { throttler.trigger() @@ -60,8 +77,6 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: // schedule traversal immediately when we detect a new decor view throttler.trigger() - } else { - Log.i(LogTag, "Stack is empty") } } } diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt index 5278561bb..b5a2cde29 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt @@ -18,15 +18,7 @@ object ApplicationRefDescriptor : ChainedDescriptor() { override fun onGetActiveChild(node: ApplicationRef): Any? { val children = onGetChildren(node) - if (children.isNotEmpty()) { - val last = children.last() - if (last.javaClass.simpleName.contains("OverlayHandlerView")) { - return children.getOrNull(children.size - 2) - } - return last - } - - return null + return children.lastOrNull(ApplicationRefDescriptor::isUsefulRoot) } override fun onGetBounds(node: ApplicationRef): Bounds = DisplayMetrics.getDisplayBounds() @@ -48,19 +40,30 @@ object ApplicationRefDescriptor : ChainedDescriptor() { for (root in activeRoots) { // if there is an activity for this root view use that, - // if not just return the mystery floating decor view + // if not just return the root view that was added directly to the window manager val activity = decorViewToActivity[root] if (activity != null) { children.add(activity) } else { - if (root is ViewGroup && root.childCount > 0) { - // sometimes there is a root view on top that has no children and we dont want to add - // these as they will become active - children.add(root) - } + children.add(root) } } return children } + + fun isUsefulRoot(obj: Any): Boolean { + if (obj is Activity) { + return true + } + val isFoldableOverlayInfraView = javaClass.simpleName.contains("OverlayHandlerView") + return if (isFoldableOverlayInfraView) { + false + } else if (obj is ViewGroup) { + // sometimes there is a root view on top that has no children that isn't useful to inspect + obj.childCount > 0 + } else { + false + } + } } From 44b8a39874c98d61a5e61b429ecaf3934bc24f08 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 33/43] remove common package Summary: Just cleaning up some packages Reviewed By: lblasa Differential Revision: D50849169 fbshipit-source-id: 2b732e41ff11361dc7462598f282abb2d4116ce7 --- .../litho/descriptors/props/LayoutPropExtractor.kt | 2 +- .../plugins/uidebugger/{common => core}/BitmapPool.kt | 2 +- .../facebook/flipper/plugins/uidebugger/core/Snapshot.kt | 1 - .../facebook/flipper/plugins/uidebugger/core/UIDContext.kt | 1 - .../facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt | 1 - .../plugins/uidebugger/descriptors/DescriptorRegister.kt | 2 +- .../plugins/uidebugger/descriptors/ImageViewDescriptor.kt | 6 +++--- .../plugins/uidebugger/descriptors/ViewDescriptor.kt | 2 +- .../plugins/uidebugger/descriptors/ViewGroupDescriptor.kt | 2 +- .../plugins/uidebugger/{common => util}/EnumMapping.kt | 2 +- .../plugins/uidebugger/{common => util}/Exceptions.kt | 2 +- .../facebook/flipper/plugins/uidebugger/EnumMappingTest.kt | 2 +- 12 files changed, 11 insertions(+), 14 deletions(-) rename android/src/main/java/com/facebook/flipper/plugins/uidebugger/{common => core}/BitmapPool.kt (97%) rename android/src/main/java/com/facebook/flipper/plugins/uidebugger/{common => util}/EnumMapping.kt (97%) rename android/src/main/java/com/facebook/flipper/plugins/uidebugger/{common => util}/Exceptions.kt (82%) diff --git a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/props/LayoutPropExtractor.kt b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/props/LayoutPropExtractor.kt index 22a9f1f6c..c50549c18 100644 --- a/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/props/LayoutPropExtractor.kt +++ b/android/plugins/litho/src/main/java/com/facebook/flipper/plugins/uidebugger/litho/descriptors/props/LayoutPropExtractor.kt @@ -9,9 +9,9 @@ package com.facebook.flipper.plugins.uidebugger.litho.descriptors.props import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable -import com.facebook.flipper.plugins.uidebugger.common.enumToInspectableSet import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister import com.facebook.flipper.plugins.uidebugger.model.* +import com.facebook.flipper.plugins.uidebugger.util.enumToInspectableSet import com.facebook.litho.DebugComponent import com.facebook.yoga.* diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/BitmapPool.kt similarity index 97% rename from android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt rename to android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/BitmapPool.kt index 5a779c1a9..7d2dd19b8 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/BitmapPool.kt @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.flipper.plugins.uidebugger.common +package com.facebook.flipper.plugins.uidebugger.core import android.graphics.Bitmap import kotlinx.coroutines.CoroutineScope diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index 814c68793..3e003bc41 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -17,7 +17,6 @@ import android.view.PixelCopy import android.view.View import androidx.annotation.RequiresApi import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt index 32737c736..9d2fd9761 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UIDContext.kt @@ -12,7 +12,6 @@ import android.os.Build import android.util.Log import com.facebook.flipper.core.FlipperConnection import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister import com.facebook.flipper.plugins.uidebugger.model.FrameworkEvent import com.facebook.flipper.plugins.uidebugger.model.FrameworkEventMetadata diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt index 218ff2cd2..fd785728c 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt @@ -13,7 +13,6 @@ import android.util.Base64 import android.util.Base64OutputStream import android.util.Log import com.facebook.flipper.plugins.uidebugger.LogTag -import com.facebook.flipper.plugins.uidebugger.common.BitmapPool import com.facebook.flipper.plugins.uidebugger.descriptors.Id import com.facebook.flipper.plugins.uidebugger.descriptors.MetadataRegister import com.facebook.flipper.plugins.uidebugger.model.FrameScanEvent diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/DescriptorRegister.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/DescriptorRegister.kt index 8bdc78965..f3088bd26 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/DescriptorRegister.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/DescriptorRegister.kt @@ -16,8 +16,8 @@ import android.view.Window import android.widget.ImageView import android.widget.TextView import androidx.viewpager.widget.ViewPager -import com.facebook.flipper.plugins.uidebugger.common.UIDebuggerException import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef +import com.facebook.flipper.plugins.uidebugger.util.UIDebuggerException class DescriptorRegister { private val register: MutableMap, NodeDescriptor<*>> = HashMap() diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ImageViewDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ImageViewDescriptor.kt index a6b37146e..a85be2441 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ImageViewDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ImageViewDescriptor.kt @@ -9,12 +9,12 @@ package com.facebook.flipper.plugins.uidebugger.descriptors import android.widget.ImageView import android.widget.ImageView.ScaleType -import com.facebook.flipper.plugins.uidebugger.common.EnumMapping -import com.facebook.flipper.plugins.uidebugger.common.enumMapping -import com.facebook.flipper.plugins.uidebugger.common.enumToInspectableSet import com.facebook.flipper.plugins.uidebugger.model.Inspectable import com.facebook.flipper.plugins.uidebugger.model.InspectableObject import com.facebook.flipper.plugins.uidebugger.model.MetadataId +import com.facebook.flipper.plugins.uidebugger.util.EnumMapping +import com.facebook.flipper.plugins.uidebugger.util.enumMapping +import com.facebook.flipper.plugins.uidebugger.util.enumToInspectableSet object ImageViewDescriptor : ChainedDescriptor() { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt index 5003bb3f2..3b0b40425 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewDescriptor.kt @@ -19,8 +19,8 @@ import android.view.ViewGroup import android.widget.FrameLayout import android.widget.LinearLayout import androidx.viewpager.widget.ViewPager -import com.facebook.flipper.plugins.uidebugger.common.* import com.facebook.flipper.plugins.uidebugger.model.* +import com.facebook.flipper.plugins.uidebugger.util.EnumMapping import com.facebook.flipper.plugins.uidebugger.util.ResourcesUtil import java.lang.reflect.Field import kotlinx.serialization.json.JsonElement diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewGroupDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewGroupDescriptor.kt index bce9d9ce2..140116e4b 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewGroupDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ViewGroupDescriptor.kt @@ -11,9 +11,9 @@ import android.os.Build import android.view.View import android.view.ViewGroup import androidx.core.view.ViewGroupCompat -import com.facebook.flipper.plugins.uidebugger.common.EnumMapping import com.facebook.flipper.plugins.uidebugger.core.FragmentTracker import com.facebook.flipper.plugins.uidebugger.model.* +import com.facebook.flipper.plugins.uidebugger.util.EnumMapping object ViewGroupDescriptor : ChainedDescriptor() { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/EnumMapping.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt similarity index 97% rename from android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/EnumMapping.kt rename to android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt index 5468dc901..bd0f41edc 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/EnumMapping.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.flipper.plugins.uidebugger.common +package com.facebook.flipper.plugins.uidebugger.util import android.util.Log import com.facebook.flipper.plugins.uidebugger.LogTag diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/Exceptions.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Exceptions.kt similarity index 82% rename from android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/Exceptions.kt rename to android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Exceptions.kt index f5efa9f16..49c55aad9 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/Exceptions.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/Exceptions.kt @@ -5,6 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.flipper.plugins.uidebugger.common +package com.facebook.flipper.plugins.uidebugger.util class UIDebuggerException(message: String) : Exception(message) diff --git a/android/src/test/java/com/facebook/flipper/plugins/uidebugger/EnumMappingTest.kt b/android/src/test/java/com/facebook/flipper/plugins/uidebugger/EnumMappingTest.kt index 226c6c671..4111040f2 100644 --- a/android/src/test/java/com/facebook/flipper/plugins/uidebugger/EnumMappingTest.kt +++ b/android/src/test/java/com/facebook/flipper/plugins/uidebugger/EnumMappingTest.kt @@ -8,8 +8,8 @@ package com.facebook.flipper.plugins.uidebugger import android.view.View -import com.facebook.flipper.plugins.uidebugger.common.EnumMapping import com.facebook.flipper.plugins.uidebugger.model.InspectableValue +import com.facebook.flipper.plugins.uidebugger.util.EnumMapping import org.hamcrest.CoreMatchers.* import org.hamcrest.MatcherAssert.assertThat import org.junit.Test From bd6e1285dacb9923685f5739df20c27416f8f445 Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 34/43] Only pixel copy if view is hardwell accell Summary: You can only use pixel copy if the view is drawn by the hardware, this sort of makes sense as there is no hardware buffer to copy from. we were falling back but there was a lot of noise in the logs Reviewed By: lblasa Differential Revision: D50853427 fbshipit-source-id: 9365a3d566a05de9082afb8bc2915922c624fd88 --- .../plugins/uidebugger/core/Snapshot.kt | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index 3e003bc41..fb38f0130 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -55,17 +55,22 @@ class ModernPixelCopySnapshotter( override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { - return SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback) { reusableBitmap - -> - suspendCoroutine { continuation -> - // Since android U this api is actually async - val request = - PixelCopy.Request.Builder.ofWindow(view) - .setDestinationBitmap(reusableBitmap.bitmap) - .build() - PixelCopy.request( - request, { handler.post(it) }, { continuation.resume(it.status == PixelCopy.SUCCESS) }) + return if (view.isHardwareAccelerated) { + SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback) { reusableBitmap -> + suspendCoroutine { continuation -> + // Since android U this api is actually async + val request = + PixelCopy.Request.Builder.ofWindow(view) + .setDestinationBitmap(reusableBitmap.bitmap) + .build() + PixelCopy.request( + request, + { handler.post(it) }, + { continuation.resume(it.status == PixelCopy.SUCCESS) }) + } } + } else { + fallback.takeSnapshot(view) } } } @@ -85,8 +90,12 @@ class PixelCopySnapshotter( override suspend fun takeSnapshot(view: View): BitmapPool.ReusableBitmap? { - return SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback) { - tryCopyViaActivityWindow(view, it) || tryCopyViaInternalSurface(view, it) + return if (view.isHardwareAccelerated) { + SnapshotCommon.doSnapshotWithErrorHandling(bitmapPool, view, fallback) { + tryCopyViaActivityWindow(view, it) || tryCopyViaInternalSurface(view, it) + } + } else { + fallback.takeSnapshot(view) } } From 62e9181075f614123adfb060ddb4fe3510de2f3c Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 35/43] Improve logging Summary: Lets make the logging higher signal Reviewed By: passy Differential Revision: D50853449 fbshipit-source-id: 95ebfbc142c34c36fb11e459c573842580cd6e4c --- .../flipper/plugins/uidebugger/core/DecorViewTracker.kt | 7 ++++--- .../flipper/plugins/uidebugger/core/UpdateQueue.kt | 2 -- .../flipper/plugins/uidebugger/util/EnumMapping.kt | 5 ----- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt index 83aef111f..64a7fab24 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt @@ -43,7 +43,6 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: private val mStopWatch = StopWatch() fun start() { - Log.i(LogTag, "Subscribing activity / root view changes") val applicationRef = context.applicationRef @@ -55,6 +54,7 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: override fun onRootViewsChanged(rootViews: List) { // remove predraw listen from current view as its going away or will be covered + Log.i(LogTag, "Removing pre draw listener from ${currentDecorView?.objectIdentity()}") currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener) // setup new listener on top most view, that will be the active child in traversal @@ -85,8 +85,9 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: // On subscribe, trigger a traversal on whatever roots we have rootViewListener.onRootViewsChanged(applicationRef.rootsResolver.rootViews()) - Log.i(LogTag, "${context.applicationRef.rootsResolver.rootViews().size} root views") - Log.i(LogTag, "${context.applicationRef.activitiesStack.size} activities") + Log.i( + LogTag, + "Starting tracking root views, currently ${context.applicationRef.rootsResolver.rootViews().size} root views") } fun stop() { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt index fd785728c..23b6b59cb 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/UpdateQueue.kt @@ -131,8 +131,6 @@ class UpdateQueue(val context: UIDContext) { val (_, sendTimeMs) = StopWatch.time { context.connectionRef.connection?.send(FrameScanEvent.name, serialized) } - Log.i(LogTag, "Sent frame with nodes ${nodes.size}") - // Note about payload size: // Payload size is an approximation as it assumes all characters // are ASCII encodable, this should be true for most of the payload content. diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt index bd0f41edc..71f5a786f 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/util/EnumMapping.kt @@ -7,8 +7,6 @@ package com.facebook.flipper.plugins.uidebugger.util -import android.util.Log -import com.facebook.flipper.plugins.uidebugger.LogTag import com.facebook.flipper.plugins.uidebugger.model.InspectableValue // Maintains 2 way mapping between some enum value and a readable string representation @@ -19,9 +17,6 @@ open class EnumMapping(private val mapping: Map) { return if (entry != null) { entry.key } else { - Log.v( - LogTag, - "Could not convert enum value ${enumValue.toString()} to string, known values ${mapping.entries}") NoMapping } } From 3bb3ce6a667f381b58d3b90fd24546074840f04d Mon Sep 17 00:00:00 2001 From: Luke De Feo Date: Thu, 2 Nov 2023 12:29:07 -0700 Subject: [PATCH 36/43] Fix media gallery activity Summary: Weird edge case, this activity doesnt actualy contain the content and instead its in the decor view behind it, solution is to filter it out from traversal and snapshot https://fb.workplace.com/groups/443457641253219/permalink/643518977913750/ Reviewed By: elboman, lblasa Differential Revision: D50936817 fbshipit-source-id: 8c1e276d4d943c42c9c2085bf70113347cbd5c74 --- .../uidebugger/core/ActivityTracker.kt | 6 ++++ .../plugins/uidebugger/core/ApplicationRef.kt | 1 + .../uidebugger/core/DecorViewTracker.kt | 10 +++++- .../plugins/uidebugger/core/Snapshot.kt | 4 +-- .../descriptors/ApplicationRefDescriptor.kt | 33 ++++++++++++++----- 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ActivityTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ActivityTracker.kt index 15e707cb8..0fa8745f8 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ActivityTracker.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ActivityTracker.kt @@ -12,6 +12,7 @@ import android.app.Activity import android.app.Application import android.os.Build import android.os.Bundle +import android.view.View import java.lang.ref.WeakReference import java.lang.reflect.Field import java.lang.reflect.Method @@ -103,6 +104,11 @@ object ActivityTracker : Application.ActivityLifecycleCallbacks { return stack } + val decorViewToActivityMap: Map + get() { + return activitiesStack.toList().associateBy { it.window.decorView } + } + /** * Activity tracker is used to track activities. However, it cannot track via life-cycle events * all those activities that were created prior to initialisation via the `start(application: diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt index 69f4e307d..52bf230d1 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt @@ -9,6 +9,7 @@ package com.facebook.flipper.plugins.uidebugger.core import android.app.Activity import android.app.Application +import android.view.View class ApplicationRef(val application: Application) { init { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt index 64a7fab24..25f57ac69 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/DecorViewTracker.kt @@ -7,6 +7,7 @@ package com.facebook.flipper.plugins.uidebugger.core +import android.app.Activity import android.util.Log import android.view.View import android.view.ViewTreeObserver @@ -58,7 +59,14 @@ class DecorViewTracker(private val context: UIDContext, private val snapshotter: currentDecorView?.viewTreeObserver?.removeOnPreDrawListener(preDrawListener) // setup new listener on top most view, that will be the active child in traversal - val topView = rootViews.lastOrNull(ApplicationRefDescriptor::isUsefulRoot) + + val decorViewToActivity: Map = ActivityTracker.decorViewToActivityMap + + val topView = + rootViews.lastOrNull { view -> + val activityOrView = decorViewToActivity[view] ?: view + ApplicationRefDescriptor.isUsefulRoot(activityOrView) + } if (topView != null) { val throttler = diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index fb38f0130..24c564944 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -104,8 +104,8 @@ class PixelCopySnapshotter( bitmap: BitmapPool.ReusableBitmap ): Boolean { - val decorViewToActivity: Map = - applicationRef.activitiesStack.toList().associateBy { it.window.decorView } + + val decorViewToActivity: Map = ActivityTracker.decorViewToActivityMap val activityForDecorView = decorViewToActivity[view] ?: return false diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt index b5a2cde29..3195c5409 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/descriptors/ApplicationRefDescriptor.kt @@ -10,6 +10,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors import android.app.Activity import android.view.View import android.view.ViewGroup +import com.facebook.flipper.plugins.uidebugger.core.ActivityTracker import com.facebook.flipper.plugins.uidebugger.core.ApplicationRef import com.facebook.flipper.plugins.uidebugger.model.Bounds import com.facebook.flipper.plugins.uidebugger.util.DisplayMetrics @@ -33,12 +34,11 @@ object ApplicationRefDescriptor : ChainedDescriptor() { override fun onGetChildren(node: ApplicationRef): List { val children = mutableListOf() - val activeRoots = node.rootsResolver.rootViews() + val rootViews = node.rootsResolver.rootViews() - val decorViewToActivity: Map = - node.activitiesStack.toList().associateBy { it.window.decorView } + val decorViewToActivity: Map = ActivityTracker.decorViewToActivityMap - for (root in activeRoots) { + for (root in rootViews) { // if there is an activity for this root view use that, // if not just return the root view that was added directly to the window manager val activity = decorViewToActivity[root] @@ -52,16 +52,31 @@ object ApplicationRefDescriptor : ChainedDescriptor() { return children } - fun isUsefulRoot(obj: Any): Boolean { - if (obj is Activity) { + /** + * arg is either an acitivity if the root view has one other views the root view attached to the + * window manager returns boolean indicating whether we are interested in it and whether we should + * track, traverse and snapshot it + */ + fun isUsefulRoot(rootViewOrActivity: Any): Boolean { + val className = rootViewOrActivity.javaClass.name + + if (className.contains("mediagallery.ui.MediaGalleryActivity")) { + // this activity doesn't contain the content and its actually in the decor view behind it, so + // skip it :/ + return false + } + + if (rootViewOrActivity is Activity) { + // in general we want views attached to activities return true } - val isFoldableOverlayInfraView = javaClass.simpleName.contains("OverlayHandlerView") + + val isFoldableOverlayInfraView = className.contains("OverlayHandlerView") return if (isFoldableOverlayInfraView) { false - } else if (obj is ViewGroup) { + } else if (rootViewOrActivity is ViewGroup) { // sometimes there is a root view on top that has no children that isn't useful to inspect - obj.childCount > 0 + rootViewOrActivity.childCount > 0 } else { false } From 99dbcfa079d5d5c39df53cf5aed85e8c2489eb1f Mon Sep 17 00:00:00 2001 From: Anton Kastritskiy Date: Fri, 3 Nov 2023 06:16:18 -0700 Subject: [PATCH 37/43] casing convension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: [eslint-typescript/naming-convension rule docs](https://typescript-eslint.io/rules/naming-convention/) Initially looked into it to enforce UPPER_CASE for top most constants like `const DELAY = 10` which is a standard in js ecosystem, which turned to be more difficuilt(we will still get there). Turns out we had casing checks disabled for everything but typeLike names. What I did in this diff - use default setting for eslint rule `✖ 9890 problems` - with any propery names `✖ 8229 problems` - without checking properies at all `✖ 3683 problems` - without checking enum members `✖ 3231 problems` - without checking object properties/methods `✖ 2978 problems` - allowing PascalCase for variables `✖ 1657 problems - allowing PascalCase for functions `✖ 975 problems - not checking typeMethod and parameters `✖ 916 problems` - allow double underscore before after variable `✖ 461 problems` - allow snake_case variables `✖ 49 problems` Fix remaining problems. Future plans. Ban usage of PascalCase for variables that are not components Reviewed By: LukeDefeo Differential Revision: D50970193 fbshipit-source-id: d9f3abe6b02c9f7822598c8fa5382f58d067f70e --- desktop/.eslintrc.js | 24 +++++++++++++++++++ .../src/__tests__/TestPlugin.tsx | 2 +- .../src/globalsReplacements/fakeReactDOM.tsx | 1 + .../src/__tests__/test-utils/TestPlugin.tsx | 2 +- .../src/ui/components/Orderable.tsx | 1 + .../components/searchable/SearchableTable.tsx | 1 + .../src/ui/components/table/ManagedTable.tsx | 1 + 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/desktop/.eslintrc.js b/desktop/.eslintrc.js index c66b79852..bf176de6d 100644 --- a/desktop/.eslintrc.js +++ b/desktop/.eslintrc.js @@ -214,11 +214,35 @@ module.exports = { ], '@typescript-eslint/naming-convention': [ 2, + { + selector: 'default', + format: ['camelCase'], + leadingUnderscore: 'allow', + trailingUnderscore: 'allow', + }, + { + selector: 'variable', + format: ['camelCase', 'UPPER_CASE', 'PascalCase', 'snake_case'], + leadingUnderscore: 'allowSingleOrDouble', + trailingUnderscore: 'allowSingleOrDouble', + }, + { + selector: 'function', + format: ['camelCase', 'PascalCase'], + leadingUnderscore: 'allow', + trailingUnderscore: 'allow', + }, { selector: 'typeLike', format: ['PascalCase', 'UPPER_CASE'], leadingUnderscore: 'allow', }, + { + selector: ['property', 'method', 'memberLike', 'parameter'], + // do not enforce naming convention for properties + // no support for kebab-case + format: null, + }, ], '@typescript-eslint/no-non-null-assertion': 'warn', }, diff --git a/desktop/flipper-plugin/src/__tests__/TestPlugin.tsx b/desktop/flipper-plugin/src/__tests__/TestPlugin.tsx index 17705ab4e..5465cc6f9 100644 --- a/desktop/flipper-plugin/src/__tests__/TestPlugin.tsx +++ b/desktop/flipper-plugin/src/__tests__/TestPlugin.tsx @@ -57,7 +57,7 @@ export function plugin(client: PluginClient) { }); }); - function _unused_JustTypeChecks() { + function _unusedJustTypeChecks() { // @ts-expect-error Argument of type '"bla"' is not assignable client.send('bla', {}); // @ts-expect-error Argument of type '{ stuff: string; }' is not assignable to parameter of type diff --git a/desktop/flipper-server-companion/src/globalsReplacements/fakeReactDOM.tsx b/desktop/flipper-server-companion/src/globalsReplacements/fakeReactDOM.tsx index cf6fbc190..b7c372de3 100644 --- a/desktop/flipper-server-companion/src/globalsReplacements/fakeReactDOM.tsx +++ b/desktop/flipper-server-companion/src/globalsReplacements/fakeReactDOM.tsx @@ -7,6 +7,7 @@ * @format */ +// eslint-disable-next-line @typescript-eslint/naming-convention export const unstable_batchedUpdates = (cb: () => void) => { return cb(); }; diff --git a/desktop/flipper-ui-core/src/__tests__/test-utils/TestPlugin.tsx b/desktop/flipper-ui-core/src/__tests__/test-utils/TestPlugin.tsx index ed3a8a4ca..279d96de5 100644 --- a/desktop/flipper-ui-core/src/__tests__/test-utils/TestPlugin.tsx +++ b/desktop/flipper-ui-core/src/__tests__/test-utils/TestPlugin.tsx @@ -52,7 +52,7 @@ export function plugin(client: PluginClient) { }); }); - function _unused_JustTypeChecks() { + function _unusedJustTypeChecks() { // @ts-expect-error Argument of type '"bla"' is not assignable client.send('bla', {}); // @ts-expect-error Argument of type '{ stuff: string; }' is not assignable to parameter of type diff --git a/desktop/flipper-ui-core/src/ui/components/Orderable.tsx b/desktop/flipper-ui-core/src/ui/components/Orderable.tsx index d639ff095..2210a7e07 100644 --- a/desktop/flipper-ui-core/src/ui/components/Orderable.tsx +++ b/desktop/flipper-ui-core/src/ui/components/Orderable.tsx @@ -120,6 +120,7 @@ export default class Orderable extends React.Component< return !this.state.movingOrder; } + // eslint-disable-next-line @typescript-eslint/naming-convention UNSAFE_componentWillReceiveProps(nextProps: OrderableProps) { this.setState({ order: nextProps.order, diff --git a/desktop/flipper-ui-core/src/ui/components/searchable/SearchableTable.tsx b/desktop/flipper-ui-core/src/ui/components/searchable/SearchableTable.tsx index d3df581bd..7718b45c6 100644 --- a/desktop/flipper-ui-core/src/ui/components/searchable/SearchableTable.tsx +++ b/desktop/flipper-ui-core/src/ui/components/searchable/SearchableTable.tsx @@ -120,6 +120,7 @@ class SearchableManagedTable extends PureComponent { this.props.defaultFilters.map(this.props.addFilter); } + // eslint-disable-next-line @typescript-eslint/naming-convention UNSAFE_componentWillReceiveProps(nextProps: Props) { if ( nextProps.searchTerm !== this.props.searchTerm || diff --git a/desktop/flipper-ui-core/src/ui/components/table/ManagedTable.tsx b/desktop/flipper-ui-core/src/ui/components/table/ManagedTable.tsx index f9c3919af..b40b075ec 100644 --- a/desktop/flipper-ui-core/src/ui/components/table/ManagedTable.tsx +++ b/desktop/flipper-ui-core/src/ui/components/table/ManagedTable.tsx @@ -229,6 +229,7 @@ export class ManagedTable extends React.Component< } } + // eslint-disable-next-line @typescript-eslint/naming-convention UNSAFE_componentWillReceiveProps(nextProps: ManagedTableProps) { // if columnSizes has changed if (nextProps.columnSizes !== this.props.columnSizes) { From 36cb69e1fdac749cc6fd7208a7692c991bbeb6f5 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005325672 Date: Fri, 3 Nov 2023 07:00:14 -0700 Subject: [PATCH 38/43] Daily `arc lint --take KTFMT` Reviewed By: martintrojer Differential Revision: D50964272 fbshipit-source-id: 1bdfffd1b32f76f2a81e95c6a59e15805a3a9436 --- .../facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt | 1 - .../com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt index 52bf230d1..69f4e307d 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/ApplicationRef.kt @@ -9,7 +9,6 @@ package com.facebook.flipper.plugins.uidebugger.core import android.app.Activity import android.app.Application -import android.view.View class ApplicationRef(val application: Application) { init { diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt index 24c564944..dc4f6b9fb 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/core/Snapshot.kt @@ -104,8 +104,7 @@ class PixelCopySnapshotter( bitmap: BitmapPool.ReusableBitmap ): Boolean { - - val decorViewToActivity: Map = ActivityTracker.decorViewToActivityMap + val decorViewToActivity: Map = ActivityTracker.decorViewToActivityMap val activityForDecorView = decorViewToActivity[view] ?: return false From 9c5df1516fd40b998c39f74c30ef3722e9bd22ff Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Fri, 3 Nov 2023 08:03:50 -0700 Subject: [PATCH 39/43] Export legacy MasterDetail and DataTable Summary: Allow plugin developers to force old search for migration purposes Reviewed By: LukeDefeo Differential Revision: D50969832 fbshipit-source-id: 7fe5c3e65680d628bced2cd09823f7f3c132d33a --- desktop/flipper-plugin/src/__tests__/api.node.tsx | 4 ++++ desktop/flipper-plugin/src/index.tsx | 7 +++++++ docs/extending/flipper-plugin.mdx | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/desktop/flipper-plugin/src/__tests__/api.node.tsx b/desktop/flipper-plugin/src/__tests__/api.node.tsx index ecdcd71e3..a42f69b26 100644 --- a/desktop/flipper-plugin/src/__tests__/api.node.tsx +++ b/desktop/flipper-plugin/src/__tests__/api.node.tsx @@ -35,6 +35,7 @@ test('Correct top level API exposed', () => { "DataList", "DataSource", "DataTable", + "DataTableLegacy", "DetailSidebar", "Dialog", "ElementsInspector", @@ -44,6 +45,7 @@ test('Correct top level API exposed', () => { "Layout", "MarkerTimeline", "MasterDetail", + "MasterDetailLegacy", "NUX", "Panel", "PowerSearch", @@ -97,7 +99,9 @@ test('Correct top level API exposed', () => { "DataInspectorExpanded", "DataSourceVirtualizer", "DataTableColumn", + "DataTableColumnLegacy", "DataTableManager", + "DataTableManagerLegacy", "DataValueExtractor", "DefaultKeyboardAction", "Device", diff --git a/desktop/flipper-plugin/src/index.tsx b/desktop/flipper-plugin/src/index.tsx index 9c3c403cb..7b6e0ce6a 100644 --- a/desktop/flipper-plugin/src/index.tsx +++ b/desktop/flipper-plugin/src/index.tsx @@ -37,7 +37,9 @@ export { export {Sidebar as _Sidebar} from './ui/Sidebar'; export {DetailSidebar} from './ui/DetailSidebar'; export {Toolbar} from './ui/Toolbar'; + export {MasterDetail} from './ui/MasterDetail'; +export {MasterDetail as MasterDetailLegacy} from './ui/MasterDetail'; export {MasterDetailWithPowerSearch as _MasterDetailWithPowerSearch} from './ui/MasterDetailWithPowerSearch'; export {CodeBlock} from './ui/CodeBlock'; @@ -58,7 +60,12 @@ export {DataFormatter} from './ui/DataFormatter'; export {useLogger, _LoggerContext} from './utils/useLogger'; export {DataTable, DataTableColumn} from './ui/data-table/DataTable'; +export { + DataTable as DataTableLegacy, + DataTableColumn as DataTableColumnLegacy, +} from './ui/data-table/DataTable'; export {DataTableManager} from './ui/data-table/DataTableManager'; +export {DataTableManager as DataTableManagerLegacy} from './ui/data-table/DataTableManager'; export { DataTable as _DataTableWithPowerSearch, DataTableColumn as _DataTableColumnWithPowerSearch, diff --git a/docs/extending/flipper-plugin.mdx b/docs/extending/flipper-plugin.mdx index 7fcb3748c..c4c9c9a1c 100644 --- a/docs/extending/flipper-plugin.mdx +++ b/docs/extending/flipper-plugin.mdx @@ -982,6 +982,10 @@ function HighlightedText(props: {text: string}) { ### dataTablePowerSearchOperators +### MasterDetailLegacy + +### DataTableLegacy + Coming soon ### MasterDetail From d9ecac4bc2811d6ba68bfaa76eb7f81a05484868 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Fri, 3 Nov 2023 08:03:50 -0700 Subject: [PATCH 40/43] Track legacy manager API access Summary: We swap legacy MasterDetail and DataTable with the new ones that have power search. The new ones have partially incompatible table manager API. This diff adds a warning, a migration guide and tracking for these cases. Reviewed By: LukeDefeo Differential Revision: D50969831 fbshipit-source-id: ef4153fec9720ea5d7ae1cb4df3528c5d6bca2bb --- .../DataTableWithPowerSearchManager.tsx | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx b/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx index 897d02d0f..7295309f9 100644 --- a/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx +++ b/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearchManager.tsx @@ -15,6 +15,7 @@ import produce, {castDraft, immerable, original} from 'immer'; import {DataSource, getFlipperLib, _DataSourceView} from 'flipper-plugin-core'; import {SearchExpressionTerm} from '../PowerSearch'; import {PowerSearchOperatorProcessorConfig} from './DataTableDefaultPowerSearchOperators'; +import {DataTableManager as DataTableManagerLegacy} from './DataTableManager'; export type OnColumnResize = (id: string, size: number | Percentage) => void; export type Sorting = { @@ -259,6 +260,16 @@ export type DataTableManager = { stateRef: RefObject>>; toggleSideBySide(): void; setFilterExceptions(exceptions: string[] | undefined): void; +} & Omit, 'stateRef'>; + +const showPowerSearchMigrationWarning = () => { + console.warn( + 'Flipper is migrating to the new power search (see https://fburl.com/workplace/eewxik3o). Your plugin uses tableManagerRef which is partially incompatible with the new API. THIS API CALL DOES NOTHING AT THIS POINT! Please, migrate to the new API by explicitly using _MasterDetailWithPowerSearch, _DataTableWithPowerSearch, _DataTableWithPowerSearchManager (see https://fburl.com/code/dpawdt69). As a temporary workaround, feel free to use legacy MasterDetailLegacy, DataTableLegacy, DataTableManagerLegacy components to force the usage of the old search.', + ); + getFlipperLib().logger.track( + 'usage', + 'data-table:filter:power-search-legacy-api-access', + ); }; export function createDataTableManager( @@ -313,6 +324,30 @@ export function createDataTableManager( }, dataView, stateRef, + showSearchDropdown() { + showPowerSearchMigrationWarning(); + }, + setSearchValue() { + showPowerSearchMigrationWarning(); + }, + setSearchHighlightColor() { + showPowerSearchMigrationWarning(); + }, + setShowNumberedHistory() { + showPowerSearchMigrationWarning(); + }, + toggleSearchValue() { + showPowerSearchMigrationWarning(); + }, + toggleHighlightSearch() { + showPowerSearchMigrationWarning(); + }, + addColumnFilter() { + showPowerSearchMigrationWarning(); + }, + removeColumnFilter() { + showPowerSearchMigrationWarning(); + }, }; } From 7c5ede7a5e43809ab22ea990f9d6e8d7d27b68fc Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Fri, 3 Nov 2023 08:03:50 -0700 Subject: [PATCH 41/43] Force legacy search for network plugin Summary: Uses legacy API `tableManagerRef.current?.setSearchValue` not currently available in power search Reviewed By: LukeDefeo Differential Revision: D50969833 fbshipit-source-id: c83d9dce24f5d7a37b6cc68e19da2ae5da374941 --- desktop/plugins/public/network/index.tsx | 6 +++--- .../public/network/request-mocking/NetworkRouteManager.tsx | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/desktop/plugins/public/network/index.tsx b/desktop/plugins/public/network/index.tsx index e056dd712..5a991a007 100644 --- a/desktop/plugins/public/network/index.tsx +++ b/desktop/plugins/public/network/index.tsx @@ -28,9 +28,9 @@ import { usePlugin, useValue, createDataSource, - DataTable, - DataTableColumn, - DataTableManager, + DataTableLegacy as DataTable, + DataTableColumnLegacy as DataTableColumn, + DataTableManagerLegacy as DataTableManager, theme, renderReactRoot, batch, diff --git a/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx b/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx index 9322d0bc8..d058e0201 100644 --- a/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx +++ b/desktop/plugins/public/network/request-mocking/NetworkRouteManager.tsx @@ -7,7 +7,11 @@ * @format */ -import {Atom, DataTableManager, getFlipperLib} from 'flipper-plugin'; +import { + Atom, + DataTableManagerLegacy as DataTableManager, + getFlipperLib, +} from 'flipper-plugin'; import {createContext} from 'react'; import {Header, Request} from '../types'; From ddeda3f851710647e9485479355a62d7cf2f61fd Mon Sep 17 00:00:00 2001 From: generatedunixname89002005306973 Date: Fri, 3 Nov 2023 16:03:43 -0700 Subject: [PATCH 42/43] Flipper Release: v0.236.0 Summary: Releasing version 0.236.0 Reviewed By: aigoncharov Differential Revision: D50975304 fbshipit-source-id: 3181dd2f913c23324e0dfbdaa068bfc32e653e12 --- desktop/package.json | 2 +- desktop/plugins/public/layout/docs/setup.mdx | 2 +- desktop/plugins/public/leak_canary/docs/setup.mdx | 2 +- desktop/plugins/public/network/docs/setup.mdx | 2 +- docs/getting-started/android-native.mdx | 4 ++-- docs/getting-started/react-native-ios.mdx | 2 +- docs/getting-started/react-native.mdx | 4 ++-- gradle.properties | 2 +- js/js-flipper/package.json | 2 +- react-native/react-native-flipper/package.json | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/desktop/package.json b/desktop/package.json index 7bda8730d..d38a3eb76 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -170,7 +170,7 @@ "npm": "use yarn instead", "yarn": "^1.16" }, - "version": "0.235.0", + "version": "0.236.0", "workspaces": { "packages": [ "scripts", diff --git a/desktop/plugins/public/layout/docs/setup.mdx b/desktop/plugins/public/layout/docs/setup.mdx index 6952b86b1..6e412487f 100644 --- a/desktop/plugins/public/layout/docs/setup.mdx +++ b/desktop/plugins/public/layout/docs/setup.mdx @@ -27,7 +27,7 @@ You also need to compile in the `litho-annotations` package, as Flipper reflects ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-litho-plugin:0.235.0' + debugImplementation 'com.facebook.flipper:flipper-litho-plugin:0.236.0' debugImplementation 'com.facebook.litho:litho-annotations:0.19.0' // ... } diff --git a/desktop/plugins/public/leak_canary/docs/setup.mdx b/desktop/plugins/public/leak_canary/docs/setup.mdx index 4d673f419..de5fa68a8 100644 --- a/desktop/plugins/public/leak_canary/docs/setup.mdx +++ b/desktop/plugins/public/leak_canary/docs/setup.mdx @@ -8,7 +8,7 @@ To setup the LeakCan ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-leakcanary2-plugin:0.235.0' + debugImplementation 'com.facebook.flipper:flipper-leakcanary2-plugin:0.236.0' debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' } ``` diff --git a/desktop/plugins/public/network/docs/setup.mdx b/desktop/plugins/public/network/docs/setup.mdx index f9f355a37..f48aa99c8 100644 --- a/desktop/plugins/public/network/docs/setup.mdx +++ b/desktop/plugins/public/network/docs/setup.mdx @@ -12,7 +12,7 @@ The network plugin is shipped as a separate Maven artifact, as follows: ```groovy dependencies { - debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.235.0' + debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.236.0' } ``` diff --git a/docs/getting-started/android-native.mdx b/docs/getting-started/android-native.mdx index cc01bee33..fa3ac3b59 100644 --- a/docs/getting-started/android-native.mdx +++ b/docs/getting-started/android-native.mdx @@ -24,10 +24,10 @@ repositories { } dependencies { - debugImplementation 'com.facebook.flipper:flipper:0.235.0' + debugImplementation 'com.facebook.flipper:flipper:0.236.0' debugImplementation 'com.facebook.soloader:soloader:0.10.5' - releaseImplementation 'com.facebook.flipper:flipper-noop:0.235.0' + releaseImplementation 'com.facebook.flipper:flipper-noop:0.236.0' } ``` diff --git a/docs/getting-started/react-native-ios.mdx b/docs/getting-started/react-native-ios.mdx index a968f4da9..55ae4a470 100644 --- a/docs/getting-started/react-native-ios.mdx +++ b/docs/getting-started/react-native-ios.mdx @@ -51,7 +51,7 @@ Add all of the code below to your `ios/Podfile`: platform :ios, '9.0' def flipper_pods() - flipperkit_version = '0.235.0' # should match the version of your Flipper client app + flipperkit_version = '0.236.0' # should match the version of your Flipper client app pod 'FlipperKit', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/FlipperKitLayoutPlugin', '~>' + flipperkit_version, :configuration => 'Debug' pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version, :configuration => 'Debug' diff --git a/docs/getting-started/react-native.mdx b/docs/getting-started/react-native.mdx index 8dbb900ec..3ae9808fb 100644 --- a/docs/getting-started/react-native.mdx +++ b/docs/getting-started/react-native.mdx @@ -34,7 +34,7 @@ Latest version of Flipper requires react-native 0.69+! If you use react-native < Android: -1. Bump the `FLIPPER_VERSION` variable in `android/gradle.properties`, for example: `FLIPPER_VERSION=0.235.0`. +1. Bump the `FLIPPER_VERSION` variable in `android/gradle.properties`, for example: `FLIPPER_VERSION=0.236.0`. 2. Run `./gradlew clean` in the `android` directory. iOS: @@ -44,7 +44,7 @@ react-native version => 0.69.0 2. Run `pod install --repo-update` in the `ios` directory. react-native version < 0.69.0 -1. Call `use_flipper` with a specific version in `ios/Podfile`, for example: `use_flipper!({ 'Flipper' => '0.235.0' })`. +1. Call `use_flipper` with a specific version in `ios/Podfile`, for example: `use_flipper!({ 'Flipper' => '0.236.0' })`. 2. Run `pod install --repo-update` in the `ios` directory. ## Manual Setup diff --git a/gradle.properties b/gradle.properties index 22aa4764e..ad2752c71 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # POM publishing constants -VERSION_NAME=0.235.1-SNAPSHOT +VERSION_NAME=0.236.0 GROUP=com.facebook.flipper SONATYPE_STAGING_PROFILE=comfacebook POM_URL=https://github.com/facebook/flipper diff --git a/js/js-flipper/package.json b/js/js-flipper/package.json index 153db6da1..fb8effe64 100644 --- a/js/js-flipper/package.json +++ b/js/js-flipper/package.json @@ -1,7 +1,7 @@ { "name": "js-flipper", "title": "JS Flipper Bindings for Web-Socket based clients", - "version": "0.235.0", + "version": "0.236.0", "main": "lib/index.js", "browser": { "os": false diff --git a/react-native/react-native-flipper/package.json b/react-native/react-native-flipper/package.json index 80a69c62a..b423a3895 100644 --- a/react-native/react-native-flipper/package.json +++ b/react-native/react-native-flipper/package.json @@ -1,7 +1,7 @@ { "name": "react-native-flipper", "title": "React Native Flipper Bindings", - "version": "0.235.0", + "version": "0.236.0", "description": "Flipper bindings for React Native", "main": "index.js", "types": "index.d.ts", From 4fa25b077057970d071c724259893bbb36a74960 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005306973 Date: Fri, 3 Nov 2023 16:03:43 -0700 Subject: [PATCH 43/43] Flipper Snapshot Bump: v0.236.1-SNAPSHOT Summary: Releasing snapshot version 0.236.1-SNAPSHOT Reviewed By: aigoncharov Differential Revision: D50975303 fbshipit-source-id: 47629fbf8fd241ebcc05d4fd09ec72234ae3c53c --- docs/getting-started/android-native.mdx | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/android-native.mdx b/docs/getting-started/android-native.mdx index fa3ac3b59..8d5c5bc09 100644 --- a/docs/getting-started/android-native.mdx +++ b/docs/getting-started/android-native.mdx @@ -124,10 +124,10 @@ repositories { } dependencies { - debugImplementation 'com.facebook.flipper:flipper:0.235.1-SNAPSHOT' + debugImplementation 'com.facebook.flipper:flipper:0.236.1-SNAPSHOT' debugImplementation 'com.facebook.soloader:soloader:0.10.5' - releaseImplementation 'com.facebook.flipper:flipper-noop:0.235.1-SNAPSHOT' + releaseImplementation 'com.facebook.flipper:flipper-noop:0.236.1-SNAPSHOT' } ``` diff --git a/gradle.properties b/gradle.properties index ad2752c71..534de3e27 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # POM publishing constants -VERSION_NAME=0.236.0 +VERSION_NAME=0.236.1-SNAPSHOT GROUP=com.facebook.flipper SONATYPE_STAGING_PROFILE=comfacebook POM_URL=https://github.com/facebook/flipper