@salve-software/mako-react-native 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NitroMako.podspec +31 -0
- package/README.md +90 -0
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +148 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +9 -0
- package/android/src/main/java/com/margelo/nitro/mako/HybridMako.kt +235 -0
- package/android/src/main/java/com/margelo/nitro/mako/MakoPackage.kt +18 -0
- package/android/src/main/java/com/margelo/nitro/mako/PerformanceMonitor.kt +260 -0
- package/ios/Bridge.h +8 -0
- package/ios/HybridMako.swift +245 -0
- package/ios/PerformanceMonitor.swift +223 -0
- package/lib/commonjs/index.js +17 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/library/client/constants.js +34 -0
- package/lib/commonjs/library/client/constants.js.map +1 -0
- package/lib/commonjs/library/client/index.js +28 -0
- package/lib/commonjs/library/client/index.js.map +1 -0
- package/lib/commonjs/library/client/mako-client.js +419 -0
- package/lib/commonjs/library/client/mako-client.js.map +1 -0
- package/lib/commonjs/library/component-handler/component-handler.js +158 -0
- package/lib/commonjs/library/component-handler/component-handler.js.map +1 -0
- package/lib/commonjs/library/component-handler/index.js +39 -0
- package/lib/commonjs/library/component-handler/index.js.map +1 -0
- package/lib/commonjs/library/component-handler/types.js +6 -0
- package/lib/commonjs/library/component-handler/types.js.map +1 -0
- package/lib/commonjs/library/component-handler/utils/index.js +26 -0
- package/lib/commonjs/library/component-handler/utils/index.js.map +1 -0
- package/lib/commonjs/library/device/device-handler.js +80 -0
- package/lib/commonjs/library/device/device-handler.js.map +1 -0
- package/lib/commonjs/library/device/index.js +9 -0
- package/lib/commonjs/library/device/index.js.map +1 -0
- package/lib/commonjs/library/device/types.js +2 -0
- package/lib/commonjs/library/device/types.js.map +1 -0
- package/lib/commonjs/library/device/utils/generate-uuid.js +14 -0
- package/lib/commonjs/library/device/utils/generate-uuid.js.map +1 -0
- package/lib/commonjs/library/index.js +156 -0
- package/lib/commonjs/library/index.js.map +1 -0
- package/lib/commonjs/library/interceptors/index.js +13 -0
- package/lib/commonjs/library/interceptors/index.js.map +1 -0
- package/lib/commonjs/library/interceptors/js-console.js +88 -0
- package/lib/commonjs/library/interceptors/js-console.js.map +1 -0
- package/lib/commonjs/library/interceptors/react-devtools.js +219 -0
- package/lib/commonjs/library/interceptors/react-devtools.js.map +1 -0
- package/lib/commonjs/library/interceptors/xhr.js +74 -0
- package/lib/commonjs/library/interceptors/xhr.js.map +1 -0
- package/lib/commonjs/library/network-handler/index.js +17 -0
- package/lib/commonjs/library/network-handler/index.js.map +1 -0
- package/lib/commonjs/library/network-handler/network-handler.js +103 -0
- package/lib/commonjs/library/network-handler/network-handler.js.map +1 -0
- package/lib/commonjs/library/network-handler/types.js +6 -0
- package/lib/commonjs/library/network-handler/types.js.map +1 -0
- package/lib/commonjs/library/network-handler/utils/generate-request-id.js +13 -0
- package/lib/commonjs/library/network-handler/utils/generate-request-id.js.map +1 -0
- package/lib/commonjs/library/network-handler/utils/index.js +41 -0
- package/lib/commonjs/library/network-handler/utils/index.js.map +1 -0
- package/lib/commonjs/library/network-handler/utils/parse-response-headers.js +26 -0
- package/lib/commonjs/library/network-handler/utils/parse-response-headers.js.map +1 -0
- package/lib/commonjs/library/network-handler/utils/read-blob-as-text.js +18 -0
- package/lib/commonjs/library/network-handler/utils/read-blob-as-text.js.map +1 -0
- package/lib/commonjs/library/network-handler/utils/response-to-string.js +35 -0
- package/lib/commonjs/library/network-handler/utils/response-to-string.js.map +1 -0
- package/lib/commonjs/library/network-handler/utils/should-ignore-url.js +13 -0
- package/lib/commonjs/library/network-handler/utils/should-ignore-url.js.map +1 -0
- package/lib/commonjs/library/performance-handler/index.js +13 -0
- package/lib/commonjs/library/performance-handler/index.js.map +1 -0
- package/lib/commonjs/library/performance-handler/performance-handler.js +94 -0
- package/lib/commonjs/library/performance-handler/performance-handler.js.map +1 -0
- package/lib/commonjs/library/performance-handler/types.js +6 -0
- package/lib/commonjs/library/performance-handler/types.js.map +1 -0
- package/lib/commonjs/library/project/index.js +15 -0
- package/lib/commonjs/library/project/index.js.map +1 -0
- package/lib/commonjs/library/project/project-handler.js +31 -0
- package/lib/commonjs/library/project/project-handler.js.map +1 -0
- package/lib/commonjs/library/types.js +2 -0
- package/lib/commonjs/library/types.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/mako.nitro.js +6 -0
- package/lib/commonjs/specs/mako.nitro.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/library/client/constants.js +30 -0
- package/lib/module/library/client/constants.js.map +1 -0
- package/lib/module/library/client/index.js +6 -0
- package/lib/module/library/client/index.js.map +1 -0
- package/lib/module/library/client/mako-client.js +415 -0
- package/lib/module/library/client/mako-client.js.map +1 -0
- package/lib/module/library/component-handler/component-handler.js +153 -0
- package/lib/module/library/component-handler/component-handler.js.map +1 -0
- package/lib/module/library/component-handler/index.js +6 -0
- package/lib/module/library/component-handler/index.js.map +1 -0
- package/lib/module/library/component-handler/types.js +4 -0
- package/lib/module/library/component-handler/types.js.map +1 -0
- package/lib/module/library/component-handler/utils/index.js +21 -0
- package/lib/module/library/component-handler/utils/index.js.map +1 -0
- package/lib/module/library/device/device-handler.js +75 -0
- package/lib/module/library/device/device-handler.js.map +1 -0
- package/lib/module/library/device/index.js +5 -0
- package/lib/module/library/device/index.js.map +1 -0
- package/lib/module/library/device/types.js +2 -0
- package/lib/module/library/device/types.js.map +1 -0
- package/lib/module/library/device/utils/generate-uuid.js +10 -0
- package/lib/module/library/device/utils/generate-uuid.js.map +1 -0
- package/lib/module/library/index.js +155 -0
- package/lib/module/library/index.js.map +1 -0
- package/lib/module/library/interceptors/index.js +9 -0
- package/lib/module/library/interceptors/index.js.map +1 -0
- package/lib/module/library/interceptors/js-console.js +83 -0
- package/lib/module/library/interceptors/js-console.js.map +1 -0
- package/lib/module/library/interceptors/react-devtools.js +214 -0
- package/lib/module/library/interceptors/react-devtools.js.map +1 -0
- package/lib/module/library/interceptors/xhr.js +69 -0
- package/lib/module/library/interceptors/xhr.js.map +1 -0
- package/lib/module/library/network-handler/index.js +4 -0
- package/lib/module/library/network-handler/index.js.map +1 -0
- package/lib/module/library/network-handler/network-handler.js +98 -0
- package/lib/module/library/network-handler/network-handler.js.map +1 -0
- package/lib/module/library/network-handler/types.js +4 -0
- package/lib/module/library/network-handler/types.js.map +1 -0
- package/lib/module/library/network-handler/utils/generate-request-id.js +9 -0
- package/lib/module/library/network-handler/utils/generate-request-id.js.map +1 -0
- package/lib/module/library/network-handler/utils/index.js +8 -0
- package/lib/module/library/network-handler/utils/index.js.map +1 -0
- package/lib/module/library/network-handler/utils/parse-response-headers.js +22 -0
- package/lib/module/library/network-handler/utils/parse-response-headers.js.map +1 -0
- package/lib/module/library/network-handler/utils/read-blob-as-text.js +14 -0
- package/lib/module/library/network-handler/utils/read-blob-as-text.js.map +1 -0
- package/lib/module/library/network-handler/utils/response-to-string.js +31 -0
- package/lib/module/library/network-handler/utils/response-to-string.js.map +1 -0
- package/lib/module/library/network-handler/utils/should-ignore-url.js +9 -0
- package/lib/module/library/network-handler/utils/should-ignore-url.js.map +1 -0
- package/lib/module/library/performance-handler/index.js +4 -0
- package/lib/module/library/performance-handler/index.js.map +1 -0
- package/lib/module/library/performance-handler/performance-handler.js +89 -0
- package/lib/module/library/performance-handler/performance-handler.js.map +1 -0
- package/lib/module/library/performance-handler/types.js +4 -0
- package/lib/module/library/performance-handler/types.js.map +1 -0
- package/lib/module/library/project/index.js +6 -0
- package/lib/module/library/project/index.js.map +1 -0
- package/lib/module/library/project/project-handler.js +26 -0
- package/lib/module/library/project/project-handler.js.map +1 -0
- package/lib/module/library/types.js +2 -0
- package/lib/module/library/types.js.map +1 -0
- package/lib/module/specs/mako.nitro.js +4 -0
- package/lib/module/specs/mako.nitro.js.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/library/client/constants.d.ts +24 -0
- package/lib/typescript/src/library/client/constants.d.ts.map +1 -0
- package/lib/typescript/src/library/client/index.d.ts +4 -0
- package/lib/typescript/src/library/client/index.d.ts.map +1 -0
- package/lib/typescript/src/library/client/mako-client.d.ts +87 -0
- package/lib/typescript/src/library/client/mako-client.d.ts.map +1 -0
- package/lib/typescript/src/library/component-handler/component-handler.d.ts +21 -0
- package/lib/typescript/src/library/component-handler/component-handler.d.ts.map +1 -0
- package/lib/typescript/src/library/component-handler/index.d.ts +4 -0
- package/lib/typescript/src/library/component-handler/index.d.ts.map +1 -0
- package/lib/typescript/src/library/component-handler/types.d.ts +22 -0
- package/lib/typescript/src/library/component-handler/types.d.ts.map +1 -0
- package/lib/typescript/src/library/component-handler/utils/index.d.ts +13 -0
- package/lib/typescript/src/library/component-handler/utils/index.d.ts.map +1 -0
- package/lib/typescript/src/library/device/__tests__/device-handler.test.d.ts +2 -0
- package/lib/typescript/src/library/device/__tests__/device-handler.test.d.ts.map +1 -0
- package/lib/typescript/src/library/device/device-handler.d.ts +11 -0
- package/lib/typescript/src/library/device/device-handler.d.ts.map +1 -0
- package/lib/typescript/src/library/device/index.d.ts +3 -0
- package/lib/typescript/src/library/device/index.d.ts.map +1 -0
- package/lib/typescript/src/library/device/types.d.ts +8 -0
- package/lib/typescript/src/library/device/types.d.ts.map +1 -0
- package/lib/typescript/src/library/device/utils/generate-uuid.d.ts +2 -0
- package/lib/typescript/src/library/device/utils/generate-uuid.d.ts.map +1 -0
- package/lib/typescript/src/library/index.d.ts +120 -0
- package/lib/typescript/src/library/index.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/__tests__/js-console.test.d.ts +2 -0
- package/lib/typescript/src/library/interceptors/__tests__/js-console.test.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/__tests__/react-devtools.test.d.ts +2 -0
- package/lib/typescript/src/library/interceptors/__tests__/react-devtools.test.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/__tests__/xhr.test.d.ts +2 -0
- package/lib/typescript/src/library/interceptors/__tests__/xhr.test.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/index.d.ts +7 -0
- package/lib/typescript/src/library/interceptors/index.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/js-console.d.ts +17 -0
- package/lib/typescript/src/library/interceptors/js-console.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/react-devtools.d.ts +54 -0
- package/lib/typescript/src/library/interceptors/react-devtools.d.ts.map +1 -0
- package/lib/typescript/src/library/interceptors/xhr.d.ts +14 -0
- package/lib/typescript/src/library/interceptors/xhr.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/__tests__/network-handler.test.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/__tests__/network-handler.test.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/index.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/index.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/network-handler.d.ts +19 -0
- package/lib/typescript/src/library/network-handler/network-handler.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/types.d.ts +6 -0
- package/lib/typescript/src/library/network-handler/types.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/generate-request-id.test.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/generate-request-id.test.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/parse-response-headers.test.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/parse-response-headers.test.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/read-blob-as-text.test.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/read-blob-as-text.test.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/response-to-string.test.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/response-to-string.test.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/should-ignore-url.test.d.ts +2 -0
- package/lib/typescript/src/library/network-handler/utils/__tests__/should-ignore-url.test.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/generate-request-id.d.ts +5 -0
- package/lib/typescript/src/library/network-handler/utils/generate-request-id.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/index.d.ts +6 -0
- package/lib/typescript/src/library/network-handler/utils/index.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/parse-response-headers.d.ts +5 -0
- package/lib/typescript/src/library/network-handler/utils/parse-response-headers.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/read-blob-as-text.d.ts +5 -0
- package/lib/typescript/src/library/network-handler/utils/read-blob-as-text.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/response-to-string.d.ts +5 -0
- package/lib/typescript/src/library/network-handler/utils/response-to-string.d.ts.map +1 -0
- package/lib/typescript/src/library/network-handler/utils/should-ignore-url.d.ts +5 -0
- package/lib/typescript/src/library/network-handler/utils/should-ignore-url.d.ts.map +1 -0
- package/lib/typescript/src/library/performance-handler/index.d.ts +3 -0
- package/lib/typescript/src/library/performance-handler/index.d.ts.map +1 -0
- package/lib/typescript/src/library/performance-handler/performance-handler.d.ts +27 -0
- package/lib/typescript/src/library/performance-handler/performance-handler.d.ts.map +1 -0
- package/lib/typescript/src/library/performance-handler/types.d.ts +20 -0
- package/lib/typescript/src/library/performance-handler/types.d.ts.map +1 -0
- package/lib/typescript/src/library/project/index.d.ts +4 -0
- package/lib/typescript/src/library/project/index.d.ts.map +1 -0
- package/lib/typescript/src/library/project/project-handler.d.ts +7 -0
- package/lib/typescript/src/library/project/project-handler.d.ts.map +1 -0
- package/lib/typescript/src/library/types.d.ts +41 -0
- package/lib/typescript/src/library/types.d.ts.map +1 -0
- package/lib/typescript/src/specs/mako.nitro.d.ts +100 -0
- package/lib/typescript/src/specs/mako.nitro.d.ts.map +1 -0
- package/nitro.json +24 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NitroMako+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NitroMako+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroMakoOnLoad.cpp +58 -0
- package/nitrogen/generated/android/NitroMakoOnLoad.hpp +34 -0
- package/nitrogen/generated/android/c++/JDeviceInfoResult.hpp +69 -0
- package/nitrogen/generated/android/c++/JFunc_void_NativeLogEntry.hpp +80 -0
- package/nitrogen/generated/android/c++/JFunc_void_PerformanceMetrics.hpp +77 -0
- package/nitrogen/generated/android/c++/JHybridNitroMakoSpec.cpp +124 -0
- package/nitrogen/generated/android/c++/JHybridNitroMakoSpec.hpp +74 -0
- package/nitrogen/generated/android/c++/JNativeLogEntry.hpp +71 -0
- package/nitrogen/generated/android/c++/JNativeLogLevel.hpp +64 -0
- package/nitrogen/generated/android/c++/JPerformanceMetrics.hpp +69 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/DeviceInfoResult.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/Func_void_NativeLogEntry.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/Func_void_PerformanceMetrics.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/HybridNitroMakoSpec.kt +108 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/NativeLogEntry.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/NativeLogLevel.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/NitroMakoOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mako/PerformanceMetrics.kt +47 -0
- package/nitrogen/generated/ios/NitroMako+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NitroMako-Swift-Cxx-Bridge.cpp +49 -0
- package/nitrogen/generated/ios/NitroMako-Swift-Cxx-Bridge.hpp +185 -0
- package/nitrogen/generated/ios/NitroMako-Swift-Cxx-Umbrella.hpp +58 -0
- package/nitrogen/generated/ios/NitroMakoAutolinking.mm +33 -0
- package/nitrogen/generated/ios/NitroMakoAutolinking.swift +26 -0
- package/nitrogen/generated/ios/c++/HybridNitroMakoSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNitroMakoSpecSwift.hpp +175 -0
- package/nitrogen/generated/ios/swift/DeviceInfoResult.swift +44 -0
- package/nitrogen/generated/ios/swift/Func_void_NativeLogEntry.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_PerformanceMetrics.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridNitroMakoSpec.swift +66 -0
- package/nitrogen/generated/ios/swift/HybridNitroMakoSpec_cxx.swift +289 -0
- package/nitrogen/generated/ios/swift/NativeLogEntry.swift +44 -0
- package/nitrogen/generated/ios/swift/NativeLogLevel.swift +48 -0
- package/nitrogen/generated/ios/swift/PerformanceMetrics.swift +44 -0
- package/nitrogen/generated/shared/c++/DeviceInfoResult.hpp +95 -0
- package/nitrogen/generated/shared/c++/HybridNitroMakoSpec.cpp +32 -0
- package/nitrogen/generated/shared/c++/HybridNitroMakoSpec.hpp +83 -0
- package/nitrogen/generated/shared/c++/NativeLogEntry.hpp +97 -0
- package/nitrogen/generated/shared/c++/NativeLogLevel.hpp +84 -0
- package/nitrogen/generated/shared/c++/PerformanceMetrics.hpp +95 -0
- package/package.json +128 -0
- package/react-native.config.js +16 -0
- package/src/index.ts +7 -0
- package/src/library/client/constants.ts +36 -0
- package/src/library/client/index.ts +9 -0
- package/src/library/client/mako-client.ts +494 -0
- package/src/library/component-handler/component-handler.ts +162 -0
- package/src/library/component-handler/index.ts +3 -0
- package/src/library/component-handler/types.ts +24 -0
- package/src/library/component-handler/utils/index.ts +23 -0
- package/src/library/device/__tests__/device-handler.test.ts +86 -0
- package/src/library/device/device-handler.ts +85 -0
- package/src/library/device/index.ts +3 -0
- package/src/library/device/types.ts +7 -0
- package/src/library/device/utils/generate-uuid.ts +7 -0
- package/src/library/index.ts +183 -0
- package/src/library/interceptors/__tests__/js-console.test.ts +186 -0
- package/src/library/interceptors/__tests__/react-devtools.test.ts +848 -0
- package/src/library/interceptors/__tests__/xhr.test.ts +313 -0
- package/src/library/interceptors/index.ts +7 -0
- package/src/library/interceptors/js-console.ts +93 -0
- package/src/library/interceptors/react-devtools.ts +268 -0
- package/src/library/interceptors/xhr.ts +123 -0
- package/src/library/network-handler/__tests__/network-handler.test.ts +265 -0
- package/src/library/network-handler/index.ts +1 -0
- package/src/library/network-handler/network-handler.ts +141 -0
- package/src/library/network-handler/types.ts +6 -0
- package/src/library/network-handler/utils/__tests__/generate-request-id.test.ts +22 -0
- package/src/library/network-handler/utils/__tests__/parse-response-headers.test.ts +71 -0
- package/src/library/network-handler/utils/__tests__/read-blob-as-text.test.ts +79 -0
- package/src/library/network-handler/utils/__tests__/response-to-string.test.ts +85 -0
- package/src/library/network-handler/utils/__tests__/should-ignore-url.test.ts +45 -0
- package/src/library/network-handler/utils/generate-request-id.ts +6 -0
- package/src/library/network-handler/utils/index.ts +5 -0
- package/src/library/network-handler/utils/parse-response-headers.ts +20 -0
- package/src/library/network-handler/utils/read-blob-as-text.ts +11 -0
- package/src/library/network-handler/utils/response-to-string.ts +32 -0
- package/src/library/network-handler/utils/should-ignore-url.ts +6 -0
- package/src/library/performance-handler/index.ts +2 -0
- package/src/library/performance-handler/performance-handler.ts +104 -0
- package/src/library/performance-handler/types.ts +22 -0
- package/src/library/project/index.ts +4 -0
- package/src/library/project/project-handler.ts +28 -0
- package/src/library/types.ts +82 -0
- package/src/specs/mako.nitro.ts +114 -0
|
@@ -0,0 +1,848 @@
|
|
|
1
|
+
import { ReactDevToolsInterceptor } from '../react-devtools'
|
|
2
|
+
import type {
|
|
3
|
+
ComponentRenderCallbacks,
|
|
4
|
+
ComponentRenderInfo,
|
|
5
|
+
} from '../react-devtools'
|
|
6
|
+
describe('ReactDevToolsInterceptor', () => {
|
|
7
|
+
let interceptor: ReactDevToolsInterceptor
|
|
8
|
+
|
|
9
|
+
const originalGlobal = { ...global }
|
|
10
|
+
|
|
11
|
+
const createMockFiber = (overrides: Partial<any> = {}): any => ({
|
|
12
|
+
tag: 0, // Function component
|
|
13
|
+
type: function TestComponent() {},
|
|
14
|
+
elementType: null,
|
|
15
|
+
stateNode: null,
|
|
16
|
+
return: null,
|
|
17
|
+
child: null,
|
|
18
|
+
sibling: null,
|
|
19
|
+
alternate: null,
|
|
20
|
+
memoizedProps: {},
|
|
21
|
+
memoizedState: null,
|
|
22
|
+
updateQueue: null,
|
|
23
|
+
dependencies: null,
|
|
24
|
+
actualDuration: 5.5,
|
|
25
|
+
actualStartTime: 1000,
|
|
26
|
+
...overrides,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const createMockHook = (overrides: Partial<any> = {}): any => ({
|
|
30
|
+
supportsFiber: true,
|
|
31
|
+
inject: jest.fn().mockReturnValue(1),
|
|
32
|
+
onCommitFiberRoot: jest.fn(),
|
|
33
|
+
onCommitFiberUnmount: jest.fn(),
|
|
34
|
+
...overrides,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const createMockCallbacks = (): ComponentRenderCallbacks => ({
|
|
38
|
+
onComponentRender: jest.fn(),
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
jest.clearAllMocks()
|
|
43
|
+
|
|
44
|
+
jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
45
|
+
jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
46
|
+
|
|
47
|
+
// Reset singleton for each test
|
|
48
|
+
;(ReactDevToolsInterceptor as any).instance = null
|
|
49
|
+
|
|
50
|
+
interceptor = ReactDevToolsInterceptor.getInstance()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
afterEach(() => {
|
|
54
|
+
interceptor.disable()
|
|
55
|
+
|
|
56
|
+
jest.restoreAllMocks()
|
|
57
|
+
|
|
58
|
+
delete (global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
afterAll(() => {
|
|
62
|
+
Object.assign(global, originalGlobal)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe('getInstance', () => {
|
|
66
|
+
it('should return singleton instance', () => {
|
|
67
|
+
const instance1 = ReactDevToolsInterceptor.getInstance()
|
|
68
|
+
const instance2 = ReactDevToolsInterceptor.getInstance()
|
|
69
|
+
|
|
70
|
+
expect(instance1).toBe(instance2)
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('enable', () => {
|
|
75
|
+
it('should enable interceptor when hook exists', () => {
|
|
76
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = createMockHook()
|
|
77
|
+
|
|
78
|
+
const result = interceptor.enable(createMockCallbacks())
|
|
79
|
+
|
|
80
|
+
expect(result).toBe(true)
|
|
81
|
+
expect(interceptor.isEnabled()).toBe(true)
|
|
82
|
+
expect(console.log).toHaveBeenCalledWith(
|
|
83
|
+
'[Mako] Component inspector enabled (React DevTools hook)'
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('should prevent double enable', () => {
|
|
88
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = createMockHook()
|
|
89
|
+
|
|
90
|
+
interceptor.enable(createMockCallbacks())
|
|
91
|
+
const result = interceptor.enable(createMockCallbacks())
|
|
92
|
+
|
|
93
|
+
expect(result).toBe(false)
|
|
94
|
+
expect(console.warn).toHaveBeenCalledWith(
|
|
95
|
+
'[Mako] Component inspector already enabled'
|
|
96
|
+
)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should fail when hook not present', () => {
|
|
100
|
+
const result = interceptor.enable(createMockCallbacks())
|
|
101
|
+
|
|
102
|
+
expect(result).toBe(false)
|
|
103
|
+
expect(interceptor.isEnabled()).toBe(false)
|
|
104
|
+
expect(console.warn).toHaveBeenCalledWith(
|
|
105
|
+
'[Mako] React DevTools hook not found or does not support Fiber'
|
|
106
|
+
)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('should fail when hook does not support fiber', () => {
|
|
110
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = createMockHook({
|
|
111
|
+
supportsFiber: false,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
const result = interceptor.enable(createMockCallbacks())
|
|
115
|
+
|
|
116
|
+
expect(result).toBe(false)
|
|
117
|
+
expect(interceptor.isEnabled()).toBe(false)
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe('disable', () => {
|
|
122
|
+
it('should disable interceptor', () => {
|
|
123
|
+
const mockHook = createMockHook()
|
|
124
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
125
|
+
|
|
126
|
+
interceptor.enable(createMockCallbacks())
|
|
127
|
+
interceptor.disable()
|
|
128
|
+
|
|
129
|
+
expect(interceptor.isEnabled()).toBe(false)
|
|
130
|
+
expect(console.log).toHaveBeenCalledWith(
|
|
131
|
+
'[Mako] Component inspector disabled'
|
|
132
|
+
)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('should restore original onCommitFiberRoot', () => {
|
|
136
|
+
const originalHandler = jest.fn()
|
|
137
|
+
const mockHook = createMockHook({
|
|
138
|
+
onCommitFiberRoot: originalHandler,
|
|
139
|
+
})
|
|
140
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
141
|
+
|
|
142
|
+
interceptor.enable(createMockCallbacks())
|
|
143
|
+
|
|
144
|
+
expect(mockHook.onCommitFiberRoot).not.toBe(originalHandler)
|
|
145
|
+
|
|
146
|
+
interceptor.disable()
|
|
147
|
+
|
|
148
|
+
expect(mockHook.onCommitFiberRoot).toBe(originalHandler)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('should do nothing when not enabled', () => {
|
|
152
|
+
interceptor.disable()
|
|
153
|
+
|
|
154
|
+
expect(console.log).not.toHaveBeenCalledWith(
|
|
155
|
+
'[Mako] Component inspector disabled'
|
|
156
|
+
)
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
describe('isEnabled', () => {
|
|
161
|
+
it('should return false initially', () => {
|
|
162
|
+
expect(interceptor.isEnabled()).toBe(false)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('should return true after enable', () => {
|
|
166
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = createMockHook()
|
|
167
|
+
|
|
168
|
+
interceptor.enable(createMockCallbacks())
|
|
169
|
+
|
|
170
|
+
expect(interceptor.isEnabled()).toBe(true)
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('should return false after disable', () => {
|
|
174
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = createMockHook()
|
|
175
|
+
|
|
176
|
+
interceptor.enable(createMockCallbacks())
|
|
177
|
+
interceptor.disable()
|
|
178
|
+
|
|
179
|
+
expect(interceptor.isEnabled()).toBe(false)
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
describe('onCommitFiberRoot interception', () => {
|
|
184
|
+
it('should call original handler first', () => {
|
|
185
|
+
const originalHandler = jest.fn()
|
|
186
|
+
const mockHook = createMockHook({
|
|
187
|
+
onCommitFiberRoot: originalHandler,
|
|
188
|
+
})
|
|
189
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
190
|
+
|
|
191
|
+
interceptor.enable(createMockCallbacks())
|
|
192
|
+
|
|
193
|
+
const mockRoot = {
|
|
194
|
+
current: createMockFiber({
|
|
195
|
+
type: { displayName: 'TestComponent' },
|
|
196
|
+
}),
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
200
|
+
|
|
201
|
+
expect(originalHandler).toHaveBeenCalledWith(1, mockRoot, undefined)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
it('should trigger callback for component fiber', () => {
|
|
205
|
+
const mockHook = createMockHook()
|
|
206
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
207
|
+
|
|
208
|
+
const callbacks = createMockCallbacks()
|
|
209
|
+
interceptor.enable(callbacks)
|
|
210
|
+
|
|
211
|
+
const fiber = createMockFiber({
|
|
212
|
+
type: function MyComponent() {},
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
const mockRoot = { current: fiber }
|
|
216
|
+
|
|
217
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
218
|
+
|
|
219
|
+
expect(callbacks.onComponentRender).toHaveBeenCalled()
|
|
220
|
+
|
|
221
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
222
|
+
.calls[0][0] as ComponentRenderInfo
|
|
223
|
+
|
|
224
|
+
expect(callArg.componentName).toBe('MyComponent')
|
|
225
|
+
expect(callArg.renderDuration).toBe(5.5)
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('should not trigger callback when disabled', () => {
|
|
229
|
+
const mockHook = createMockHook()
|
|
230
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
231
|
+
|
|
232
|
+
const callbacks = createMockCallbacks()
|
|
233
|
+
interceptor.enable(callbacks)
|
|
234
|
+
interceptor.disable()
|
|
235
|
+
|
|
236
|
+
const mockRoot = {
|
|
237
|
+
current: createMockFiber({
|
|
238
|
+
type: function TestComponent() {},
|
|
239
|
+
}),
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Call directly since we restored original
|
|
243
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
244
|
+
|
|
245
|
+
expect(callbacks.onComponentRender).not.toHaveBeenCalled()
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
describe('fiber traversal', () => {
|
|
250
|
+
it('should traverse child fibers', () => {
|
|
251
|
+
const mockHook = createMockHook()
|
|
252
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
253
|
+
|
|
254
|
+
const callbacks = createMockCallbacks()
|
|
255
|
+
interceptor.enable(callbacks)
|
|
256
|
+
|
|
257
|
+
const childFiber = createMockFiber({
|
|
258
|
+
type: function ChildComponent() {},
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
const parentFiber = createMockFiber({
|
|
262
|
+
type: function ParentComponent() {},
|
|
263
|
+
child: childFiber,
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
childFiber.return = parentFiber
|
|
267
|
+
|
|
268
|
+
const mockRoot = { current: parentFiber }
|
|
269
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
270
|
+
|
|
271
|
+
expect(callbacks.onComponentRender).toHaveBeenCalledTimes(2)
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
it('should traverse sibling fibers', () => {
|
|
275
|
+
const mockHook = createMockHook()
|
|
276
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
277
|
+
|
|
278
|
+
const callbacks = createMockCallbacks()
|
|
279
|
+
interceptor.enable(callbacks)
|
|
280
|
+
|
|
281
|
+
const siblingFiber = createMockFiber({
|
|
282
|
+
type: function SiblingComponent() {},
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
const firstFiber = createMockFiber({
|
|
286
|
+
type: function FirstComponent() {},
|
|
287
|
+
sibling: siblingFiber,
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
const mockRoot = { current: firstFiber }
|
|
291
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
292
|
+
|
|
293
|
+
expect(callbacks.onComponentRender).toHaveBeenCalledTimes(2)
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
describe('isComponentFiber', () => {
|
|
298
|
+
it('should identify function component (tag 0)', () => {
|
|
299
|
+
const mockHook = createMockHook()
|
|
300
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
301
|
+
|
|
302
|
+
const callbacks = createMockCallbacks()
|
|
303
|
+
interceptor.enable(callbacks)
|
|
304
|
+
|
|
305
|
+
const fiber = createMockFiber({
|
|
306
|
+
tag: 0,
|
|
307
|
+
type: function FunctionComponent() {},
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
const mockRoot = { current: fiber }
|
|
311
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
312
|
+
|
|
313
|
+
expect(callbacks.onComponentRender).toHaveBeenCalled()
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
it('should identify class component (tag 1)', () => {
|
|
317
|
+
const mockHook = createMockHook()
|
|
318
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
319
|
+
|
|
320
|
+
const callbacks = createMockCallbacks()
|
|
321
|
+
interceptor.enable(callbacks)
|
|
322
|
+
|
|
323
|
+
const fiber = createMockFiber({
|
|
324
|
+
tag: 1,
|
|
325
|
+
type: class ClassComponent {},
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
const mockRoot = { current: fiber }
|
|
329
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
330
|
+
|
|
331
|
+
expect(callbacks.onComponentRender).toHaveBeenCalled()
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
it('should identify memo component (tag 11)', () => {
|
|
335
|
+
const mockHook = createMockHook()
|
|
336
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
337
|
+
|
|
338
|
+
const callbacks = createMockCallbacks()
|
|
339
|
+
interceptor.enable(callbacks)
|
|
340
|
+
|
|
341
|
+
const fiber = createMockFiber({
|
|
342
|
+
tag: 11,
|
|
343
|
+
type: function MemoComponent() {},
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
const mockRoot = { current: fiber }
|
|
347
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
348
|
+
|
|
349
|
+
expect(callbacks.onComponentRender).toHaveBeenCalled()
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
it('should skip non-component fibers', () => {
|
|
353
|
+
const mockHook = createMockHook()
|
|
354
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
355
|
+
|
|
356
|
+
const callbacks = createMockCallbacks()
|
|
357
|
+
interceptor.enable(callbacks)
|
|
358
|
+
|
|
359
|
+
// HostComponent tag = 5
|
|
360
|
+
const fiber = createMockFiber({
|
|
361
|
+
tag: 5,
|
|
362
|
+
type: 'div',
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
const mockRoot = { current: fiber }
|
|
366
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
367
|
+
|
|
368
|
+
expect(callbacks.onComponentRender).not.toHaveBeenCalled()
|
|
369
|
+
})
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
describe('getComponentName', () => {
|
|
373
|
+
it('should get name from displayName', () => {
|
|
374
|
+
const mockHook = createMockHook()
|
|
375
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
376
|
+
|
|
377
|
+
const callbacks = createMockCallbacks()
|
|
378
|
+
interceptor.enable(callbacks)
|
|
379
|
+
|
|
380
|
+
const Component = function () {}
|
|
381
|
+
Component.displayName = 'CustomDisplayName'
|
|
382
|
+
|
|
383
|
+
const fiber = createMockFiber({ type: Component })
|
|
384
|
+
const mockRoot = { current: fiber }
|
|
385
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
386
|
+
|
|
387
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
388
|
+
.calls[0][0] as ComponentRenderInfo
|
|
389
|
+
|
|
390
|
+
expect(callArg.componentName).toBe('CustomDisplayName')
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
it('should get name from function name', () => {
|
|
394
|
+
const mockHook = createMockHook()
|
|
395
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
396
|
+
|
|
397
|
+
const callbacks = createMockCallbacks()
|
|
398
|
+
interceptor.enable(callbacks)
|
|
399
|
+
|
|
400
|
+
const fiber = createMockFiber({
|
|
401
|
+
type: function NamedComponent() {},
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
const mockRoot = { current: fiber }
|
|
405
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
406
|
+
|
|
407
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
408
|
+
.calls[0][0] as ComponentRenderInfo
|
|
409
|
+
|
|
410
|
+
expect(callArg.componentName).toBe('NamedComponent')
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
it('should skip Anonymous components', () => {
|
|
414
|
+
const mockHook = createMockHook()
|
|
415
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
416
|
+
|
|
417
|
+
const callbacks = createMockCallbacks()
|
|
418
|
+
interceptor.enable(callbacks)
|
|
419
|
+
|
|
420
|
+
// Create truly anonymous function (not inferred from object property)
|
|
421
|
+
const anonFn = (() => function () {})()
|
|
422
|
+
|
|
423
|
+
const fiber = createMockFiber({
|
|
424
|
+
type: anonFn,
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
const mockRoot = { current: fiber }
|
|
428
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
429
|
+
|
|
430
|
+
expect(callbacks.onComponentRender).not.toHaveBeenCalled()
|
|
431
|
+
})
|
|
432
|
+
|
|
433
|
+
it('should handle React.memo wrapped components', () => {
|
|
434
|
+
const mockHook = createMockHook()
|
|
435
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
436
|
+
|
|
437
|
+
const callbacks = createMockCallbacks()
|
|
438
|
+
interceptor.enable(callbacks)
|
|
439
|
+
|
|
440
|
+
const MemoizedComponent = function OriginalComponent() {}
|
|
441
|
+
|
|
442
|
+
const fiber = createMockFiber({
|
|
443
|
+
tag: 11,
|
|
444
|
+
type: {
|
|
445
|
+
$$typeof: Symbol.for('react.memo'),
|
|
446
|
+
type: MemoizedComponent,
|
|
447
|
+
},
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
const mockRoot = { current: fiber }
|
|
451
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
452
|
+
|
|
453
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
454
|
+
.calls[0][0] as ComponentRenderInfo
|
|
455
|
+
|
|
456
|
+
expect(callArg.componentName).toBe('OriginalComponent')
|
|
457
|
+
})
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
describe('change detection', () => {
|
|
461
|
+
it('should detect props change', () => {
|
|
462
|
+
const mockHook = createMockHook()
|
|
463
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
464
|
+
|
|
465
|
+
const callbacks = createMockCallbacks()
|
|
466
|
+
interceptor.enable(callbacks)
|
|
467
|
+
|
|
468
|
+
const oldProps = { value: 1 }
|
|
469
|
+
const newProps = { value: 2 }
|
|
470
|
+
|
|
471
|
+
const alternateFiber = createMockFiber({
|
|
472
|
+
memoizedProps: oldProps,
|
|
473
|
+
})
|
|
474
|
+
|
|
475
|
+
const fiber = createMockFiber({
|
|
476
|
+
type: function TestComponent() {},
|
|
477
|
+
memoizedProps: newProps,
|
|
478
|
+
alternate: alternateFiber,
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
const mockRoot = { current: fiber }
|
|
482
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
483
|
+
|
|
484
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
485
|
+
.calls[0][0] as ComponentRenderInfo
|
|
486
|
+
|
|
487
|
+
expect(callArg.propsChanged).toBe(true)
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
it('should detect state change', () => {
|
|
491
|
+
const mockHook = createMockHook()
|
|
492
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
493
|
+
|
|
494
|
+
const callbacks = createMockCallbacks()
|
|
495
|
+
interceptor.enable(callbacks)
|
|
496
|
+
|
|
497
|
+
const oldState = { count: 0 }
|
|
498
|
+
const newState = { count: 1 }
|
|
499
|
+
|
|
500
|
+
const alternateFiber = createMockFiber({
|
|
501
|
+
memoizedState: oldState,
|
|
502
|
+
})
|
|
503
|
+
|
|
504
|
+
const fiber = createMockFiber({
|
|
505
|
+
type: function TestComponent() {},
|
|
506
|
+
memoizedState: newState,
|
|
507
|
+
alternate: alternateFiber,
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
const mockRoot = { current: fiber }
|
|
511
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
512
|
+
|
|
513
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
514
|
+
.calls[0][0] as ComponentRenderInfo
|
|
515
|
+
|
|
516
|
+
expect(callArg.stateChanged).toBe(true)
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
it('should not trigger callback when props reference unchanged (bailout)', () => {
|
|
520
|
+
const mockHook = createMockHook()
|
|
521
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
522
|
+
|
|
523
|
+
const callbacks = createMockCallbacks()
|
|
524
|
+
interceptor.enable(callbacks)
|
|
525
|
+
|
|
526
|
+
const sameProps = { value: 1 }
|
|
527
|
+
const sameState = { count: 0 }
|
|
528
|
+
|
|
529
|
+
const alternateFiber = createMockFiber({
|
|
530
|
+
memoizedProps: sameProps,
|
|
531
|
+
memoizedState: sameState,
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
const fiber = createMockFiber({
|
|
535
|
+
type: function TestComponent() {},
|
|
536
|
+
memoizedProps: sameProps,
|
|
537
|
+
memoizedState: sameState,
|
|
538
|
+
alternate: alternateFiber,
|
|
539
|
+
})
|
|
540
|
+
|
|
541
|
+
const mockRoot = { current: fiber }
|
|
542
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
543
|
+
|
|
544
|
+
// When props reference is unchanged, didFiberRender returns false (bailout)
|
|
545
|
+
// so no callback should be made
|
|
546
|
+
expect(callbacks.onComponentRender).not.toHaveBeenCalled()
|
|
547
|
+
})
|
|
548
|
+
|
|
549
|
+
it('should report propsChanged false when props ref same but render triggered by other means', () => {
|
|
550
|
+
const mockHook = createMockHook()
|
|
551
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
552
|
+
|
|
553
|
+
const callbacks = createMockCallbacks()
|
|
554
|
+
interceptor.enable(callbacks)
|
|
555
|
+
|
|
556
|
+
// First commit - initial render
|
|
557
|
+
const fiber1 = createMockFiber({
|
|
558
|
+
type: function TestComponent() {},
|
|
559
|
+
memoizedProps: { value: 1 },
|
|
560
|
+
alternate: null,
|
|
561
|
+
})
|
|
562
|
+
mockHook.onCommitFiberRoot(1, { current: fiber1 }, undefined)
|
|
563
|
+
|
|
564
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
565
|
+
.calls[0][0] as ComponentRenderInfo
|
|
566
|
+
|
|
567
|
+
// Initial render always has propsChanged: true
|
|
568
|
+
expect(callArg.propsChanged).toBe(true)
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
it('should mark changes as true for initial render (no alternate)', () => {
|
|
572
|
+
const mockHook = createMockHook()
|
|
573
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
574
|
+
|
|
575
|
+
const callbacks = createMockCallbacks()
|
|
576
|
+
interceptor.enable(callbacks)
|
|
577
|
+
|
|
578
|
+
const fiber = createMockFiber({
|
|
579
|
+
type: function TestComponent() {},
|
|
580
|
+
alternate: null,
|
|
581
|
+
})
|
|
582
|
+
|
|
583
|
+
const mockRoot = { current: fiber }
|
|
584
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
585
|
+
|
|
586
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
587
|
+
.calls[0][0] as ComponentRenderInfo
|
|
588
|
+
|
|
589
|
+
expect(callArg.propsChanged).toBe(true)
|
|
590
|
+
expect(callArg.stateChanged).toBe(true)
|
|
591
|
+
})
|
|
592
|
+
})
|
|
593
|
+
|
|
594
|
+
describe('memoization detection', () => {
|
|
595
|
+
it('should detect React.memo component', () => {
|
|
596
|
+
const mockHook = createMockHook()
|
|
597
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
598
|
+
|
|
599
|
+
const callbacks = createMockCallbacks()
|
|
600
|
+
interceptor.enable(callbacks)
|
|
601
|
+
|
|
602
|
+
const fiber = createMockFiber({
|
|
603
|
+
tag: 14, // MemoComponent
|
|
604
|
+
type: function MemoComponent() {},
|
|
605
|
+
})
|
|
606
|
+
|
|
607
|
+
const mockRoot = { current: fiber }
|
|
608
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
609
|
+
|
|
610
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
611
|
+
.calls[0][0] as ComponentRenderInfo
|
|
612
|
+
|
|
613
|
+
expect(callArg.isMemoized).toBe(true)
|
|
614
|
+
expect(callArg.memoType).toBe('React.memo')
|
|
615
|
+
})
|
|
616
|
+
|
|
617
|
+
it('should detect PureComponent', () => {
|
|
618
|
+
const mockHook = createMockHook()
|
|
619
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
620
|
+
|
|
621
|
+
const callbacks = createMockCallbacks()
|
|
622
|
+
interceptor.enable(callbacks)
|
|
623
|
+
|
|
624
|
+
class PureComp {}
|
|
625
|
+
;(PureComp as any).prototype.isPureReactComponent = true
|
|
626
|
+
|
|
627
|
+
const fiber = createMockFiber({
|
|
628
|
+
tag: 1, // Class component
|
|
629
|
+
type: PureComp,
|
|
630
|
+
})
|
|
631
|
+
|
|
632
|
+
const mockRoot = { current: fiber }
|
|
633
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
634
|
+
|
|
635
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
636
|
+
.calls[0][0] as ComponentRenderInfo
|
|
637
|
+
|
|
638
|
+
expect(callArg.isMemoized).toBe(true)
|
|
639
|
+
expect(callArg.memoType).toBe('PureComponent')
|
|
640
|
+
})
|
|
641
|
+
|
|
642
|
+
it('should return none for regular component', () => {
|
|
643
|
+
const mockHook = createMockHook()
|
|
644
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
645
|
+
|
|
646
|
+
const callbacks = createMockCallbacks()
|
|
647
|
+
interceptor.enable(callbacks)
|
|
648
|
+
|
|
649
|
+
const fiber = createMockFiber({
|
|
650
|
+
tag: 0, // Function component
|
|
651
|
+
type: function RegularComponent() {},
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
const mockRoot = { current: fiber }
|
|
655
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
656
|
+
|
|
657
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
658
|
+
.calls[0][0] as ComponentRenderInfo
|
|
659
|
+
|
|
660
|
+
expect(callArg.isMemoized).toBe(false)
|
|
661
|
+
expect(callArg.memoType).toBe('none')
|
|
662
|
+
})
|
|
663
|
+
})
|
|
664
|
+
|
|
665
|
+
describe('parent ID tracking', () => {
|
|
666
|
+
it('should track parent component ID', () => {
|
|
667
|
+
const mockHook = createMockHook()
|
|
668
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
669
|
+
|
|
670
|
+
const callbacks = createMockCallbacks()
|
|
671
|
+
interceptor.enable(callbacks)
|
|
672
|
+
|
|
673
|
+
const childFiber = createMockFiber({
|
|
674
|
+
type: function ChildComponent() {},
|
|
675
|
+
})
|
|
676
|
+
|
|
677
|
+
const parentFiber = createMockFiber({
|
|
678
|
+
tag: 0,
|
|
679
|
+
type: function ParentComponent() {},
|
|
680
|
+
child: childFiber,
|
|
681
|
+
})
|
|
682
|
+
|
|
683
|
+
childFiber.return = parentFiber
|
|
684
|
+
|
|
685
|
+
const mockRoot = { current: parentFiber }
|
|
686
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
687
|
+
|
|
688
|
+
const calls = (callbacks.onComponentRender as jest.Mock).mock.calls
|
|
689
|
+
const parentCall = calls.find(
|
|
690
|
+
(c: any) => c[0].componentName === 'ParentComponent'
|
|
691
|
+
)
|
|
692
|
+
const childCall = calls.find(
|
|
693
|
+
(c: any) => c[0].componentName === 'ChildComponent'
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
expect(parentCall[0].parentId).toBeNull()
|
|
697
|
+
expect(childCall[0].parentId).toBe(parentCall[0].componentId)
|
|
698
|
+
})
|
|
699
|
+
|
|
700
|
+
it('should skip non-component fibers when finding parent', () => {
|
|
701
|
+
const mockHook = createMockHook()
|
|
702
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
703
|
+
|
|
704
|
+
const callbacks = createMockCallbacks()
|
|
705
|
+
interceptor.enable(callbacks)
|
|
706
|
+
|
|
707
|
+
const childFiber = createMockFiber({
|
|
708
|
+
type: function ChildComponent() {},
|
|
709
|
+
})
|
|
710
|
+
|
|
711
|
+
// HostComponent (div) in between
|
|
712
|
+
const hostFiber = createMockFiber({
|
|
713
|
+
tag: 5, // HostComponent
|
|
714
|
+
type: 'div',
|
|
715
|
+
child: childFiber,
|
|
716
|
+
})
|
|
717
|
+
|
|
718
|
+
const parentFiber = createMockFiber({
|
|
719
|
+
tag: 0,
|
|
720
|
+
type: function ParentComponent() {},
|
|
721
|
+
child: hostFiber,
|
|
722
|
+
})
|
|
723
|
+
|
|
724
|
+
childFiber.return = hostFiber
|
|
725
|
+
hostFiber.return = parentFiber
|
|
726
|
+
|
|
727
|
+
const mockRoot = { current: parentFiber }
|
|
728
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
729
|
+
|
|
730
|
+
const calls = (callbacks.onComponentRender as jest.Mock).mock.calls
|
|
731
|
+
const parentCall = calls.find(
|
|
732
|
+
(c: any) => c[0].componentName === 'ParentComponent'
|
|
733
|
+
)
|
|
734
|
+
const childCall = calls.find(
|
|
735
|
+
(c: any) => c[0].componentName === 'ChildComponent'
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
// Child should have parent ID pointing to ParentComponent, not div
|
|
739
|
+
expect(childCall[0].parentId).toBe(parentCall[0].componentId)
|
|
740
|
+
})
|
|
741
|
+
})
|
|
742
|
+
|
|
743
|
+
describe('fiber ID generation', () => {
|
|
744
|
+
it('should generate unique IDs for different fibers', () => {
|
|
745
|
+
const mockHook = createMockHook()
|
|
746
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
747
|
+
|
|
748
|
+
const callbacks = createMockCallbacks()
|
|
749
|
+
interceptor.enable(callbacks)
|
|
750
|
+
|
|
751
|
+
const fiber1 = createMockFiber({
|
|
752
|
+
type: function Component1() {},
|
|
753
|
+
})
|
|
754
|
+
|
|
755
|
+
const fiber2 = createMockFiber({
|
|
756
|
+
type: function Component2() {},
|
|
757
|
+
sibling: null,
|
|
758
|
+
})
|
|
759
|
+
|
|
760
|
+
fiber1.sibling = fiber2
|
|
761
|
+
|
|
762
|
+
const mockRoot = { current: fiber1 }
|
|
763
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
764
|
+
|
|
765
|
+
const calls = (callbacks.onComponentRender as jest.Mock).mock.calls
|
|
766
|
+
const id1 = calls[0][0].componentId
|
|
767
|
+
const id2 = calls[1][0].componentId
|
|
768
|
+
|
|
769
|
+
expect(id1).not.toBe(id2)
|
|
770
|
+
expect(id1).toMatch(/^fiber-\d+$/)
|
|
771
|
+
expect(id2).toMatch(/^fiber-\d+$/)
|
|
772
|
+
})
|
|
773
|
+
|
|
774
|
+
it('should reuse ID for same fiber across re-renders', () => {
|
|
775
|
+
const mockHook = createMockHook()
|
|
776
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
777
|
+
|
|
778
|
+
const callbacks = createMockCallbacks()
|
|
779
|
+
interceptor.enable(callbacks)
|
|
780
|
+
|
|
781
|
+
const ComponentType = function TestComponent() {}
|
|
782
|
+
|
|
783
|
+
// First render - no alternate
|
|
784
|
+
const fiber1 = createMockFiber({
|
|
785
|
+
type: ComponentType,
|
|
786
|
+
memoizedProps: { value: 1 },
|
|
787
|
+
alternate: null,
|
|
788
|
+
})
|
|
789
|
+
mockHook.onCommitFiberRoot(1, { current: fiber1 }, undefined)
|
|
790
|
+
|
|
791
|
+
// Second render - fiber1 becomes alternate, new props triggers render
|
|
792
|
+
const fiber2 = createMockFiber({
|
|
793
|
+
type: ComponentType,
|
|
794
|
+
memoizedProps: { value: 2 }, // Different props = triggers render
|
|
795
|
+
alternate: fiber1,
|
|
796
|
+
})
|
|
797
|
+
mockHook.onCommitFiberRoot(1, { current: fiber2 }, undefined)
|
|
798
|
+
|
|
799
|
+
const calls = (callbacks.onComponentRender as jest.Mock).mock.calls
|
|
800
|
+
expect(calls).toHaveLength(2)
|
|
801
|
+
expect(calls[0][0].componentId).toBe(calls[1][0].componentId)
|
|
802
|
+
})
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
describe('render duration', () => {
|
|
806
|
+
it('should capture actualDuration from fiber', () => {
|
|
807
|
+
const mockHook = createMockHook()
|
|
808
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
809
|
+
|
|
810
|
+
const callbacks = createMockCallbacks()
|
|
811
|
+
interceptor.enable(callbacks)
|
|
812
|
+
|
|
813
|
+
const fiber = createMockFiber({
|
|
814
|
+
type: function TestComponent() {},
|
|
815
|
+
actualDuration: 12.34,
|
|
816
|
+
})
|
|
817
|
+
|
|
818
|
+
const mockRoot = { current: fiber }
|
|
819
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
820
|
+
|
|
821
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
822
|
+
.calls[0][0] as ComponentRenderInfo
|
|
823
|
+
|
|
824
|
+
expect(callArg.renderDuration).toBe(12.34)
|
|
825
|
+
})
|
|
826
|
+
|
|
827
|
+
it('should default to 0 when actualDuration is undefined', () => {
|
|
828
|
+
const mockHook = createMockHook()
|
|
829
|
+
;(global as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = mockHook
|
|
830
|
+
|
|
831
|
+
const callbacks = createMockCallbacks()
|
|
832
|
+
interceptor.enable(callbacks)
|
|
833
|
+
|
|
834
|
+
const fiber = createMockFiber({
|
|
835
|
+
type: function TestComponent() {},
|
|
836
|
+
actualDuration: undefined,
|
|
837
|
+
})
|
|
838
|
+
|
|
839
|
+
const mockRoot = { current: fiber }
|
|
840
|
+
mockHook.onCommitFiberRoot(1, mockRoot, undefined)
|
|
841
|
+
|
|
842
|
+
const callArg = (callbacks.onComponentRender as jest.Mock).mock
|
|
843
|
+
.calls[0][0] as ComponentRenderInfo
|
|
844
|
+
|
|
845
|
+
expect(callArg.renderDuration).toBe(0)
|
|
846
|
+
})
|
|
847
|
+
})
|
|
848
|
+
})
|