@osdk/react-devtools 0.5.0
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 +79 -0
- package/build/esm/DevToolsContext.js +19 -0
- package/build/esm/DevToolsContext.js.map +1 -0
- package/build/esm/components/ActionMetrics.js +89 -0
- package/build/esm/components/ActionMetrics.js.map +1 -0
- package/build/esm/components/BubbleChart.js +175 -0
- package/build/esm/components/BubbleChart.js.map +1 -0
- package/build/esm/components/BubbleChart.module.scss.js +6 -0
- package/build/esm/components/CacheInspectorTab.js +291 -0
- package/build/esm/components/CacheInspectorTab.js.map +1 -0
- package/build/esm/components/CacheInspectorTab.module.scss.js +39 -0
- package/build/esm/components/CacheMetrics.js +55 -0
- package/build/esm/components/CacheMetrics.js.map +1 -0
- package/build/esm/components/ComponentCard.js +124 -0
- package/build/esm/components/ComponentCard.js.map +1 -0
- package/build/esm/components/ComponentCard.module.scss.js +31 -0
- package/build/esm/components/ComputeTab.js +175 -0
- package/build/esm/components/ComputeTab.js.map +1 -0
- package/build/esm/components/CopyableCodeBlock.js +49 -0
- package/build/esm/components/CopyableCodeBlock.js.map +1 -0
- package/build/esm/components/CopyableCodeBlock.module.scss.js +10 -0
- package/build/esm/components/DebuggingTab.js +342 -0
- package/build/esm/components/DebuggingTab.js.map +1 -0
- package/build/esm/components/DebuggingTab.module.scss.js +18 -0
- package/build/esm/components/HookRow.js +180 -0
- package/build/esm/components/HookRow.js.map +1 -0
- package/build/esm/components/HookRow.module.scss.js +16 -0
- package/build/esm/components/ImprovementsTab.js +138 -0
- package/build/esm/components/ImprovementsTab.js.map +1 -0
- package/build/esm/components/ImprovementsTab.module.scss.js +30 -0
- package/build/esm/components/InspectorSelectionHeader.js +65 -0
- package/build/esm/components/InspectorSelectionHeader.js.map +1 -0
- package/build/esm/components/InterceptTab.js +862 -0
- package/build/esm/components/InterceptTab.js.map +1 -0
- package/build/esm/components/InterceptTab.module.scss.js +49 -0
- package/build/esm/components/IssueCard.js +115 -0
- package/build/esm/components/IssueCard.js.map +1 -0
- package/build/esm/components/IssueCard.module.scss.js +24 -0
- package/build/esm/components/LogEntryCard.js +94 -0
- package/build/esm/components/LogEntryCard.js.map +1 -0
- package/build/esm/components/LogEntryCard.module.scss.js +19 -0
- package/build/esm/components/MockEditor.js +316 -0
- package/build/esm/components/MockEditor.js.map +1 -0
- package/build/esm/components/MonitorErrorBoundary.js +64 -0
- package/build/esm/components/MonitorErrorBoundary.js.map +1 -0
- package/build/esm/components/MonitorErrorBoundary.module.scss.js +9 -0
- package/build/esm/components/MonitoringPanel.js +434 -0
- package/build/esm/components/MonitoringPanel.js.map +1 -0
- package/build/esm/components/MonitoringPanel.module.scss.js +81 -0
- package/build/esm/components/ObjectLoadingMetrics.js +60 -0
- package/build/esm/components/ObjectLoadingMetrics.js.map +1 -0
- package/build/esm/components/OsdkAppErrorBoundary.js +68 -0
- package/build/esm/components/OsdkAppErrorBoundary.js.map +1 -0
- package/build/esm/components/OsdkDevTools.js +40 -0
- package/build/esm/components/OsdkDevTools.js.map +1 -0
- package/build/esm/components/OverrideEditor.js +197 -0
- package/build/esm/components/OverrideEditor.js.map +1 -0
- package/build/esm/components/PerformanceTab.js +297 -0
- package/build/esm/components/PerformanceTab.js.map +1 -0
- package/build/esm/components/PrimitiveSelectionPanel.js +220 -0
- package/build/esm/components/PrimitiveSelectionPanel.js.map +1 -0
- package/build/esm/components/PrimitiveSelectionPanel.module.scss.js +26 -0
- package/build/esm/components/issueTypes.js +2 -0
- package/build/esm/components/issueTypes.js.map +1 -0
- package/build/esm/components/resolveComponentName.js +57 -0
- package/build/esm/components/resolveComponentName.js.map +1 -0
- package/build/esm/components/testHelpers.js +312 -0
- package/build/esm/components/testHelpers.js.map +1 -0
- package/build/esm/css.d.ts +20 -0
- package/build/esm/fiber/DegradationNotice.js +193 -0
- package/build/esm/fiber/DegradationNotice.js.map +1 -0
- package/build/esm/fiber/DevtoolsHook.js +252 -0
- package/build/esm/fiber/DevtoolsHook.js.map +1 -0
- package/build/esm/fiber/FiberAccess.js +65 -0
- package/build/esm/fiber/FiberAccess.js.map +1 -0
- package/build/esm/fiber/FiberInspection.js +140 -0
- package/build/esm/fiber/FiberInspection.js.map +1 -0
- package/build/esm/fiber/FiberTags.js +52 -0
- package/build/esm/fiber/FiberTags.js.map +1 -0
- package/build/esm/fiber/HookStateInspector.js +254 -0
- package/build/esm/fiber/HookStateInspector.js.map +1 -0
- package/build/esm/fiber/SafeFiberOperation.js +35 -0
- package/build/esm/fiber/SafeFiberOperation.js.map +1 -0
- package/build/esm/fiber/capabilities.js +180 -0
- package/build/esm/fiber/capabilities.js.map +1 -0
- package/build/esm/fiber/traverseFiber.js +129 -0
- package/build/esm/fiber/traverseFiber.js.map +1 -0
- package/build/esm/fiber/types.js +2 -0
- package/build/esm/fiber/types.js.map +1 -0
- package/build/esm/fiber/validation.js +155 -0
- package/build/esm/fiber/validation.js.map +1 -0
- package/build/esm/hooks/createPollingStore.js +81 -0
- package/build/esm/hooks/createPollingStore.js.map +1 -0
- package/build/esm/hooks/useActiveComponents.js +27 -0
- package/build/esm/hooks/useActiveComponents.js.map +1 -0
- package/build/esm/hooks/useComponentRegistry.js +25 -0
- package/build/esm/hooks/useComponentRegistry.js.map +1 -0
- package/build/esm/hooks/useComputeSelectors.js +43 -0
- package/build/esm/hooks/useComputeSelectors.js.map +1 -0
- package/build/esm/hooks/useConsoleLogs.js +46 -0
- package/build/esm/hooks/useConsoleLogs.js.map +1 -0
- package/build/esm/hooks/useInspectorSelection.js +93 -0
- package/build/esm/hooks/useInspectorSelection.js.map +1 -0
- package/build/esm/hooks/useMetrics.js +23 -0
- package/build/esm/hooks/useMetrics.js.map +1 -0
- package/build/esm/hooks/usePersistedState.js +89 -0
- package/build/esm/hooks/usePersistedState.js.map +1 -0
- package/build/esm/hooks/useRecommendations.js +123 -0
- package/build/esm/hooks/useRecommendations.js.map +1 -0
- package/build/esm/hooks/useSharedTick.js +49 -0
- package/build/esm/hooks/useSharedTick.js.map +1 -0
- package/build/esm/hooks/useTimeElapsed.js +51 -0
- package/build/esm/hooks/useTimeElapsed.js.map +1 -0
- package/build/esm/hooks/useTrackerSubscription.js +97 -0
- package/build/esm/hooks/useTrackerSubscription.js.map +1 -0
- package/build/esm/hooks/useUnusedFieldAnalysis.js +99 -0
- package/build/esm/hooks/useUnusedFieldAnalysis.js.map +1 -0
- package/build/esm/index.js +31 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/inspector/ClickToInspectSystem.js +228 -0
- package/build/esm/inspector/ClickToInspectSystem.js.map +1 -0
- package/build/esm/inspector/components/ComponentLabel.js +175 -0
- package/build/esm/inspector/components/ComponentLabel.js.map +1 -0
- package/build/esm/inspector/components/ComponentLabel.module.scss.js +12 -0
- package/build/esm/inspector/components/InspectorBanner.js +79 -0
- package/build/esm/inspector/components/InspectorBanner.js.map +1 -0
- package/build/esm/inspector/components/InspectorOverlay.js +149 -0
- package/build/esm/inspector/components/InspectorOverlay.js.map +1 -0
- package/build/esm/inspector/components/SelectionHighlight.js +74 -0
- package/build/esm/inspector/components/SelectionHighlight.js.map +1 -0
- package/build/esm/inspector/createClickToInspect.js +21 -0
- package/build/esm/inspector/createClickToInspect.js.map +1 -0
- package/build/esm/inspector/hooks/useAnimatedBounds.js +167 -0
- package/build/esm/inspector/hooks/useAnimatedBounds.js.map +1 -0
- package/build/esm/inspector/index.js +40 -0
- package/build/esm/inspector/index.js.map +1 -0
- package/build/esm/inspector/inspectorController.js +328 -0
- package/build/esm/inspector/inspectorController.js.map +1 -0
- package/build/esm/inspector/types.js +2 -0
- package/build/esm/inspector/types.js.map +1 -0
- package/build/esm/inspector/utils/elementBounds.js +72 -0
- package/build/esm/inspector/utils/elementBounds.js.map +1 -0
- package/build/esm/inspector/utils/interpolation.js +26 -0
- package/build/esm/inspector/utils/interpolation.js.map +1 -0
- package/build/esm/inspector/utils/labelPositioning.js +62 -0
- package/build/esm/inspector/utils/labelPositioning.js.map +1 -0
- package/build/esm/mocking/MockCacheKeyGenerator.js +109 -0
- package/build/esm/mocking/MockCacheKeyGenerator.js.map +1 -0
- package/build/esm/mocking/MockManager.js +281 -0
- package/build/esm/mocking/MockManager.js.map +1 -0
- package/build/esm/prototyping/PrototypeOverrideStore.js +66 -0
- package/build/esm/prototyping/PrototypeOverrideStore.js.map +1 -0
- package/build/esm/prototyping/index.js +18 -0
- package/build/esm/prototyping/index.js.map +1 -0
- package/build/esm/public/vite.js +19 -0
- package/build/esm/public/vite.js.map +1 -0
- package/build/esm/register.js +41 -0
- package/build/esm/register.js.map +1 -0
- package/build/esm/scss.d.ts +20 -0
- package/build/esm/store/ComputeStore.js +269 -0
- package/build/esm/store/ComputeStore.js.map +1 -0
- package/build/esm/store/ConsoleLogStore.js +289 -0
- package/build/esm/store/ConsoleLogStore.js.map +1 -0
- package/build/esm/store/MetricsStore.js +428 -0
- package/build/esm/store/MetricsStore.js.map +1 -0
- package/build/esm/store/MonitorStore.js +288 -0
- package/build/esm/store/MonitorStore.js.map +1 -0
- package/build/esm/store/SubscribableStore.js +38 -0
- package/build/esm/store/SubscribableStore.js.map +1 -0
- package/build/esm/store/WindowErrorStore.js +195 -0
- package/build/esm/store/WindowErrorStore.js.map +1 -0
- package/build/esm/styles.css +19441 -0
- package/build/esm/styles.js +31 -0
- package/build/esm/styles.js.map +1 -0
- package/build/esm/types/compute.js +2 -0
- package/build/esm/types/compute.js.map +1 -0
- package/build/esm/types/emissions.js +2 -0
- package/build/esm/types/emissions.js.map +1 -0
- package/build/esm/types/index.js +23 -0
- package/build/esm/types/index.js.map +1 -0
- package/build/esm/utils/ActionLifecycleTracker.js +178 -0
- package/build/esm/utils/ActionLifecycleTracker.js.map +1 -0
- package/build/esm/utils/CacheEfficiencyAnalyzer.js +198 -0
- package/build/esm/utils/CacheEfficiencyAnalyzer.js.map +1 -0
- package/build/esm/utils/CircularBuffer.js +96 -0
- package/build/esm/utils/CircularBuffer.js.map +1 -0
- package/build/esm/utils/ComponentContextCapture.js +215 -0
- package/build/esm/utils/ComponentContextCapture.js.map +1 -0
- package/build/esm/utils/ComponentPrimitiveDiscovery.js +173 -0
- package/build/esm/utils/ComponentPrimitiveDiscovery.js.map +1 -0
- package/build/esm/utils/ComponentQueryRegistry.js +340 -0
- package/build/esm/utils/ComponentQueryRegistry.js.map +1 -0
- package/build/esm/utils/ComputeMonitor.js +199 -0
- package/build/esm/utils/ComputeMonitor.js.map +1 -0
- package/build/esm/utils/EventTimeline.js +130 -0
- package/build/esm/utils/EventTimeline.js.map +1 -0
- package/build/esm/utils/LinkTraversalTracker.js +116 -0
- package/build/esm/utils/LinkTraversalTracker.js.map +1 -0
- package/build/esm/utils/MockDataGenerator.js +473 -0
- package/build/esm/utils/MockDataGenerator.js.map +1 -0
- package/build/esm/utils/ObservableClientMonitor.js +768 -0
- package/build/esm/utils/ObservableClientMonitor.js.map +1 -0
- package/build/esm/utils/PerformanceRecommendationEngine.js +185 -0
- package/build/esm/utils/PerformanceRecommendationEngine.js.map +1 -0
- package/build/esm/utils/PropertyAccessTracker.js +238 -0
- package/build/esm/utils/PropertyAccessTracker.js.map +1 -0
- package/build/esm/utils/RecommendationMatcher.js +53 -0
- package/build/esm/utils/RecommendationMatcher.js.map +1 -0
- package/build/esm/utils/SubscriptionTracker.js +132 -0
- package/build/esm/utils/SubscriptionTracker.js.map +1 -0
- package/build/esm/utils/UnusedFieldAnalyzer.js +186 -0
- package/build/esm/utils/UnusedFieldAnalyzer.js.map +1 -0
- package/build/esm/utils/WaterfallDetector.js +200 -0
- package/build/esm/utils/WaterfallDetector.js.map +1 -0
- package/build/esm/utils/computePayload.js +37 -0
- package/build/esm/utils/computePayload.js.map +1 -0
- package/build/esm/utils/computeRequest.js +29 -0
- package/build/esm/utils/computeRequest.js.map +1 -0
- package/build/esm/utils/format.js +69 -0
- package/build/esm/utils/format.js.map +1 -0
- package/build/esm/utils/logger.js +31 -0
- package/build/esm/utils/logger.js.map +1 -0
- package/build/esm/vite/constants.js +18 -0
- package/build/esm/vite/constants.js.map +1 -0
- package/build/esm/vite/hookInstaller.js +99 -0
- package/build/esm/vite/hookInstaller.js.map +1 -0
- package/build/esm/vite/index.js +77 -0
- package/build/esm/vite/index.js.map +1 -0
- package/build/types/DevToolsContext.d.ts +3 -0
- package/build/types/DevToolsContext.d.ts.map +1 -0
- package/build/types/components/ActionMetrics.d.ts +6 -0
- package/build/types/components/ActionMetrics.d.ts.map +1 -0
- package/build/types/components/BubbleChart.d.ts +10 -0
- package/build/types/components/BubbleChart.d.ts.map +1 -0
- package/build/types/components/CacheInspectorTab.d.ts +6 -0
- package/build/types/components/CacheInspectorTab.d.ts.map +1 -0
- package/build/types/components/CacheMetrics.d.ts +6 -0
- package/build/types/components/CacheMetrics.d.ts.map +1 -0
- package/build/types/components/ComponentCard.d.ts +13 -0
- package/build/types/components/ComponentCard.d.ts.map +1 -0
- package/build/types/components/ComputeTab.d.ts +6 -0
- package/build/types/components/ComputeTab.d.ts.map +1 -0
- package/build/types/components/CopyableCodeBlock.d.ts +7 -0
- package/build/types/components/CopyableCodeBlock.d.ts.map +1 -0
- package/build/types/components/DebuggingTab.d.ts +6 -0
- package/build/types/components/DebuggingTab.d.ts.map +1 -0
- package/build/types/components/HookRow.d.ts +9 -0
- package/build/types/components/HookRow.d.ts.map +1 -0
- package/build/types/components/ImprovementsTab.d.ts +7 -0
- package/build/types/components/ImprovementsTab.d.ts.map +1 -0
- package/build/types/components/InspectorSelectionHeader.d.ts +12 -0
- package/build/types/components/InspectorSelectionHeader.d.ts.map +1 -0
- package/build/types/components/InterceptTab.d.ts +126 -0
- package/build/types/components/InterceptTab.d.ts.map +1 -0
- package/build/types/components/IssueCard.d.ts +8 -0
- package/build/types/components/IssueCard.d.ts.map +1 -0
- package/build/types/components/LogEntryCard.d.ts +7 -0
- package/build/types/components/LogEntryCard.d.ts.map +1 -0
- package/build/types/components/MockEditor.d.ts +58 -0
- package/build/types/components/MockEditor.d.ts.map +1 -0
- package/build/types/components/MonitorErrorBoundary.d.ts +16 -0
- package/build/types/components/MonitorErrorBoundary.d.ts.map +1 -0
- package/build/types/components/MonitoringPanel.d.ts +8 -0
- package/build/types/components/MonitoringPanel.d.ts.map +1 -0
- package/build/types/components/ObjectLoadingMetrics.d.ts +7 -0
- package/build/types/components/ObjectLoadingMetrics.d.ts.map +1 -0
- package/build/types/components/OsdkAppErrorBoundary.d.ts +18 -0
- package/build/types/components/OsdkAppErrorBoundary.d.ts.map +1 -0
- package/build/types/components/OsdkDevTools.d.ts +2 -0
- package/build/types/components/OsdkDevTools.d.ts.map +1 -0
- package/build/types/components/OverrideEditor.d.ts +26 -0
- package/build/types/components/OverrideEditor.d.ts.map +1 -0
- package/build/types/components/PerformanceTab.d.ts +8 -0
- package/build/types/components/PerformanceTab.d.ts.map +1 -0
- package/build/types/components/PrimitiveSelectionPanel.d.ts +28 -0
- package/build/types/components/PrimitiveSelectionPanel.d.ts.map +1 -0
- package/build/types/components/issueTypes.d.ts +16 -0
- package/build/types/components/issueTypes.d.ts.map +1 -0
- package/build/types/components/resolveComponentName.d.ts +3 -0
- package/build/types/components/resolveComponentName.d.ts.map +1 -0
- package/build/types/components/testHelpers.d.ts +2 -0
- package/build/types/components/testHelpers.d.ts.map +1 -0
- package/build/types/css.d.d.ts +4 -0
- package/build/types/css.d.d.ts.map +1 -0
- package/build/types/fiber/DegradationNotice.d.ts +8 -0
- package/build/types/fiber/DegradationNotice.d.ts.map +1 -0
- package/build/types/fiber/DevtoolsHook.d.ts +7 -0
- package/build/types/fiber/DevtoolsHook.d.ts.map +1 -0
- package/build/types/fiber/FiberAccess.d.ts +2 -0
- package/build/types/fiber/FiberAccess.d.ts.map +1 -0
- package/build/types/fiber/FiberInspection.d.ts +6 -0
- package/build/types/fiber/FiberInspection.d.ts.map +1 -0
- package/build/types/fiber/FiberTags.d.ts +33 -0
- package/build/types/fiber/FiberTags.d.ts.map +1 -0
- package/build/types/fiber/HookStateInspector.d.ts +45 -0
- package/build/types/fiber/HookStateInspector.d.ts.map +1 -0
- package/build/types/fiber/SafeFiberOperation.d.ts +7 -0
- package/build/types/fiber/SafeFiberOperation.d.ts.map +1 -0
- package/build/types/fiber/capabilities.d.ts +38 -0
- package/build/types/fiber/capabilities.d.ts.map +1 -0
- package/build/types/fiber/traverseFiber.d.ts +5 -0
- package/build/types/fiber/traverseFiber.d.ts.map +1 -0
- package/build/types/fiber/types.d.ts +87 -0
- package/build/types/fiber/types.d.ts.map +1 -0
- package/build/types/fiber/validation.d.ts +10 -0
- package/build/types/fiber/validation.d.ts.map +1 -0
- package/build/types/hooks/createPollingStore.d.ts +5 -0
- package/build/types/hooks/createPollingStore.d.ts.map +1 -0
- package/build/types/hooks/useActiveComponents.d.ts +3 -0
- package/build/types/hooks/useActiveComponents.d.ts.map +1 -0
- package/build/types/hooks/useComponentRegistry.d.ts +3 -0
- package/build/types/hooks/useComponentRegistry.d.ts.map +1 -0
- package/build/types/hooks/useComputeSelectors.d.ts +7 -0
- package/build/types/hooks/useComputeSelectors.d.ts.map +1 -0
- package/build/types/hooks/useConsoleLogs.d.ts +7 -0
- package/build/types/hooks/useConsoleLogs.d.ts.map +1 -0
- package/build/types/hooks/useInspectorSelection.d.ts +9 -0
- package/build/types/hooks/useInspectorSelection.d.ts.map +1 -0
- package/build/types/hooks/useMetrics.d.ts +3 -0
- package/build/types/hooks/useMetrics.d.ts.map +1 -0
- package/build/types/hooks/usePersistedState.d.ts +1 -0
- package/build/types/hooks/usePersistedState.d.ts.map +1 -0
- package/build/types/hooks/useRecommendations.d.ts +10 -0
- package/build/types/hooks/useRecommendations.d.ts.map +1 -0
- package/build/types/hooks/useSharedTick.d.ts +1 -0
- package/build/types/hooks/useSharedTick.d.ts.map +1 -0
- package/build/types/hooks/useTimeElapsed.d.ts +1 -0
- package/build/types/hooks/useTimeElapsed.d.ts.map +1 -0
- package/build/types/hooks/useTrackerSubscription.d.ts +16 -0
- package/build/types/hooks/useTrackerSubscription.d.ts.map +1 -0
- package/build/types/hooks/useUnusedFieldAnalysis.d.ts +8 -0
- package/build/types/hooks/useUnusedFieldAnalysis.d.ts.map +1 -0
- package/build/types/index.d.ts +21 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/inspector/ClickToInspectSystem.d.ts +40 -0
- package/build/types/inspector/ClickToInspectSystem.d.ts.map +1 -0
- package/build/types/inspector/components/ComponentLabel.d.ts +3 -0
- package/build/types/inspector/components/ComponentLabel.d.ts.map +1 -0
- package/build/types/inspector/components/InspectorBanner.d.ts +5 -0
- package/build/types/inspector/components/InspectorBanner.d.ts.map +1 -0
- package/build/types/inspector/components/InspectorOverlay.d.ts +3 -0
- package/build/types/inspector/components/InspectorOverlay.d.ts.map +1 -0
- package/build/types/inspector/components/SelectionHighlight.d.ts +3 -0
- package/build/types/inspector/components/SelectionHighlight.d.ts.map +1 -0
- package/build/types/inspector/createClickToInspect.d.ts +3 -0
- package/build/types/inspector/createClickToInspect.d.ts.map +1 -0
- package/build/types/inspector/hooks/useAnimatedBounds.d.ts +2 -0
- package/build/types/inspector/hooks/useAnimatedBounds.d.ts.map +1 -0
- package/build/types/inspector/index.d.ts +13 -0
- package/build/types/inspector/index.d.ts.map +1 -0
- package/build/types/inspector/inspectorController.d.ts +2 -0
- package/build/types/inspector/inspectorController.d.ts.map +1 -0
- package/build/types/inspector/types.d.ts +94 -0
- package/build/types/inspector/types.d.ts.map +1 -0
- package/build/types/inspector/utils/elementBounds.d.ts +3 -0
- package/build/types/inspector/utils/elementBounds.d.ts.map +1 -0
- package/build/types/inspector/utils/interpolation.d.ts +7 -0
- package/build/types/inspector/utils/interpolation.d.ts.map +1 -0
- package/build/types/inspector/utils/labelPositioning.d.ts +3 -0
- package/build/types/inspector/utils/labelPositioning.d.ts.map +1 -0
- package/build/types/mocking/MockCacheKeyGenerator.d.ts +41 -0
- package/build/types/mocking/MockCacheKeyGenerator.d.ts.map +1 -0
- package/build/types/mocking/MockManager.d.ts +103 -0
- package/build/types/mocking/MockManager.d.ts.map +1 -0
- package/build/types/prototyping/PrototypeOverrideStore.d.ts +33 -0
- package/build/types/prototyping/PrototypeOverrideStore.d.ts.map +1 -0
- package/build/types/prototyping/index.d.ts +1 -0
- package/build/types/prototyping/index.d.ts.map +1 -0
- package/build/types/public/vite.d.ts +2 -0
- package/build/types/public/vite.d.ts.map +1 -0
- package/build/types/register.d.ts +1 -0
- package/build/types/register.d.ts.map +1 -0
- package/build/types/scss.d.d.ts +6 -0
- package/build/types/scss.d.d.ts.map +1 -0
- package/build/types/store/ComputeStore.d.ts +47 -0
- package/build/types/store/ComputeStore.d.ts.map +1 -0
- package/build/types/store/ConsoleLogStore.d.ts +29 -0
- package/build/types/store/ConsoleLogStore.d.ts.map +1 -0
- package/build/types/store/MetricsStore.d.ts +42 -0
- package/build/types/store/MetricsStore.d.ts.map +1 -0
- package/build/types/store/MonitorStore.d.ts +86 -0
- package/build/types/store/MonitorStore.d.ts.map +1 -0
- package/build/types/store/SubscribableStore.d.ts +6 -0
- package/build/types/store/SubscribableStore.d.ts.map +1 -0
- package/build/types/store/WindowErrorStore.d.ts +32 -0
- package/build/types/store/WindowErrorStore.d.ts.map +1 -0
- package/build/types/styles.d.ts +1 -0
- package/build/types/styles.d.ts.map +1 -0
- package/build/types/types/compute.d.ts +73 -0
- package/build/types/types/compute.d.ts.map +1 -0
- package/build/types/types/emissions.d.ts +24 -0
- package/build/types/types/emissions.d.ts.map +1 -0
- package/build/types/types/index.d.ts +143 -0
- package/build/types/types/index.d.ts.map +1 -0
- package/build/types/utils/ActionLifecycleTracker.d.ts +39 -0
- package/build/types/utils/ActionLifecycleTracker.d.ts.map +1 -0
- package/build/types/utils/CacheEfficiencyAnalyzer.d.ts +45 -0
- package/build/types/utils/CacheEfficiencyAnalyzer.d.ts.map +1 -0
- package/build/types/utils/CircularBuffer.d.ts +18 -0
- package/build/types/utils/CircularBuffer.d.ts.map +1 -0
- package/build/types/utils/ComponentContextCapture.d.ts +29 -0
- package/build/types/utils/ComponentContextCapture.d.ts.map +1 -0
- package/build/types/utils/ComponentPrimitiveDiscovery.d.ts +62 -0
- package/build/types/utils/ComponentPrimitiveDiscovery.d.ts.map +1 -0
- package/build/types/utils/ComponentQueryRegistry.d.ts +91 -0
- package/build/types/utils/ComponentQueryRegistry.d.ts.map +1 -0
- package/build/types/utils/ComputeMonitor.d.ts +14 -0
- package/build/types/utils/ComputeMonitor.d.ts.map +1 -0
- package/build/types/utils/EventTimeline.d.ts +102 -0
- package/build/types/utils/EventTimeline.d.ts.map +1 -0
- package/build/types/utils/LinkTraversalTracker.d.ts +43 -0
- package/build/types/utils/LinkTraversalTracker.d.ts.map +1 -0
- package/build/types/utils/MockDataGenerator.d.ts +23 -0
- package/build/types/utils/MockDataGenerator.d.ts.map +1 -0
- package/build/types/utils/ObservableClientMonitor.d.ts +62 -0
- package/build/types/utils/ObservableClientMonitor.d.ts.map +1 -0
- package/build/types/utils/PerformanceRecommendationEngine.d.ts +67 -0
- package/build/types/utils/PerformanceRecommendationEngine.d.ts.map +1 -0
- package/build/types/utils/PropertyAccessTracker.d.ts +50 -0
- package/build/types/utils/PropertyAccessTracker.d.ts.map +1 -0
- package/build/types/utils/RecommendationMatcher.d.ts +5 -0
- package/build/types/utils/RecommendationMatcher.d.ts.map +1 -0
- package/build/types/utils/SubscriptionTracker.d.ts +17 -0
- package/build/types/utils/SubscriptionTracker.d.ts.map +1 -0
- package/build/types/utils/UnusedFieldAnalyzer.d.ts +46 -0
- package/build/types/utils/UnusedFieldAnalyzer.d.ts.map +1 -0
- package/build/types/utils/WaterfallDetector.d.ts +28 -0
- package/build/types/utils/WaterfallDetector.d.ts.map +1 -0
- package/build/types/utils/computePayload.d.ts +3 -0
- package/build/types/utils/computePayload.d.ts.map +1 -0
- package/build/types/utils/computeRequest.d.ts +20 -0
- package/build/types/utils/computeRequest.d.ts.map +1 -0
- package/build/types/utils/format.d.ts +5 -0
- package/build/types/utils/format.d.ts.map +1 -0
- package/build/types/utils/logger.d.ts +2 -0
- package/build/types/utils/logger.d.ts.map +1 -0
- package/build/types/vite/constants.d.ts +1 -0
- package/build/types/vite/constants.d.ts.map +1 -0
- package/build/types/vite/hookInstaller.d.ts +1 -0
- package/build/types/vite/hookInstaller.d.ts.map +1 -0
- package/build/types/vite/index.d.ts +20 -0
- package/build/types/vite/index.d.ts.map +1 -0
- package/package.json +114 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","names":[],"sources":["styles.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Placeholder. scripts/build-css.mjs replaces the transpiled\n// build/esm/styles.js with a runtime-injection module that adds devtools\n// styles (including Blueprint) to document.head when the package is\n// imported.\n\nexport {};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute.js","names":[],"sources":["compute.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ninterface ComputeRequestBase {\n id: string;\n requestUrl: string;\n requestTimestamp: Date;\n requestPayload: string;\n requestPayloadHash: number;\n}\n\nexport interface PendingComputeRequest extends ComputeRequestBase {\n type: \"pending\";\n}\n\nexport type ComputeRequestError =\n | { type: \"osdk-network-paused\" }\n | {\n type: \"api-gateway-error\";\n status: number;\n errorCode: string;\n errorInstanceId: string;\n errorName: string;\n }\n | { type: \"http-error\"; status: number; message?: string }\n | { type: \"fetch-error\"; message: string }\n | { type: \"unknown\" };\n\nexport interface FailedComputeRequest extends ComputeRequestBase {\n type: \"failed\";\n failedTimestamp: Date;\n error: ComputeRequestError;\n}\n\nexport interface FulfilledComputeRequest extends ComputeRequestBase {\n type: \"fulfilled\";\n computeUsage: number;\n responseTimestamp: Date;\n responsePayload: string;\n responsePayloadBytes: number;\n responsePayloadHash: number;\n}\n\nexport interface FulfilledWithoutUsageComputeRequest\n extends ComputeRequestBase\n{\n type: \"fulfilled-without-usage\";\n responseTimestamp: Date;\n responsePayload: string;\n responsePayloadBytes: number;\n responsePayloadHash: number;\n}\n\nexport type ComputeRequest =\n | FulfilledComputeRequest\n | FulfilledWithoutUsageComputeRequest\n | PendingComputeRequest\n | FailedComputeRequest;\n\nexport interface ComputeMetrics {\n readonly totalUsage: number;\n readonly lastMinuteUsage: number;\n readonly requestCount: number;\n readonly fulfilledCount: number;\n readonly fulfilledWithoutUsageCount: number;\n readonly failedCount: number;\n readonly pendingCount: number;\n readonly averageUsagePerRequest: number;\n readonly averageResponseBytes: number;\n}\n\nexport interface RecordingEvent {\n type: \"started\" | \"ended\";\n timestamp: Date;\n endTimestamp?: Date;\n}\n\nexport interface ComputeSnapshot {\n readonly metrics: ComputeMetrics;\n readonly requests: ReadonlyArray<ComputeRequest>;\n readonly isRecording: boolean;\n readonly isNetworkPaused: boolean;\n readonly lastRecordingEvent: RecordingEvent | undefined;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emissions.js","names":[],"sources":["emissions.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type EmissionStatus = \"init\" | \"loading\" | \"loaded\" | \"error\";\n\nexport interface EmissionRecord {\n readonly timestamp: number;\n readonly status: EmissionStatus;\n readonly hasData: boolean;\n readonly isOptimistic: boolean;\n readonly optimisticId?: string | number;\n readonly sequenceNumber: number;\n}\n\nexport interface SubscriptionMetadata {\n readonly signature: string;\n readonly subscribeTime: number;\n readonly emissions: EmissionRecord[];\n unsubscribeTime?: number;\n}\n\nexport interface EmissionAnalysis {\n readonly wasCached: boolean;\n readonly wasOptimistic: boolean;\n readonly loadTime?: number;\n readonly emissionCount: number;\n readonly firstOptimisticTimestamp?: number;\n readonly lastOptimisticTimestamp?: number;\n readonly firstNonOptimisticAfterOptimisticTimestamp?: number;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const DEFAULT_MONITOR_CONFIG = {
|
|
18
|
+
cacheDetectionThresholdMs: 10,
|
|
19
|
+
cleanupIntervalMs: 60000,
|
|
20
|
+
maxOperations: 1000,
|
|
21
|
+
timeSeriesSize: 60
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["DEFAULT_MONITOR_CONFIG","cacheDetectionThresholdMs","cleanupIntervalMs","maxOperations","timeSeriesSize"],"sources":["index.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Logger } from \"@osdk/api\";\n\nexport type OperationType =\n | \"cache-hit\"\n | \"cache-miss\"\n | \"revalidation\"\n | \"deduplication\"\n | \"optimistic-update\"\n | \"network-request\"\n | \"action\"\n | \"action-validation\";\n\nexport interface Operation {\n readonly id: string;\n readonly type: OperationType;\n readonly signature: string;\n readonly timestamp: number;\n readonly responseTime?: number;\n readonly saved?: number;\n readonly metadata?: OperationMetadata;\n readonly objectCount?: number;\n readonly actionName?: string;\n readonly optimisticConfigured?: boolean;\n readonly optimisticObserved?: boolean;\n readonly optimisticRenderTime?: number;\n readonly serverRoundTripTime?: number;\n readonly perceivedSpeedup?: number;\n readonly rollback?: boolean;\n readonly optimisticObjectsAffected?: number;\n readonly renderGapBeforeServer?: number;\n readonly optimisticLayerCount?: number;\n}\n\nexport interface OperationMetadata {\n readonly apiName?: string;\n readonly primaryKey?: string;\n readonly actionName?: string;\n readonly objectType?: string;\n readonly whereClause?: string;\n readonly pageSize?: number;\n}\n\nexport interface AggregateMetrics {\n readonly cacheHits: number;\n readonly cacheMisses: number;\n readonly deduplications: number;\n readonly optimisticUpdates: number;\n readonly totalResponseTime: number;\n readonly cachedResponseTime: number;\n readonly networkResponseTime: number;\n readonly requestsSaved: number;\n readonly bytesServedFromCache: number;\n readonly totalObjectsFromCache: number;\n readonly totalObjectsFromNetwork: number;\n readonly actionCount: number;\n readonly configuredOptimisticActionCount: number;\n readonly optimisticActionCount: number;\n readonly rollbackActionCount: number;\n readonly totalOptimisticRenderTime: number;\n readonly totalServerRoundTripTime: number;\n readonly totalPerceivedSpeedup: number;\n readonly totalOptimisticObjectsAffected: number;\n readonly revalidations: number;\n readonly validationCount: number;\n readonly totalValidationTime: number;\n}\n\nexport interface MetricsSnapshot {\n readonly recent: ReadonlyArray<Operation>;\n readonly aggregates: AggregateMetrics;\n readonly rates: MetricRates;\n readonly timeSeries: TimeSeriesData;\n}\n\nexport interface MetricRates {\n readonly cacheHitRate: number;\n readonly deduplicationRate: number;\n readonly optimisticUpdateRate: number;\n readonly averageResponseTime: number;\n readonly averageCachedResponseTime: number;\n readonly optimisticActionCoverage: number;\n readonly configuredOptimisticActionRate: number;\n readonly rollbackRate: number;\n readonly averageOptimisticRenderTime: number;\n readonly averageServerRoundTripTime: number;\n readonly averagePerceivedSpeedup: number;\n readonly averageValidationTime: number;\n readonly validationTimeSaved: number;\n}\n\nexport interface TimeSeriesData {\n readonly timestamps: ReadonlyArray<number>;\n readonly cacheHits: ReadonlyArray<number>;\n readonly cacheMisses: ReadonlyArray<number>;\n readonly revalidations: ReadonlyArray<number>;\n readonly deduplications: ReadonlyArray<number>;\n}\n\nexport type DockMode = \"floating\" | \"docked-bottom\" | \"docked-right\";\n\nexport interface PanelPosition {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly collapsed: boolean;\n readonly dockMode: DockMode;\n}\n\nexport interface ObservableDebugMetadata {\n readonly optimisticId?: string | number;\n readonly servedFromCache?: boolean;\n readonly servedFromMock?: boolean;\n readonly mockId?: string;\n readonly fetchSource?:\n | \"network\"\n | \"stream\"\n | \"optimistic\"\n | \"cross-propagation\";\n}\n\nexport interface MonitoringConfig {\n readonly logger?: Logger;\n readonly cacheDetectionThresholdMs: number;\n readonly cleanupIntervalMs: number;\n readonly maxOperations: number;\n readonly timeSeriesSize: number;\n}\n\nexport const DEFAULT_MONITOR_CONFIG: MonitoringConfig = {\n cacheDetectionThresholdMs: 10,\n cleanupIntervalMs: 60000,\n maxOperations: 1000,\n timeSeriesSize: 60,\n};\n\nexport interface ActionError {\n readonly id: string;\n readonly actionType: string;\n readonly timestamp: number;\n readonly message: string;\n readonly stack?: string;\n readonly parameters: Record<string, unknown>;\n readonly validationErrors?: ValidationError[];\n}\n\nexport interface ValidationError {\n readonly field: string;\n readonly message: string;\n readonly value: unknown;\n}\n\nexport interface WastedRender {\n readonly componentId: string;\n readonly componentName: string;\n readonly count: number;\n readonly timestamp: number;\n}\n\nexport interface UnusedProperty {\n readonly componentId: string;\n readonly componentName: string;\n readonly propertyName: string;\n readonly totalRenders: number;\n readonly accessCount: number;\n}\n\nexport interface OsdkMonitorGlobal {\n readonly componentRegistry: object;\n readonly componentContextCapture: object;\n readonly prototypeOverrideStore: object;\n}\n\ndeclare global {\n interface Window {\n __OSDK_MONITOR__?: OsdkMonitorGlobal;\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmIA,OAAO,MAAMA,sBAAwC,GAAG;EACtDC,yBAAyB,EAAE,EAAE;EAC7BC,iBAAiB,EAAE,KAAK;EACxBC,aAAa,EAAE,IAAI;EACnBC,cAAc,EAAE;AAClB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export class ActionLifecycleTracker {
|
|
18
|
+
actions = new Map();
|
|
19
|
+
layerToAction = new Map();
|
|
20
|
+
subscriptions = new Map();
|
|
21
|
+
constructor(metricsStore, eventTimeline) {
|
|
22
|
+
this.metricsStore = metricsStore;
|
|
23
|
+
this.eventTimeline = eventTimeline;
|
|
24
|
+
}
|
|
25
|
+
startAction(options) {
|
|
26
|
+
const actionId = crypto.randomUUID();
|
|
27
|
+
const timestamp = Date.now();
|
|
28
|
+
this.actions.set(actionId, {
|
|
29
|
+
actionId,
|
|
30
|
+
signature: options.signature,
|
|
31
|
+
metadata: options.metadata,
|
|
32
|
+
actionName: options.actionName,
|
|
33
|
+
startedAt: timestamp,
|
|
34
|
+
optimisticConfigured: options.optimisticConfigured,
|
|
35
|
+
optimisticSeen: false,
|
|
36
|
+
rollback: false,
|
|
37
|
+
optimisticObjectsAffected: 0,
|
|
38
|
+
optimisticLayerIds: new Set(),
|
|
39
|
+
optimisticLayerCount: 0
|
|
40
|
+
});
|
|
41
|
+
if (this.eventTimeline && options.actionName) {
|
|
42
|
+
this.eventTimeline.record({
|
|
43
|
+
type: "ACTION_START",
|
|
44
|
+
actionId,
|
|
45
|
+
actionName: options.actionName,
|
|
46
|
+
timestamp,
|
|
47
|
+
componentId: options.componentId
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return actionId;
|
|
51
|
+
}
|
|
52
|
+
registerOptimisticLayer(actionId, layerId) {
|
|
53
|
+
const action = this.actions.get(actionId);
|
|
54
|
+
if (!action) return;
|
|
55
|
+
action.optimisticLayerIds.add(layerId);
|
|
56
|
+
action.optimisticSeen = true;
|
|
57
|
+
action.optimisticLayerCount++;
|
|
58
|
+
this.layerToAction.set(layerId, actionId);
|
|
59
|
+
}
|
|
60
|
+
handleLayerCleared(layerId, timestamp) {
|
|
61
|
+
const actionId = this.layerToAction.get(layerId);
|
|
62
|
+
if (!actionId) return;
|
|
63
|
+
const action = this.actions.get(actionId);
|
|
64
|
+
if (!action) {
|
|
65
|
+
this.layerToAction.delete(layerId);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
action.optimisticLayerIds.delete(layerId);
|
|
69
|
+
action.lastLayerClearedTimestamp = timestamp;
|
|
70
|
+
if (action.firstConfirmationTimestamp === undefined) {
|
|
71
|
+
action.firstConfirmationTimestamp = timestamp;
|
|
72
|
+
}
|
|
73
|
+
this.layerToAction.delete(layerId);
|
|
74
|
+
}
|
|
75
|
+
noteEmission(options) {
|
|
76
|
+
const {
|
|
77
|
+
subscriptionId,
|
|
78
|
+
optimisticId,
|
|
79
|
+
isOptimistic,
|
|
80
|
+
timestamp,
|
|
81
|
+
objectCount
|
|
82
|
+
} = options;
|
|
83
|
+
if (isOptimistic && optimisticId != null) {
|
|
84
|
+
const actionId = this.layerToAction.get(optimisticId);
|
|
85
|
+
if (!actionId) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const action = this.actions.get(actionId);
|
|
89
|
+
if (!action) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
action.optimisticSeen = true;
|
|
93
|
+
if (action.optimisticRenderTimestamp === undefined || timestamp < action.optimisticRenderTimestamp) {
|
|
94
|
+
action.optimisticRenderTimestamp = timestamp;
|
|
95
|
+
}
|
|
96
|
+
const state = this.subscriptions.get(subscriptionId) ?? {};
|
|
97
|
+
if (state.actionId !== actionId) {
|
|
98
|
+
state.counted = false;
|
|
99
|
+
}
|
|
100
|
+
state.actionId = actionId;
|
|
101
|
+
state.optimisticId = optimisticId;
|
|
102
|
+
if (objectCount > 0 && state.counted !== true) {
|
|
103
|
+
action.optimisticObjectsAffected += objectCount;
|
|
104
|
+
state.counted = true;
|
|
105
|
+
}
|
|
106
|
+
this.subscriptions.set(subscriptionId, state);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const state = this.subscriptions.get(subscriptionId);
|
|
110
|
+
if (!state?.actionId) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const action = this.actions.get(state.actionId);
|
|
114
|
+
if (!action) {
|
|
115
|
+
this.subscriptions.delete(subscriptionId);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (action.firstConfirmationTimestamp === undefined) {
|
|
119
|
+
action.firstConfirmationTimestamp = timestamp;
|
|
120
|
+
}
|
|
121
|
+
if (!isOptimistic) {
|
|
122
|
+
this.subscriptions.delete(subscriptionId);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
clearSubscription(subscriptionId) {
|
|
126
|
+
this.subscriptions.delete(subscriptionId);
|
|
127
|
+
}
|
|
128
|
+
markActionSettled(options) {
|
|
129
|
+
const action = this.actions.get(options.actionId);
|
|
130
|
+
if (!action) return;
|
|
131
|
+
action.completedAt = options.completedAt;
|
|
132
|
+
action.rollback = !options.succeeded;
|
|
133
|
+
if (action.firstConfirmationTimestamp === undefined) {
|
|
134
|
+
action.firstConfirmationTimestamp = action.lastLayerClearedTimestamp ?? options.completedAt;
|
|
135
|
+
}
|
|
136
|
+
if (this.eventTimeline) {
|
|
137
|
+
this.eventTimeline.record({
|
|
138
|
+
type: "ACTION_COMPLETE",
|
|
139
|
+
actionId: options.actionId,
|
|
140
|
+
timestamp: options.completedAt,
|
|
141
|
+
success: options.succeeded
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
this.finalizeAction(action);
|
|
145
|
+
}
|
|
146
|
+
finalizeAction(action) {
|
|
147
|
+
const completedAt = action.completedAt ?? Date.now();
|
|
148
|
+
const serverRoundTripTime = completedAt - action.startedAt;
|
|
149
|
+
const optimisticRenderTime = action.optimisticRenderTimestamp != null ? action.optimisticRenderTimestamp - action.startedAt : undefined;
|
|
150
|
+
const perceivedSpeedup = optimisticRenderTime != null ? serverRoundTripTime - optimisticRenderTime : undefined;
|
|
151
|
+
const renderGapBeforeServer = action.optimisticRenderTimestamp != null && action.firstConfirmationTimestamp != null ? action.firstConfirmationTimestamp - action.optimisticRenderTimestamp : undefined;
|
|
152
|
+
const optimisticObserved = action.optimisticLayerCount > 0 || action.optimisticSeen;
|
|
153
|
+
this.metricsStore.recordActionLifecycle({
|
|
154
|
+
id: action.actionId,
|
|
155
|
+
type: "action",
|
|
156
|
+
signature: action.signature,
|
|
157
|
+
timestamp: completedAt,
|
|
158
|
+
metadata: action.metadata,
|
|
159
|
+
actionName: action.actionName,
|
|
160
|
+
optimisticConfigured: action.optimisticConfigured,
|
|
161
|
+
optimisticObserved,
|
|
162
|
+
optimisticRenderTime,
|
|
163
|
+
serverRoundTripTime,
|
|
164
|
+
perceivedSpeedup,
|
|
165
|
+
rollback: action.rollback,
|
|
166
|
+
optimisticObjectsAffected: action.optimisticObjectsAffected,
|
|
167
|
+
renderGapBeforeServer,
|
|
168
|
+
optimisticLayerCount: action.optimisticLayerCount
|
|
169
|
+
});
|
|
170
|
+
this.actions.delete(action.actionId);
|
|
171
|
+
}
|
|
172
|
+
dispose() {
|
|
173
|
+
this.actions.clear();
|
|
174
|
+
this.layerToAction.clear();
|
|
175
|
+
this.subscriptions.clear();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=ActionLifecycleTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionLifecycleTracker.js","names":["ActionLifecycleTracker","actions","Map","layerToAction","subscriptions","constructor","metricsStore","eventTimeline","startAction","options","actionId","crypto","randomUUID","timestamp","Date","now","set","signature","metadata","actionName","startedAt","optimisticConfigured","optimisticSeen","rollback","optimisticObjectsAffected","optimisticLayerIds","Set","optimisticLayerCount","record","type","componentId","registerOptimisticLayer","layerId","action","get","add","handleLayerCleared","delete","lastLayerClearedTimestamp","firstConfirmationTimestamp","undefined","noteEmission","subscriptionId","optimisticId","isOptimistic","objectCount","optimisticRenderTimestamp","state","counted","clearSubscription","markActionSettled","completedAt","succeeded","success","finalizeAction","serverRoundTripTime","optimisticRenderTime","perceivedSpeedup","renderGapBeforeServer","optimisticObserved","recordActionLifecycle","id","dispose","clear"],"sources":["ActionLifecycleTracker.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { MetricsStore } from \"../store/MetricsStore.js\";\nimport type { OperationMetadata } from \"../types/index.js\";\nimport type { EventTimeline } from \"./EventTimeline.js\";\n\ninterface ActionLifecycleData {\n readonly actionId: string;\n readonly signature: string;\n readonly metadata?: OperationMetadata;\n readonly startedAt: number;\n readonly optimisticConfigured: boolean;\n readonly actionName?: string;\n optimisticSeen: boolean;\n optimisticRenderTimestamp?: number;\n firstConfirmationTimestamp?: number;\n lastLayerClearedTimestamp?: number;\n completedAt?: number;\n rollback: boolean;\n optimisticObjectsAffected: number;\n optimisticLayerIds: Set<unknown>;\n optimisticLayerCount: number;\n}\n\ninterface SubscriptionState {\n actionId?: string;\n optimisticId?: string | number;\n counted?: boolean;\n}\n\ninterface StartActionOptions {\n signature: string;\n actionName?: string;\n metadata?: OperationMetadata;\n optimisticConfigured: boolean;\n componentId?: string;\n}\n\ninterface SettleActionOptions {\n actionId: string;\n succeeded: boolean;\n completedAt: number;\n}\n\ninterface EmissionOptions {\n subscriptionId: string;\n optimisticId?: string | number;\n isOptimistic: boolean;\n timestamp: number;\n objectCount: number;\n}\n\nexport class ActionLifecycleTracker {\n private readonly actions = new Map<string, ActionLifecycleData>();\n private readonly layerToAction = new Map<unknown, string>();\n private readonly subscriptions = new Map<string, SubscriptionState>();\n\n constructor(\n private readonly metricsStore: MetricsStore,\n private readonly eventTimeline?: EventTimeline,\n ) {}\n\n startAction(options: StartActionOptions): string {\n const actionId = crypto.randomUUID();\n const timestamp = Date.now();\n\n this.actions.set(actionId, {\n actionId,\n signature: options.signature,\n metadata: options.metadata,\n actionName: options.actionName,\n startedAt: timestamp,\n optimisticConfigured: options.optimisticConfigured,\n optimisticSeen: false,\n rollback: false,\n optimisticObjectsAffected: 0,\n optimisticLayerIds: new Set(),\n optimisticLayerCount: 0,\n });\n\n if (this.eventTimeline && options.actionName) {\n this.eventTimeline.record({\n type: \"ACTION_START\",\n actionId,\n actionName: options.actionName,\n timestamp,\n componentId: options.componentId,\n });\n }\n\n return actionId;\n }\n\n registerOptimisticLayer(actionId: string, layerId: unknown): void {\n const action = this.actions.get(actionId);\n if (!action) return;\n\n action.optimisticLayerIds.add(layerId);\n action.optimisticSeen = true;\n action.optimisticLayerCount++;\n this.layerToAction.set(layerId, actionId);\n }\n\n handleLayerCleared(layerId: unknown, timestamp: number): void {\n const actionId = this.layerToAction.get(layerId);\n if (!actionId) return;\n\n const action = this.actions.get(actionId);\n if (!action) {\n this.layerToAction.delete(layerId);\n return;\n }\n\n action.optimisticLayerIds.delete(layerId);\n action.lastLayerClearedTimestamp = timestamp;\n if (action.firstConfirmationTimestamp === undefined) {\n action.firstConfirmationTimestamp = timestamp;\n }\n\n this.layerToAction.delete(layerId);\n }\n\n noteEmission(options: EmissionOptions): void {\n const {\n subscriptionId,\n optimisticId,\n isOptimistic,\n timestamp,\n objectCount,\n } = options;\n\n if (isOptimistic && optimisticId != null) {\n const actionId = this.layerToAction.get(optimisticId);\n if (!actionId) {\n return;\n }\n\n const action = this.actions.get(actionId);\n if (!action) {\n return;\n }\n\n action.optimisticSeen = true;\n if (\n action.optimisticRenderTimestamp === undefined\n || timestamp < action.optimisticRenderTimestamp\n ) {\n action.optimisticRenderTimestamp = timestamp;\n }\n\n const state = this.subscriptions.get(subscriptionId) ?? {};\n if (state.actionId !== actionId) {\n state.counted = false;\n }\n state.actionId = actionId;\n state.optimisticId = optimisticId;\n\n if (objectCount > 0 && state.counted !== true) {\n action.optimisticObjectsAffected += objectCount;\n state.counted = true;\n }\n\n this.subscriptions.set(subscriptionId, state);\n return;\n }\n\n const state = this.subscriptions.get(subscriptionId);\n if (!state?.actionId) {\n return;\n }\n\n const action = this.actions.get(state.actionId);\n if (!action) {\n this.subscriptions.delete(subscriptionId);\n return;\n }\n\n if (action.firstConfirmationTimestamp === undefined) {\n action.firstConfirmationTimestamp = timestamp;\n }\n\n if (!isOptimistic) {\n this.subscriptions.delete(subscriptionId);\n }\n }\n\n clearSubscription(subscriptionId: string): void {\n this.subscriptions.delete(subscriptionId);\n }\n\n markActionSettled(options: SettleActionOptions): void {\n const action = this.actions.get(options.actionId);\n if (!action) return;\n\n action.completedAt = options.completedAt;\n action.rollback = !options.succeeded;\n\n if (action.firstConfirmationTimestamp === undefined) {\n action.firstConfirmationTimestamp = action.lastLayerClearedTimestamp\n ?? options.completedAt;\n }\n\n if (this.eventTimeline) {\n this.eventTimeline.record({\n type: \"ACTION_COMPLETE\",\n actionId: options.actionId,\n timestamp: options.completedAt,\n success: options.succeeded,\n });\n }\n\n this.finalizeAction(action);\n }\n\n private finalizeAction(action: ActionLifecycleData): void {\n const completedAt = action.completedAt ?? Date.now();\n const serverRoundTripTime = completedAt - action.startedAt;\n const optimisticRenderTime = action.optimisticRenderTimestamp != null\n ? action.optimisticRenderTimestamp - action.startedAt\n : undefined;\n const perceivedSpeedup = optimisticRenderTime != null\n ? serverRoundTripTime - optimisticRenderTime\n : undefined;\n const renderGapBeforeServer = action.optimisticRenderTimestamp != null\n && action.firstConfirmationTimestamp != null\n ? action.firstConfirmationTimestamp\n - action.optimisticRenderTimestamp\n : undefined;\n const optimisticObserved = action.optimisticLayerCount > 0\n || action.optimisticSeen;\n\n this.metricsStore.recordActionLifecycle({\n id: action.actionId,\n type: \"action\",\n signature: action.signature,\n timestamp: completedAt,\n metadata: action.metadata,\n actionName: action.actionName,\n optimisticConfigured: action.optimisticConfigured,\n optimisticObserved,\n optimisticRenderTime,\n serverRoundTripTime,\n perceivedSpeedup,\n rollback: action.rollback,\n optimisticObjectsAffected: action.optimisticObjectsAffected,\n renderGapBeforeServer,\n optimisticLayerCount: action.optimisticLayerCount,\n });\n\n this.actions.delete(action.actionId);\n }\n\n dispose(): void {\n this.actions.clear();\n this.layerToAction.clear();\n this.subscriptions.clear();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export class CacheEfficiencyAnalyzer {
|
|
18
|
+
constructor(metricsStore, coldThresholdMs = 5 * 60 * 1000 // 5 minutes
|
|
19
|
+
) {
|
|
20
|
+
this.metricsStore = metricsStore;
|
|
21
|
+
this.coldThresholdMs = coldThresholdMs;
|
|
22
|
+
}
|
|
23
|
+
analyze(cacheSnapshot) {
|
|
24
|
+
const snapshot = this.metricsStore.getSnapshot();
|
|
25
|
+
const metrics = snapshot.aggregates;
|
|
26
|
+
const totalRequests = metrics.cacheHits + metrics.cacheMisses + metrics.revalidations;
|
|
27
|
+
const hitRate = totalRequests > 0 ? (metrics.cacheHits + metrics.revalidations) / totalRequests : 0;
|
|
28
|
+
const cacheMissRate = 1 - hitRate;
|
|
29
|
+
const avgNetworkTime = this.estimateAverageNetworkTime(metrics);
|
|
30
|
+
const cacheSavings = (metrics.cacheHits + metrics.revalidations) * avgNetworkTime;
|
|
31
|
+
const entries = cacheSnapshot.entries || [];
|
|
32
|
+
const sortedByAccess = [...entries].sort((a, b) => (b.metadata.hitCount || 0) - (a.metadata.hitCount || 0));
|
|
33
|
+
const hotEntries = sortedByAccess.slice(0, 10);
|
|
34
|
+
const coldEntries = entries.filter(e => Date.now() - (e.metadata.timestamp || 0) > this.coldThresholdMs);
|
|
35
|
+
const totalSize = entries.reduce((sum, e) => sum + (e.metadata.size || 0), 0);
|
|
36
|
+
const avgSize = entries.length > 0 ? totalSize / entries.length : 0;
|
|
37
|
+
const recommendations = this.generateRecommendations({
|
|
38
|
+
hitRate,
|
|
39
|
+
cacheMissRate,
|
|
40
|
+
totalEntries: entries.length,
|
|
41
|
+
totalSizeBytes: totalSize,
|
|
42
|
+
coldEntries: coldEntries.length,
|
|
43
|
+
cacheHits: metrics.cacheHits,
|
|
44
|
+
cacheMisses: metrics.cacheMisses,
|
|
45
|
+
revalidations: metrics.revalidations,
|
|
46
|
+
deduplications: metrics.deduplications
|
|
47
|
+
}, cacheSnapshot);
|
|
48
|
+
const score = this.calculateEfficiencyScore({
|
|
49
|
+
hitRate,
|
|
50
|
+
coldEntriesRatio: entries.length > 0 ? coldEntries.length / entries.length : 0,
|
|
51
|
+
totalSizeBytes: totalSize,
|
|
52
|
+
recommendationCount: recommendations.filter(r => r.level === "warning" || r.level === "critical").length
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
hitRate,
|
|
56
|
+
hitRateTrend: this.getHitRateTrend(),
|
|
57
|
+
cacheMissRate,
|
|
58
|
+
cacheSavings,
|
|
59
|
+
bypassedRequests: metrics.cacheHits,
|
|
60
|
+
avgNetworkTime,
|
|
61
|
+
totalEntries: entries.length,
|
|
62
|
+
totalSizeBytes: totalSize,
|
|
63
|
+
averageEntrySize: avgSize,
|
|
64
|
+
hotEntries,
|
|
65
|
+
coldEntries,
|
|
66
|
+
coldThresholdMs: this.coldThresholdMs,
|
|
67
|
+
deduplications: metrics.deduplications,
|
|
68
|
+
recommendations,
|
|
69
|
+
score,
|
|
70
|
+
grade: this.scoreToGrade(score)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
getHitRateTrend(windowSeconds = 60) {
|
|
74
|
+
const snapshot = this.metricsStore.getSnapshot();
|
|
75
|
+
const {
|
|
76
|
+
cacheHits,
|
|
77
|
+
cacheMisses,
|
|
78
|
+
revalidations
|
|
79
|
+
} = snapshot.timeSeries;
|
|
80
|
+
const hitRates = [];
|
|
81
|
+
const count = Math.min(windowSeconds, cacheHits.length);
|
|
82
|
+
for (let i = cacheHits.length - count; i < cacheHits.length; i++) {
|
|
83
|
+
if (i < 0) continue;
|
|
84
|
+
const total = cacheHits[i] + cacheMisses[i] + revalidations[i];
|
|
85
|
+
hitRates.push(total > 0 ? (cacheHits[i] + revalidations[i]) / total : 0);
|
|
86
|
+
}
|
|
87
|
+
return hitRates;
|
|
88
|
+
}
|
|
89
|
+
generateRecommendations(metrics) {
|
|
90
|
+
const recommendations = [];
|
|
91
|
+
if (metrics.hitRate < 0.3 && metrics.cacheHits + metrics.cacheMisses + metrics.revalidations > 20) {
|
|
92
|
+
recommendations.push({
|
|
93
|
+
level: "critical",
|
|
94
|
+
title: "Very low cache hit rate",
|
|
95
|
+
message: `Only ${(metrics.hitRate * 100).toFixed(1)}% of queries are served from cache`,
|
|
96
|
+
suggestion: "Consider increasing cache TTL, prefetching related data, or memoizing components"
|
|
97
|
+
});
|
|
98
|
+
} else if (metrics.hitRate < 0.5 && metrics.cacheHits + metrics.cacheMisses + metrics.revalidations > 20) {
|
|
99
|
+
recommendations.push({
|
|
100
|
+
level: "warning",
|
|
101
|
+
title: "Low cache hit rate",
|
|
102
|
+
message: `Only ${(metrics.hitRate * 100).toFixed(1)}% of queries are served from cache`,
|
|
103
|
+
suggestion: "Enable prefetching or increase cache TTL for frequently accessed data"
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (metrics.coldEntries > 50) {
|
|
107
|
+
recommendations.push({
|
|
108
|
+
level: "warning",
|
|
109
|
+
title: "Many stale cache entries",
|
|
110
|
+
message: `${metrics.coldEntries} entries haven't been accessed in ${this.coldThresholdMs / 60 / 1000} minutes`,
|
|
111
|
+
suggestion: "Consider implementing automatic cache eviction policy"
|
|
112
|
+
});
|
|
113
|
+
} else if (metrics.coldEntries > 20 && metrics.coldEntries > metrics.totalEntries / 2) {
|
|
114
|
+
recommendations.push({
|
|
115
|
+
level: "info",
|
|
116
|
+
title: "Many cold cache entries",
|
|
117
|
+
message: `${metrics.coldEntries}/${metrics.totalEntries} entries are not actively used`,
|
|
118
|
+
suggestion: "You can safely evict cold entries if memory is constrained"
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (metrics.totalSizeBytes > 50 * 1024 * 1024) {
|
|
122
|
+
recommendations.push({
|
|
123
|
+
level: "critical",
|
|
124
|
+
title: "Very large cache",
|
|
125
|
+
message: `Cache is using ${(metrics.totalSizeBytes / 1024 / 1024).toFixed(1)}MB - potential memory pressure`,
|
|
126
|
+
suggestion: "Implement cache size limits, TTL-based eviction, or LRU eviction policy"
|
|
127
|
+
});
|
|
128
|
+
} else if (metrics.totalSizeBytes > 10 * 1024 * 1024) {
|
|
129
|
+
recommendations.push({
|
|
130
|
+
level: "warning",
|
|
131
|
+
title: "Large cache",
|
|
132
|
+
message: `Cache is using ${(metrics.totalSizeBytes / 1024 / 1024).toFixed(1)}MB`,
|
|
133
|
+
suggestion: "Monitor memory usage and consider implementing cache size limits if not present"
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (metrics.deduplications > 5) {
|
|
137
|
+
recommendations.push({
|
|
138
|
+
level: "success",
|
|
139
|
+
title: "Good query deduplication",
|
|
140
|
+
message: `${metrics.deduplications} duplicate queries deduplicated - cache is working well!`,
|
|
141
|
+
suggestion: "Keep current architecture - components are efficiently sharing cache"
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (metrics.hitRate > 0.8) {
|
|
145
|
+
recommendations.push({
|
|
146
|
+
level: "success",
|
|
147
|
+
title: "Excellent cache hit rate",
|
|
148
|
+
message: `${(metrics.hitRate * 100).toFixed(1)}% of queries served from cache`,
|
|
149
|
+
suggestion: "Cache configuration is optimal for your app"
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (metrics.cacheHits + metrics.cacheMisses + metrics.revalidations === 0 && metrics.totalEntries > 0) {
|
|
153
|
+
recommendations.push({
|
|
154
|
+
level: "info",
|
|
155
|
+
title: "Cache not being used",
|
|
156
|
+
message: "Cache entries exist but no hits/misses recorded yet",
|
|
157
|
+
suggestion: "Monitor cache usage as you interact with the app"
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return recommendations;
|
|
161
|
+
}
|
|
162
|
+
calculateEfficiencyScore(params) {
|
|
163
|
+
let score = 100;
|
|
164
|
+
if (params.hitRate < 0.3) {
|
|
165
|
+
score -= 30;
|
|
166
|
+
} else if (params.hitRate < 0.5) {
|
|
167
|
+
score -= 15;
|
|
168
|
+
} else if (params.hitRate < 0.7) {
|
|
169
|
+
score -= 5;
|
|
170
|
+
}
|
|
171
|
+
if (params.coldEntriesRatio > 0.5) {
|
|
172
|
+
score -= 20;
|
|
173
|
+
} else if (params.coldEntriesRatio > 0.3) {
|
|
174
|
+
score -= 10;
|
|
175
|
+
}
|
|
176
|
+
if (params.totalSizeBytes > 50 * 1024 * 1024) {
|
|
177
|
+
score -= 20;
|
|
178
|
+
} else if (params.totalSizeBytes > 10 * 1024 * 1024) {
|
|
179
|
+
score -= 10;
|
|
180
|
+
}
|
|
181
|
+
score -= Math.min(params.recommendationCount * 5, 20);
|
|
182
|
+
return Math.max(0, Math.round(score));
|
|
183
|
+
}
|
|
184
|
+
scoreToGrade(score) {
|
|
185
|
+
if (score >= 90) return "A";
|
|
186
|
+
if (score >= 80) return "B";
|
|
187
|
+
if (score >= 70) return "C";
|
|
188
|
+
if (score >= 60) return "D";
|
|
189
|
+
return "F";
|
|
190
|
+
}
|
|
191
|
+
estimateAverageNetworkTime(metrics) {
|
|
192
|
+
if (metrics.cacheMisses > 0 && metrics.networkResponseTime > 0) {
|
|
193
|
+
return metrics.networkResponseTime / metrics.cacheMisses;
|
|
194
|
+
}
|
|
195
|
+
return 200;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=CacheEfficiencyAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheEfficiencyAnalyzer.js","names":["CacheEfficiencyAnalyzer","constructor","metricsStore","coldThresholdMs","analyze","cacheSnapshot","snapshot","getSnapshot","metrics","aggregates","totalRequests","cacheHits","cacheMisses","revalidations","hitRate","cacheMissRate","avgNetworkTime","estimateAverageNetworkTime","cacheSavings","entries","sortedByAccess","sort","a","b","metadata","hitCount","hotEntries","slice","coldEntries","filter","e","Date","now","timestamp","totalSize","reduce","sum","size","avgSize","length","recommendations","generateRecommendations","totalEntries","totalSizeBytes","deduplications","score","calculateEfficiencyScore","coldEntriesRatio","recommendationCount","r","level","hitRateTrend","getHitRateTrend","bypassedRequests","averageEntrySize","grade","scoreToGrade","windowSeconds","timeSeries","hitRates","count","Math","min","i","total","push","title","message","toFixed","suggestion","params","max","round","networkResponseTime"],"sources":["CacheEfficiencyAnalyzer.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { CacheEntry, CacheSnapshot } from \"@osdk/client/observable\";\nimport type { MetricsStore } from \"../store/MetricsStore.js\";\n\nexport interface NetworkMetrics {\n cacheMisses: number;\n networkResponseTime: number;\n}\n\nexport interface CacheRecommendation {\n level: \"critical\" | \"warning\" | \"info\" | \"success\";\n title: string;\n message: string;\n suggestion: string;\n action?: {\n label: string;\n handler: () => void;\n };\n}\n\nexport interface CacheEfficiencyMetrics {\n hitRate: number;\n hitRateTrend: number[];\n cacheMissRate: number;\n cacheSavings: number;\n bypassedRequests: number;\n avgNetworkTime: number;\n totalEntries: number;\n totalSizeBytes: number;\n averageEntrySize: number;\n hotEntries: CacheEntry[];\n coldEntries: CacheEntry[];\n coldThresholdMs: number;\n deduplications: number;\n recommendations: CacheRecommendation[];\n score: number;\n grade: \"A\" | \"B\" | \"C\" | \"D\" | \"F\";\n}\n\nexport class CacheEfficiencyAnalyzer {\n constructor(\n private metricsStore: MetricsStore,\n private coldThresholdMs: number = 5 * 60 * 1000, // 5 minutes\n ) {}\n\n analyze(cacheSnapshot: CacheSnapshot): CacheEfficiencyMetrics {\n const snapshot = this.metricsStore.getSnapshot();\n const metrics = snapshot.aggregates;\n\n const totalRequests = metrics.cacheHits + metrics.cacheMisses\n + metrics.revalidations;\n const hitRate = totalRequests > 0\n ? (metrics.cacheHits + metrics.revalidations) / totalRequests\n : 0;\n const cacheMissRate = 1 - hitRate;\n\n const avgNetworkTime = this.estimateAverageNetworkTime(metrics);\n const cacheSavings = (metrics.cacheHits + metrics.revalidations)\n * avgNetworkTime;\n\n const entries = cacheSnapshot.entries || [];\n const sortedByAccess = [...entries].sort((a, b) =>\n (b.metadata.hitCount || 0) - (a.metadata.hitCount || 0)\n );\n const hotEntries = sortedByAccess.slice(0, 10);\n const coldEntries = entries.filter(e =>\n Date.now() - (e.metadata.timestamp || 0) > this.coldThresholdMs\n );\n\n const totalSize = entries.reduce(\n (sum, e) => sum + (e.metadata.size || 0),\n 0,\n );\n const avgSize = entries.length > 0 ? totalSize / entries.length : 0;\n\n const recommendations = this.generateRecommendations(\n {\n hitRate,\n cacheMissRate,\n totalEntries: entries.length,\n totalSizeBytes: totalSize,\n coldEntries: coldEntries.length,\n cacheHits: metrics.cacheHits,\n cacheMisses: metrics.cacheMisses,\n revalidations: metrics.revalidations,\n deduplications: metrics.deduplications,\n },\n cacheSnapshot,\n );\n\n const score = this.calculateEfficiencyScore({\n hitRate,\n coldEntriesRatio: entries.length > 0\n ? coldEntries.length / entries.length\n : 0,\n totalSizeBytes: totalSize,\n recommendationCount: recommendations.filter(r =>\n r.level === \"warning\" || r.level === \"critical\"\n ).length,\n });\n\n return {\n hitRate,\n hitRateTrend: this.getHitRateTrend(),\n cacheMissRate,\n cacheSavings,\n bypassedRequests: metrics.cacheHits,\n avgNetworkTime,\n totalEntries: entries.length,\n totalSizeBytes: totalSize,\n averageEntrySize: avgSize,\n hotEntries,\n coldEntries,\n coldThresholdMs: this.coldThresholdMs,\n deduplications: metrics.deduplications,\n recommendations,\n score,\n grade: this.scoreToGrade(score),\n };\n }\n\n getHitRateTrend(windowSeconds: number = 60): number[] {\n const snapshot = this.metricsStore.getSnapshot();\n const { cacheHits, cacheMisses, revalidations } = snapshot.timeSeries;\n\n const hitRates: number[] = [];\n const count = Math.min(windowSeconds, cacheHits.length);\n\n for (let i = cacheHits.length - count; i < cacheHits.length; i++) {\n if (i < 0) continue;\n const total = cacheHits[i] + cacheMisses[i] + revalidations[i];\n hitRates.push(total > 0 ? (cacheHits[i] + revalidations[i]) / total : 0);\n }\n\n return hitRates;\n }\n\n private generateRecommendations(\n metrics: {\n hitRate: number;\n cacheMissRate: number;\n totalEntries: number;\n totalSizeBytes: number;\n coldEntries: number;\n cacheHits: number;\n cacheMisses: number;\n revalidations: number;\n deduplications: number;\n },\n cacheSnapshot: CacheSnapshot,\n ): CacheRecommendation[] {\n const recommendations: CacheRecommendation[] = [];\n\n if (\n metrics.hitRate < 0.3\n && metrics.cacheHits + metrics.cacheMisses + metrics.revalidations > 20\n ) {\n recommendations.push({\n level: \"critical\",\n title: \"Very low cache hit rate\",\n message: `Only ${\n (metrics.hitRate * 100).toFixed(1)\n }% of queries are served from cache`,\n suggestion:\n \"Consider increasing cache TTL, prefetching related data, or memoizing components\",\n });\n } else if (\n metrics.hitRate < 0.5\n && metrics.cacheHits + metrics.cacheMisses + metrics.revalidations > 20\n ) {\n recommendations.push({\n level: \"warning\",\n title: \"Low cache hit rate\",\n message: `Only ${\n (metrics.hitRate * 100).toFixed(1)\n }% of queries are served from cache`,\n suggestion:\n \"Enable prefetching or increase cache TTL for frequently accessed data\",\n });\n }\n\n if (metrics.coldEntries > 50) {\n recommendations.push({\n level: \"warning\",\n title: \"Many stale cache entries\",\n message: `${metrics.coldEntries} entries haven't been accessed in ${\n this.coldThresholdMs / 60 / 1000\n } minutes`,\n suggestion: \"Consider implementing automatic cache eviction policy\",\n });\n } else if (\n metrics.coldEntries > 20 && metrics.coldEntries > metrics.totalEntries / 2\n ) {\n recommendations.push({\n level: \"info\",\n title: \"Many cold cache entries\",\n message:\n `${metrics.coldEntries}/${metrics.totalEntries} entries are not actively used`,\n suggestion:\n \"You can safely evict cold entries if memory is constrained\",\n });\n }\n\n if (metrics.totalSizeBytes > 50 * 1024 * 1024) {\n recommendations.push({\n level: \"critical\",\n title: \"Very large cache\",\n message: `Cache is using ${\n (metrics.totalSizeBytes / 1024 / 1024).toFixed(1)\n }MB - potential memory pressure`,\n suggestion:\n \"Implement cache size limits, TTL-based eviction, or LRU eviction policy\",\n });\n } else if (metrics.totalSizeBytes > 10 * 1024 * 1024) {\n recommendations.push({\n level: \"warning\",\n title: \"Large cache\",\n message: `Cache is using ${\n (metrics.totalSizeBytes / 1024 / 1024).toFixed(1)\n }MB`,\n suggestion:\n \"Monitor memory usage and consider implementing cache size limits if not present\",\n });\n }\n\n if (metrics.deduplications > 5) {\n recommendations.push({\n level: \"success\",\n title: \"Good query deduplication\",\n message:\n `${metrics.deduplications} duplicate queries deduplicated - cache is working well!`,\n suggestion:\n \"Keep current architecture - components are efficiently sharing cache\",\n });\n }\n\n if (metrics.hitRate > 0.8) {\n recommendations.push({\n level: \"success\",\n title: \"Excellent cache hit rate\",\n message: `${\n (metrics.hitRate * 100).toFixed(1)\n }% of queries served from cache`,\n suggestion: \"Cache configuration is optimal for your app\",\n });\n }\n\n if (\n metrics.cacheHits + metrics.cacheMisses + metrics.revalidations === 0\n && metrics.totalEntries > 0\n ) {\n recommendations.push({\n level: \"info\",\n title: \"Cache not being used\",\n message: \"Cache entries exist but no hits/misses recorded yet\",\n suggestion: \"Monitor cache usage as you interact with the app\",\n });\n }\n\n return recommendations;\n }\n\n private calculateEfficiencyScore(params: {\n hitRate: number;\n coldEntriesRatio: number;\n totalSizeBytes: number;\n recommendationCount: number;\n }): number {\n let score = 100;\n\n if (params.hitRate < 0.3) {\n score -= 30;\n } else if (params.hitRate < 0.5) {\n score -= 15;\n } else if (params.hitRate < 0.7) {\n score -= 5;\n }\n\n if (params.coldEntriesRatio > 0.5) {\n score -= 20;\n } else if (params.coldEntriesRatio > 0.3) {\n score -= 10;\n }\n\n if (params.totalSizeBytes > 50 * 1024 * 1024) {\n score -= 20;\n } else if (params.totalSizeBytes > 10 * 1024 * 1024) {\n score -= 10;\n }\n\n score -= Math.min(params.recommendationCount * 5, 20);\n\n return Math.max(0, Math.round(score));\n }\n\n private scoreToGrade(score: number): \"A\" | \"B\" | \"C\" | \"D\" | \"F\" {\n if (score >= 90) return \"A\";\n if (score >= 80) return \"B\";\n if (score >= 70) return \"C\";\n if (score >= 60) return \"D\";\n return \"F\";\n }\n\n private estimateAverageNetworkTime(metrics: NetworkMetrics): number {\n if (metrics.cacheMisses > 0 && metrics.networkResponseTime > 0) {\n return metrics.networkResponseTime / metrics.cacheMisses;\n }\n return 200;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export class CircularBuffer {
|
|
18
|
+
head = 0;
|
|
19
|
+
tail = 0;
|
|
20
|
+
size = 0;
|
|
21
|
+
constructor(capacity, onEvict) {
|
|
22
|
+
if (capacity <= 0) {
|
|
23
|
+
throw new Error("CircularBuffer capacity must be positive");
|
|
24
|
+
}
|
|
25
|
+
this.capacity = capacity;
|
|
26
|
+
this.buffer = new Array(capacity);
|
|
27
|
+
this.onEvict = onEvict;
|
|
28
|
+
}
|
|
29
|
+
push(item) {
|
|
30
|
+
const index = this.tail;
|
|
31
|
+
if (this.size === this.capacity) {
|
|
32
|
+
const evicted = this.buffer[this.tail];
|
|
33
|
+
if (this.onEvict && evicted !== undefined) {
|
|
34
|
+
this.onEvict(evicted);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
this.buffer[this.tail] = item;
|
|
38
|
+
this.tail = (this.tail + 1) % this.capacity;
|
|
39
|
+
if (this.size < this.capacity) {
|
|
40
|
+
this.size++;
|
|
41
|
+
} else {
|
|
42
|
+
this.head = (this.head + 1) % this.capacity;
|
|
43
|
+
}
|
|
44
|
+
return index;
|
|
45
|
+
}
|
|
46
|
+
get(index) {
|
|
47
|
+
if (index < 0 || index >= this.capacity) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
return this.buffer[index];
|
|
51
|
+
}
|
|
52
|
+
toArray() {
|
|
53
|
+
const result = [];
|
|
54
|
+
let current = this.head;
|
|
55
|
+
for (let i = 0; i < this.size; i++) {
|
|
56
|
+
const item = this.buffer[current];
|
|
57
|
+
if (item !== undefined) {
|
|
58
|
+
result.push(item);
|
|
59
|
+
}
|
|
60
|
+
current = (current + 1) % this.capacity;
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
getSize() {
|
|
65
|
+
return this.size;
|
|
66
|
+
}
|
|
67
|
+
getCapacity() {
|
|
68
|
+
return this.capacity;
|
|
69
|
+
}
|
|
70
|
+
isFull() {
|
|
71
|
+
return this.size === this.capacity;
|
|
72
|
+
}
|
|
73
|
+
isEmpty() {
|
|
74
|
+
return this.size === 0;
|
|
75
|
+
}
|
|
76
|
+
getLast(n) {
|
|
77
|
+
const count = Math.min(n, this.size);
|
|
78
|
+
const result = [];
|
|
79
|
+
let index = (this.tail - count + this.capacity) % this.capacity;
|
|
80
|
+
for (let i = 0; i < count; i++) {
|
|
81
|
+
const item = this.buffer[index];
|
|
82
|
+
if (item !== undefined) {
|
|
83
|
+
result.push(item);
|
|
84
|
+
}
|
|
85
|
+
index = (index + 1) % this.capacity;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
clear() {
|
|
90
|
+
this.buffer = new Array(this.capacity);
|
|
91
|
+
this.head = 0;
|
|
92
|
+
this.tail = 0;
|
|
93
|
+
this.size = 0;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=CircularBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CircularBuffer.js","names":["CircularBuffer","head","tail","size","constructor","capacity","onEvict","Error","buffer","Array","push","item","index","evicted","undefined","get","toArray","result","current","i","getSize","getCapacity","isFull","isEmpty","getLast","n","count","Math","min","clear"],"sources":["CircularBuffer.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class CircularBuffer<T> {\n private buffer: Array<T | undefined>;\n private head = 0;\n private tail = 0;\n private size = 0;\n private readonly capacity: number;\n private readonly onEvict?: (item: T) => void;\n\n constructor(capacity: number, onEvict?: (item: T) => void) {\n if (capacity <= 0) {\n throw new Error(\"CircularBuffer capacity must be positive\");\n }\n this.capacity = capacity;\n this.buffer = new Array(capacity);\n this.onEvict = onEvict;\n }\n\n push(item: T): number {\n const index = this.tail;\n\n if (this.size === this.capacity) {\n const evicted = this.buffer[this.tail];\n if (this.onEvict && evicted !== undefined) {\n this.onEvict(evicted);\n }\n }\n\n this.buffer[this.tail] = item;\n this.tail = (this.tail + 1) % this.capacity;\n\n if (this.size < this.capacity) {\n this.size++;\n } else {\n this.head = (this.head + 1) % this.capacity;\n }\n\n return index;\n }\n\n get(index: number): T | undefined {\n if (index < 0 || index >= this.capacity) {\n return undefined;\n }\n return this.buffer[index];\n }\n\n toArray(): T[] {\n const result: T[] = [];\n let current = this.head;\n\n for (let i = 0; i < this.size; i++) {\n const item = this.buffer[current];\n if (item !== undefined) {\n result.push(item);\n }\n current = (current + 1) % this.capacity;\n }\n\n return result;\n }\n\n getSize(): number {\n return this.size;\n }\n\n getCapacity(): number {\n return this.capacity;\n }\n\n isFull(): boolean {\n return this.size === this.capacity;\n }\n\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n getLast(n: number): ReadonlyArray<T> {\n const count = Math.min(n, this.size);\n const result: T[] = [];\n\n let index = (this.tail - count + this.capacity) % this.capacity;\n\n for (let i = 0; i < count; i++) {\n const item = this.buffer[index];\n if (item !== undefined) {\n result.push(item);\n }\n index = (index + 1) % this.capacity;\n }\n\n return result;\n }\n\n clear(): void {\n this.buffer = new Array(this.capacity);\n this.head = 0;\n this.tail = 0;\n this.size = 0;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|