@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.
Files changed (443) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/build/esm/DevToolsContext.js +19 -0
  3. package/build/esm/DevToolsContext.js.map +1 -0
  4. package/build/esm/components/ActionMetrics.js +89 -0
  5. package/build/esm/components/ActionMetrics.js.map +1 -0
  6. package/build/esm/components/BubbleChart.js +175 -0
  7. package/build/esm/components/BubbleChart.js.map +1 -0
  8. package/build/esm/components/BubbleChart.module.scss.js +6 -0
  9. package/build/esm/components/CacheInspectorTab.js +291 -0
  10. package/build/esm/components/CacheInspectorTab.js.map +1 -0
  11. package/build/esm/components/CacheInspectorTab.module.scss.js +39 -0
  12. package/build/esm/components/CacheMetrics.js +55 -0
  13. package/build/esm/components/CacheMetrics.js.map +1 -0
  14. package/build/esm/components/ComponentCard.js +124 -0
  15. package/build/esm/components/ComponentCard.js.map +1 -0
  16. package/build/esm/components/ComponentCard.module.scss.js +31 -0
  17. package/build/esm/components/ComputeTab.js +175 -0
  18. package/build/esm/components/ComputeTab.js.map +1 -0
  19. package/build/esm/components/CopyableCodeBlock.js +49 -0
  20. package/build/esm/components/CopyableCodeBlock.js.map +1 -0
  21. package/build/esm/components/CopyableCodeBlock.module.scss.js +10 -0
  22. package/build/esm/components/DebuggingTab.js +342 -0
  23. package/build/esm/components/DebuggingTab.js.map +1 -0
  24. package/build/esm/components/DebuggingTab.module.scss.js +18 -0
  25. package/build/esm/components/HookRow.js +180 -0
  26. package/build/esm/components/HookRow.js.map +1 -0
  27. package/build/esm/components/HookRow.module.scss.js +16 -0
  28. package/build/esm/components/ImprovementsTab.js +138 -0
  29. package/build/esm/components/ImprovementsTab.js.map +1 -0
  30. package/build/esm/components/ImprovementsTab.module.scss.js +30 -0
  31. package/build/esm/components/InspectorSelectionHeader.js +65 -0
  32. package/build/esm/components/InspectorSelectionHeader.js.map +1 -0
  33. package/build/esm/components/InterceptTab.js +862 -0
  34. package/build/esm/components/InterceptTab.js.map +1 -0
  35. package/build/esm/components/InterceptTab.module.scss.js +49 -0
  36. package/build/esm/components/IssueCard.js +115 -0
  37. package/build/esm/components/IssueCard.js.map +1 -0
  38. package/build/esm/components/IssueCard.module.scss.js +24 -0
  39. package/build/esm/components/LogEntryCard.js +94 -0
  40. package/build/esm/components/LogEntryCard.js.map +1 -0
  41. package/build/esm/components/LogEntryCard.module.scss.js +19 -0
  42. package/build/esm/components/MockEditor.js +316 -0
  43. package/build/esm/components/MockEditor.js.map +1 -0
  44. package/build/esm/components/MonitorErrorBoundary.js +64 -0
  45. package/build/esm/components/MonitorErrorBoundary.js.map +1 -0
  46. package/build/esm/components/MonitorErrorBoundary.module.scss.js +9 -0
  47. package/build/esm/components/MonitoringPanel.js +434 -0
  48. package/build/esm/components/MonitoringPanel.js.map +1 -0
  49. package/build/esm/components/MonitoringPanel.module.scss.js +81 -0
  50. package/build/esm/components/ObjectLoadingMetrics.js +60 -0
  51. package/build/esm/components/ObjectLoadingMetrics.js.map +1 -0
  52. package/build/esm/components/OsdkAppErrorBoundary.js +68 -0
  53. package/build/esm/components/OsdkAppErrorBoundary.js.map +1 -0
  54. package/build/esm/components/OsdkDevTools.js +40 -0
  55. package/build/esm/components/OsdkDevTools.js.map +1 -0
  56. package/build/esm/components/OverrideEditor.js +197 -0
  57. package/build/esm/components/OverrideEditor.js.map +1 -0
  58. package/build/esm/components/PerformanceTab.js +297 -0
  59. package/build/esm/components/PerformanceTab.js.map +1 -0
  60. package/build/esm/components/PrimitiveSelectionPanel.js +220 -0
  61. package/build/esm/components/PrimitiveSelectionPanel.js.map +1 -0
  62. package/build/esm/components/PrimitiveSelectionPanel.module.scss.js +26 -0
  63. package/build/esm/components/issueTypes.js +2 -0
  64. package/build/esm/components/issueTypes.js.map +1 -0
  65. package/build/esm/components/resolveComponentName.js +57 -0
  66. package/build/esm/components/resolveComponentName.js.map +1 -0
  67. package/build/esm/components/testHelpers.js +312 -0
  68. package/build/esm/components/testHelpers.js.map +1 -0
  69. package/build/esm/css.d.ts +20 -0
  70. package/build/esm/fiber/DegradationNotice.js +193 -0
  71. package/build/esm/fiber/DegradationNotice.js.map +1 -0
  72. package/build/esm/fiber/DevtoolsHook.js +252 -0
  73. package/build/esm/fiber/DevtoolsHook.js.map +1 -0
  74. package/build/esm/fiber/FiberAccess.js +65 -0
  75. package/build/esm/fiber/FiberAccess.js.map +1 -0
  76. package/build/esm/fiber/FiberInspection.js +140 -0
  77. package/build/esm/fiber/FiberInspection.js.map +1 -0
  78. package/build/esm/fiber/FiberTags.js +52 -0
  79. package/build/esm/fiber/FiberTags.js.map +1 -0
  80. package/build/esm/fiber/HookStateInspector.js +254 -0
  81. package/build/esm/fiber/HookStateInspector.js.map +1 -0
  82. package/build/esm/fiber/SafeFiberOperation.js +35 -0
  83. package/build/esm/fiber/SafeFiberOperation.js.map +1 -0
  84. package/build/esm/fiber/capabilities.js +180 -0
  85. package/build/esm/fiber/capabilities.js.map +1 -0
  86. package/build/esm/fiber/traverseFiber.js +129 -0
  87. package/build/esm/fiber/traverseFiber.js.map +1 -0
  88. package/build/esm/fiber/types.js +2 -0
  89. package/build/esm/fiber/types.js.map +1 -0
  90. package/build/esm/fiber/validation.js +155 -0
  91. package/build/esm/fiber/validation.js.map +1 -0
  92. package/build/esm/hooks/createPollingStore.js +81 -0
  93. package/build/esm/hooks/createPollingStore.js.map +1 -0
  94. package/build/esm/hooks/useActiveComponents.js +27 -0
  95. package/build/esm/hooks/useActiveComponents.js.map +1 -0
  96. package/build/esm/hooks/useComponentRegistry.js +25 -0
  97. package/build/esm/hooks/useComponentRegistry.js.map +1 -0
  98. package/build/esm/hooks/useComputeSelectors.js +43 -0
  99. package/build/esm/hooks/useComputeSelectors.js.map +1 -0
  100. package/build/esm/hooks/useConsoleLogs.js +46 -0
  101. package/build/esm/hooks/useConsoleLogs.js.map +1 -0
  102. package/build/esm/hooks/useInspectorSelection.js +93 -0
  103. package/build/esm/hooks/useInspectorSelection.js.map +1 -0
  104. package/build/esm/hooks/useMetrics.js +23 -0
  105. package/build/esm/hooks/useMetrics.js.map +1 -0
  106. package/build/esm/hooks/usePersistedState.js +89 -0
  107. package/build/esm/hooks/usePersistedState.js.map +1 -0
  108. package/build/esm/hooks/useRecommendations.js +123 -0
  109. package/build/esm/hooks/useRecommendations.js.map +1 -0
  110. package/build/esm/hooks/useSharedTick.js +49 -0
  111. package/build/esm/hooks/useSharedTick.js.map +1 -0
  112. package/build/esm/hooks/useTimeElapsed.js +51 -0
  113. package/build/esm/hooks/useTimeElapsed.js.map +1 -0
  114. package/build/esm/hooks/useTrackerSubscription.js +97 -0
  115. package/build/esm/hooks/useTrackerSubscription.js.map +1 -0
  116. package/build/esm/hooks/useUnusedFieldAnalysis.js +99 -0
  117. package/build/esm/hooks/useUnusedFieldAnalysis.js.map +1 -0
  118. package/build/esm/index.js +31 -0
  119. package/build/esm/index.js.map +1 -0
  120. package/build/esm/inspector/ClickToInspectSystem.js +228 -0
  121. package/build/esm/inspector/ClickToInspectSystem.js.map +1 -0
  122. package/build/esm/inspector/components/ComponentLabel.js +175 -0
  123. package/build/esm/inspector/components/ComponentLabel.js.map +1 -0
  124. package/build/esm/inspector/components/ComponentLabel.module.scss.js +12 -0
  125. package/build/esm/inspector/components/InspectorBanner.js +79 -0
  126. package/build/esm/inspector/components/InspectorBanner.js.map +1 -0
  127. package/build/esm/inspector/components/InspectorOverlay.js +149 -0
  128. package/build/esm/inspector/components/InspectorOverlay.js.map +1 -0
  129. package/build/esm/inspector/components/SelectionHighlight.js +74 -0
  130. package/build/esm/inspector/components/SelectionHighlight.js.map +1 -0
  131. package/build/esm/inspector/createClickToInspect.js +21 -0
  132. package/build/esm/inspector/createClickToInspect.js.map +1 -0
  133. package/build/esm/inspector/hooks/useAnimatedBounds.js +167 -0
  134. package/build/esm/inspector/hooks/useAnimatedBounds.js.map +1 -0
  135. package/build/esm/inspector/index.js +40 -0
  136. package/build/esm/inspector/index.js.map +1 -0
  137. package/build/esm/inspector/inspectorController.js +328 -0
  138. package/build/esm/inspector/inspectorController.js.map +1 -0
  139. package/build/esm/inspector/types.js +2 -0
  140. package/build/esm/inspector/types.js.map +1 -0
  141. package/build/esm/inspector/utils/elementBounds.js +72 -0
  142. package/build/esm/inspector/utils/elementBounds.js.map +1 -0
  143. package/build/esm/inspector/utils/interpolation.js +26 -0
  144. package/build/esm/inspector/utils/interpolation.js.map +1 -0
  145. package/build/esm/inspector/utils/labelPositioning.js +62 -0
  146. package/build/esm/inspector/utils/labelPositioning.js.map +1 -0
  147. package/build/esm/mocking/MockCacheKeyGenerator.js +109 -0
  148. package/build/esm/mocking/MockCacheKeyGenerator.js.map +1 -0
  149. package/build/esm/mocking/MockManager.js +281 -0
  150. package/build/esm/mocking/MockManager.js.map +1 -0
  151. package/build/esm/prototyping/PrototypeOverrideStore.js +66 -0
  152. package/build/esm/prototyping/PrototypeOverrideStore.js.map +1 -0
  153. package/build/esm/prototyping/index.js +18 -0
  154. package/build/esm/prototyping/index.js.map +1 -0
  155. package/build/esm/public/vite.js +19 -0
  156. package/build/esm/public/vite.js.map +1 -0
  157. package/build/esm/register.js +41 -0
  158. package/build/esm/register.js.map +1 -0
  159. package/build/esm/scss.d.ts +20 -0
  160. package/build/esm/store/ComputeStore.js +269 -0
  161. package/build/esm/store/ComputeStore.js.map +1 -0
  162. package/build/esm/store/ConsoleLogStore.js +289 -0
  163. package/build/esm/store/ConsoleLogStore.js.map +1 -0
  164. package/build/esm/store/MetricsStore.js +428 -0
  165. package/build/esm/store/MetricsStore.js.map +1 -0
  166. package/build/esm/store/MonitorStore.js +288 -0
  167. package/build/esm/store/MonitorStore.js.map +1 -0
  168. package/build/esm/store/SubscribableStore.js +38 -0
  169. package/build/esm/store/SubscribableStore.js.map +1 -0
  170. package/build/esm/store/WindowErrorStore.js +195 -0
  171. package/build/esm/store/WindowErrorStore.js.map +1 -0
  172. package/build/esm/styles.css +19441 -0
  173. package/build/esm/styles.js +31 -0
  174. package/build/esm/styles.js.map +1 -0
  175. package/build/esm/types/compute.js +2 -0
  176. package/build/esm/types/compute.js.map +1 -0
  177. package/build/esm/types/emissions.js +2 -0
  178. package/build/esm/types/emissions.js.map +1 -0
  179. package/build/esm/types/index.js +23 -0
  180. package/build/esm/types/index.js.map +1 -0
  181. package/build/esm/utils/ActionLifecycleTracker.js +178 -0
  182. package/build/esm/utils/ActionLifecycleTracker.js.map +1 -0
  183. package/build/esm/utils/CacheEfficiencyAnalyzer.js +198 -0
  184. package/build/esm/utils/CacheEfficiencyAnalyzer.js.map +1 -0
  185. package/build/esm/utils/CircularBuffer.js +96 -0
  186. package/build/esm/utils/CircularBuffer.js.map +1 -0
  187. package/build/esm/utils/ComponentContextCapture.js +215 -0
  188. package/build/esm/utils/ComponentContextCapture.js.map +1 -0
  189. package/build/esm/utils/ComponentPrimitiveDiscovery.js +173 -0
  190. package/build/esm/utils/ComponentPrimitiveDiscovery.js.map +1 -0
  191. package/build/esm/utils/ComponentQueryRegistry.js +340 -0
  192. package/build/esm/utils/ComponentQueryRegistry.js.map +1 -0
  193. package/build/esm/utils/ComputeMonitor.js +199 -0
  194. package/build/esm/utils/ComputeMonitor.js.map +1 -0
  195. package/build/esm/utils/EventTimeline.js +130 -0
  196. package/build/esm/utils/EventTimeline.js.map +1 -0
  197. package/build/esm/utils/LinkTraversalTracker.js +116 -0
  198. package/build/esm/utils/LinkTraversalTracker.js.map +1 -0
  199. package/build/esm/utils/MockDataGenerator.js +473 -0
  200. package/build/esm/utils/MockDataGenerator.js.map +1 -0
  201. package/build/esm/utils/ObservableClientMonitor.js +768 -0
  202. package/build/esm/utils/ObservableClientMonitor.js.map +1 -0
  203. package/build/esm/utils/PerformanceRecommendationEngine.js +185 -0
  204. package/build/esm/utils/PerformanceRecommendationEngine.js.map +1 -0
  205. package/build/esm/utils/PropertyAccessTracker.js +238 -0
  206. package/build/esm/utils/PropertyAccessTracker.js.map +1 -0
  207. package/build/esm/utils/RecommendationMatcher.js +53 -0
  208. package/build/esm/utils/RecommendationMatcher.js.map +1 -0
  209. package/build/esm/utils/SubscriptionTracker.js +132 -0
  210. package/build/esm/utils/SubscriptionTracker.js.map +1 -0
  211. package/build/esm/utils/UnusedFieldAnalyzer.js +186 -0
  212. package/build/esm/utils/UnusedFieldAnalyzer.js.map +1 -0
  213. package/build/esm/utils/WaterfallDetector.js +200 -0
  214. package/build/esm/utils/WaterfallDetector.js.map +1 -0
  215. package/build/esm/utils/computePayload.js +37 -0
  216. package/build/esm/utils/computePayload.js.map +1 -0
  217. package/build/esm/utils/computeRequest.js +29 -0
  218. package/build/esm/utils/computeRequest.js.map +1 -0
  219. package/build/esm/utils/format.js +69 -0
  220. package/build/esm/utils/format.js.map +1 -0
  221. package/build/esm/utils/logger.js +31 -0
  222. package/build/esm/utils/logger.js.map +1 -0
  223. package/build/esm/vite/constants.js +18 -0
  224. package/build/esm/vite/constants.js.map +1 -0
  225. package/build/esm/vite/hookInstaller.js +99 -0
  226. package/build/esm/vite/hookInstaller.js.map +1 -0
  227. package/build/esm/vite/index.js +77 -0
  228. package/build/esm/vite/index.js.map +1 -0
  229. package/build/types/DevToolsContext.d.ts +3 -0
  230. package/build/types/DevToolsContext.d.ts.map +1 -0
  231. package/build/types/components/ActionMetrics.d.ts +6 -0
  232. package/build/types/components/ActionMetrics.d.ts.map +1 -0
  233. package/build/types/components/BubbleChart.d.ts +10 -0
  234. package/build/types/components/BubbleChart.d.ts.map +1 -0
  235. package/build/types/components/CacheInspectorTab.d.ts +6 -0
  236. package/build/types/components/CacheInspectorTab.d.ts.map +1 -0
  237. package/build/types/components/CacheMetrics.d.ts +6 -0
  238. package/build/types/components/CacheMetrics.d.ts.map +1 -0
  239. package/build/types/components/ComponentCard.d.ts +13 -0
  240. package/build/types/components/ComponentCard.d.ts.map +1 -0
  241. package/build/types/components/ComputeTab.d.ts +6 -0
  242. package/build/types/components/ComputeTab.d.ts.map +1 -0
  243. package/build/types/components/CopyableCodeBlock.d.ts +7 -0
  244. package/build/types/components/CopyableCodeBlock.d.ts.map +1 -0
  245. package/build/types/components/DebuggingTab.d.ts +6 -0
  246. package/build/types/components/DebuggingTab.d.ts.map +1 -0
  247. package/build/types/components/HookRow.d.ts +9 -0
  248. package/build/types/components/HookRow.d.ts.map +1 -0
  249. package/build/types/components/ImprovementsTab.d.ts +7 -0
  250. package/build/types/components/ImprovementsTab.d.ts.map +1 -0
  251. package/build/types/components/InspectorSelectionHeader.d.ts +12 -0
  252. package/build/types/components/InspectorSelectionHeader.d.ts.map +1 -0
  253. package/build/types/components/InterceptTab.d.ts +126 -0
  254. package/build/types/components/InterceptTab.d.ts.map +1 -0
  255. package/build/types/components/IssueCard.d.ts +8 -0
  256. package/build/types/components/IssueCard.d.ts.map +1 -0
  257. package/build/types/components/LogEntryCard.d.ts +7 -0
  258. package/build/types/components/LogEntryCard.d.ts.map +1 -0
  259. package/build/types/components/MockEditor.d.ts +58 -0
  260. package/build/types/components/MockEditor.d.ts.map +1 -0
  261. package/build/types/components/MonitorErrorBoundary.d.ts +16 -0
  262. package/build/types/components/MonitorErrorBoundary.d.ts.map +1 -0
  263. package/build/types/components/MonitoringPanel.d.ts +8 -0
  264. package/build/types/components/MonitoringPanel.d.ts.map +1 -0
  265. package/build/types/components/ObjectLoadingMetrics.d.ts +7 -0
  266. package/build/types/components/ObjectLoadingMetrics.d.ts.map +1 -0
  267. package/build/types/components/OsdkAppErrorBoundary.d.ts +18 -0
  268. package/build/types/components/OsdkAppErrorBoundary.d.ts.map +1 -0
  269. package/build/types/components/OsdkDevTools.d.ts +2 -0
  270. package/build/types/components/OsdkDevTools.d.ts.map +1 -0
  271. package/build/types/components/OverrideEditor.d.ts +26 -0
  272. package/build/types/components/OverrideEditor.d.ts.map +1 -0
  273. package/build/types/components/PerformanceTab.d.ts +8 -0
  274. package/build/types/components/PerformanceTab.d.ts.map +1 -0
  275. package/build/types/components/PrimitiveSelectionPanel.d.ts +28 -0
  276. package/build/types/components/PrimitiveSelectionPanel.d.ts.map +1 -0
  277. package/build/types/components/issueTypes.d.ts +16 -0
  278. package/build/types/components/issueTypes.d.ts.map +1 -0
  279. package/build/types/components/resolveComponentName.d.ts +3 -0
  280. package/build/types/components/resolveComponentName.d.ts.map +1 -0
  281. package/build/types/components/testHelpers.d.ts +2 -0
  282. package/build/types/components/testHelpers.d.ts.map +1 -0
  283. package/build/types/css.d.d.ts +4 -0
  284. package/build/types/css.d.d.ts.map +1 -0
  285. package/build/types/fiber/DegradationNotice.d.ts +8 -0
  286. package/build/types/fiber/DegradationNotice.d.ts.map +1 -0
  287. package/build/types/fiber/DevtoolsHook.d.ts +7 -0
  288. package/build/types/fiber/DevtoolsHook.d.ts.map +1 -0
  289. package/build/types/fiber/FiberAccess.d.ts +2 -0
  290. package/build/types/fiber/FiberAccess.d.ts.map +1 -0
  291. package/build/types/fiber/FiberInspection.d.ts +6 -0
  292. package/build/types/fiber/FiberInspection.d.ts.map +1 -0
  293. package/build/types/fiber/FiberTags.d.ts +33 -0
  294. package/build/types/fiber/FiberTags.d.ts.map +1 -0
  295. package/build/types/fiber/HookStateInspector.d.ts +45 -0
  296. package/build/types/fiber/HookStateInspector.d.ts.map +1 -0
  297. package/build/types/fiber/SafeFiberOperation.d.ts +7 -0
  298. package/build/types/fiber/SafeFiberOperation.d.ts.map +1 -0
  299. package/build/types/fiber/capabilities.d.ts +38 -0
  300. package/build/types/fiber/capabilities.d.ts.map +1 -0
  301. package/build/types/fiber/traverseFiber.d.ts +5 -0
  302. package/build/types/fiber/traverseFiber.d.ts.map +1 -0
  303. package/build/types/fiber/types.d.ts +87 -0
  304. package/build/types/fiber/types.d.ts.map +1 -0
  305. package/build/types/fiber/validation.d.ts +10 -0
  306. package/build/types/fiber/validation.d.ts.map +1 -0
  307. package/build/types/hooks/createPollingStore.d.ts +5 -0
  308. package/build/types/hooks/createPollingStore.d.ts.map +1 -0
  309. package/build/types/hooks/useActiveComponents.d.ts +3 -0
  310. package/build/types/hooks/useActiveComponents.d.ts.map +1 -0
  311. package/build/types/hooks/useComponentRegistry.d.ts +3 -0
  312. package/build/types/hooks/useComponentRegistry.d.ts.map +1 -0
  313. package/build/types/hooks/useComputeSelectors.d.ts +7 -0
  314. package/build/types/hooks/useComputeSelectors.d.ts.map +1 -0
  315. package/build/types/hooks/useConsoleLogs.d.ts +7 -0
  316. package/build/types/hooks/useConsoleLogs.d.ts.map +1 -0
  317. package/build/types/hooks/useInspectorSelection.d.ts +9 -0
  318. package/build/types/hooks/useInspectorSelection.d.ts.map +1 -0
  319. package/build/types/hooks/useMetrics.d.ts +3 -0
  320. package/build/types/hooks/useMetrics.d.ts.map +1 -0
  321. package/build/types/hooks/usePersistedState.d.ts +1 -0
  322. package/build/types/hooks/usePersistedState.d.ts.map +1 -0
  323. package/build/types/hooks/useRecommendations.d.ts +10 -0
  324. package/build/types/hooks/useRecommendations.d.ts.map +1 -0
  325. package/build/types/hooks/useSharedTick.d.ts +1 -0
  326. package/build/types/hooks/useSharedTick.d.ts.map +1 -0
  327. package/build/types/hooks/useTimeElapsed.d.ts +1 -0
  328. package/build/types/hooks/useTimeElapsed.d.ts.map +1 -0
  329. package/build/types/hooks/useTrackerSubscription.d.ts +16 -0
  330. package/build/types/hooks/useTrackerSubscription.d.ts.map +1 -0
  331. package/build/types/hooks/useUnusedFieldAnalysis.d.ts +8 -0
  332. package/build/types/hooks/useUnusedFieldAnalysis.d.ts.map +1 -0
  333. package/build/types/index.d.ts +21 -0
  334. package/build/types/index.d.ts.map +1 -0
  335. package/build/types/inspector/ClickToInspectSystem.d.ts +40 -0
  336. package/build/types/inspector/ClickToInspectSystem.d.ts.map +1 -0
  337. package/build/types/inspector/components/ComponentLabel.d.ts +3 -0
  338. package/build/types/inspector/components/ComponentLabel.d.ts.map +1 -0
  339. package/build/types/inspector/components/InspectorBanner.d.ts +5 -0
  340. package/build/types/inspector/components/InspectorBanner.d.ts.map +1 -0
  341. package/build/types/inspector/components/InspectorOverlay.d.ts +3 -0
  342. package/build/types/inspector/components/InspectorOverlay.d.ts.map +1 -0
  343. package/build/types/inspector/components/SelectionHighlight.d.ts +3 -0
  344. package/build/types/inspector/components/SelectionHighlight.d.ts.map +1 -0
  345. package/build/types/inspector/createClickToInspect.d.ts +3 -0
  346. package/build/types/inspector/createClickToInspect.d.ts.map +1 -0
  347. package/build/types/inspector/hooks/useAnimatedBounds.d.ts +2 -0
  348. package/build/types/inspector/hooks/useAnimatedBounds.d.ts.map +1 -0
  349. package/build/types/inspector/index.d.ts +13 -0
  350. package/build/types/inspector/index.d.ts.map +1 -0
  351. package/build/types/inspector/inspectorController.d.ts +2 -0
  352. package/build/types/inspector/inspectorController.d.ts.map +1 -0
  353. package/build/types/inspector/types.d.ts +94 -0
  354. package/build/types/inspector/types.d.ts.map +1 -0
  355. package/build/types/inspector/utils/elementBounds.d.ts +3 -0
  356. package/build/types/inspector/utils/elementBounds.d.ts.map +1 -0
  357. package/build/types/inspector/utils/interpolation.d.ts +7 -0
  358. package/build/types/inspector/utils/interpolation.d.ts.map +1 -0
  359. package/build/types/inspector/utils/labelPositioning.d.ts +3 -0
  360. package/build/types/inspector/utils/labelPositioning.d.ts.map +1 -0
  361. package/build/types/mocking/MockCacheKeyGenerator.d.ts +41 -0
  362. package/build/types/mocking/MockCacheKeyGenerator.d.ts.map +1 -0
  363. package/build/types/mocking/MockManager.d.ts +103 -0
  364. package/build/types/mocking/MockManager.d.ts.map +1 -0
  365. package/build/types/prototyping/PrototypeOverrideStore.d.ts +33 -0
  366. package/build/types/prototyping/PrototypeOverrideStore.d.ts.map +1 -0
  367. package/build/types/prototyping/index.d.ts +1 -0
  368. package/build/types/prototyping/index.d.ts.map +1 -0
  369. package/build/types/public/vite.d.ts +2 -0
  370. package/build/types/public/vite.d.ts.map +1 -0
  371. package/build/types/register.d.ts +1 -0
  372. package/build/types/register.d.ts.map +1 -0
  373. package/build/types/scss.d.d.ts +6 -0
  374. package/build/types/scss.d.d.ts.map +1 -0
  375. package/build/types/store/ComputeStore.d.ts +47 -0
  376. package/build/types/store/ComputeStore.d.ts.map +1 -0
  377. package/build/types/store/ConsoleLogStore.d.ts +29 -0
  378. package/build/types/store/ConsoleLogStore.d.ts.map +1 -0
  379. package/build/types/store/MetricsStore.d.ts +42 -0
  380. package/build/types/store/MetricsStore.d.ts.map +1 -0
  381. package/build/types/store/MonitorStore.d.ts +86 -0
  382. package/build/types/store/MonitorStore.d.ts.map +1 -0
  383. package/build/types/store/SubscribableStore.d.ts +6 -0
  384. package/build/types/store/SubscribableStore.d.ts.map +1 -0
  385. package/build/types/store/WindowErrorStore.d.ts +32 -0
  386. package/build/types/store/WindowErrorStore.d.ts.map +1 -0
  387. package/build/types/styles.d.ts +1 -0
  388. package/build/types/styles.d.ts.map +1 -0
  389. package/build/types/types/compute.d.ts +73 -0
  390. package/build/types/types/compute.d.ts.map +1 -0
  391. package/build/types/types/emissions.d.ts +24 -0
  392. package/build/types/types/emissions.d.ts.map +1 -0
  393. package/build/types/types/index.d.ts +143 -0
  394. package/build/types/types/index.d.ts.map +1 -0
  395. package/build/types/utils/ActionLifecycleTracker.d.ts +39 -0
  396. package/build/types/utils/ActionLifecycleTracker.d.ts.map +1 -0
  397. package/build/types/utils/CacheEfficiencyAnalyzer.d.ts +45 -0
  398. package/build/types/utils/CacheEfficiencyAnalyzer.d.ts.map +1 -0
  399. package/build/types/utils/CircularBuffer.d.ts +18 -0
  400. package/build/types/utils/CircularBuffer.d.ts.map +1 -0
  401. package/build/types/utils/ComponentContextCapture.d.ts +29 -0
  402. package/build/types/utils/ComponentContextCapture.d.ts.map +1 -0
  403. package/build/types/utils/ComponentPrimitiveDiscovery.d.ts +62 -0
  404. package/build/types/utils/ComponentPrimitiveDiscovery.d.ts.map +1 -0
  405. package/build/types/utils/ComponentQueryRegistry.d.ts +91 -0
  406. package/build/types/utils/ComponentQueryRegistry.d.ts.map +1 -0
  407. package/build/types/utils/ComputeMonitor.d.ts +14 -0
  408. package/build/types/utils/ComputeMonitor.d.ts.map +1 -0
  409. package/build/types/utils/EventTimeline.d.ts +102 -0
  410. package/build/types/utils/EventTimeline.d.ts.map +1 -0
  411. package/build/types/utils/LinkTraversalTracker.d.ts +43 -0
  412. package/build/types/utils/LinkTraversalTracker.d.ts.map +1 -0
  413. package/build/types/utils/MockDataGenerator.d.ts +23 -0
  414. package/build/types/utils/MockDataGenerator.d.ts.map +1 -0
  415. package/build/types/utils/ObservableClientMonitor.d.ts +62 -0
  416. package/build/types/utils/ObservableClientMonitor.d.ts.map +1 -0
  417. package/build/types/utils/PerformanceRecommendationEngine.d.ts +67 -0
  418. package/build/types/utils/PerformanceRecommendationEngine.d.ts.map +1 -0
  419. package/build/types/utils/PropertyAccessTracker.d.ts +50 -0
  420. package/build/types/utils/PropertyAccessTracker.d.ts.map +1 -0
  421. package/build/types/utils/RecommendationMatcher.d.ts +5 -0
  422. package/build/types/utils/RecommendationMatcher.d.ts.map +1 -0
  423. package/build/types/utils/SubscriptionTracker.d.ts +17 -0
  424. package/build/types/utils/SubscriptionTracker.d.ts.map +1 -0
  425. package/build/types/utils/UnusedFieldAnalyzer.d.ts +46 -0
  426. package/build/types/utils/UnusedFieldAnalyzer.d.ts.map +1 -0
  427. package/build/types/utils/WaterfallDetector.d.ts +28 -0
  428. package/build/types/utils/WaterfallDetector.d.ts.map +1 -0
  429. package/build/types/utils/computePayload.d.ts +3 -0
  430. package/build/types/utils/computePayload.d.ts.map +1 -0
  431. package/build/types/utils/computeRequest.d.ts +20 -0
  432. package/build/types/utils/computeRequest.d.ts.map +1 -0
  433. package/build/types/utils/format.d.ts +5 -0
  434. package/build/types/utils/format.d.ts.map +1 -0
  435. package/build/types/utils/logger.d.ts +2 -0
  436. package/build/types/utils/logger.d.ts.map +1 -0
  437. package/build/types/vite/constants.d.ts +1 -0
  438. package/build/types/vite/constants.d.ts.map +1 -0
  439. package/build/types/vite/hookInstaller.d.ts +1 -0
  440. package/build/types/vite/hookInstaller.d.ts.map +1 -0
  441. package/build/types/vite/index.d.ts +20 -0
  442. package/build/types/vite/index.d.ts.map +1 -0
  443. package/package.json +114 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PropertyAccessTracker.js","names":["CircularBuffer","PropertyAccessTracker","componentRenderCycles","Map","wrappedObjects","WeakMap","maxAccesses","maxProxyDepth","eventTimeline","componentNames","componentRenders","componentAccessesPerRender","constructor","accesses","wrapObject","obj","objectKey","componentId","depth","has","renderCycle","get","proxy","Proxy","target","prop","receiver","startsWith","recordAccess","property","timestamp","Date","now","value","Reflect","descriptor","Object","getOwnPropertyDescriptor","configurable","Array","isArray","set","event","push","record","type","setEventTimeline","timeline","incrementRenderCycle","current","renders","registerComponent","componentName","getAccessedProperties","properties","Set","access","toArray","add","getUnusedPropertiesForObject","availableProperties","accessed","filter","findWastedRenders","objectAccesses","key","accessedProperties","renderCycles","data","from","entries","map","totalRenders","size","propertiesAccessed","wastedRenders","Math","max","getRecentAccesses","limit","getLast","slice","getAccessesByComponent","a","getAccessesByObject","getAccessFrequency","frequency","clear","clearComponent","remaining","item","delete","getStats","componentCounts","objectCounts","propertyCounts","totalAccesses","getSize","uniqueComponents","uniqueObjects","uniqueProperties","mostAccessedProperties","sort","b","trackedComponents","getWastedRenders","componentRenderAccess","renderSet","rendersWithAccess","wastedCount","count","getUnusedProperties","unused","componentPropertyAccess","propMap","accessCount","propertyName"],"sources":["PropertyAccessTracker.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 { UnusedProperty, WastedRender } from \"../types/index.js\";\nimport { CircularBuffer } from \"./CircularBuffer.js\";\nimport type { EventTimeline } from \"./EventTimeline.js\";\n\nexport interface PropertyAccessEvent {\n componentId: string;\n objectKey: string;\n property: string;\n timestamp: number;\n renderCycle?: number;\n}\n\nexport class PropertyAccessTracker {\n private accesses: CircularBuffer<PropertyAccessEvent>;\n private componentRenderCycles = new Map<string, number>();\n private wrappedObjects = new WeakMap<object, string>();\n private maxAccesses = 10000;\n private maxProxyDepth = 5;\n private eventTimeline: EventTimeline | null = null;\n private componentNames = new Map<string, string>();\n private componentRenders = new Map<string, number>();\n private componentAccessesPerRender = new Map<string, Set<number>>();\n\n constructor() {\n this.accesses = new CircularBuffer<PropertyAccessEvent>(this.maxAccesses);\n }\n\n wrapObject<T extends object>(\n obj: T,\n objectKey: string,\n componentId: string,\n depth: number = 0,\n ): T {\n if (this.wrappedObjects.has(obj)) {\n return obj;\n }\n\n const renderCycle = this.componentRenderCycles.get(componentId) || 0;\n\n const proxy = new Proxy(obj, {\n get: (target, prop: string | symbol, receiver) => {\n if (typeof prop === \"string\" && !prop.startsWith(\"$\")) {\n this.recordAccess({\n componentId,\n objectKey,\n property: prop,\n timestamp: Date.now(),\n renderCycle,\n });\n }\n\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof prop === \"string\") {\n const descriptor = Object.getOwnPropertyDescriptor(target, prop);\n if (descriptor && !descriptor.configurable) {\n return value;\n }\n }\n\n if (\n value\n && typeof value === \"object\"\n && !Array.isArray(value)\n && typeof prop === \"string\"\n && !prop.startsWith(\"$\")\n && depth < this.maxProxyDepth\n ) {\n return this.wrapObject(\n value,\n `${objectKey}.${prop}`,\n componentId,\n depth + 1,\n );\n }\n\n return value;\n },\n });\n\n this.wrappedObjects.set(proxy, objectKey);\n return proxy;\n }\n\n recordAccess(event: PropertyAccessEvent): void {\n this.accesses.push(event);\n\n if (this.eventTimeline) {\n this.eventTimeline.record({\n type: \"PROPERTY_ACCESS\",\n componentId: event.componentId,\n objectKey: event.objectKey,\n property: event.property,\n timestamp: event.timestamp,\n renderCycle: event.renderCycle,\n });\n }\n }\n\n setEventTimeline(timeline: EventTimeline | null): void {\n this.eventTimeline = timeline;\n }\n\n incrementRenderCycle(componentId: string): void {\n const current = this.componentRenderCycles.get(componentId) || 0;\n this.componentRenderCycles.set(componentId, current + 1);\n\n const renders = this.componentRenders.get(componentId) || 0;\n this.componentRenders.set(componentId, renders + 1);\n }\n\n registerComponent(componentId: string, componentName: string): void {\n this.componentNames.set(componentId, componentName);\n }\n\n getAccessedProperties(\n componentId: string,\n objectKey: string,\n ): Set<string> {\n const properties = new Set<string>();\n\n for (const access of this.accesses.toArray()) {\n if (\n access.componentId === componentId\n && access.objectKey === objectKey\n ) {\n properties.add(access.property);\n }\n }\n\n return properties;\n }\n\n getUnusedPropertiesForObject(\n componentId: string,\n objectKey: string,\n availableProperties: string[],\n ): string[] {\n const accessed = this.getAccessedProperties(componentId, objectKey);\n return availableProperties.filter((prop) => !accessed.has(prop));\n }\n\n findWastedRenders(componentId: string): Array<{\n objectKey: string;\n accessedProperties: Set<string>;\n renderCycles: Set<number>;\n wastedRenders: number;\n }> {\n const objectAccesses = new Map<\n string,\n {\n accessedProperties: Set<string>;\n renderCycles: Set<number>;\n }\n >();\n\n for (const access of this.accesses.toArray()) {\n if (access.componentId === componentId && access.renderCycle != null) {\n const key = access.objectKey;\n if (!objectAccesses.has(key)) {\n objectAccesses.set(key, {\n accessedProperties: new Set(),\n renderCycles: new Set(),\n });\n }\n\n const data = objectAccesses.get(key);\n if (data) {\n data.accessedProperties.add(access.property);\n data.renderCycles.add(access.renderCycle);\n }\n }\n }\n\n return Array.from(objectAccesses.entries()).map(([objectKey, data]) => {\n const totalRenders = data.renderCycles.size;\n const propertiesAccessed = data.accessedProperties.size;\n const wastedRenders = Math.max(\n 0,\n totalRenders - propertiesAccessed,\n );\n\n return {\n objectKey,\n accessedProperties: data.accessedProperties,\n renderCycles: data.renderCycles,\n wastedRenders,\n };\n });\n }\n\n getRecentAccesses(limit: number = 100): PropertyAccessEvent[] {\n return this.accesses.getLast(limit).slice();\n }\n\n getAccessesByComponent(componentId: string): PropertyAccessEvent[] {\n return this.accesses.toArray().filter((a) => a.componentId === componentId);\n }\n\n getAccessesByObject(objectKey: string): PropertyAccessEvent[] {\n return this.accesses.toArray().filter((a) => a.objectKey === objectKey);\n }\n\n getAccessFrequency(\n componentId: string,\n objectKey: string,\n ): Map<string, number> {\n const frequency = new Map<string, number>();\n\n for (const access of this.accesses.toArray()) {\n if (\n access.componentId === componentId\n && access.objectKey === objectKey\n ) {\n frequency.set(\n access.property,\n (frequency.get(access.property) || 0) + 1,\n );\n }\n }\n\n return frequency;\n }\n\n clear(): void {\n this.accesses.clear();\n this.componentRenderCycles.clear();\n }\n\n clearComponent(componentId: string): void {\n const remaining = this.accesses.toArray().filter(\n (a) => a.componentId !== componentId,\n );\n this.accesses.clear();\n for (const item of remaining) {\n this.accesses.push(item);\n }\n this.componentRenderCycles.delete(componentId);\n }\n\n getStats(): {\n totalAccesses: number;\n uniqueComponents: number;\n uniqueObjects: number;\n uniqueProperties: number;\n mostAccessedProperties: Array<[string, number]>;\n trackedComponents: number;\n } {\n const componentCounts = new Map<string, number>();\n const objectCounts = new Map<string, number>();\n const propertyCounts = new Map<string, number>();\n\n for (const access of this.accesses.toArray()) {\n componentCounts.set(\n access.componentId,\n (componentCounts.get(access.componentId) || 0) + 1,\n );\n objectCounts.set(\n access.objectKey,\n (objectCounts.get(access.objectKey) || 0) + 1,\n );\n propertyCounts.set(\n access.property,\n (propertyCounts.get(access.property) || 0) + 1,\n );\n }\n\n return {\n totalAccesses: this.accesses.getSize(),\n uniqueComponents: componentCounts.size,\n uniqueObjects: objectCounts.size,\n uniqueProperties: propertyCounts.size,\n mostAccessedProperties: Array.from(propertyCounts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10),\n trackedComponents: this.componentRenderCycles.size,\n };\n }\n\n getWastedRenders(): WastedRender[] {\n const wastedRenders: WastedRender[] = [];\n\n const componentRenderAccess = new Map<string, Set<number>>();\n\n for (const access of this.accesses.toArray()) {\n if (access.renderCycle != null) {\n if (!componentRenderAccess.has(access.componentId)) {\n componentRenderAccess.set(access.componentId, new Set());\n }\n const renderSet = componentRenderAccess.get(access.componentId);\n if (renderSet) {\n renderSet.add(access.renderCycle);\n }\n }\n }\n\n for (const [componentId, totalRenders] of this.componentRenders) {\n const rendersWithAccess = componentRenderAccess.get(componentId)?.size\n || 0;\n const wastedCount = totalRenders - rendersWithAccess;\n\n if (wastedCount > 0 && totalRenders > 5) {\n wastedRenders.push({\n componentId,\n componentName: this.componentNames.get(componentId) || componentId,\n count: wastedCount,\n timestamp: Date.now(),\n });\n }\n }\n\n return wastedRenders;\n }\n\n getUnusedProperties(): UnusedProperty[] {\n const unused: UnusedProperty[] = [];\n\n const componentPropertyAccess = new Map<string, Map<string, number>>();\n\n for (const access of this.accesses.toArray()) {\n const key = access.componentId;\n if (!componentPropertyAccess.has(key)) {\n componentPropertyAccess.set(key, new Map());\n }\n const propMap = componentPropertyAccess.get(key);\n if (propMap) {\n propMap.set(access.property, (propMap.get(access.property) || 0) + 1);\n }\n }\n\n for (const [componentId, propMap] of componentPropertyAccess) {\n const totalRenders = this.componentRenders.get(componentId) || 0;\n\n if (totalRenders > 5) {\n for (const [property, accessCount] of propMap) {\n if (accessCount < totalRenders * 0.1) {\n unused.push({\n componentId,\n componentName: this.componentNames.get(componentId)\n || componentId,\n propertyName: property,\n totalRenders,\n accessCount,\n });\n }\n }\n }\n }\n\n return unused;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,53 @@
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 function buildRecommendationMap(recommendations) {
18
+ const map = new Map();
19
+ for (const rec of recommendations) {
20
+ const keys = extractMatchingKeys(rec);
21
+ for (const key of keys) {
22
+ const existing = map.get(key);
23
+ if (existing) {
24
+ existing.push(rec);
25
+ } else {
26
+ map.set(key, [rec]);
27
+ }
28
+ }
29
+ }
30
+ return map;
31
+ }
32
+ function extractMatchingKeys(rec) {
33
+ const keys = [];
34
+ if (rec.id.startsWith("waterfall-")) {
35
+ const stripped = rec.id.replace("waterfall-", "");
36
+ const arrowIndex = stripped.indexOf("->");
37
+ if (arrowIndex !== -1) {
38
+ keys.push(stripped.substring(0, arrowIndex));
39
+ keys.push(stripped.substring(arrowIndex + 2));
40
+ } else {
41
+ keys.push(stripped);
42
+ }
43
+ } else if (rec.id.startsWith("field-")) {
44
+ keys.push(rec.id.replace("field-", ""));
45
+ } else if (rec.id.startsWith("dup-")) {
46
+ keys.push(rec.id.replace("dup-", ""));
47
+ }
48
+ return keys;
49
+ }
50
+ export function getRecommendationsForOperation(operation, recommendationMap) {
51
+ return recommendationMap.get(operation.signature) ?? [];
52
+ }
53
+ //# sourceMappingURL=RecommendationMatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendationMatcher.js","names":["buildRecommendationMap","recommendations","map","Map","rec","keys","extractMatchingKeys","key","existing","get","push","set","id","startsWith","stripped","replace","arrowIndex","indexOf","substring","getRecommendationsForOperation","operation","recommendationMap","signature"],"sources":["RecommendationMatcher.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 { Operation } from \"../types/index.js\";\nimport type { Recommendation } from \"./PerformanceRecommendationEngine.js\";\n\nexport type RecommendationMap = Map<string, Recommendation[]>;\n\nexport function buildRecommendationMap(\n recommendations: Recommendation[],\n): RecommendationMap {\n const map = new Map<string, Recommendation[]>();\n\n for (const rec of recommendations) {\n const keys = extractMatchingKeys(rec);\n for (const key of keys) {\n const existing = map.get(key);\n if (existing) {\n existing.push(rec);\n } else {\n map.set(key, [rec]);\n }\n }\n }\n\n return map;\n}\n\nfunction extractMatchingKeys(rec: Recommendation): string[] {\n const keys: string[] = [];\n\n if (rec.id.startsWith(\"waterfall-\")) {\n const stripped = rec.id.replace(\"waterfall-\", \"\");\n const arrowIndex = stripped.indexOf(\"->\");\n if (arrowIndex !== -1) {\n keys.push(stripped.substring(0, arrowIndex));\n keys.push(stripped.substring(arrowIndex + 2));\n } else {\n keys.push(stripped);\n }\n } else if (rec.id.startsWith(\"field-\")) {\n keys.push(rec.id.replace(\"field-\", \"\"));\n } else if (rec.id.startsWith(\"dup-\")) {\n keys.push(rec.id.replace(\"dup-\", \"\"));\n }\n\n return keys;\n}\n\nexport function getRecommendationsForOperation(\n operation: Operation,\n recommendationMap: RecommendationMap,\n): Recommendation[] {\n return recommendationMap.get(operation.signature) ?? [];\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA,OAAO,SAASA,sBAAsBA,CACpCC,eAAiC,EACd;EACnB,MAAMC,GAAG,GAAG,IAAIC,GAAG,CAA2B,CAAC;EAE/C,KAAK,MAAMC,GAAG,IAAIH,eAAe,EAAE;IACjC,MAAMI,IAAI,GAAGC,mBAAmB,CAACF,GAAG,CAAC;IACrC,KAAK,MAAMG,GAAG,IAAIF,IAAI,EAAE;MACtB,MAAMG,QAAQ,GAAGN,GAAG,CAACO,GAAG,CAACF,GAAG,CAAC;MAC7B,IAAIC,QAAQ,EAAE;QACZA,QAAQ,CAACE,IAAI,CAACN,GAAG,CAAC;MACpB,CAAC,MAAM;QACLF,GAAG,CAACS,GAAG,CAACJ,GAAG,EAAE,CAACH,GAAG,CAAC,CAAC;MACrB;IACF;EACF;EAEA,OAAOF,GAAG;AACZ;AAEA,SAASI,mBAAmBA,CAACF,GAAmB,EAAY;EAC1D,MAAMC,IAAc,GAAG,EAAE;EAEzB,IAAID,GAAG,CAACQ,EAAE,CAACC,UAAU,CAAC,YAAY,CAAC,EAAE;IACnC,MAAMC,QAAQ,GAAGV,GAAG,CAACQ,EAAE,CAACG,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;IACjD,MAAMC,UAAU,GAAGF,QAAQ,CAACG,OAAO,CAAC,IAAI,CAAC;IACzC,IAAID,UAAU,KAAK,CAAC,CAAC,EAAE;MACrBX,IAAI,CAACK,IAAI,CAACI,QAAQ,CAACI,SAAS,CAAC,CAAC,EAAEF,UAAU,CAAC,CAAC;MAC5CX,IAAI,CAACK,IAAI,CAACI,QAAQ,CAACI,SAAS,CAACF,UAAU,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC,MAAM;MACLX,IAAI,CAACK,IAAI,CAACI,QAAQ,CAAC;IACrB;EACF,CAAC,MAAM,IAAIV,GAAG,CAACQ,EAAE,CAACC,UAAU,CAAC,QAAQ,CAAC,EAAE;IACtCR,IAAI,CAACK,IAAI,CAACN,GAAG,CAACQ,EAAE,CAACG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;EACzC,CAAC,MAAM,IAAIX,GAAG,CAACQ,EAAE,CAACC,UAAU,CAAC,MAAM,CAAC,EAAE;IACpCR,IAAI,CAACK,IAAI,CAACN,GAAG,CAACQ,EAAE,CAACG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;EACvC;EAEA,OAAOV,IAAI;AACb;AAEA,OAAO,SAASc,8BAA8BA,CAC5CC,SAAoB,EACpBC,iBAAoC,EAClB;EAClB,OAAOA,iBAAiB,CAACZ,GAAG,CAACW,SAAS,CAACE,SAAS,CAAC,IAAI,EAAE;AACzD","ignoreList":[]}
@@ -0,0 +1,132 @@
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 SubscriptionTracker {
18
+ subscriptions = new Map();
19
+ signatureToSubscriptions = new Map();
20
+ nextSubscriptionId = 0;
21
+ constructor(cacheThresholdMs = 10) {
22
+ this.cacheThresholdMs = cacheThresholdMs;
23
+ }
24
+ startSubscription(signature) {
25
+ const subscriptionId = `sub-${this.nextSubscriptionId++}`;
26
+ const metadata = {
27
+ signature,
28
+ subscribeTime: Date.now(),
29
+ emissions: []
30
+ };
31
+ this.subscriptions.set(subscriptionId, metadata);
32
+ if (!this.signatureToSubscriptions.has(signature)) {
33
+ this.signatureToSubscriptions.set(signature, new Set());
34
+ }
35
+ const subs = this.signatureToSubscriptions.get(signature);
36
+ if (subs) {
37
+ subs.add(subscriptionId);
38
+ }
39
+ return subscriptionId;
40
+ }
41
+ recordEmission(subscriptionId, status, hasData, isOptimistic, optimisticId, timestamp = Date.now()) {
42
+ const metadata = this.subscriptions.get(subscriptionId);
43
+ if (!metadata) return;
44
+ if (!this.isValidStatus(status)) {
45
+ return;
46
+ }
47
+ const emission = {
48
+ timestamp,
49
+ status,
50
+ hasData,
51
+ isOptimistic,
52
+ optimisticId,
53
+ sequenceNumber: metadata.emissions.length
54
+ };
55
+ metadata.emissions.push(emission);
56
+ }
57
+ isValidStatus(status) {
58
+ return status === "init" || status === "loading" || status === "loaded" || status === "error";
59
+ }
60
+ endSubscription(subscriptionId) {
61
+ const metadata = this.subscriptions.get(subscriptionId);
62
+ if (!metadata) return;
63
+ metadata.unsubscribeTime = Date.now();
64
+ const subs = this.signatureToSubscriptions.get(metadata.signature);
65
+ if (subs) {
66
+ subs.delete(subscriptionId);
67
+ if (subs.size === 0) {
68
+ this.signatureToSubscriptions.delete(metadata.signature);
69
+ }
70
+ }
71
+ }
72
+ analyzeEmissions(subscriptionId) {
73
+ const metadata = this.subscriptions.get(subscriptionId);
74
+ if (!metadata || metadata.emissions.length === 0) {
75
+ return null;
76
+ }
77
+ const emissions = metadata.emissions;
78
+ let wasCached = false;
79
+ let wasOptimistic = false;
80
+ let loadTime;
81
+ let firstOptimisticTimestamp;
82
+ let lastOptimisticTimestamp;
83
+ let firstNonOptimisticAfterOptimisticTimestamp;
84
+ wasOptimistic = emissions.some(e => e.isOptimistic);
85
+ if (wasOptimistic) {
86
+ const optimisticEmissions = emissions.filter(e => e.isOptimistic);
87
+ firstOptimisticTimestamp = optimisticEmissions[0]?.timestamp;
88
+ lastOptimisticTimestamp = optimisticEmissions[optimisticEmissions.length - 1]?.timestamp;
89
+ firstNonOptimisticAfterOptimisticTimestamp = emissions.find(e => !e.isOptimistic && firstOptimisticTimestamp != null && e.timestamp >= firstOptimisticTimestamp)?.timestamp;
90
+ }
91
+ const subscribeTime = metadata.subscribeTime;
92
+ const firstEmission = emissions[0];
93
+ const loadedEmission = emissions.find(e => e.status === "loaded");
94
+ if (loadedEmission) {
95
+ loadTime = loadedEmission.timestamp - subscribeTime;
96
+ if (firstEmission.status === "loaded" && loadTime < this.cacheThresholdMs) {
97
+ wasCached = true;
98
+ } else {
99
+ wasCached = false;
100
+ }
101
+ }
102
+ return {
103
+ wasCached,
104
+ wasOptimistic,
105
+ loadTime,
106
+ emissionCount: emissions.length,
107
+ firstOptimisticTimestamp,
108
+ lastOptimisticTimestamp,
109
+ firstNonOptimisticAfterOptimisticTimestamp
110
+ };
111
+ }
112
+ getSharedSubscriptionCount(signature) {
113
+ return this.signatureToSubscriptions.get(signature)?.size ?? 0;
114
+ }
115
+ isDeduplicatedSubscription(signature) {
116
+ return (this.signatureToSubscriptions.get(signature)?.size ?? 0) > 0;
117
+ }
118
+ getActiveSubscriptions() {
119
+ return Array.from(this.subscriptions.values()).filter(s => s.unsubscribeTime === undefined);
120
+ }
121
+ cleanup(maxAge = 5 * 60 * 1000) {
122
+ const now = Date.now();
123
+ const toDelete = [];
124
+ for (const [id, metadata] of this.subscriptions) {
125
+ if (metadata.unsubscribeTime && now - metadata.unsubscribeTime > maxAge) {
126
+ toDelete.push(id);
127
+ }
128
+ }
129
+ toDelete.forEach(id => this.subscriptions.delete(id));
130
+ }
131
+ }
132
+ //# sourceMappingURL=SubscriptionTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionTracker.js","names":["SubscriptionTracker","subscriptions","Map","signatureToSubscriptions","nextSubscriptionId","constructor","cacheThresholdMs","startSubscription","signature","subscriptionId","metadata","subscribeTime","Date","now","emissions","set","has","Set","subs","get","add","recordEmission","status","hasData","isOptimistic","optimisticId","timestamp","isValidStatus","emission","sequenceNumber","length","push","endSubscription","unsubscribeTime","delete","size","analyzeEmissions","wasCached","wasOptimistic","loadTime","firstOptimisticTimestamp","lastOptimisticTimestamp","firstNonOptimisticAfterOptimisticTimestamp","some","e","optimisticEmissions","filter","find","firstEmission","loadedEmission","emissionCount","getSharedSubscriptionCount","isDeduplicatedSubscription","getActiveSubscriptions","Array","from","values","s","undefined","cleanup","maxAge","toDelete","id","forEach"],"sources":["SubscriptionTracker.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 {\n EmissionAnalysis,\n EmissionRecord,\n EmissionStatus,\n SubscriptionMetadata,\n} from \"../types/emissions.js\";\n\nexport class SubscriptionTracker {\n private subscriptions = new Map<string, SubscriptionMetadata>();\n private signatureToSubscriptions = new Map<string, Set<string>>();\n private nextSubscriptionId = 0;\n\n constructor(\n private readonly cacheThresholdMs: number = 10,\n ) {}\n\n startSubscription(signature: string): string {\n const subscriptionId = `sub-${this.nextSubscriptionId++}`;\n\n const metadata: SubscriptionMetadata = {\n signature,\n subscribeTime: Date.now(),\n emissions: [],\n };\n\n this.subscriptions.set(subscriptionId, metadata);\n\n if (!this.signatureToSubscriptions.has(signature)) {\n this.signatureToSubscriptions.set(signature, new Set());\n }\n const subs = this.signatureToSubscriptions.get(signature);\n if (subs) {\n subs.add(subscriptionId);\n }\n\n return subscriptionId;\n }\n\n recordEmission(\n subscriptionId: string,\n status: string,\n hasData: boolean,\n isOptimistic: boolean,\n optimisticId?: string | number,\n timestamp: number = Date.now(),\n ): void {\n const metadata = this.subscriptions.get(subscriptionId);\n if (!metadata) return;\n\n if (!this.isValidStatus(status)) {\n return;\n }\n\n const emission: EmissionRecord = {\n timestamp,\n status,\n hasData,\n isOptimistic,\n optimisticId,\n sequenceNumber: metadata.emissions.length,\n };\n\n metadata.emissions.push(emission);\n }\n\n private isValidStatus(status: string): status is EmissionStatus {\n return (\n status === \"init\"\n || status === \"loading\"\n || status === \"loaded\"\n || status === \"error\"\n );\n }\n\n endSubscription(subscriptionId: string): void {\n const metadata = this.subscriptions.get(subscriptionId);\n if (!metadata) return;\n\n metadata.unsubscribeTime = Date.now();\n\n const subs = this.signatureToSubscriptions.get(metadata.signature);\n if (subs) {\n subs.delete(subscriptionId);\n if (subs.size === 0) {\n this.signatureToSubscriptions.delete(metadata.signature);\n }\n }\n }\n\n analyzeEmissions(subscriptionId: string): EmissionAnalysis | null {\n const metadata = this.subscriptions.get(subscriptionId);\n if (!metadata || metadata.emissions.length === 0) {\n return null;\n }\n\n const emissions = metadata.emissions;\n\n let wasCached = false;\n let wasOptimistic = false;\n let loadTime: number | undefined;\n let firstOptimisticTimestamp: number | undefined;\n let lastOptimisticTimestamp: number | undefined;\n let firstNonOptimisticAfterOptimisticTimestamp: number | undefined;\n\n wasOptimistic = emissions.some(e => e.isOptimistic);\n if (wasOptimistic) {\n const optimisticEmissions = emissions.filter(e => e.isOptimistic);\n firstOptimisticTimestamp = optimisticEmissions[0]?.timestamp;\n lastOptimisticTimestamp =\n optimisticEmissions[optimisticEmissions.length - 1]\n ?.timestamp;\n firstNonOptimisticAfterOptimisticTimestamp = emissions.find((e) =>\n !e.isOptimistic\n && firstOptimisticTimestamp != null\n && e.timestamp >= firstOptimisticTimestamp\n )?.timestamp;\n }\n\n const subscribeTime = metadata.subscribeTime;\n const firstEmission = emissions[0];\n const loadedEmission = emissions.find(e => e.status === \"loaded\");\n\n if (loadedEmission) {\n loadTime = loadedEmission.timestamp - subscribeTime;\n\n if (\n firstEmission.status === \"loaded\" && loadTime < this.cacheThresholdMs\n ) {\n wasCached = true;\n } else {\n wasCached = false;\n }\n }\n\n return {\n wasCached,\n wasOptimistic,\n loadTime,\n emissionCount: emissions.length,\n firstOptimisticTimestamp,\n lastOptimisticTimestamp,\n firstNonOptimisticAfterOptimisticTimestamp,\n };\n }\n\n getSharedSubscriptionCount(signature: string): number {\n return this.signatureToSubscriptions.get(signature)?.size ?? 0;\n }\n\n isDeduplicatedSubscription(signature: string): boolean {\n return (this.signatureToSubscriptions.get(signature)?.size ?? 0) > 0;\n }\n\n getActiveSubscriptions(): SubscriptionMetadata[] {\n return Array.from(this.subscriptions.values())\n .filter(s => s.unsubscribeTime === undefined);\n }\n\n cleanup(maxAge: number = 5 * 60 * 1000): void {\n const now = Date.now();\n const toDelete: string[] = [];\n\n for (const [id, metadata] of this.subscriptions) {\n if (\n metadata.unsubscribeTime\n && now - metadata.unsubscribeTime > maxAge\n ) {\n toDelete.push(id);\n }\n }\n\n toDelete.forEach(id => this.subscriptions.delete(id));\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,186 @@
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
+ const QUERY_SIGNATURE_RE = /^(\w+):(.+)/;
18
+ export class UnusedFieldAnalyzer {
19
+ constructor(registry, propertyTracker, estimateCacheEntrySize = data => UnusedFieldAnalyzer.defaultSizeEstimator(data)) {
20
+ this.registry = registry;
21
+ this.propertyTracker = propertyTracker;
22
+ this.estimateCacheEntrySize = estimateCacheEntrySize;
23
+ }
24
+ analyzeBinding(binding, cacheSnapshot) {
25
+ const {
26
+ componentId,
27
+ querySignature,
28
+ componentName
29
+ } = binding;
30
+ const accessed = this.getAccessedProperties(componentId, querySignature);
31
+ const cacheEntry = cacheSnapshot.entries?.find(e => e.key === querySignature);
32
+ const fetchedProps = cacheEntry?.data ? Object.keys(cacheEntry.data) : [];
33
+ const cleanFetched = fetchedProps.filter(p => !p.startsWith("$") && p !== "__typename");
34
+ const unused = cleanFetched.filter(prop => !accessed.has(prop));
35
+ const entrySize = cacheEntry?.metadata.size ?? this.estimateCacheEntrySize(cacheEntry?.data);
36
+ const wastedBytes = unused.length > 0 && cleanFetched.length > 0 ? Math.floor(entrySize * (unused.length / cleanFetched.length)) : 0;
37
+ const efficiency = cleanFetched.length > 0 ? accessed.size / cleanFetched.length : 1;
38
+ const suggestion = this.generateSuggestion(binding, Array.from(accessed));
39
+ const renderCount = binding.renderCount;
40
+ return {
41
+ componentName,
42
+ querySignature,
43
+ fetched: cleanFetched,
44
+ accessed: Array.from(accessed),
45
+ unused,
46
+ efficiency,
47
+ wastedBytes,
48
+ renderCount,
49
+ suggestion
50
+ };
51
+ }
52
+ generateGlobalReport(cacheSnapshot) {
53
+ const allBindings = this.registry.getAllBindings().filter(b => !b.unmountedAt);
54
+ const analyses = allBindings.map(b => this.analyzeBinding(b, cacheSnapshot));
55
+ const inefficient = analyses.filter(a => a.efficiency < 0.7) // Using <70% of fetched data
56
+ .sort((a, b) => a.efficiency - b.efficiency);
57
+ const totalWaste = analyses.reduce((sum, a) => sum + a.wastedBytes, 0);
58
+ const commonUnused = this.findCommonUnusedFields(analyses);
59
+ const avgEfficiency = analyses.length > 0 ? analyses.reduce((sum, a) => sum + a.efficiency, 0) / analyses.length : 1;
60
+ const recommendation = this.generateGlobalRecommendation(analyses, totalWaste, commonUnused);
61
+ return {
62
+ totalComponents: analyses.length,
63
+ inefficientComponents: inefficient.length,
64
+ totalWastedBytes: totalWaste,
65
+ topOffenders: inefficient.slice(0, 10),
66
+ commonUnused,
67
+ averageEfficiency: avgEfficiency,
68
+ recommendation
69
+ };
70
+ }
71
+ getAccessedProperties(componentId, querySignature) {
72
+ if (!this.propertyTracker) {
73
+ return new Set();
74
+ }
75
+ return this.propertyTracker.getAccessedProperties(componentId, querySignature);
76
+ }
77
+ findCommonUnusedFields(analyses) {
78
+ const fieldCount = new Map();
79
+ for (const analysis of analyses) {
80
+ const match = analysis.querySignature.match(QUERY_SIGNATURE_RE);
81
+ const objectType = match ? match[1] : undefined;
82
+ for (const field of analysis.unused) {
83
+ const key = `${objectType}:${field}`;
84
+ const current = fieldCount.get(key) || {
85
+ unused: 0,
86
+ total: 0,
87
+ objectType
88
+ };
89
+ current.unused++;
90
+ current.total++;
91
+ fieldCount.set(key, current);
92
+ }
93
+ }
94
+ return Array.from(fieldCount.entries()).map(([key, {
95
+ unused,
96
+ total,
97
+ objectType
98
+ }]) => ({
99
+ field: key,
100
+ objectType,
101
+ unusedCount: unused,
102
+ totalQueries: total,
103
+ unusedRate: unused / total
104
+ })).filter(f => f.unusedRate > 0.7 && f.totalQueries > 2) // 70%+ unused, 3+ queries
105
+ .sort((a, b) => b.unusedCount - a.unusedCount);
106
+ }
107
+ generateSuggestion(binding, usedProps) {
108
+ const {
109
+ hookType,
110
+ queryParams,
111
+ componentName
112
+ } = binding;
113
+ if (hookType === "useOsdkObject" && queryParams.type === "object") {
114
+ return `
115
+ // In ${componentName}.tsx:
116
+ // Current: Fetching all properties
117
+ const { object } = useOsdkObject(${queryParams.objectType}, id);
118
+
119
+ // Optimized: Only fetch what you use
120
+ const { object } = useOsdkObject(${queryParams.objectType}, id, {
121
+ $select: [${usedProps.length > 0 ? usedProps.map(p => `"${p}"`).join(", ") : "\"id\"" // fallback
122
+ }]
123
+ });
124
+
125
+ // This query will be more efficient!
126
+ `.trim();
127
+ } else if (hookType === "useOsdkObjects" && queryParams.type === "list") {
128
+ return `
129
+ // In ${componentName}.tsx:
130
+ // Current: Fetching all properties
131
+ const { data } = useOsdkObjects(${queryParams.objectType}, {
132
+ where: ${JSON.stringify(queryParams.where || {})}
133
+ });
134
+
135
+ // Optimized: Only fetch what you use
136
+ const { data } = useOsdkObjects(${queryParams.objectType}, {
137
+ where: ${JSON.stringify(queryParams.where || {})},
138
+ $select: [${usedProps.length > 0 ? usedProps.map(p => `"${p}"`).join(", ") : "\"id\""}]
139
+ });
140
+ `.trim();
141
+ }
142
+ return "Consider using $select to only fetch used properties";
143
+ }
144
+ generateGlobalRecommendation(analyses, totalWaste) {
145
+ if (analyses.length === 0) {
146
+ return "No queries analyzed yet";
147
+ }
148
+ const inefficientCount = analyses.filter(a => a.efficiency < 0.7).length;
149
+ const inefficiencyRate = inefficientCount / analyses.length;
150
+ if (inefficiencyRate > 0.5) {
151
+ return `
152
+ šŸ”“ HIGH PRIORITY: ${inefficientCount} of ${analyses.length} components are fetching unused data (${(totalWaste / 1024).toFixed(1)}KB total waste).
153
+
154
+ Consider adding $select clauses to your queries to only fetch used properties.
155
+ This will reduce bandwidth, improve performance, and lower data costs.
156
+
157
+ Start with the top offenders listed above.
158
+ `.trim();
159
+ } else if (inefficientCount > 0) {
160
+ return `
161
+ 🟔 MEDIUM PRIORITY: ${inefficientCount} components have unused fields.
162
+
163
+ You could optimize these queries with $select to save ~${(totalWaste / 1024).toFixed(1)}KB bandwidth.
164
+ `.trim();
165
+ } else {
166
+ return `
167
+ āœ… EXCELLENT: All queries are using fetched data efficiently!
168
+ Continue monitoring as features change.
169
+ `.trim();
170
+ }
171
+ }
172
+ static defaultSizeEstimator(data) {
173
+ if (!data) return 0;
174
+ if (typeof data === "string") return data.length;
175
+ if (typeof data === "number") return 8;
176
+ if (typeof data === "boolean") return 1;
177
+ if (Array.isArray(data)) {
178
+ return data.reduce((sum, item) => sum + UnusedFieldAnalyzer.defaultSizeEstimator(item), 0);
179
+ }
180
+ if (typeof data === "object") {
181
+ return Object.values(data).reduce((sum, value) => sum + UnusedFieldAnalyzer.defaultSizeEstimator(value), 0);
182
+ }
183
+ return 100; // Rough estimate for unknowns
184
+ }
185
+ }
186
+ //# sourceMappingURL=UnusedFieldAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnusedFieldAnalyzer.js","names":["QUERY_SIGNATURE_RE","UnusedFieldAnalyzer","constructor","registry","propertyTracker","estimateCacheEntrySize","data","defaultSizeEstimator","analyzeBinding","binding","cacheSnapshot","componentId","querySignature","componentName","accessed","getAccessedProperties","cacheEntry","entries","find","e","key","fetchedProps","Object","keys","cleanFetched","filter","p","startsWith","unused","prop","has","entrySize","metadata","size","wastedBytes","length","Math","floor","efficiency","suggestion","generateSuggestion","Array","from","renderCount","fetched","generateGlobalReport","allBindings","getAllBindings","b","unmountedAt","analyses","map","inefficient","a","sort","totalWaste","reduce","sum","commonUnused","findCommonUnusedFields","avgEfficiency","recommendation","generateGlobalRecommendation","totalComponents","inefficientComponents","totalWastedBytes","topOffenders","slice","averageEfficiency","Set","fieldCount","Map","analysis","match","objectType","undefined","field","current","get","total","set","unusedCount","totalQueries","unusedRate","f","usedProps","hookType","queryParams","type","join","trim","JSON","stringify","where","inefficientCount","inefficiencyRate","toFixed","isArray","item","values","value"],"sources":["UnusedFieldAnalyzer.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 { CacheSnapshot } from \"@osdk/client/observable\";\nimport type {\n ComponentHookBinding,\n ComponentQueryRegistry,\n} from \"./ComponentQueryRegistry.js\";\nimport type { PropertyAccessTracker } from \"./PropertyAccessTracker.js\";\n\nexport interface PropertyAccessTrackerWithAnalysis\n extends PropertyAccessTracker\n{\n getAccessedProperties(\n componentId: string,\n querySignature: string,\n ): Set<string>;\n}\n\nexport interface FieldUsageReport {\n componentName: string;\n querySignature: string;\n fetched: string[];\n accessed: string[];\n unused: string[];\n efficiency: number; // 0-1 ratio of accessed/fetched\n wastedBytes: number;\n renderCount: number;\n suggestion: string;\n}\n\nexport interface CommonUnusedField {\n field: string;\n objectType?: string;\n unusedCount: number;\n totalQueries: number;\n unusedRate: number;\n}\n\nexport interface UnusedFieldReport {\n totalComponents: number;\n inefficientComponents: number;\n totalWastedBytes: number;\n topOffenders: FieldUsageReport[];\n commonUnused: CommonUnusedField[];\n averageEfficiency: number;\n recommendation: string;\n}\n\nconst QUERY_SIGNATURE_RE = /^(\\w+):(.+)/;\n\nexport class UnusedFieldAnalyzer {\n constructor(\n private registry: ComponentQueryRegistry,\n private propertyTracker: PropertyAccessTrackerWithAnalysis | undefined,\n private estimateCacheEntrySize: (data: unknown) => number = (data) =>\n UnusedFieldAnalyzer.defaultSizeEstimator(data),\n ) {}\n\n analyzeBinding(\n binding: ComponentHookBinding,\n cacheSnapshot: CacheSnapshot,\n ): FieldUsageReport {\n const { componentId, querySignature, componentName } = binding;\n\n const accessed = this.getAccessedProperties(componentId, querySignature);\n\n const cacheEntry = cacheSnapshot.entries?.find(e =>\n e.key === querySignature\n );\n const fetchedProps = cacheEntry?.data ? Object.keys(cacheEntry.data) : [];\n\n const cleanFetched = fetchedProps.filter(p =>\n !p.startsWith(\"$\") && p !== \"__typename\"\n );\n\n const unused = cleanFetched.filter(prop => !accessed.has(prop));\n\n const entrySize = cacheEntry?.metadata.size\n ?? this.estimateCacheEntrySize(cacheEntry?.data);\n const wastedBytes = unused.length > 0 && cleanFetched.length > 0\n ? Math.floor(entrySize * (unused.length / cleanFetched.length))\n : 0;\n\n const efficiency = cleanFetched.length > 0\n ? accessed.size / cleanFetched.length\n : 1;\n\n const suggestion = this.generateSuggestion(binding, Array.from(accessed));\n\n const renderCount = binding.renderCount;\n\n return {\n componentName,\n querySignature,\n fetched: cleanFetched,\n accessed: Array.from(accessed),\n unused,\n efficiency,\n wastedBytes,\n renderCount,\n suggestion,\n };\n }\n\n generateGlobalReport(cacheSnapshot: CacheSnapshot): UnusedFieldReport {\n const allBindings = this.registry\n .getAllBindings()\n .filter(b => !b.unmountedAt);\n\n const analyses = allBindings.map(b =>\n this.analyzeBinding(b, cacheSnapshot)\n );\n\n const inefficient = analyses\n .filter(a => a.efficiency < 0.7) // Using <70% of fetched data\n .sort((a, b) => a.efficiency - b.efficiency);\n\n const totalWaste = analyses.reduce((sum, a) => sum + a.wastedBytes, 0);\n const commonUnused = this.findCommonUnusedFields(analyses);\n const avgEfficiency = analyses.length > 0\n ? analyses.reduce((sum, a) => sum + a.efficiency, 0) / analyses.length\n : 1;\n\n const recommendation = this.generateGlobalRecommendation(\n analyses,\n totalWaste,\n commonUnused,\n );\n\n return {\n totalComponents: analyses.length,\n inefficientComponents: inefficient.length,\n totalWastedBytes: totalWaste,\n topOffenders: inefficient.slice(0, 10),\n commonUnused,\n averageEfficiency: avgEfficiency,\n recommendation,\n };\n }\n\n private getAccessedProperties(\n componentId: string,\n querySignature: string,\n ): Set<string> {\n if (!this.propertyTracker) {\n return new Set<string>();\n }\n return this.propertyTracker.getAccessedProperties(\n componentId,\n querySignature,\n );\n }\n\n private findCommonUnusedFields(\n analyses: FieldUsageReport[],\n ): CommonUnusedField[] {\n const fieldCount: Map<\n string,\n { unused: number; total: number; objectType?: string }\n > = new Map();\n\n for (const analysis of analyses) {\n const match = analysis.querySignature.match(QUERY_SIGNATURE_RE);\n const objectType = match ? match[1] : undefined;\n\n for (const field of analysis.unused) {\n const key = `${objectType}:${field}`;\n const current = fieldCount.get(key)\n || { unused: 0, total: 0, objectType };\n current.unused++;\n current.total++;\n fieldCount.set(key, current);\n }\n }\n\n return Array.from(fieldCount.entries())\n .map(([key, { unused, total, objectType }]) => ({\n field: key,\n objectType,\n unusedCount: unused,\n totalQueries: total,\n unusedRate: unused / total,\n }))\n .filter(f => f.unusedRate > 0.7 && f.totalQueries > 2) // 70%+ unused, 3+ queries\n .sort((a, b) => b.unusedCount - a.unusedCount);\n }\n\n private generateSuggestion(\n binding: ComponentHookBinding,\n usedProps: string[],\n ): string {\n const { hookType, queryParams, componentName } = binding;\n\n if (hookType === \"useOsdkObject\" && queryParams.type === \"object\") {\n return `\n// In ${componentName}.tsx:\n// Current: Fetching all properties\nconst { object } = useOsdkObject(${queryParams.objectType}, id);\n\n// Optimized: Only fetch what you use\nconst { object } = useOsdkObject(${queryParams.objectType}, id, {\n $select: [${\n usedProps.length > 0\n ? usedProps.map(p => `\"${p}\"`).join(\", \")\n : \"\\\"id\\\"\" // fallback\n }]\n});\n\n// This query will be more efficient!\n `.trim();\n } else if (hookType === \"useOsdkObjects\" && queryParams.type === \"list\") {\n return `\n// In ${componentName}.tsx:\n// Current: Fetching all properties\nconst { data } = useOsdkObjects(${queryParams.objectType}, {\n where: ${JSON.stringify(queryParams.where || {})}\n});\n\n// Optimized: Only fetch what you use\nconst { data } = useOsdkObjects(${queryParams.objectType}, {\n where: ${JSON.stringify(queryParams.where || {})},\n $select: [${\n usedProps.length > 0\n ? usedProps.map(p => `\"${p}\"`).join(\", \")\n : \"\\\"id\\\"\"\n }]\n});\n `.trim();\n }\n\n return \"Consider using $select to only fetch used properties\";\n }\n\n private generateGlobalRecommendation(\n analyses: FieldUsageReport[],\n totalWaste: number,\n commonUnused: CommonUnusedField[],\n ): string {\n if (analyses.length === 0) {\n return \"No queries analyzed yet\";\n }\n\n const inefficientCount = analyses.filter(a => a.efficiency < 0.7).length;\n const inefficiencyRate = inefficientCount / analyses.length;\n\n if (inefficiencyRate > 0.5) {\n return `\nšŸ”“ HIGH PRIORITY: ${inefficientCount} of ${analyses.length} components are fetching unused data (${\n (totalWaste / 1024).toFixed(1)\n }KB total waste).\n\nConsider adding $select clauses to your queries to only fetch used properties.\nThis will reduce bandwidth, improve performance, and lower data costs.\n\nStart with the top offenders listed above.\n `.trim();\n } else if (inefficientCount > 0) {\n return `\n🟔 MEDIUM PRIORITY: ${inefficientCount} components have unused fields.\n\nYou could optimize these queries with $select to save ~${\n (totalWaste / 1024).toFixed(1)\n }KB bandwidth.\n `.trim();\n } else {\n return `\nāœ… EXCELLENT: All queries are using fetched data efficiently!\nContinue monitoring as features change.\n `.trim();\n }\n }\n\n private static defaultSizeEstimator(data: unknown): number {\n if (!data) return 0;\n if (typeof data === \"string\") return data.length;\n if (typeof data === \"number\") return 8;\n if (typeof data === \"boolean\") return 1;\n if (Array.isArray(data)) {\n return data.reduce<number>(\n (sum, item) => sum + UnusedFieldAnalyzer.defaultSizeEstimator(item),\n 0,\n );\n }\n if (typeof data === \"object\") {\n return Object.values(data as Record<string, unknown>).reduce<number>(\n (sum, value) => sum + UnusedFieldAnalyzer.defaultSizeEstimator(value),\n 0,\n );\n }\n return 100; // Rough estimate for unknowns\n }\n}\n"],"mappings":"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","ignoreList":[]}