catalyst-core 0.3.0-beta.5 → 0.3.0-canary.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +185 -71
- package/dist/errors/generateDocs.js +100 -0
- package/dist/errors/index.js +243 -0
- package/dist/errors/registry.js +483 -0
- package/dist/errors-index.json +506 -0
- package/dist/globals.d.ts +62 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.jsx +5 -8
- package/dist/logger.js +1 -1
- package/dist/native/androidProject/app/build.gradle.kts +142 -7
- package/dist/native/androidProject/app/src/main/AndroidManifest.xml +4 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +2 -2
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/camera/BarcodeDetector.kt +3 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/camera/CameraSessionManager.kt +3 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +43 -8
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/BridgeUtilsTest.kt +181 -1
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/CameraUtilsTest.kt +156 -236
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FileSizeRouterUtilsTest.kt +471 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FileUtilsTest.kt +222 -226
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/FrameworkServerUtilsTest.kt +300 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/IntentUtilsTest.kt +244 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/MetricsMonitorTest.kt +359 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/NativeBridgeTest.kt +108 -63
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/NotificationUtilsTest.kt +329 -385
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/OfflineCacheServiceTest.kt +302 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/PerfEventBufferTest.kt +133 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/UtilsKtTest.kt +152 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/WebCacheManagerTest.kt +145 -324
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/BarcodeDetectorTest.kt +132 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/HoldControllerTest.kt +155 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/TorchControllerTest.kt +150 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/VideoStreamStateMachineTest.kt +120 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/VideoStreamStateTest.kt +62 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/ViewfinderMapperTest.kt +143 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/camera/ZoomControllerTest.kt +421 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/design/DesignTokensTest.kt +207 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/plugins/PluginBridgeTest.kt +368 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/FridaDetectorTest.kt +193 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/SecurityCheckManagerTest.kt +260 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/security/SecurityCheckSchedulerTest.kt +166 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/DeviceInfoUtilsTest.kt +167 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/DownloadUtilsTest.kt +197 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/NetworkMonitorTest.kt +271 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/PushNotificationUtilsTest.kt +119 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/utils/SafeAreaUtilsTest.kt +108 -0
- package/dist/native/androidProject/build.gradle.kts +1 -0
- package/dist/native/androidProject/gradle/libs.versions.toml +26 -0
- package/dist/native/androidProject/settings.gradle.kts +11 -8
- package/dist/native/androidSetup.js +2 -2
- package/dist/native/bridge/WebBridge.d.ts +98 -0
- package/dist/native/bridge/WebBridge.js +40 -6
- package/dist/native/bridge/constants/NativeInterfaces.d.ts +391 -0
- package/dist/native/bridge/errors.d.ts +67 -0
- package/dist/native/bridge/errors.js +66 -151
- package/dist/native/bridge/hooks/index.d.ts +13 -0
- package/dist/native/bridge/hooks/index.js +0 -6
- package/dist/native/bridge/hooks/useAI.d.ts +1 -0
- package/dist/native/bridge/hooks/useAI.js +3 -1
- package/dist/native/bridge/hooks/useCamera.d.ts +86 -0
- package/dist/native/bridge/hooks/useCamera.js +35 -6
- package/dist/native/bridge/hooks/useDataProtection.d.ts +17 -0
- package/dist/native/bridge/hooks/useDeviceInfo.d.ts +34 -0
- package/dist/native/bridge/hooks/useDeviceInfo.js +5 -0
- package/dist/native/bridge/hooks/useFilePicker.d.ts +53 -0
- package/dist/native/bridge/hooks/useFilePicker.js +13 -0
- package/dist/native/bridge/hooks/useGoogleSignIn.d.ts +12 -0
- package/dist/native/bridge/hooks/useHapticFeedback.d.ts +76 -0
- package/dist/native/bridge/hooks/useHapticFeedback.js +6 -1
- package/dist/native/bridge/hooks/useIntent.d.ts +33 -0
- package/dist/native/bridge/hooks/useIntent.js +2 -0
- package/dist/native/bridge/hooks/useNativeTransition.d.ts +53 -0
- package/dist/native/bridge/hooks/useNativeTransition.js +12 -5
- package/dist/native/bridge/hooks/useNetworkStatus.d.ts +22 -0
- package/dist/native/bridge/hooks/useNetworkStatus.js +7 -0
- package/dist/native/bridge/hooks/useNotification.d.ts +83 -0
- package/dist/native/bridge/hooks/useNotification.js +81 -34
- package/dist/native/bridge/hooks/useSafeArea.d.ts +12 -0
- package/dist/native/bridge/hooks/useSafeArea.js +8 -0
- package/dist/native/bridge/hooks/useVideoStream.d.ts +67 -0
- package/dist/native/bridge/hooks/useVideoStream.js +38 -52
- package/dist/native/bridge/hooks/utils.d.ts +4 -0
- package/dist/native/bridge/hooks.d.ts +1 -0
- package/dist/native/bridge/perf/collectors/ApiCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/ApiCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.d.ts +43 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/HookCollector.d.ts +37 -0
- package/dist/native/bridge/perf/collectors/HookCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.d.ts +103 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.d.ts +53 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.d.ts +37 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.d.ts +30 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.d.ts +47 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.js +8 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.d.ts +29 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.js +4 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.d.ts +31 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.js +4 -0
- package/dist/native/bridge/perf/core/constants.d.ts +76 -0
- package/dist/native/bridge/perf/core/measure.d.ts +39 -0
- package/dist/native/bridge/perf/core/measure.js +4 -0
- package/dist/native/bridge/perf/core/session.d.ts +49 -0
- package/dist/native/bridge/perf/core/session.js +4 -0
- package/dist/native/bridge/perf/core/store.d.ts +37 -0
- package/dist/native/bridge/perf/core/store.js +4 -0
- package/dist/native/bridge/perf/core/summary.d.ts +60 -0
- package/dist/native/bridge/perf/core/traceExport.d.ts +10 -0
- package/dist/native/bridge/perf/core/waterfalls.d.ts +2 -0
- package/dist/native/bridge/perf/index.d.ts +63 -0
- package/dist/native/bridge/perf/index.js +4 -0
- package/dist/native/bridge/safeArea.d.ts +11 -0
- package/dist/native/bridge/safeArea.js +2 -0
- package/dist/native/bridge/useBaseHook.d.ts +137 -0
- package/dist/native/bridge/useBaseHook.js +34 -4
- package/dist/native/bridge/utils/CameraUtils.d.ts +94 -0
- package/dist/native/bridge/utils/CameraUtils.js +4 -0
- package/dist/native/bridge/utils/FileObjectConverter.d.ts +36 -0
- package/dist/native/bridge/utils/NativeBridge.d.ts +270 -0
- package/dist/native/bridge/utils/NativeBridge.js +10 -0
- package/dist/native/buildAndroid/index.js +1 -1
- package/dist/native/buildAppAndroid.js +9 -0
- package/dist/native/buildAppIos.js +16 -1
- package/dist/native/buildErrorFormat.js +57 -0
- package/dist/native/buildIos/config.js +15 -1
- package/dist/native/buildIos/index.js +1 -1
- package/dist/native/buildIos/plugins.js +10 -1
- package/dist/native/iosnativeWebView/CoreLogic/Package.swift +36 -0
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Camera/VideoStreamState.swift +1 -1
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Camera/VideoStreamStateMachine.swift +6 -4
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/BootTimingUtility.swift +3 -3
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/FrameworkServerUtils.swift +14 -9
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NetworkMonitor.swift +11 -9
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NotificationHandlerProvider.swift +1 -1
- package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/URLWhitelistManager.swift +7 -7
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/AnyCodableTests.swift +154 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/BootTimingUtilityTests.swift +23 -5
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/CatalystConstantsTests.swift +192 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/ConfigMappingTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/FrameworkServerUtilsErrorPathTests.swift +106 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/FrameworkServerUtilsLoopbackTests.swift +243 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/FrameworkServerUtilsTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/NetworkMonitorTests.swift +119 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/NotificationHandlerProviderTests.swift +59 -0
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/NotificationHandlerTests.swift +1 -1
- package/dist/native/iosnativeWebView/{iosnativeWebViewTests → CoreLogic/Tests/CatalystCoreLogicTests}/URLWhitelistManagerTests.swift +1 -1
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/VideoStreamStateMachineTests.swift +171 -0
- package/dist/native/iosnativeWebView/CoreLogic/Tests/CatalystCoreLogicTests/VideoStreamStateTests.swift +91 -0
- package/dist/native/iosnativeWebView/Package.swift +10 -9
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/LocalNotificationHandler.swift +7 -2
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/NotificationManager.swift +1 -2
- package/dist/native/iosnativeWebView/Sources/CatalystNotifications/PushNotificationHandler.swift +5 -4
- package/dist/native/iosnativeWebView/Sources/Core/Camera/CameraSessionManager.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Camera/HoldController.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Camera/NativeCameraManager.swift +6 -5
- package/dist/native/iosnativeWebView/Sources/Core/Camera/ZoomController.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Plugins/PluginBridge.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CacheManager.swift +31 -30
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CameraTransportUtils.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/DeviceInfoUtils.swift +1 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/FilePickerHandler.swift +22 -19
- package/dist/native/iosnativeWebView/Sources/Core/Utils/ImageHandler.swift +40 -39
- package/dist/native/iosnativeWebView/Sources/Core/Utils/PerfEventBuffer.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/ResourceURLProtocol.swift +15 -15
- package/dist/native/iosnativeWebView/Sources/Core/Utils/WebKitConfig.swift +4 -3
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeCommandHandler.swift +6 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeDelegateHandler.swift +1 -0
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeFileHandler.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeJavaScriptInterface.swift +2 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeMessageValidator.swift +3 -5
- package/dist/native/iosnativeWebView/Sources/Core/WebView/NativeBridge.swift +20 -13
- package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashView.swift +6 -5
- package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashViewModel.swift +14 -13
- package/dist/native/iosnativeWebView/Sources/Core/WebView/TransitionManager.swift +3 -3
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebView.swift +9 -8
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewModel.swift +7 -6
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewNavigationDelegate.swift +24 -25
- package/dist/native/iosnativeWebView/iosnativeWebView/AppDelegate.swift +6 -1
- package/dist/native/iosnativeWebView/iosnativeWebView/ContentView.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/iosnativeWebViewApp.swift +4 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.pbxproj +2 -22
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/BridgeMessageValidatorTests.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/CacheManagerTests.swift +1 -0
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/FilePickerHandlerTests.swift +2 -1
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/NativeBridgeTests.swift +15 -9
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/WebViewTests.swift +1 -0
- package/dist/native/setupEmulatorIos.js +2 -2
- package/dist/native/terminalProgress.js +17 -17
- package/dist/router/ClientRouter.d.ts +8 -0
- package/dist/router/ClientRouter.js +13 -11
- package/dist/router/ServerRouter.d.ts +13 -0
- package/dist/router/ServerRouter.js +19 -7
- package/dist/scripts/build.js +14 -2
- package/dist/scripts/loadEnvironmentVariables.js +3 -2
- package/dist/scripts/plugins.js +1 -1
- package/dist/scripts/preServerInit.js +49 -3
- package/dist/scripts/preflight.js +111 -0
- package/dist/scripts/scriptUtils.js +46 -1
- package/dist/scripts/serve.js +7 -3
- package/dist/scripts/start.js +8 -3
- package/dist/server/expressServer.d.ts +1 -0
- package/dist/server/expressServer.js +247 -271
- package/dist/server/manifestCache.d.ts +2 -0
- package/dist/server/manifestCache.js +25 -33
- package/dist/server/renderer/ChunkExtractor.d.ts +44 -0
- package/dist/server/renderer/ChunkExtractor.js +113 -125
- package/dist/server/renderer/document/Body.d.ts +21 -0
- package/dist/server/renderer/document/Body.jsx +45 -45
- package/dist/server/renderer/document/FastRefresh.d.ts +3 -0
- package/dist/server/renderer/document/FastRefresh.jsx +7 -13
- package/dist/server/renderer/document/Head.d.ts +20 -0
- package/dist/server/renderer/document/Head.jsx +32 -32
- package/dist/server/renderer/document/index.d.ts +2 -0
- package/dist/server/renderer/document/index.jsx +2 -2
- package/dist/server/renderer/extract.d.ts +67 -0
- package/dist/server/renderer/extract.js +92 -89
- package/dist/server/renderer/handler.d.ts +2 -0
- package/dist/server/renderer/handler.jsx +401 -404
- package/dist/server/renderer/index.d.ts +2 -0
- package/dist/server/renderer/index.js +5 -8
- package/dist/server/renderer/render.d.ts +35 -0
- package/dist/server/renderer/render.js +25 -32
- package/dist/server/utils/botDetectionMiddleware.d.ts +1 -0
- package/dist/server/utils/botDetectionMiddleware.js +33 -23
- package/dist/server/utils/cjsRequire.d.ts +8 -0
- package/dist/server/utils/cjsRequire.js +2 -2
- package/dist/server/utils/userAgentUtil.d.ts +7 -0
- package/dist/server/utils/userAgentUtil.js +68 -71
- package/dist/server/utils/validator.d.ts +31 -0
- package/dist/server/utils/validator.js +133 -158
- package/dist/vite/inject-cache-key-plugin.js +3 -27
- package/dist/vite/moduleAliases.js +36 -0
- package/dist/vite/node-loader.mjs +2 -29
- package/dist/vite/resolveDevServerConfig.js +4 -1
- package/dist/vite/vite.config.js +2 -29
- package/dist/web-router/components/MetaTag.d.ts +4 -0
- package/dist/web-router/components/MetaTag.jsx +26 -28
- package/dist/web-router/components/MetaTag.test.jsx +100 -0
- package/dist/web-router/components/RouterDataProvider.d.ts +96 -0
- package/dist/web-router/components/RouterDataProvider.jsx +260 -259
- package/dist/web-router/components/RouterDataProvider.server.test.jsx +98 -0
- package/dist/web-router/components/RouterDataProvider.test.jsx +310 -0
- package/dist/web-router/components/Split.d.ts +74 -0
- package/dist/web-router/components/Split.jsx +147 -156
- package/dist/web-router/components/Split.server.test.jsx +52 -0
- package/dist/web-router/components/Split.test.jsx +167 -0
- package/dist/web-router/components/SplitInview.d.ts +22 -0
- package/dist/web-router/components/SplitInview.jsx +78 -89
- package/dist/web-router/components/SplitInview.test.jsx +112 -0
- package/dist/web-router/components/SsrRequestContext.d.ts +20 -0
- package/dist/web-router/components/SsrRequestContext.jsx +17 -7
- package/dist/web-router/components/SsrRequestContext.test.jsx +53 -0
- package/dist/web-router/context.d.ts +15 -0
- package/dist/web-router/context.jsx +5 -5
- package/dist/web-router/context.test.jsx +10 -0
- package/dist/web-router/utils/metaDataUtils.d.ts +24 -0
- package/dist/web-router/utils/metaDataUtils.jsx +86 -86
- package/dist/web-router/utils/metaDataUtils.test.jsx +188 -0
- package/dist/web-router/vitest.setup.js +12 -0
- package/mcp_v2/knowledge-base.json +115 -17
- package/mcp_v2/mcp.js +141 -3
- package/mcp_v2/package-lock.json +2031 -0
- package/mcp_v2/package.json +13 -2
- package/mcp_v2/scripts/copyErrorsIndex.cjs +34 -0
- package/mcp_v2/test/errors.test.ts +123 -0
- package/mcp_v2/test/github.test.ts +177 -0
- package/mcp_v2/tools/errors.d.ts +20 -0
- package/mcp_v2/tools/errors.js +63 -0
- package/mcp_v2/tools/github.d.ts +41 -0
- package/mcp_v2/tools/github.js +231 -0
- package/mcp_v2/vitest.config.mjs +22 -0
- package/package.json +60 -11
- package/test/errors/docsDrift.test.ts +113 -0
- package/test/errors/index.test.ts +200 -0
- package/test/errors/registry.test.ts +108 -0
- package/test/scripts/preflight.test.ts +118 -0
- package/test/server/ChunkExtractor.test.ts +97 -0
- package/test/server/extract.test.ts +128 -0
- package/test/server/fixtures/template/server/document.jsx +19 -0
- package/test/server/fixtures/template/server/index.js +10 -0
- package/test/server/fixtures/template/src/js/containers/App/index.jsx +33 -0
- package/test/server/fixtures/template/src/js/routes/index.jsx +72 -0
- package/test/server/fixtures/template/src/js/routes/utils.jsx +39 -0
- package/test/server/fixtures/template/src/js/store/index.js +19 -0
- package/test/server/handler.assets.test.ts +330 -0
- package/test/server/handler.test.ts +208 -0
- package/test/server/manifestCache.test.ts +71 -0
- package/test/server/render.test.ts +71 -0
- package/test/server/scriptUtils.test.ts +103 -0
- package/test/server/userAgentUtil.test.ts +48 -0
- package/test/server/validator.test.ts +225 -0
- package/test/vite/resolveDevServerConfig.test.js +4 -1
- package/tsconfig.test.json +23 -0
- package/vitest.config.ts +93 -0
- package/dist/caching.js +0 -1
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/DeviceInfoUtilsTest.kt +0 -187
- package/dist/native/bridge/standardizedHooks.js +0 -611
- package/dist/router.js +0 -1
- package/dist/scripts/validator.js +0 -149
- package/dist/web-router/hooks.jsx +0 -72
- package/dist/web-router/types/components/MetaTag.d.ts +0 -2
- package/dist/web-router/types/components/RouterDataProvider.d.ts +0 -95
- package/dist/web-router/types/context.d.ts +0 -14
- package/dist/web-router/types/hooks.d.ts +0 -1
- package/dist/web-router/types/index.d.ts +0 -3
- package/dist/web-router/types/utils/metaDataUtils.d.ts +0 -40
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Constants/CatalystConstants.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Constants/ConfigConstants.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Notifications/NotificationModels.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Protocols/NotificationHandlerProtocol.swift +0 -0
- /package/dist/native/iosnativeWebView/{Sources/Core → CoreLogic/Sources/CatalystCoreLogic}/Utils/NullNotificationHandler.swift +0 -0
|
@@ -8,6 +8,7 @@ var _react = require("react");
|
|
|
8
8
|
var _NativeBridge = _interopRequireDefault(require("../utils/NativeBridge.js"));
|
|
9
9
|
var _NativeInterfaces = require("../constants/NativeInterfaces.js");
|
|
10
10
|
var _useBaseHook = require("../useBaseHook.js");
|
|
11
|
+
var _errors = require("../errors.js");
|
|
11
12
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
13
|
/* eslint-disable react-compiler/react-compiler, react-hooks/exhaustive-deps */
|
|
13
14
|
|
|
@@ -19,6 +20,11 @@ const STREAM_STATE_DEFAULT = {
|
|
|
19
20
|
fpsMin: null,
|
|
20
21
|
fpsMax: null
|
|
21
22
|
};
|
|
23
|
+
|
|
24
|
+
/** Options accepted when starting the native or web video stream. */
|
|
25
|
+
|
|
26
|
+
/** Options accepted by {@link useVideoStream}. */
|
|
27
|
+
|
|
22
28
|
const useVideoStream = ({
|
|
23
29
|
onQRDetected,
|
|
24
30
|
webFallback
|
|
@@ -66,22 +72,16 @@ const useVideoStream = ({
|
|
|
66
72
|
try {
|
|
67
73
|
await track.applyConstraints(constraints);
|
|
68
74
|
} catch (e) {
|
|
69
|
-
base.setError({
|
|
70
|
-
message: `applyConstraints failed: ${e.message}`
|
|
71
|
-
});
|
|
75
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INTERNAL_ERROR, `applyConstraints failed: ${e.message}`, e));
|
|
72
76
|
}
|
|
73
77
|
}, [base]);
|
|
74
78
|
const webStart = (0, _react.useCallback)(async (options = {}) => {
|
|
75
79
|
if (!window.isSecureContext) {
|
|
76
|
-
base.setError(
|
|
77
|
-
message: "getUserMedia requires a secure context (HTTPS or localhost)"
|
|
78
|
-
});
|
|
80
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.FEATURE_UNSUPPORTED, "getUserMedia requires a secure context (HTTPS or localhost)"));
|
|
79
81
|
return;
|
|
80
82
|
}
|
|
81
83
|
if (!navigator.mediaDevices?.getUserMedia) {
|
|
82
|
-
base.setError(
|
|
83
|
-
message: "getUserMedia is not available in this browser"
|
|
84
|
-
});
|
|
84
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.FEATURE_UNSUPPORTED, "getUserMedia is not available in this browser"));
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
87
|
try {
|
|
@@ -114,9 +114,8 @@ const useVideoStream = ({
|
|
|
114
114
|
}));
|
|
115
115
|
} catch (e) {
|
|
116
116
|
base.setLoading(false);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
});
|
|
117
|
+
const code = e?.name === "NotAllowedError" ? _errors.ERROR_CODES.PERMISSION_DENIED : e?.name === "NotReadableError" ? _errors.ERROR_CODES.CAMERA_IN_USE : _errors.ERROR_CODES.CAMERA_UNAVAILABLE;
|
|
118
|
+
base.setError((0, _errors.createStandardError)(code, e.message || "getUserMedia failed", e));
|
|
120
119
|
}
|
|
121
120
|
}, [base]);
|
|
122
121
|
const webStop = (0, _react.useCallback)(() => {
|
|
@@ -135,18 +134,14 @@ const useVideoStream = ({
|
|
|
135
134
|
}, [webStart, webStop]);
|
|
136
135
|
const webSendCommand = (0, _react.useCallback)(async (type, value) => {
|
|
137
136
|
if (!isStreamingWeb) {
|
|
138
|
-
base.setError({
|
|
139
|
-
message: `sendCommand('${type}') called but stream is not active`
|
|
140
|
-
});
|
|
137
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand('${type}') called but stream is not active`));
|
|
141
138
|
return;
|
|
142
139
|
}
|
|
143
140
|
switch (type) {
|
|
144
141
|
case "zoom":
|
|
145
142
|
{
|
|
146
143
|
if (typeof value !== "number" || value < 1.0) {
|
|
147
|
-
base.setError({
|
|
148
|
-
message: `sendCommand zoom: value must be a multiplier >= 1.0, got ${value}`
|
|
149
|
-
});
|
|
144
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand zoom: value must be a multiplier >= 1.0, got ${value}`));
|
|
150
145
|
return;
|
|
151
146
|
}
|
|
152
147
|
await applyTrackConstraints({
|
|
@@ -163,9 +158,7 @@ const useVideoStream = ({
|
|
|
163
158
|
case "torch":
|
|
164
159
|
{
|
|
165
160
|
if (typeof value !== "boolean") {
|
|
166
|
-
base.setError({
|
|
167
|
-
message: `sendCommand torch: value must be boolean, got ${value}`
|
|
168
|
-
});
|
|
161
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand torch: value must be boolean, got ${value}`));
|
|
169
162
|
return;
|
|
170
163
|
}
|
|
171
164
|
await applyTrackConstraints({
|
|
@@ -182,9 +175,7 @@ const useVideoStream = ({
|
|
|
182
175
|
case "fps":
|
|
183
176
|
{
|
|
184
177
|
if (typeof value !== "object" || value === null) {
|
|
185
|
-
base.setError({
|
|
186
|
-
message: `sendCommand fps: value must be { min, max }, got ${value}`
|
|
187
|
-
});
|
|
178
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand fps: value must be { min, max }, got ${value}`));
|
|
188
179
|
return;
|
|
189
180
|
}
|
|
190
181
|
const {
|
|
@@ -205,9 +196,7 @@ const useVideoStream = ({
|
|
|
205
196
|
break;
|
|
206
197
|
}
|
|
207
198
|
default:
|
|
208
|
-
base.setError({
|
|
209
|
-
message: `sendCommand: unknown type '${type}'`
|
|
210
|
-
});
|
|
199
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand: unknown type '${type}'`));
|
|
211
200
|
}
|
|
212
201
|
}, [isStreamingWeb, applyTrackConstraints, base]);
|
|
213
202
|
|
|
@@ -292,9 +281,7 @@ const useVideoStream = ({
|
|
|
292
281
|
}, []);
|
|
293
282
|
const nativeSendCommand = (0, _react.useCallback)((type, value) => {
|
|
294
283
|
if (!isStreaming) {
|
|
295
|
-
base.setError({
|
|
296
|
-
message: `sendCommand('${type}') called but stream is not active`
|
|
297
|
-
});
|
|
284
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand('${type}') called but stream is not active`));
|
|
298
285
|
return;
|
|
299
286
|
}
|
|
300
287
|
console.log(`[useVideoStream] sendCommand(${type}, ${value})`);
|
|
@@ -302,9 +289,7 @@ const useVideoStream = ({
|
|
|
302
289
|
case "zoom":
|
|
303
290
|
{
|
|
304
291
|
if (typeof value !== "number" || value < 1.0) {
|
|
305
|
-
base.setError({
|
|
306
|
-
message: `sendCommand zoom: value must be a multiplier >= 1.0 (e.g. 1.0=1x, 2.0=2x), got ${value}`
|
|
307
|
-
});
|
|
292
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand zoom: value must be a multiplier >= 1.0 (e.g. 1.0=1x, 2.0=2x), got ${value}`));
|
|
308
293
|
return;
|
|
309
294
|
}
|
|
310
295
|
_NativeBridge.default.videoStream.setZoom(value);
|
|
@@ -313,9 +298,7 @@ const useVideoStream = ({
|
|
|
313
298
|
case "torch":
|
|
314
299
|
{
|
|
315
300
|
if (typeof value !== "boolean") {
|
|
316
|
-
base.setError({
|
|
317
|
-
message: `sendCommand torch: value must be boolean, got ${value}`
|
|
318
|
-
});
|
|
301
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand torch: value must be boolean, got ${value}`));
|
|
319
302
|
return;
|
|
320
303
|
}
|
|
321
304
|
_NativeBridge.default.videoStream.setTorch(value);
|
|
@@ -324,9 +307,7 @@ const useVideoStream = ({
|
|
|
324
307
|
case "fps":
|
|
325
308
|
{
|
|
326
309
|
if (typeof value !== "object" || value === null) {
|
|
327
|
-
base.setError({
|
|
328
|
-
message: `sendCommand fps: value must be { min, max }, got ${value}`
|
|
329
|
-
});
|
|
310
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand fps: value must be { min, max }, got ${value}`));
|
|
330
311
|
return;
|
|
331
312
|
}
|
|
332
313
|
const {
|
|
@@ -334,21 +315,15 @@ const useVideoStream = ({
|
|
|
334
315
|
max = null
|
|
335
316
|
} = value;
|
|
336
317
|
if (min !== null && (typeof min !== "number" || min < 1)) {
|
|
337
|
-
base.setError({
|
|
338
|
-
message: `sendCommand fps: min must be a positive number, got ${min}`
|
|
339
|
-
});
|
|
318
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand fps: min must be a positive number, got ${min}`));
|
|
340
319
|
return;
|
|
341
320
|
}
|
|
342
321
|
if (max !== null && (typeof max !== "number" || max < 1)) {
|
|
343
|
-
base.setError({
|
|
344
|
-
message: `sendCommand fps: max must be a positive number, got ${max}`
|
|
345
|
-
});
|
|
322
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand fps: max must be a positive number, got ${max}`));
|
|
346
323
|
return;
|
|
347
324
|
}
|
|
348
325
|
if (min !== null && max !== null && min > max) {
|
|
349
|
-
base.setError({
|
|
350
|
-
message: `sendCommand fps: min (${min}) must be <= max (${max})`
|
|
351
|
-
});
|
|
326
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand fps: min (${min}) must be <= max (${max})`));
|
|
352
327
|
return;
|
|
353
328
|
}
|
|
354
329
|
_NativeBridge.default.videoStream.setFps(min, max);
|
|
@@ -360,20 +335,22 @@ const useVideoStream = ({
|
|
|
360
335
|
break;
|
|
361
336
|
}
|
|
362
337
|
default:
|
|
363
|
-
base.setError({
|
|
364
|
-
message: `sendCommand: unknown type '${type}'`
|
|
365
|
-
});
|
|
338
|
+
base.setError((0, _errors.createStandardError)(_errors.ERROR_CODES.INVALID_PARAMETERS, `sendCommand: unknown type '${type}'`));
|
|
366
339
|
}
|
|
367
340
|
}, [isStreaming, base.setError]);
|
|
368
341
|
if (typeof window === "undefined") {
|
|
369
342
|
return {
|
|
370
343
|
isStreaming: false,
|
|
371
344
|
streamState: STREAM_STATE_DEFAULT,
|
|
345
|
+
loading: false,
|
|
372
346
|
error: null,
|
|
373
347
|
isNative: false,
|
|
374
|
-
|
|
348
|
+
isWeb: true,
|
|
349
|
+
webFallbackActive: base.webFallbackActive,
|
|
375
350
|
webFallbackDisabled: false,
|
|
376
351
|
setWebFallback: () => {},
|
|
352
|
+
mediaStream: null,
|
|
353
|
+
viewfinderRef,
|
|
377
354
|
start: () => {},
|
|
378
355
|
stop: () => {},
|
|
379
356
|
sendCommand: () => {},
|
|
@@ -385,11 +362,15 @@ const useVideoStream = ({
|
|
|
385
362
|
return {
|
|
386
363
|
isStreaming: false,
|
|
387
364
|
streamState: STREAM_STATE_DEFAULT,
|
|
365
|
+
loading: base.loading,
|
|
388
366
|
error: null,
|
|
389
367
|
isNative: false,
|
|
368
|
+
isWeb: base.isWeb,
|
|
390
369
|
webFallbackActive: false,
|
|
391
370
|
webFallbackDisabled: true,
|
|
392
371
|
setWebFallback: base.setWebFallback,
|
|
372
|
+
mediaStream: null,
|
|
373
|
+
viewfinderRef,
|
|
393
374
|
start: () => {},
|
|
394
375
|
stop: () => {},
|
|
395
376
|
sendCommand: () => {},
|
|
@@ -401,8 +382,10 @@ const useVideoStream = ({
|
|
|
401
382
|
return {
|
|
402
383
|
isStreaming: isStreamingWeb,
|
|
403
384
|
streamState: streamStateWeb,
|
|
385
|
+
loading: base.loading,
|
|
404
386
|
error: base.error,
|
|
405
387
|
isNative: false,
|
|
388
|
+
isWeb: base.isWeb,
|
|
406
389
|
webFallbackActive: true,
|
|
407
390
|
webFallbackDisabled: false,
|
|
408
391
|
setWebFallback: base.setWebFallback,
|
|
@@ -418,11 +401,14 @@ const useVideoStream = ({
|
|
|
418
401
|
return {
|
|
419
402
|
isStreaming,
|
|
420
403
|
streamState,
|
|
404
|
+
loading: base.loading,
|
|
421
405
|
error: base.error,
|
|
422
406
|
isNative: base.isNative,
|
|
407
|
+
isWeb: base.isWeb,
|
|
423
408
|
webFallbackActive: false,
|
|
424
409
|
webFallbackDisabled: false,
|
|
425
410
|
setWebFallback: base.setWebFallback,
|
|
411
|
+
mediaStream: null,
|
|
426
412
|
viewfinderRef,
|
|
427
413
|
start: nativeStart,
|
|
428
414
|
stop: nativeStop,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./hooks/index.js";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApiCollector.js
|
|
3
|
+
*
|
|
4
|
+
* Instruments native API call timing — how long each @JavascriptInterface
|
|
5
|
+
* method takes from native receipt until its immediate native handler work is
|
|
6
|
+
* dispatched. It does not measure JS-to-native transport, JS callback delivery,
|
|
7
|
+
* or UI completion.
|
|
8
|
+
*
|
|
9
|
+
* Native events received (via __catalystPerfBatch drain):
|
|
10
|
+
* api-call { callId, method, nativeStartMs, nativeEndMs, durationMs, thread }
|
|
11
|
+
*
|
|
12
|
+
* Spans emitted (one per call, on Catalyst > Native API track):
|
|
13
|
+
* catalyst:api/<method> — nativeStart → nativeEnd
|
|
14
|
+
* color: primary-dark (<50ms), secondary (<200ms), error (>200ms)
|
|
15
|
+
* properties: method, durationMs, callId, thread, simulatorValid: false
|
|
16
|
+
*
|
|
17
|
+
* Reading the track:
|
|
18
|
+
* Blue = fast native call (<50ms) — expected for sync APIs (getDeviceInfo, haptic)
|
|
19
|
+
* Grey = medium native call (<200ms) — native work worth inspecting
|
|
20
|
+
* Red = slow native call (>200ms) — native work worth inspecting
|
|
21
|
+
*/
|
|
22
|
+
export declare class ApiCollector {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
constructor(measure: any, nativeToWeb: any);
|
|
25
|
+
init(): void;
|
|
26
|
+
/** Called by index.js to feed the normalized perf store. */
|
|
27
|
+
setWaterfallSource(fn: any): void;
|
|
28
|
+
setInteractionSource(fn: any): void;
|
|
29
|
+
onBatchEvent(event: any): void;
|
|
30
|
+
}
|
|
@@ -28,6 +28,10 @@ var _constants = require("../core/constants.js");
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
class ApiCollector {
|
|
31
|
+
// Internal collector state, assigned in the constructor. The perf module is
|
|
32
|
+
// internal to the bridge and deliberately left loosely typed during the
|
|
33
|
+
// migration, so an index signature stands in for per-field declarations.
|
|
34
|
+
|
|
31
35
|
constructor(measure, nativeToWeb) {
|
|
32
36
|
this._measure = measure;
|
|
33
37
|
this._nativeToWeb = nativeToWeb;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CacheCollector.js
|
|
3
|
+
*
|
|
4
|
+
* Instruments: bugs #1, #2, #10
|
|
5
|
+
* #1 page slowness OTC pages → cache miss → slow fetch → resource blocks render
|
|
6
|
+
* #2 back-forward reloads screen → back navigation triggers a burst of cache misses
|
|
7
|
+
* #10 footer flash on Drug/OTC → cache miss for footer chunk → layout shift after load
|
|
8
|
+
*
|
|
9
|
+
* Native events received in two modes:
|
|
10
|
+
*
|
|
11
|
+
* 1. Live (legacy path — only used if buffer disabled):
|
|
12
|
+
* cache-hit-memory / cache-hit-disk / cache-miss-fetch / network-fetch-complete
|
|
13
|
+
* → Each emits immediately to Catalyst > Cache track via onNativeEvent()
|
|
14
|
+
*
|
|
15
|
+
* 2. Batched (primary path via __catalystPerfBatch drain in index.js):
|
|
16
|
+
* Same event types arrive as part of the native buffer flush after onPageFinished.
|
|
17
|
+
* JS drains via requestIdleCallback → onBatchEvent() → emits spans on Catalyst > Cache > Detail
|
|
18
|
+
*
|
|
19
|
+
* cache-summary { hits, misses, fetches, total, hitRatePct, avgFetchMs, topSlowest[] }
|
|
20
|
+
* → One summary span emitted on main Catalyst > Cache track for InsightsCollector
|
|
21
|
+
*
|
|
22
|
+
* Spans emitted:
|
|
23
|
+
* Catalyst > Cache > Detail individual spans (one per file) during idle drain
|
|
24
|
+
* Catalyst > Cache summary span (hit rate, avg fetch, top slowest)
|
|
25
|
+
*
|
|
26
|
+
* Reading the track:
|
|
27
|
+
* Blue = cache HIT memory — fastest path
|
|
28
|
+
* Blue-light = cache HIT disk — good, slightly slower
|
|
29
|
+
* Red = cache MISS — matched pattern but not cached
|
|
30
|
+
* Yellow/Orange = network fetch — orange if slow >300ms
|
|
31
|
+
*/
|
|
32
|
+
export declare class CacheCollector {
|
|
33
|
+
[key: string]: any;
|
|
34
|
+
constructor(measure: any, nativeToWeb: any);
|
|
35
|
+
/** Called by index.js to wire up insights notifications for cache-summary. */
|
|
36
|
+
setInsightsSource(fn: any): void;
|
|
37
|
+
init(): void;
|
|
38
|
+
onNativeEvent(event: any): void;
|
|
39
|
+
onBatchEvent(event: any): void;
|
|
40
|
+
_emitCacheSpan(event: any, track: any): void;
|
|
41
|
+
_emitSummarySpan(event: any): void;
|
|
42
|
+
_filename(url: any): string;
|
|
43
|
+
}
|
|
@@ -39,6 +39,10 @@ var _constants = require("../core/constants.js");
|
|
|
39
39
|
|
|
40
40
|
const TRACK_CACHE_DETAIL = "Cache > Detail";
|
|
41
41
|
class CacheCollector {
|
|
42
|
+
// Internal collector state, assigned in the constructor. The perf module is
|
|
43
|
+
// internal to the bridge and deliberately left loosely typed during the
|
|
44
|
+
// migration, so an index signature stands in for per-field declarations.
|
|
45
|
+
|
|
42
46
|
constructor(measure, nativeToWeb) {
|
|
43
47
|
this._measure = measure;
|
|
44
48
|
this._nativeToWeb = nativeToWeb;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HookCollector.js — Option A (symptom detection only)
|
|
3
|
+
*
|
|
4
|
+
* Instruments: bugs #13, #15, #16
|
|
5
|
+
* #13 cart computation loop jank → LoAF bursts sustained over time, not tied to a single interaction
|
|
6
|
+
* detected as: LoAF count > threshold within a rolling window
|
|
7
|
+
* #15 quantity selector slow first → interaction → first LoAF burst → long gap → paint
|
|
8
|
+
* detected as: LoAF fires within LAZY_LOAF_WINDOW_MS after tap
|
|
9
|
+
* #16 prescription screen touch lag → same pattern as #15
|
|
10
|
+
*
|
|
11
|
+
* Option A strategy (no React hooks needed):
|
|
12
|
+
* - Watch for LoAF bursts within 2s of a pointerdown (taps that might trigger lazy load)
|
|
13
|
+
* - If LoAF count > 0 in that window → emit hook/lazy span showing the blocked period
|
|
14
|
+
* - Sustained LoAF (3+ frames in 5s with no user interaction) → emit hook/mount span
|
|
15
|
+
* flagging a background computation loop
|
|
16
|
+
*
|
|
17
|
+
* Spans emitted:
|
|
18
|
+
* catalyst:hook/lazy|<label> — LoAF burst after interaction (Track: Hook)
|
|
19
|
+
* detail: loafCount, totalBlockingMs, triggerTarget
|
|
20
|
+
* catalyst:hook/mount|loop — sustained background LoAF (Track: Hook)
|
|
21
|
+
* detail: loafCount, windowMs, likelyCause='computation-loop'
|
|
22
|
+
*
|
|
23
|
+
* TODO (Option B — future):
|
|
24
|
+
* Expose window.catalyst.markComponentMount(name) / markComponentReady(name)
|
|
25
|
+
* for precise hook-lifecycle spans without symptom inference.
|
|
26
|
+
*/
|
|
27
|
+
export declare class HookCollector {
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
constructor(measure: any);
|
|
30
|
+
init(): void;
|
|
31
|
+
/** Called by index.js to feed the normalized perf store. */
|
|
32
|
+
setWaterfallSource(fn: any): void;
|
|
33
|
+
onLoaf(start: any, end: any): void;
|
|
34
|
+
_onPointerDown(e: any): void;
|
|
35
|
+
_closeLazySpan(): void;
|
|
36
|
+
_emitLoopSpan(): void;
|
|
37
|
+
}
|
|
@@ -36,6 +36,10 @@ const LOOP_LOAF_COUNT = 3; // ≥3 LoAFs in the loop window = computation loop
|
|
|
36
36
|
const LOOP_WINDOW_MS = 5000; // rolling window to count sustained LoAFs
|
|
37
37
|
|
|
38
38
|
class HookCollector {
|
|
39
|
+
// Internal collector state, assigned in the constructor. The perf module is
|
|
40
|
+
// internal to the bridge and deliberately left loosely typed during the
|
|
41
|
+
// migration, so an index signature stands in for per-field declarations.
|
|
42
|
+
|
|
39
43
|
constructor(measure) {
|
|
40
44
|
this._measure = measure;
|
|
41
45
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InsightsCollector.js
|
|
3
|
+
*
|
|
4
|
+
* Watches accumulated perf data and emits actionable warnings to the
|
|
5
|
+
* Catalyst > Insights track in Chrome DevTools.
|
|
6
|
+
*
|
|
7
|
+
* Each insight is a point-in-time span with:
|
|
8
|
+
* - severity: 'critical' | 'warning' | 'info'
|
|
9
|
+
* - rule: short machine-readable id (e.g. 'slow-page-load')
|
|
10
|
+
* - message: one-sentence human diagnosis
|
|
11
|
+
* - fix: immediate actionable recommendation
|
|
12
|
+
* - evidence: the numbers that triggered the rule
|
|
13
|
+
*
|
|
14
|
+
* Insights are emitted in two modes:
|
|
15
|
+
* 1. Reactive — emitted immediately when a threshold breach is detected
|
|
16
|
+
* (e.g. an fps-drop episode during interaction)
|
|
17
|
+
* 2. Summary — emitted once after SESSION_SUMMARY_DELAY_MS of inactivity
|
|
18
|
+
* to give a rolled-up view of what happened in the last session
|
|
19
|
+
*
|
|
20
|
+
* How to read this in DevTools:
|
|
21
|
+
* Performance tab → Catalyst > Insights track
|
|
22
|
+
* Click any span → Tooltip shows: severity, rule, message, fix, evidence
|
|
23
|
+
* Red spans = critical (user-visible jank/failure)
|
|
24
|
+
* Yellow (tertiary) = warning
|
|
25
|
+
* Blue (secondary) = info / optimization opportunity
|
|
26
|
+
*/
|
|
27
|
+
export declare class InsightsCollector {
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
constructor(measure: any);
|
|
30
|
+
init(): void;
|
|
31
|
+
setStoreSource(fn: any): void;
|
|
32
|
+
notifyFpsDrop({ minFps, avgFps, durationMs, duringInteraction, deltaFps, baselineFps, startTime, endTime, interactionId, }: {
|
|
33
|
+
avgFps: any;
|
|
34
|
+
baselineFps: any;
|
|
35
|
+
deltaFps: any;
|
|
36
|
+
durationMs: any;
|
|
37
|
+
duringInteraction: any;
|
|
38
|
+
endTime: any;
|
|
39
|
+
interactionId: any;
|
|
40
|
+
minFps: any;
|
|
41
|
+
startTime: any;
|
|
42
|
+
}): void;
|
|
43
|
+
notifySlowLoad({ url, durationMs, startTime, endTime }: {
|
|
44
|
+
durationMs: any;
|
|
45
|
+
endTime: any;
|
|
46
|
+
startTime: any;
|
|
47
|
+
url: any;
|
|
48
|
+
}): void;
|
|
49
|
+
notifyColdStart({ durationMs, startTime, endTime }: {
|
|
50
|
+
durationMs: any;
|
|
51
|
+
endTime: any;
|
|
52
|
+
startTime: any;
|
|
53
|
+
}): void;
|
|
54
|
+
notifyLoafDuringNav({ durationMs, startTime, endTime }: {
|
|
55
|
+
durationMs: any;
|
|
56
|
+
endTime: any;
|
|
57
|
+
startTime: any;
|
|
58
|
+
}): void;
|
|
59
|
+
notifySlowInteraction({ target, responseMs, startTime, endTime, interactionId }: {
|
|
60
|
+
endTime: any;
|
|
61
|
+
interactionId: any;
|
|
62
|
+
responseMs: any;
|
|
63
|
+
startTime: any;
|
|
64
|
+
target: any;
|
|
65
|
+
}): void;
|
|
66
|
+
notifyHighMemory({ currentMb, startTime, endTime, memoryId }: {
|
|
67
|
+
currentMb: any;
|
|
68
|
+
endTime: any;
|
|
69
|
+
memoryId: any;
|
|
70
|
+
startTime: any;
|
|
71
|
+
}): void;
|
|
72
|
+
notifyHwAccelDuringFrame({ durationMs, thread, trigger, startTime, endTime }: {
|
|
73
|
+
durationMs: any;
|
|
74
|
+
endTime: any;
|
|
75
|
+
startTime: any;
|
|
76
|
+
thread: any;
|
|
77
|
+
trigger: any;
|
|
78
|
+
}): void;
|
|
79
|
+
notifyLayoutShift({ value, sessionContext, startTime, endTime }: {
|
|
80
|
+
endTime: any;
|
|
81
|
+
sessionContext: any;
|
|
82
|
+
startTime: any;
|
|
83
|
+
value: any;
|
|
84
|
+
}): void;
|
|
85
|
+
notifyScrollJank({ minFps, frameDropCount, startTime, endTime }: {
|
|
86
|
+
endTime: any;
|
|
87
|
+
frameDropCount: any;
|
|
88
|
+
minFps: any;
|
|
89
|
+
startTime: any;
|
|
90
|
+
}): void;
|
|
91
|
+
notifyCacheSummary({ hitRatePct, total, avgFetchMs, startTime, endTime }: {
|
|
92
|
+
avgFetchMs: any;
|
|
93
|
+
endTime: any;
|
|
94
|
+
hitRatePct: any;
|
|
95
|
+
startTime: any;
|
|
96
|
+
total: any;
|
|
97
|
+
}): void;
|
|
98
|
+
_emitReactive({ severity, rule, message, fix, evidence, startTime, endTime, related }: any): void;
|
|
99
|
+
_titleFor(rule: any, evidence: any, message: any): any;
|
|
100
|
+
_categoryFor(rule: any): "cache" | "general" | "interaction" | "memory" | "navigation" | "render" | "scroll" | "session";
|
|
101
|
+
_scheduleSummary(): void;
|
|
102
|
+
_emitSummary(): void;
|
|
103
|
+
}
|
|
@@ -37,6 +37,10 @@ function round(value) {
|
|
|
37
37
|
return Number.isFinite(value) ? Math.round(value) : value;
|
|
38
38
|
}
|
|
39
39
|
class InsightsCollector {
|
|
40
|
+
// Internal collector state, assigned in the constructor. The perf module is
|
|
41
|
+
// internal to the bridge and deliberately left loosely typed during the
|
|
42
|
+
// migration, so an index signature stands in for per-field declarations.
|
|
43
|
+
|
|
40
44
|
constructor(measure) {
|
|
41
45
|
this._measure = measure;
|
|
42
46
|
this._summaryTimer = null;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InteractionCollector.js
|
|
3
|
+
*
|
|
4
|
+
* Instruments: bugs #6, #8, #13, #17
|
|
5
|
+
* #6 blank screens → tap → no paint → LoAF blocked first render
|
|
6
|
+
* detected as: interaction span with no following rAF / LoAF overlap
|
|
7
|
+
* #8 long press context menu → pointerdown held > 500ms = native context menu will appear
|
|
8
|
+
* detected as: long-press span so devs see which elements trigger it
|
|
9
|
+
* #13 cart jank haywire clicks → interaction timestamps vs render timestamps diverge
|
|
10
|
+
* detected as: tap → paint delta > INTERACTION_SLOW_MS
|
|
11
|
+
* #17 prescription modal wrong → event queue backed up: pointerdown fires long after it was queued
|
|
12
|
+
* detected as: slow interaction span overlapping LoAF
|
|
13
|
+
*
|
|
14
|
+
* Spans emitted:
|
|
15
|
+
* catalyst:session/interaction|<tag>#<id> — currently disabled; preserved below as the
|
|
16
|
+
* old 2s grouping window for future re-enable.
|
|
17
|
+
* catalyst:interaction|<tag>#<id> — pointerdown → next rAF (Track: Interaction)
|
|
18
|
+
* detail: responseMs, loafOverlap, target, sessionId
|
|
19
|
+
* catalyst:long-press|<tag> — pointerdown held > 500ms (Track: Interaction)
|
|
20
|
+
* detail: target, heldMs
|
|
21
|
+
*
|
|
22
|
+
* Correlation:
|
|
23
|
+
* A lightweight interaction ID remains active from pointerdown to the next frame.
|
|
24
|
+
* Related work is tagged without emitting a parent session track.
|
|
25
|
+
*
|
|
26
|
+
* Disabled session nesting:
|
|
27
|
+
* On pointerdown, a 2-second interaction session opens.
|
|
28
|
+
* RenderCollector queries activeSessionId to tag its spans.
|
|
29
|
+
* Session closes after SESSION_WINDOW_MS (2s) or next pointerdown, whichever comes first.
|
|
30
|
+
*/
|
|
31
|
+
export declare class InteractionCollector {
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
constructor(measure: any);
|
|
34
|
+
get activeInteractionId(): any;
|
|
35
|
+
interactionIdForRange(startTime: any, endTime?: any): any;
|
|
36
|
+
/** Called by index.js to wire up insights notifications. */
|
|
37
|
+
setInsightsSource(fn: any): void;
|
|
38
|
+
/** Called by index.js to feed the normalized perf store. */
|
|
39
|
+
setWaterfallSource(fn: any): void;
|
|
40
|
+
/** Called by RenderCollector when an fps-drop-episode fires. */
|
|
41
|
+
onFpsDrop(): void;
|
|
42
|
+
/** Called by NetworkTimingCollector when a fetch/XHR starts during an interaction. */
|
|
43
|
+
onNetworkCall(): void;
|
|
44
|
+
init(): void;
|
|
45
|
+
_openSession(target: any, startTime: any): void;
|
|
46
|
+
_closeSession(): void;
|
|
47
|
+
_onPointerDown(e: any): void;
|
|
48
|
+
_onPointerUp(e: any): void;
|
|
49
|
+
_onPointerCancel(e: any): void;
|
|
50
|
+
_rememberInteraction(id: any, startTime: any, endTime: any): void;
|
|
51
|
+
_emitLongPress(pointerId: any, target: any, startTime: any): void;
|
|
52
|
+
_describeTarget(el: any): string;
|
|
53
|
+
}
|
|
@@ -40,6 +40,10 @@ var _session = require("../core/session.js");
|
|
|
40
40
|
const SESSION_WINDOW_MS = 2000;
|
|
41
41
|
const MAX_RECENT_INTERACTIONS = 50;
|
|
42
42
|
class InteractionCollector {
|
|
43
|
+
// Internal collector state, assigned in the constructor. The perf module is
|
|
44
|
+
// internal to the bridge and deliberately left loosely typed during the
|
|
45
|
+
// migration, so an index signature stands in for per-field declarations.
|
|
46
|
+
|
|
43
47
|
constructor(measure) {
|
|
44
48
|
this._measure = measure;
|
|
45
49
|
this._pendingTaps = new Map(); // pointerId → { startMark, startTime, target }
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KeyboardCollector.js
|
|
3
|
+
*
|
|
4
|
+
* Instruments: bugs #3, #12
|
|
5
|
+
* #3 keyboard sticky scroll → keyboard-show → viewport-resize → scroll fires during session
|
|
6
|
+
* if sticky element recalcs during this window it causes thrash
|
|
7
|
+
* #12 search input no auto-focus → keyboard-show event should fire after route transition to search
|
|
8
|
+
* if it doesn't, the native WebView suppressed programmatic focus
|
|
9
|
+
*
|
|
10
|
+
* Native events received (via index.js router):
|
|
11
|
+
* keyboard-show { nativeTime, keyboardHeight }
|
|
12
|
+
* keyboard-hide { nativeTime }
|
|
13
|
+
*
|
|
14
|
+
* Spans emitted:
|
|
15
|
+
* catalyst:session/keyboard — keyboard-show → viewport settled (Track: Keyboard)
|
|
16
|
+
* detail: keyboardHeight, viewportDelta, hadScrollDuringSession
|
|
17
|
+
* catalyst:viewport-resize — visualViewport resize → next rAF (Track: Keyboard)
|
|
18
|
+
* detail: deltaHeight
|
|
19
|
+
*/
|
|
20
|
+
export declare class KeyboardCollector {
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
constructor(measure: any, nativeToWeb: any);
|
|
23
|
+
init(): void;
|
|
24
|
+
setWaterfallSource(fn: any): void;
|
|
25
|
+
onKeyboardShow(event: any): void;
|
|
26
|
+
onKeyboardHide(event: any): void;
|
|
27
|
+
onScrollDuringKeyboard(): void;
|
|
28
|
+
_observeVisualViewport(): void;
|
|
29
|
+
_closeSession(endTime: any): void;
|
|
30
|
+
}
|
|
@@ -27,6 +27,10 @@ var _session = require("../core/session.js");
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
class KeyboardCollector {
|
|
30
|
+
// Internal collector state, assigned in the constructor. The perf module is
|
|
31
|
+
// internal to the bridge and deliberately left loosely typed during the
|
|
32
|
+
// migration, so an index signature stands in for per-field declarations.
|
|
33
|
+
|
|
30
34
|
constructor(measure, nativeToWeb) {
|
|
31
35
|
this._measure = measure;
|
|
32
36
|
this._nativeToWeb = nativeToWeb;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NavigationCollector.js
|
|
3
|
+
*
|
|
4
|
+
* Instruments: bugs #2, #7, #9, #11, #14
|
|
5
|
+
* #2 back-forward reloads screen → new nav session opens, cache miss burst follows
|
|
6
|
+
* #7 header disappears on back → route-transition span shows animation torn down early
|
|
7
|
+
* #9 forward transition broken → route-transition fires but no visual end mark
|
|
8
|
+
* #11 banner overlaps search box → nav session ends but layout-shift fires after
|
|
9
|
+
* #14 transitions not soft → skeleton→content swap visible as layout-shift during nav
|
|
10
|
+
*
|
|
11
|
+
* Spans emitted:
|
|
12
|
+
* catalyst:session/navigation — page start → LCP finalized (Track: Navigation)
|
|
13
|
+
* catalyst:route-transition|<from→to> — popstate/hashchange → rAF settle (Track: Navigation)
|
|
14
|
+
* catalyst:lcp|<ms>ms — LCP candidate finalized (Track: Navigation)
|
|
15
|
+
* catalyst:fcp|<ms>ms — FCP (iOS fallback) (Track: Navigation)
|
|
16
|
+
* catalyst:page-load|<url> — native page-load-start → page-load-end (Track: Navigation)
|
|
17
|
+
* catalyst:cold-start|<ms>ms — native app cold start duration (Track: Navigation)
|
|
18
|
+
* catalyst:boot/activity-created — batch: MainActivity.onCreate (Track: Navigation)
|
|
19
|
+
* catalyst:boot/webview-constructed — batch: CustomWebView init{} (Track: Navigation)
|
|
20
|
+
* catalyst:boot/load-url — batch: WebView.loadUrl() call (Track: Navigation)
|
|
21
|
+
* catalyst:boot/page-started — batch: onPageStarted callback (Track: Navigation)
|
|
22
|
+
* catalyst:boot/page-finished — batch: onPageFinished callback (Track: Navigation)
|
|
23
|
+
*/
|
|
24
|
+
export declare class NavigationCollector {
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
constructor(measure: any, nativeToWeb: any);
|
|
27
|
+
init(): void;
|
|
28
|
+
/** Called by index.js to feed the normalized perf store. */
|
|
29
|
+
setWaterfallSource(fn: any): void;
|
|
30
|
+
get isLoading(): any;
|
|
31
|
+
_observeLCP(): void;
|
|
32
|
+
_setupLcpFinalization(): void;
|
|
33
|
+
_finalizeLcp(): void;
|
|
34
|
+
_observeRouteTransitions(): void;
|
|
35
|
+
onNativeEvent(event: any): void;
|
|
36
|
+
onBatchEvent(event: any): void;
|
|
37
|
+
}
|