@osdk/react-devtools 0.10.0 → 0.10.1-main-e39a72892d538f3130e2cd51cee05d83d11fa493

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 (199) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/build/esm/DevToolsContext.js.map +1 -1
  3. package/build/esm/components/ActionMetrics.js +2 -2
  4. package/build/esm/components/ActionMetrics.js.map +1 -1
  5. package/build/esm/components/BubbleChart.js +1 -1
  6. package/build/esm/components/BubbleChart.js.map +1 -1
  7. package/build/esm/components/CacheInspectorTab.js +1 -1
  8. package/build/esm/components/CacheInspectorTab.js.map +1 -1
  9. package/build/esm/components/CacheMetrics.js +1 -1
  10. package/build/esm/components/CacheMetrics.js.map +1 -1
  11. package/build/esm/components/ComponentCard.js +1 -1
  12. package/build/esm/components/ComponentCard.js.map +1 -1
  13. package/build/esm/components/ComputeTab.js +6 -6
  14. package/build/esm/components/ComputeTab.js.map +1 -1
  15. package/build/esm/components/CopyableCodeBlock.js.map +1 -1
  16. package/build/esm/components/DebuggingTab.js +2 -2
  17. package/build/esm/components/DebuggingTab.js.map +1 -1
  18. package/build/esm/components/HookRow.js.map +1 -1
  19. package/build/esm/components/ImprovementsTab.js.map +1 -1
  20. package/build/esm/components/InspectorSelectionHeader.js.map +1 -1
  21. package/build/esm/components/InterceptTab.js +5 -5
  22. package/build/esm/components/InterceptTab.js.map +1 -1
  23. package/build/esm/components/IssueCard.js.map +1 -1
  24. package/build/esm/components/LogEntryCard.js.map +1 -1
  25. package/build/esm/components/MockEditor.js.map +1 -1
  26. package/build/esm/components/MonitorErrorBoundary.js.map +1 -1
  27. package/build/esm/components/MonitoringPanel.js +1 -1
  28. package/build/esm/components/MonitoringPanel.js.map +1 -1
  29. package/build/esm/components/ObjectLoadingMetrics.js.map +1 -1
  30. package/build/esm/components/OsdkAppErrorBoundary.js.map +1 -1
  31. package/build/esm/components/OsdkDevTools.js.map +1 -1
  32. package/build/esm/components/OverrideEditor.js.map +1 -1
  33. package/build/esm/components/PerformanceTab.js +8 -8
  34. package/build/esm/components/PerformanceTab.js.map +1 -1
  35. package/build/esm/components/PrimitiveSelectionPanel.js +1 -1
  36. package/build/esm/components/PrimitiveSelectionPanel.js.map +1 -1
  37. package/build/esm/components/resolveComponentName.js +2 -2
  38. package/build/esm/components/resolveComponentName.js.map +1 -1
  39. package/build/esm/components/testHelpers.js.map +1 -1
  40. package/build/esm/fiber/DegradationNotice.js +2 -2
  41. package/build/esm/fiber/DegradationNotice.js.map +1 -1
  42. package/build/esm/fiber/DevtoolsHook.js +4 -4
  43. package/build/esm/fiber/DevtoolsHook.js.map +1 -1
  44. package/build/esm/fiber/FiberAccess.js.map +1 -1
  45. package/build/esm/fiber/FiberInspection.js.map +1 -1
  46. package/build/esm/fiber/FiberTags.js.map +1 -1
  47. package/build/esm/fiber/HookStateInspector.js.map +1 -1
  48. package/build/esm/fiber/SafeFiberOperation.js.map +1 -1
  49. package/build/esm/fiber/capabilities.js.map +1 -1
  50. package/build/esm/fiber/traverseFiber.js.map +1 -1
  51. package/build/esm/fiber/types.js.map +1 -1
  52. package/build/esm/fiber/validation.js +1 -1
  53. package/build/esm/fiber/validation.js.map +1 -1
  54. package/build/esm/hooks/createPollingStore.js.map +1 -1
  55. package/build/esm/hooks/useActiveComponents.js.map +1 -1
  56. package/build/esm/hooks/useComponentRegistry.js.map +1 -1
  57. package/build/esm/hooks/useComputeSelectors.js.map +1 -1
  58. package/build/esm/hooks/useConsoleLogs.js.map +1 -1
  59. package/build/esm/hooks/useInspectorSelection.js.map +1 -1
  60. package/build/esm/hooks/useMetrics.js.map +1 -1
  61. package/build/esm/hooks/usePersistedState.js.map +1 -1
  62. package/build/esm/hooks/useRecommendations.js +1 -1
  63. package/build/esm/hooks/useRecommendations.js.map +1 -1
  64. package/build/esm/hooks/useSharedTick.js.map +1 -1
  65. package/build/esm/hooks/useTimeElapsed.js.map +1 -1
  66. package/build/esm/hooks/useTrackerSubscription.js.map +1 -1
  67. package/build/esm/hooks/useUnusedFieldAnalysis.js.map +1 -1
  68. package/build/esm/inspector/ClickToInspectSystem.js.map +1 -1
  69. package/build/esm/inspector/components/ComponentLabel.js.map +1 -1
  70. package/build/esm/inspector/components/InspectorBanner.js.map +1 -1
  71. package/build/esm/inspector/components/InspectorOverlay.js.map +1 -1
  72. package/build/esm/inspector/components/SelectionHighlight.js.map +1 -1
  73. package/build/esm/inspector/createClickToInspect.js.map +1 -1
  74. package/build/esm/inspector/hooks/useAnimatedBounds.js.map +1 -1
  75. package/build/esm/inspector/inspectorController.js.map +1 -1
  76. package/build/esm/inspector/utils/elementBounds.js.map +1 -1
  77. package/build/esm/inspector/utils/interpolation.js.map +1 -1
  78. package/build/esm/inspector/utils/labelPositioning.js.map +1 -1
  79. package/build/esm/mocking/MockCacheKeyGenerator.js +3 -3
  80. package/build/esm/mocking/MockCacheKeyGenerator.js.map +1 -1
  81. package/build/esm/mocking/MockManager.js +4 -4
  82. package/build/esm/mocking/MockManager.js.map +1 -1
  83. package/build/esm/prototyping/PrototypeOverrideStore.js +1 -1
  84. package/build/esm/prototyping/PrototypeOverrideStore.js.map +1 -1
  85. package/build/esm/register.js.map +1 -1
  86. package/build/esm/store/ComputeStore.js.map +1 -1
  87. package/build/esm/store/ConsoleLogStore.js +2 -2
  88. package/build/esm/store/ConsoleLogStore.js.map +1 -1
  89. package/build/esm/store/MetricsStore.js.map +1 -1
  90. package/build/esm/store/MonitorStore.js.map +1 -1
  91. package/build/esm/store/WindowErrorStore.js.map +1 -1
  92. package/build/esm/styles.js.map +1 -1
  93. package/build/esm/types/compute.js.map +1 -1
  94. package/build/esm/utils/ActionLifecycleTracker.js.map +1 -1
  95. package/build/esm/utils/CacheEfficiencyAnalyzer.js.map +1 -1
  96. package/build/esm/utils/ComponentContextCapture.js +10 -10
  97. package/build/esm/utils/ComponentContextCapture.js.map +1 -1
  98. package/build/esm/utils/ComponentPrimitiveDiscovery.js.map +1 -1
  99. package/build/esm/utils/ComponentQueryRegistry.js +8 -8
  100. package/build/esm/utils/ComponentQueryRegistry.js.map +1 -1
  101. package/build/esm/utils/ComputeMonitor.js +2 -2
  102. package/build/esm/utils/ComputeMonitor.js.map +1 -1
  103. package/build/esm/utils/EventTimeline.js.map +1 -1
  104. package/build/esm/utils/LinkTraversalTracker.js +2 -2
  105. package/build/esm/utils/LinkTraversalTracker.js.map +1 -1
  106. package/build/esm/utils/MockDataGenerator.js +4 -4
  107. package/build/esm/utils/MockDataGenerator.js.map +1 -1
  108. package/build/esm/utils/ObservableClientMonitor.js +2 -2
  109. package/build/esm/utils/ObservableClientMonitor.js.map +1 -1
  110. package/build/esm/utils/PerformanceRecommendationEngine.js +1 -1
  111. package/build/esm/utils/PerformanceRecommendationEngine.js.map +1 -1
  112. package/build/esm/utils/PropertyAccessTracker.js +3 -3
  113. package/build/esm/utils/PropertyAccessTracker.js.map +1 -1
  114. package/build/esm/utils/RecommendationMatcher.js.map +1 -1
  115. package/build/esm/utils/SubscriptionTracker.js +1 -1
  116. package/build/esm/utils/SubscriptionTracker.js.map +1 -1
  117. package/build/esm/utils/UnusedFieldAnalyzer.js +6 -7
  118. package/build/esm/utils/UnusedFieldAnalyzer.js.map +1 -1
  119. package/build/esm/utils/WaterfallDetector.js.map +1 -1
  120. package/build/esm/utils/computePayload.js +2 -2
  121. package/build/esm/utils/computePayload.js.map +1 -1
  122. package/build/esm/utils/computeRequest.js.map +1 -1
  123. package/build/esm/utils/format.js.map +1 -1
  124. package/build/esm/vite/hookInstaller.js.map +1 -1
  125. package/build/esm/vite/index.js +2 -3
  126. package/build/esm/vite/index.js.map +1 -1
  127. package/build/types/DevToolsContext.d.ts.map +1 -1
  128. package/build/types/components/ActionMetrics.d.ts.map +1 -1
  129. package/build/types/components/BubbleChart.d.ts.map +1 -1
  130. package/build/types/components/CacheInspectorTab.d.ts.map +1 -1
  131. package/build/types/components/CacheMetrics.d.ts.map +1 -1
  132. package/build/types/components/ComponentCard.d.ts.map +1 -1
  133. package/build/types/components/ComputeTab.d.ts.map +1 -1
  134. package/build/types/components/CopyableCodeBlock.d.ts.map +1 -1
  135. package/build/types/components/DebuggingTab.d.ts.map +1 -1
  136. package/build/types/components/HookRow.d.ts.map +1 -1
  137. package/build/types/components/ImprovementsTab.d.ts.map +1 -1
  138. package/build/types/components/InspectorSelectionHeader.d.ts.map +1 -1
  139. package/build/types/components/InterceptTab.d.ts.map +1 -1
  140. package/build/types/components/IssueCard.d.ts.map +1 -1
  141. package/build/types/components/LogEntryCard.d.ts.map +1 -1
  142. package/build/types/components/MockEditor.d.ts.map +1 -1
  143. package/build/types/components/MonitorErrorBoundary.d.ts.map +1 -1
  144. package/build/types/components/MonitoringPanel.d.ts.map +1 -1
  145. package/build/types/components/ObjectLoadingMetrics.d.ts.map +1 -1
  146. package/build/types/components/OsdkAppErrorBoundary.d.ts.map +1 -1
  147. package/build/types/components/OsdkDevTools.d.ts.map +1 -1
  148. package/build/types/components/OverrideEditor.d.ts.map +1 -1
  149. package/build/types/components/PerformanceTab.d.ts.map +1 -1
  150. package/build/types/components/PrimitiveSelectionPanel.d.ts.map +1 -1
  151. package/build/types/components/resolveComponentName.d.ts.map +1 -1
  152. package/build/types/components/testHelpers.d.ts.map +1 -1
  153. package/build/types/fiber/DegradationNotice.d.ts.map +1 -1
  154. package/build/types/fiber/DevtoolsHook.d.ts.map +1 -1
  155. package/build/types/fiber/FiberInspection.d.ts.map +1 -1
  156. package/build/types/fiber/HookStateInspector.d.ts.map +1 -1
  157. package/build/types/fiber/capabilities.d.ts.map +1 -1
  158. package/build/types/fiber/traverseFiber.d.ts.map +1 -1
  159. package/build/types/fiber/types.d.ts.map +1 -1
  160. package/build/types/hooks/useActiveComponents.d.ts.map +1 -1
  161. package/build/types/hooks/useComponentRegistry.d.ts.map +1 -1
  162. package/build/types/hooks/useComputeSelectors.d.ts.map +1 -1
  163. package/build/types/hooks/useConsoleLogs.d.ts.map +1 -1
  164. package/build/types/hooks/useInspectorSelection.d.ts.map +1 -1
  165. package/build/types/hooks/useMetrics.d.ts.map +1 -1
  166. package/build/types/hooks/useRecommendations.d.ts.map +1 -1
  167. package/build/types/hooks/useUnusedFieldAnalysis.d.ts.map +1 -1
  168. package/build/types/inspector/ClickToInspectSystem.d.ts.map +1 -1
  169. package/build/types/inspector/components/ComponentLabel.d.ts.map +1 -1
  170. package/build/types/inspector/components/InspectorOverlay.d.ts.map +1 -1
  171. package/build/types/inspector/components/SelectionHighlight.d.ts.map +1 -1
  172. package/build/types/inspector/hooks/useAnimatedBounds.d.ts.map +1 -1
  173. package/build/types/mocking/MockManager.d.ts.map +1 -1
  174. package/build/types/store/ComputeStore.d.ts.map +1 -1
  175. package/build/types/store/ConsoleLogStore.d.ts.map +1 -1
  176. package/build/types/store/MetricsStore.d.ts.map +1 -1
  177. package/build/types/store/MonitorStore.d.ts.map +1 -1
  178. package/build/types/store/WindowErrorStore.d.ts.map +1 -1
  179. package/build/types/styles.d.ts +0 -1
  180. package/build/types/styles.d.ts.map +1 -1
  181. package/build/types/types/compute.d.ts.map +1 -1
  182. package/build/types/utils/ActionLifecycleTracker.d.ts.map +1 -1
  183. package/build/types/utils/CacheEfficiencyAnalyzer.d.ts.map +1 -1
  184. package/build/types/utils/ComponentContextCapture.d.ts.map +1 -1
  185. package/build/types/utils/ComponentPrimitiveDiscovery.d.ts.map +1 -1
  186. package/build/types/utils/ComponentQueryRegistry.d.ts.map +1 -1
  187. package/build/types/utils/ComputeMonitor.d.ts.map +1 -1
  188. package/build/types/utils/EventTimeline.d.ts.map +1 -1
  189. package/build/types/utils/LinkTraversalTracker.d.ts.map +1 -1
  190. package/build/types/utils/MockDataGenerator.d.ts.map +1 -1
  191. package/build/types/utils/ObservableClientMonitor.d.ts.map +1 -1
  192. package/build/types/utils/PerformanceRecommendationEngine.d.ts.map +1 -1
  193. package/build/types/utils/PropertyAccessTracker.d.ts.map +1 -1
  194. package/build/types/utils/SubscriptionTracker.d.ts.map +1 -1
  195. package/build/types/utils/UnusedFieldAnalyzer.d.ts.map +1 -1
  196. package/build/types/utils/WaterfallDetector.d.ts.map +1 -1
  197. package/build/types/utils/computeRequest.d.ts.map +1 -1
  198. package/build/types/vite/index.d.ts.map +1 -1
  199. package/package.json +6 -6
@@ -1 +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":[]}
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":[]}
@@ -116,7 +116,7 @@ export class SubscriptionTracker {
116
116
  return (this.signatureToSubscriptions.get(signature)?.size ?? 0) > 0;
117
117
  }
118
118
  getActiveSubscriptions() {
119
- return Array.from(this.subscriptions.values()).filter(s => s.unsubscribeTime === undefined);
119
+ return [...this.subscriptions.values()].filter(s => s.unsubscribeTime === undefined);
120
120
  }
121
121
  cleanup(maxAge = 5 * 60 * 1000) {
122
122
  const now = Date.now();
@@ -1 +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":[]}
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","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(private readonly cacheThresholdMs: number = 10) {}\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]?.timestamp;\n firstNonOptimisticAfterOptimisticTimestamp = emissions.find(\n (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\" &&\n 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 [...this.subscriptions.values()].filter(\n (s) => s.unsubscribeTime === undefined\n );\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 (metadata.unsubscribeTime && now - metadata.unsubscribeTime > maxAge) {\n toDelete.push(id);\n }\n }\n\n toDelete.forEach((id) => this.subscriptions.delete(id));\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASA,OAAO,MAAMA,mBAAmB,CAAC;EACvBC,aAAa,GAAG,IAAIC,GAAG,CAA+B,CAAC;EACvDC,wBAAwB,GAAG,IAAID,GAAG,CAAsB,CAAC;EACzDE,kBAAkB,GAAG,CAAC;EAE9BC,WAAWA,CAAkBC,gBAAwB,GAAG,EAAE,EAAE;IAAA,KAA/BA,gBAAwB,GAAxBA,gBAAwB;EAAQ;EAE7DC,iBAAiBA,CAACC,SAAiB,EAAU;IAC3C,MAAMC,cAAc,GAAG,OAAO,IAAI,CAACL,kBAAkB,EAAE,EAAE;IAEzD,MAAMM,QAA8B,GAAG;MACrCF,SAAS;MACTG,aAAa,EAAEC,IAAI,CAACC,GAAG,CAAC,CAAC;MACzBC,SAAS,EAAE;IACb,CAAC;IAED,IAAI,CAACb,aAAa,CAACc,GAAG,CAACN,cAAc,EAAEC,QAAQ,CAAC;IAEhD,IAAI,CAAC,IAAI,CAACP,wBAAwB,CAACa,GAAG,CAACR,SAAS,CAAC,EAAE;MACjD,IAAI,CAACL,wBAAwB,CAACY,GAAG,CAACP,SAAS,EAAE,IAAIS,GAAG,CAAC,CAAC,CAAC;IACzD;IACA,MAAMC,IAAI,GAAG,IAAI,CAACf,wBAAwB,CAACgB,GAAG,CAACX,SAAS,CAAC;IACzD,IAAIU,IAAI,EAAE;MACRA,IAAI,CAACE,GAAG,CAACX,cAAc,CAAC;IAC1B;IAEA,OAAOA,cAAc;EACvB;EAEAY,cAAcA,CACZZ,cAAsB,EACtBa,MAAc,EACdC,OAAgB,EAChBC,YAAqB,EACrBC,YAA8B,EAC9BC,SAAiB,GAAGd,IAAI,CAACC,GAAG,CAAC,CAAC,EACxB;IACN,MAAMH,QAAQ,GAAG,IAAI,CAACT,aAAa,CAACkB,GAAG,CAACV,cAAc,CAAC;IACvD,IAAI,CAACC,QAAQ,EAAE;IAEf,IAAI,CAAC,IAAI,CAACiB,aAAa,CAACL,MAAM,CAAC,EAAE;MAC/B;IACF;IAEA,MAAMM,QAAwB,GAAG;MAC/BF,SAAS;MACTJ,MAAM;MACNC,OAAO;MACPC,YAAY;MACZC,YAAY;MACZI,cAAc,EAAEnB,QAAQ,CAACI,SAAS,CAACgB;IACrC,CAAC;IAEDpB,QAAQ,CAACI,SAAS,CAACiB,IAAI,CAACH,QAAQ,CAAC;EACnC;EAEQD,aAAaA,CAACL,MAAc,EAA4B;IAC9D,OACEA,MAAM,KAAK,MAAM,IACjBA,MAAM,KAAK,SAAS,IACpBA,MAAM,KAAK,QAAQ,IACnBA,MAAM,KAAK,OAAO;EAEtB;EAEAU,eAAeA,CAACvB,cAAsB,EAAQ;IAC5C,MAAMC,QAAQ,GAAG,IAAI,CAACT,aAAa,CAACkB,GAAG,CAACV,cAAc,CAAC;IACvD,IAAI,CAACC,QAAQ,EAAE;IAEfA,QAAQ,CAACuB,eAAe,GAAGrB,IAAI,CAACC,GAAG,CAAC,CAAC;IAErC,MAAMK,IAAI,GAAG,IAAI,CAACf,wBAAwB,CAACgB,GAAG,CAACT,QAAQ,CAACF,SAAS,CAAC;IAClE,IAAIU,IAAI,EAAE;MACRA,IAAI,CAACgB,MAAM,CAACzB,cAAc,CAAC;MAC3B,IAAIS,IAAI,CAACiB,IAAI,KAAK,CAAC,EAAE;QACnB,IAAI,CAAChC,wBAAwB,CAAC+B,MAAM,CAACxB,QAAQ,CAACF,SAAS,CAAC;MAC1D;IACF;EACF;EAEA4B,gBAAgBA,CAAC3B,cAAsB,EAA2B;IAChE,MAAMC,QAAQ,GAAG,IAAI,CAACT,aAAa,CAACkB,GAAG,CAACV,cAAc,CAAC;IACvD,IAAI,CAACC,QAAQ,IAAIA,QAAQ,CAACI,SAAS,CAACgB,MAAM,KAAK,CAAC,EAAE;MAChD,OAAO,IAAI;IACb;IAEA,MAAMhB,SAAS,GAAGJ,QAAQ,CAACI,SAAS;IAEpC,IAAIuB,SAAS,GAAG,KAAK;IACrB,IAAIC,aAAa,GAAG,KAAK;IACzB,IAAIC,QAA4B;IAChC,IAAIC,wBAA4C;IAChD,IAAIC,uBAA2C;IAC/C,IAAIC,0CAA8D;IAElEJ,aAAa,GAAGxB,SAAS,CAAC6B,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACpB,YAAY,CAAC;IACrD,IAAIc,aAAa,EAAE;MACjB,MAAMO,mBAAmB,GAAG/B,SAAS,CAACgC,MAAM,CAAEF,CAAC,IAAKA,CAAC,CAACpB,YAAY,CAAC;MACnEgB,wBAAwB,GAAGK,mBAAmB,CAAC,CAAC,CAAC,EAAEnB,SAAS;MAC5De,uBAAuB,GACrBI,mBAAmB,CAACA,mBAAmB,CAACf,MAAM,GAAG,CAAC,CAAC,EAAEJ,SAAS;MAChEgB,0CAA0C,GAAG5B,SAAS,CAACiC,IAAI,CACxDH,CAAC,IACA,CAACA,CAAC,CAACpB,YAAY,IACfgB,wBAAwB,IAAI,IAAI,IAChCI,CAAC,CAAClB,SAAS,IAAIc,wBACnB,CAAC,EAAEd,SAAS;IACd;IAEA,MAAMf,aAAa,GAAGD,QAAQ,CAACC,aAAa;IAC5C,MAAMqC,aAAa,GAAGlC,SAAS,CAAC,CAAC,CAAC;IAClC,MAAMmC,cAAc,GAAGnC,SAAS,CAACiC,IAAI,CAAEH,CAAC,IAAKA,CAAC,CAACtB,MAAM,KAAK,QAAQ,CAAC;IAEnE,IAAI2B,cAAc,EAAE;MAClBV,QAAQ,GAAGU,cAAc,CAACvB,SAAS,GAAGf,aAAa;MAEnD,IACEqC,aAAa,CAAC1B,MAAM,KAAK,QAAQ,IACjCiB,QAAQ,GAAG,IAAI,CAACjC,gBAAgB,EAChC;QACA+B,SAAS,GAAG,IAAI;MAClB,CAAC,MAAM;QACLA,SAAS,GAAG,KAAK;MACnB;IACF;IAEA,OAAO;MACLA,SAAS;MACTC,aAAa;MACbC,QAAQ;MACRW,aAAa,EAAEpC,SAAS,CAACgB,MAAM;MAC/BU,wBAAwB;MACxBC,uBAAuB;MACvBC;IACF,CAAC;EACH;EAEAS,0BAA0BA,CAAC3C,SAAiB,EAAU;IACpD,OAAO,IAAI,CAACL,wBAAwB,CAACgB,GAAG,CAACX,SAAS,CAAC,EAAE2B,IAAI,IAAI,CAAC;EAChE;EAEAiB,0BAA0BA,CAAC5C,SAAiB,EAAW;IACrD,OAAO,CAAC,IAAI,CAACL,wBAAwB,CAACgB,GAAG,CAACX,SAAS,CAAC,EAAE2B,IAAI,IAAI,CAAC,IAAI,CAAC;EACtE;EAEAkB,sBAAsBA,CAAA,EAA2B;IAC/C,OAAO,CAAC,GAAG,IAAI,CAACpD,aAAa,CAACqD,MAAM,CAAC,CAAC,CAAC,CAACR,MAAM,CAC3CS,CAAC,IAAKA,CAAC,CAACtB,eAAe,KAAKuB,SAC/B,CAAC;EACH;EAEAC,OAAOA,CAACC,MAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,EAAQ;IAC5C,MAAM7C,GAAG,GAAGD,IAAI,CAACC,GAAG,CAAC,CAAC;IACtB,MAAM8C,QAAkB,GAAG,EAAE;IAE7B,KAAK,MAAM,CAACC,EAAE,EAAElD,QAAQ,CAAC,IAAI,IAAI,CAACT,aAAa,EAAE;MAC/C,IAAIS,QAAQ,CAACuB,eAAe,IAAIpB,GAAG,GAAGH,QAAQ,CAACuB,eAAe,GAAGyB,MAAM,EAAE;QACvEC,QAAQ,CAAC5B,IAAI,CAAC6B,EAAE,CAAC;MACnB;IACF;IAEAD,QAAQ,CAACE,OAAO,CAAED,EAAE,IAAK,IAAI,CAAC3D,aAAa,CAACiC,MAAM,CAAC0B,EAAE,CAAC,CAAC;EACzD;AACF","ignoreList":[]}
@@ -35,13 +35,13 @@ export class UnusedFieldAnalyzer {
35
35
  const entrySize = cacheEntry?.metadata.size ?? this.estimateCacheEntrySize(cacheEntry?.data);
36
36
  const wastedBytes = unused.length > 0 && cleanFetched.length > 0 ? Math.floor(entrySize * (unused.length / cleanFetched.length)) : 0;
37
37
  const efficiency = cleanFetched.length > 0 ? accessed.size / cleanFetched.length : 1;
38
- const suggestion = this.generateSuggestion(binding, Array.from(accessed));
38
+ const suggestion = this.generateSuggestion(binding, [...accessed]);
39
39
  const renderCount = binding.renderCount;
40
40
  return {
41
41
  componentName,
42
42
  querySignature,
43
43
  fetched: cleanFetched,
44
- accessed: Array.from(accessed),
44
+ accessed: [...accessed],
45
45
  unused,
46
46
  efficiency,
47
47
  wastedBytes,
@@ -91,7 +91,7 @@ export class UnusedFieldAnalyzer {
91
91
  fieldCount.set(key, current);
92
92
  }
93
93
  }
94
- return Array.from(fieldCount.entries()).map(([key, {
94
+ return [...fieldCount.entries()].map(([key, {
95
95
  unused,
96
96
  total,
97
97
  objectType
@@ -118,12 +118,11 @@ const { object } = useOsdkObject(${queryParams.objectType}, id);
118
118
 
119
119
  // Optimized: Only fetch what you use
120
120
  const { object } = useOsdkObject(${queryParams.objectType}, id, {
121
- $select: [${usedProps.length > 0 ? usedProps.map(p => `"${p}"`).join(", ") : "\"id\"" // fallback
122
- }]
121
+ $select: [${usedProps.length > 0 ? usedProps.map(p => `"${p}"`).join(", ") : '"id"'}]
123
122
  });
124
123
 
125
124
  // This query will be more efficient!
126
- `.trim();
125
+ `.trim(); // fallback
127
126
  } else if (hookType === "useOsdkObjects" && queryParams.type === "list") {
128
127
  return `
129
128
  // In ${componentName}.tsx:
@@ -135,7 +134,7 @@ const { data } = useOsdkObjects(${queryParams.objectType}, {
135
134
  // Optimized: Only fetch what you use
136
135
  const { data } = useOsdkObjects(${queryParams.objectType}, {
137
136
  where: ${JSON.stringify(queryParams.where || {})},
138
- $select: [${usedProps.length > 0 ? usedProps.map(p => `"${p}"`).join(", ") : "\"id\""}]
137
+ $select: [${usedProps.length > 0 ? usedProps.map(p => `"${p}"`).join(", ") : '"id"'}]
139
138
  });
140
139
  `.trim();
141
140
  }
@@ -1 +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":[]}
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","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","Array","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\";\n\nimport type {\n ComponentHookBinding,\n ComponentQueryRegistry,\n} from \"./ComponentQueryRegistry.js\";\nimport type { PropertyAccessTracker } from \"./PropertyAccessTracker.js\";\n\nexport interface PropertyAccessTrackerWithAnalysis extends PropertyAccessTracker {\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(\n (e) => e.key === querySignature\n );\n const fetchedProps = cacheEntry?.data ? Object.keys(cacheEntry.data) : [];\n\n const cleanFetched = fetchedProps.filter(\n (p) => !p.startsWith(\"$\") && p !== \"__typename\"\n );\n\n const unused = cleanFetched.filter((prop) => !accessed.has(prop));\n\n const entrySize =\n cacheEntry?.metadata.size ??\n this.estimateCacheEntrySize(cacheEntry?.data);\n const wastedBytes =\n unused.length > 0 && cleanFetched.length > 0\n ? Math.floor(entrySize * (unused.length / cleanFetched.length))\n : 0;\n\n const efficiency =\n cleanFetched.length > 0 ? accessed.size / cleanFetched.length : 1;\n\n const suggestion = this.generateSuggestion(binding, [...accessed]);\n\n const renderCount = binding.renderCount;\n\n return {\n componentName,\n querySignature,\n fetched: cleanFetched,\n accessed: [...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 =\n 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 = new Map<\n string,\n { unused: number; total: number; objectType?: string }\n >();\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,\n total: 0,\n objectType,\n };\n current.unused++;\n current.total++;\n fieldCount.set(key, current);\n }\n }\n\n return [...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 ? usedProps.map((p) => `\"${p}\"`).join(\", \") : '\"id\"'\n }]\n});\n\n// This query will be more efficient!\n `.trim(); // fallback\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 ? usedProps.map((p) => `\"${p}\"`).join(\", \") : '\"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\n ).toFixed(1)}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\n ).toFixed(1)}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":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"WaterfallDetector.js","names":["WaterfallDetector","constructor","registry","timeline","detectWaterfalls","timingThresholdMs","waterfalls","push","detectLinkWaterfalls","detectMapWaterfalls","detectSequentialPatterns","sort","a","b","timeSaved","emissions","getEventsByType","linkTraversals","i","length","emissionA","emissionB","timeBetween","timestamp","linkInWindow","find","link","estimatedFetchTime","type","priority","suggestion","linkName","code","generateLinkWaterfallCode","subscriptionId","details","parentQuery","childQuery","components","getActiveComponents","componentId","bindings","objectQueries","filter","hookType","grouped","Map","query","queryParams","key","objectType","has","set","group","get","queries","getComponentBindings","binding","undefined","generateMapWaterfallCode","component","componentName","count","sequenceLength","totalTime","trim"],"sources":["WaterfallDetector.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 ComponentHookBinding,\n ComponentQueryRegistry,\n} from \"./ComponentQueryRegistry.js\";\nimport type { EventTimeline } from \"./EventTimeline.js\";\n\nexport type WaterfallType =\n | \"LINK_WATERFALL\"\n | \"MAP_WATERFALL\"\n | \"SEQUENTIAL_WATERFALL\";\n\nexport interface Waterfall {\n type: WaterfallType;\n priority: \"high\" | \"medium\" | \"low\";\n timeSaved: number; // ms that could be saved\n suggestion: string;\n code: string;\n details: {\n parentQuery?: string;\n childQuery?: string;\n component?: string;\n count?: number;\n objectType?: string;\n };\n}\n\nexport class WaterfallDetector {\n constructor(\n private registry: ComponentQueryRegistry,\n private timeline: EventTimeline,\n ) {}\n\n detectWaterfalls(timingThresholdMs: number = 50): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n\n waterfalls.push(...this.detectLinkWaterfalls(timingThresholdMs));\n waterfalls.push(...this.detectMapWaterfalls());\n waterfalls.push(...this.detectSequentialPatterns(timingThresholdMs));\n\n return waterfalls.sort((a, b) => b.timeSaved - a.timeSaved);\n }\n\n private detectLinkWaterfalls(timingThresholdMs: number): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n\n const emissions = this.timeline.getEventsByType(\"EMISSION\");\n const linkTraversals = this.timeline.getEventsByType(\"LINK_TRAVERSAL\");\n\n for (let i = 0; i < emissions.length - 1; i++) {\n const emissionA = emissions[i];\n const emissionB = emissions[i + 1];\n\n const timeBetween = emissionB.timestamp - emissionA.timestamp;\n if (timeBetween > 0 && timeBetween < timingThresholdMs) {\n const linkInWindow = linkTraversals.find(link =>\n link.timestamp > emissionA.timestamp\n && link.timestamp < emissionB.timestamp\n );\n\n if (linkInWindow) {\n const estimatedFetchTime = emissionB.timestamp - emissionA.timestamp;\n\n waterfalls.push({\n type: \"LINK_WATERFALL\",\n priority: estimatedFetchTime > 200 ? \"high\" : \"medium\",\n timeSaved: estimatedFetchTime,\n suggestion:\n `Prefetch the \"${linkInWindow.linkName}\" relationship to run queries in parallel`,\n code: this.generateLinkWaterfallCode(\n emissionA.subscriptionId,\n emissionB.subscriptionId,\n linkInWindow.linkName,\n ),\n details: {\n parentQuery: emissionA.subscriptionId,\n childQuery: emissionB.subscriptionId,\n },\n });\n }\n }\n }\n\n return waterfalls;\n }\n\n private detectMapWaterfalls(): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n const components = this.registry.getActiveComponents();\n\n for (const [componentId, bindings] of components) {\n const objectQueries = bindings.filter(b =>\n b.hookType === \"useOsdkObject\"\n );\n const grouped = new Map<string, ComponentHookBinding[]>();\n\n for (const query of objectQueries) {\n if (query.queryParams.type === \"object\") {\n const key = query.queryParams.objectType;\n if (!grouped.has(key)) {\n grouped.set(key, []);\n }\n const group = grouped.get(key);\n if (group) {\n group.push(query);\n }\n }\n }\n\n for (const [objectType, queries] of grouped) {\n if (queries.length > 3) {\n const bindings = this.registry.getComponentBindings(componentId);\n const binding = bindings.length > 0 ? bindings[0] : undefined;\n\n waterfalls.push({\n type: \"MAP_WATERFALL\",\n priority: queries.length > 10 ? \"high\" : \"medium\",\n timeSaved: queries.length * 100, // Rough estimate\n suggestion:\n `Replace ${queries.length} useOsdkObject calls with single useOsdkObjects batch query`,\n code: this.generateMapWaterfallCode(objectType, queries.length),\n details: {\n component: binding ? binding.componentName : undefined,\n count: queries.length,\n objectType,\n },\n });\n }\n }\n }\n\n return waterfalls;\n }\n\n private detectSequentialPatterns(timingThresholdMs: number): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n const emissions = this.timeline.getEventsByType(\"EMISSION\");\n\n let sequenceStart = 0;\n let sequenceLength = 1;\n let totalTime = 0;\n\n for (let i = 1; i < emissions.length; i++) {\n const timeBetween = emissions[i].timestamp - emissions[i - 1].timestamp;\n\n if (timeBetween < timingThresholdMs) {\n sequenceLength++;\n totalTime += timeBetween;\n } else {\n if (sequenceLength > 3 && totalTime > 300) {\n waterfalls.push({\n type: \"SEQUENTIAL_WATERFALL\",\n priority: totalTime > 500 ? \"high\" : \"medium\",\n timeSaved: totalTime,\n suggestion:\n \"Consider parallelizing these queries or prefetching data\",\n code:\n \"// Analyze the queries in this sequence and look for prefetching opportunities\",\n details: {},\n });\n }\n\n sequenceStart = i;\n sequenceLength = 1;\n totalTime = 0;\n }\n }\n\n return waterfalls;\n }\n\n private generateLinkWaterfallCode(\n parentQuery: string,\n childQuery: string,\n linkName: string,\n ): string {\n return `\n// ⚠️ WATERFALL DETECTED\n// ${parentQuery} loads → triggers ${childQuery} (linked via \"${linkName}\")\n\n// Problem: Sequential loading adds latency\n// Timeline:\n// ━━━━ Parent query (t0-t200ms)\n// ↓ gap\n// ━━━━ Child/link query (t210-t260ms)\n// Total: 260ms\n\n// This is a known sequential pattern with useOsdkObject + useLinks.\n// The link query cannot start until the parent object is loaded.\n\n// Current pattern:\nconst { object: parent } = useOsdkObject(ParentType, id);\nconst { links } = useLinks(parent, \"${linkName}\");\n\n// Option 1: If you have the linked IDs available upfront, load in parallel:\nconst [parentResult, childResult] = await Promise.all([\n useOsdkObject(ParentType, parentId),\n useOsdkObjects(ChildType, { where: { id: { $in: knownChildIds } } }),\n]);\n\n// Option 2: If data permits, restructure to load the parent object\n// at a higher level so the link query starts sooner.\n `.trim();\n }\n\n private generateMapWaterfallCode(objectType: string, count: number): string {\n return `\n// ⚠️ MAP WATERFALL DETECTED (N+1 Pattern)\n// ${count} useOsdkObject calls for ${objectType} - each triggers separate fetch!\n\n// Problem: Loads ${count} items sequentially instead of one batch request\n// Timeline (Example):\n// ━━ Item 1 (t0-t100ms)\n// ━━ Item 2 (t100-t200ms)\n// ━━ Item 3 (t200-t300ms)\n// Total: 300ms for 3 items\n\n// Solution: Use useOsdkObjects for batch loading\n\n// Before (❌ N+1 pattern):\n{items.map(item => (\n <Item key={item.id} itemId={item.id} />\n))}\n\n// In Item component:\nfunction Item({ itemId }) {\n const { object } = useOsdkObject(${objectType}, itemId); // ❌ Runs ${count} times!\n return <div>{object.name}</div>;\n}\n\n// After (✅ Batch query):\nfunction ItemList({ items }) {\n const itemIds = items.map(item => item.id);\n const { data } = useOsdkObjects(${objectType}, {\n where: { id: { $in: itemIds } } // ✅ Single query!\n });\n\n return items.map(item => (\n <Item key={item.id} data={data} />\n ));\n}\n\nfunction Item({ data }) {\n // Just receive data as prop - no query needed!\n return <div>{data.name}</div>;\n}\n\n// Result: 1 batch request instead of ${count} individual requests\n// Time saved: ~${(count - 1) * 100}ms\n `.trim();\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"WaterfallDetector.js","names":["WaterfallDetector","constructor","registry","timeline","detectWaterfalls","timingThresholdMs","waterfalls","push","detectLinkWaterfalls","detectMapWaterfalls","detectSequentialPatterns","sort","a","b","timeSaved","emissions","getEventsByType","linkTraversals","i","length","emissionA","emissionB","timeBetween","timestamp","linkInWindow","find","link","estimatedFetchTime","type","priority","suggestion","linkName","code","generateLinkWaterfallCode","subscriptionId","details","parentQuery","childQuery","components","getActiveComponents","componentId","bindings","objectQueries","filter","hookType","grouped","Map","query","queryParams","key","objectType","has","set","group","get","queries","getComponentBindings","binding","undefined","generateMapWaterfallCode","component","componentName","count","sequenceLength","totalTime","trim"],"sources":["WaterfallDetector.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 ComponentHookBinding,\n ComponentQueryRegistry,\n} from \"./ComponentQueryRegistry.js\";\nimport type { EventTimeline } from \"./EventTimeline.js\";\n\nexport type WaterfallType =\n | \"LINK_WATERFALL\"\n | \"MAP_WATERFALL\"\n | \"SEQUENTIAL_WATERFALL\";\n\nexport interface Waterfall {\n type: WaterfallType;\n priority: \"high\" | \"medium\" | \"low\";\n timeSaved: number; // ms that could be saved\n suggestion: string;\n code: string;\n details: {\n parentQuery?: string;\n childQuery?: string;\n component?: string;\n count?: number;\n objectType?: string;\n };\n}\n\nexport class WaterfallDetector {\n constructor(\n private registry: ComponentQueryRegistry,\n private timeline: EventTimeline\n ) {}\n\n detectWaterfalls(timingThresholdMs: number = 50): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n\n waterfalls.push(...this.detectLinkWaterfalls(timingThresholdMs));\n waterfalls.push(...this.detectMapWaterfalls());\n waterfalls.push(...this.detectSequentialPatterns(timingThresholdMs));\n\n return waterfalls.sort((a, b) => b.timeSaved - a.timeSaved);\n }\n\n private detectLinkWaterfalls(timingThresholdMs: number): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n\n const emissions = this.timeline.getEventsByType(\"EMISSION\");\n const linkTraversals = this.timeline.getEventsByType(\"LINK_TRAVERSAL\");\n\n for (let i = 0; i < emissions.length - 1; i++) {\n const emissionA = emissions[i];\n const emissionB = emissions[i + 1];\n\n const timeBetween = emissionB.timestamp - emissionA.timestamp;\n if (timeBetween > 0 && timeBetween < timingThresholdMs) {\n const linkInWindow = linkTraversals.find(\n (link) =>\n link.timestamp > emissionA.timestamp &&\n link.timestamp < emissionB.timestamp\n );\n\n if (linkInWindow) {\n const estimatedFetchTime = emissionB.timestamp - emissionA.timestamp;\n\n waterfalls.push({\n type: \"LINK_WATERFALL\",\n priority: estimatedFetchTime > 200 ? \"high\" : \"medium\",\n timeSaved: estimatedFetchTime,\n suggestion: `Prefetch the \"${linkInWindow.linkName}\" relationship to run queries in parallel`,\n code: this.generateLinkWaterfallCode(\n emissionA.subscriptionId,\n emissionB.subscriptionId,\n linkInWindow.linkName\n ),\n details: {\n parentQuery: emissionA.subscriptionId,\n childQuery: emissionB.subscriptionId,\n },\n });\n }\n }\n }\n\n return waterfalls;\n }\n\n private detectMapWaterfalls(): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n const components = this.registry.getActiveComponents();\n\n for (const [componentId, bindings] of components) {\n const objectQueries = bindings.filter(\n (b) => b.hookType === \"useOsdkObject\"\n );\n const grouped = new Map<string, ComponentHookBinding[]>();\n\n for (const query of objectQueries) {\n if (query.queryParams.type === \"object\") {\n const key = query.queryParams.objectType;\n if (!grouped.has(key)) {\n grouped.set(key, []);\n }\n const group = grouped.get(key);\n if (group) {\n group.push(query);\n }\n }\n }\n\n for (const [objectType, queries] of grouped) {\n if (queries.length > 3) {\n const bindings = this.registry.getComponentBindings(componentId);\n const binding = bindings.length > 0 ? bindings[0] : undefined;\n\n waterfalls.push({\n type: \"MAP_WATERFALL\",\n priority: queries.length > 10 ? \"high\" : \"medium\",\n timeSaved: queries.length * 100, // Rough estimate\n suggestion: `Replace ${queries.length} useOsdkObject calls with single useOsdkObjects batch query`,\n code: this.generateMapWaterfallCode(objectType, queries.length),\n details: {\n component: binding ? binding.componentName : undefined,\n count: queries.length,\n objectType,\n },\n });\n }\n }\n }\n\n return waterfalls;\n }\n\n private detectSequentialPatterns(timingThresholdMs: number): Waterfall[] {\n const waterfalls: Waterfall[] = [];\n const emissions = this.timeline.getEventsByType(\"EMISSION\");\n\n let sequenceStart = 0;\n let sequenceLength = 1;\n let totalTime = 0;\n\n for (let i = 1; i < emissions.length; i++) {\n const timeBetween = emissions[i].timestamp - emissions[i - 1].timestamp;\n\n if (timeBetween < timingThresholdMs) {\n sequenceLength++;\n totalTime += timeBetween;\n } else {\n if (sequenceLength > 3 && totalTime > 300) {\n waterfalls.push({\n type: \"SEQUENTIAL_WATERFALL\",\n priority: totalTime > 500 ? \"high\" : \"medium\",\n timeSaved: totalTime,\n suggestion:\n \"Consider parallelizing these queries or prefetching data\",\n code: \"// Analyze the queries in this sequence and look for prefetching opportunities\",\n details: {},\n });\n }\n\n sequenceStart = i;\n sequenceLength = 1;\n totalTime = 0;\n }\n }\n\n return waterfalls;\n }\n\n private generateLinkWaterfallCode(\n parentQuery: string,\n childQuery: string,\n linkName: string\n ): string {\n return `\n// ⚠️ WATERFALL DETECTED\n// ${parentQuery} loads → triggers ${childQuery} (linked via \"${linkName}\")\n\n// Problem: Sequential loading adds latency\n// Timeline:\n// ━━━━ Parent query (t0-t200ms)\n// ↓ gap\n// ━━━━ Child/link query (t210-t260ms)\n// Total: 260ms\n\n// This is a known sequential pattern with useOsdkObject + useLinks.\n// The link query cannot start until the parent object is loaded.\n\n// Current pattern:\nconst { object: parent } = useOsdkObject(ParentType, id);\nconst { links } = useLinks(parent, \"${linkName}\");\n\n// Option 1: If you have the linked IDs available upfront, load in parallel:\nconst [parentResult, childResult] = await Promise.all([\n useOsdkObject(ParentType, parentId),\n useOsdkObjects(ChildType, { where: { id: { $in: knownChildIds } } }),\n]);\n\n// Option 2: If data permits, restructure to load the parent object\n// at a higher level so the link query starts sooner.\n `.trim();\n }\n\n private generateMapWaterfallCode(objectType: string, count: number): string {\n return `\n// ⚠️ MAP WATERFALL DETECTED (N+1 Pattern)\n// ${count} useOsdkObject calls for ${objectType} - each triggers separate fetch!\n\n// Problem: Loads ${count} items sequentially instead of one batch request\n// Timeline (Example):\n// ━━ Item 1 (t0-t100ms)\n// ━━ Item 2 (t100-t200ms)\n// ━━ Item 3 (t200-t300ms)\n// Total: 300ms for 3 items\n\n// Solution: Use useOsdkObjects for batch loading\n\n// Before (❌ N+1 pattern):\n{items.map(item => (\n <Item key={item.id} itemId={item.id} />\n))}\n\n// In Item component:\nfunction Item({ itemId }) {\n const { object } = useOsdkObject(${objectType}, itemId); // ❌ Runs ${count} times!\n return <div>{object.name}</div>;\n}\n\n// After (✅ Batch query):\nfunction ItemList({ items }) {\n const itemIds = items.map(item => item.id);\n const { data } = useOsdkObjects(${objectType}, {\n where: { id: { $in: itemIds } } // ✅ Single query!\n });\n\n return items.map(item => (\n <Item key={item.id} data={data} />\n ));\n}\n\nfunction Item({ data }) {\n // Just receive data as prop - no query needed!\n return <div>{data.name}</div>;\n}\n\n// Result: 1 batch request instead of ${count} individual requests\n// Time saved: ~${(count - 1) * 100}ms\n `.trim();\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -22,7 +22,7 @@ export function truncatePayload(payload) {
22
22
  if (payload.length <= MAX_PAYLOAD_LENGTH) {
23
23
  return payload;
24
24
  }
25
- return payload.substring(0, MAX_PAYLOAD_LENGTH) + "...";
25
+ return `${payload.substring(0, MAX_PAYLOAD_LENGTH)}...`;
26
26
  }
27
27
  export function hashPayload(payload) {
28
28
  const str = stringifyPayload(payload);
@@ -30,7 +30,7 @@ export function hashPayload(payload) {
30
30
  for (let i = 0; i < str.length; i++) {
31
31
  const char = str.charCodeAt(i);
32
32
  hash = (hash << 5) - hash + char;
33
- hash = hash & hash;
33
+ hash &= hash;
34
34
  }
35
35
  return hash;
36
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"computePayload.js","names":["MAX_PAYLOAD_LENGTH","stringifyPayload","payload","JSON","stringify","truncatePayload","length","substring","hashPayload","str","hash","i","char","charCodeAt"],"sources":["computePayload.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\nconst MAX_PAYLOAD_LENGTH = 10000;\n\nexport function stringifyPayload(payload: unknown): string {\n return JSON.stringify(payload);\n}\n\nexport function truncatePayload(payload: string): string {\n if (payload.length <= MAX_PAYLOAD_LENGTH) {\n return payload;\n }\n return payload.substring(0, MAX_PAYLOAD_LENGTH) + \"...\";\n}\n\nexport function hashPayload(payload: unknown): number {\n const str = stringifyPayload(payload);\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return hash;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAMA,kBAAkB,GAAG,KAAK;AAEhC,OAAO,SAASC,gBAAgBA,CAACC,OAAgB,EAAU;EACzD,OAAOC,IAAI,CAACC,SAAS,CAACF,OAAO,CAAC;AAChC;AAEA,OAAO,SAASG,eAAeA,CAACH,OAAe,EAAU;EACvD,IAAIA,OAAO,CAACI,MAAM,IAAIN,kBAAkB,EAAE;IACxC,OAAOE,OAAO;EAChB;EACA,OAAOA,OAAO,CAACK,SAAS,CAAC,CAAC,EAAEP,kBAAkB,CAAC,GAAG,KAAK;AACzD;AAEA,OAAO,SAASQ,WAAWA,CAACN,OAAgB,EAAU;EACpD,MAAMO,GAAG,GAAGR,gBAAgB,CAACC,OAAO,CAAC;EACrC,IAAIQ,IAAI,GAAG,CAAC;EACZ,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,GAAG,CAACH,MAAM,EAAEK,CAAC,EAAE,EAAE;IACnC,MAAMC,IAAI,GAAGH,GAAG,CAACI,UAAU,CAACF,CAAC,CAAC;IAC9BD,IAAI,GAAG,CAACA,IAAI,IAAI,CAAC,IAAIA,IAAI,GAAGE,IAAI;IAChCF,IAAI,GAAGA,IAAI,GAAGA,IAAI;EACpB;EACA,OAAOA,IAAI;AACb","ignoreList":[]}
1
+ {"version":3,"file":"computePayload.js","names":["MAX_PAYLOAD_LENGTH","stringifyPayload","payload","JSON","stringify","truncatePayload","length","substring","hashPayload","str","hash","i","char","charCodeAt"],"sources":["computePayload.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\nconst MAX_PAYLOAD_LENGTH = 10000;\n\nexport function stringifyPayload(payload: unknown): string {\n return JSON.stringify(payload);\n}\n\nexport function truncatePayload(payload: string): string {\n if (payload.length <= MAX_PAYLOAD_LENGTH) {\n return payload;\n }\n return `${payload.substring(0, MAX_PAYLOAD_LENGTH)}...`;\n}\n\nexport function hashPayload(payload: unknown): number {\n const str = stringifyPayload(payload);\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash &= hash;\n }\n return hash;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAMA,kBAAkB,GAAG,KAAK;AAEhC,OAAO,SAASC,gBAAgBA,CAACC,OAAgB,EAAU;EACzD,OAAOC,IAAI,CAACC,SAAS,CAACF,OAAO,CAAC;AAChC;AAEA,OAAO,SAASG,eAAeA,CAACH,OAAe,EAAU;EACvD,IAAIA,OAAO,CAACI,MAAM,IAAIN,kBAAkB,EAAE;IACxC,OAAOE,OAAO;EAChB;EACA,OAAO,GAAGA,OAAO,CAACK,SAAS,CAAC,CAAC,EAAEP,kBAAkB,CAAC,KAAK;AACzD;AAEA,OAAO,SAASQ,WAAWA,CAACN,OAAgB,EAAU;EACpD,MAAMO,GAAG,GAAGR,gBAAgB,CAACC,OAAO,CAAC;EACrC,IAAIQ,IAAI,GAAG,CAAC;EACZ,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,GAAG,CAACH,MAAM,EAAEK,CAAC,EAAE,EAAE;IACnC,MAAMC,IAAI,GAAGH,GAAG,CAACI,UAAU,CAACF,CAAC,CAAC;IAC9BD,IAAI,GAAG,CAACA,IAAI,IAAI,CAAC,IAAIA,IAAI,GAAGE,IAAI;IAChCF,IAAI,IAAIA,IAAI;EACd;EACA,OAAOA,IAAI;AACb","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"computeRequest.js","names":["visitComputeRequest","request","visitor","type","pending","failed","fulfilledWithoutUsage","fulfilled"],"sources":["computeRequest.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 { ComputeRequest } from \"../types/compute.js\";\n\ntype FulfilledComputeRequest = Extract<\n ComputeRequest,\n { type: \"fulfilled\" }\n>;\ntype FulfilledWithoutUsageComputeRequest = Extract<\n ComputeRequest,\n { type: \"fulfilled-without-usage\" }\n>;\ntype PendingComputeRequest = Extract<\n ComputeRequest,\n { type: \"pending\" }\n>;\ntype FailedComputeRequest = Extract<ComputeRequest, { type: \"failed\" }>;\n\nexport const visitComputeRequest = <T>(\n request: ComputeRequest,\n visitor: {\n pending: (request: PendingComputeRequest) => T;\n failed: (request: FailedComputeRequest) => T;\n fulfilled: (request: FulfilledComputeRequest) => T;\n fulfilledWithoutUsage: (request: FulfilledWithoutUsageComputeRequest) => T;\n },\n): T => {\n if (request.type === \"pending\") {\n return visitor.pending(request);\n }\n\n if (request.type === \"failed\") {\n return visitor.failed(request);\n }\n\n if (request.type === \"fulfilled-without-usage\") {\n return visitor.fulfilledWithoutUsage(request);\n }\n\n return visitor.fulfilled(request);\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBA,OAAO,MAAMA,mBAAmB,GAAGA,CACjCC,OAAuB,EACvBC,OAKC,KACK;EACN,IAAID,OAAO,CAACE,IAAI,KAAK,SAAS,EAAE;IAC9B,OAAOD,OAAO,CAACE,OAAO,CAACH,OAAO,CAAC;EACjC;EAEA,IAAIA,OAAO,CAACE,IAAI,KAAK,QAAQ,EAAE;IAC7B,OAAOD,OAAO,CAACG,MAAM,CAACJ,OAAO,CAAC;EAChC;EAEA,IAAIA,OAAO,CAACE,IAAI,KAAK,yBAAyB,EAAE;IAC9C,OAAOD,OAAO,CAACI,qBAAqB,CAACL,OAAO,CAAC;EAC/C;EAEA,OAAOC,OAAO,CAACK,SAAS,CAACN,OAAO,CAAC;AACnC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"computeRequest.js","names":["visitComputeRequest","request","visitor","type","pending","failed","fulfilledWithoutUsage","fulfilled"],"sources":["computeRequest.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 { ComputeRequest } from \"../types/compute.js\";\n\ntype FulfilledComputeRequest = Extract<ComputeRequest, { type: \"fulfilled\" }>;\ntype FulfilledWithoutUsageComputeRequest = Extract<\n ComputeRequest,\n { type: \"fulfilled-without-usage\" }\n>;\ntype PendingComputeRequest = Extract<ComputeRequest, { type: \"pending\" }>;\ntype FailedComputeRequest = Extract<ComputeRequest, { type: \"failed\" }>;\n\nexport const visitComputeRequest = <T>(\n request: ComputeRequest,\n visitor: {\n pending: (request: PendingComputeRequest) => T;\n failed: (request: FailedComputeRequest) => T;\n fulfilled: (request: FulfilledComputeRequest) => T;\n fulfilledWithoutUsage: (request: FulfilledWithoutUsageComputeRequest) => T;\n }\n): T => {\n if (request.type === \"pending\") {\n return visitor.pending(request);\n }\n\n if (request.type === \"failed\") {\n return visitor.failed(request);\n }\n\n if (request.type === \"fulfilled-without-usage\") {\n return visitor.fulfilledWithoutUsage(request);\n }\n\n return visitor.fulfilled(request);\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA,OAAO,MAAMA,mBAAmB,GAAGA,CACjCC,OAAuB,EACvBC,OAKC,KACK;EACN,IAAID,OAAO,CAACE,IAAI,KAAK,SAAS,EAAE;IAC9B,OAAOD,OAAO,CAACE,OAAO,CAACH,OAAO,CAAC;EACjC;EAEA,IAAIA,OAAO,CAACE,IAAI,KAAK,QAAQ,EAAE;IAC7B,OAAOD,OAAO,CAACG,MAAM,CAACJ,OAAO,CAAC;EAChC;EAEA,IAAIA,OAAO,CAACE,IAAI,KAAK,yBAAyB,EAAE;IAC9C,OAAOD,OAAO,CAACI,qBAAqB,CAACL,OAAO,CAAC;EAC/C;EAEA,OAAOC,OAAO,CAACK,SAAS,CAACN,OAAO,CAAC;AACnC,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","names":["formatTime","ms","toFixed","formatNumber","num","formatBytes","bytes","formatRelativeTime","timestamp","diff","Date","now","Math","floor","formatMilliseconds","value","includeSpace","space","seconds","minutes"],"sources":["format.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 function formatTime(ms: number): string {\n if (ms < 1) {\n return \"<1ms\";\n }\n if (ms < 1000) {\n return `${ms.toFixed(0)}ms`;\n }\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nexport function formatNumber(num: number): string {\n if (num >= 1000000) {\n return `${(num / 1000000).toFixed(1)}M`;\n }\n if (num >= 1000) {\n return `${(num / 1000).toFixed(1)}K`;\n }\n return num.toFixed(0);\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes}B`;\n }\n if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)}KB`;\n }\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\nexport function formatRelativeTime(timestamp: number): string {\n const diff = Date.now() - timestamp;\n if (diff < 1000) {\n return \"just now\";\n }\n if (diff < 60000) {\n return `${Math.floor(diff / 1000)}s ago`;\n }\n if (diff < 3600000) {\n return `${Math.floor(diff / 60000)}m ago`;\n }\n return `${Math.floor(diff / 3600000)}h ago`;\n}\n\nexport const formatMilliseconds = (\n value: number,\n includeSpace: boolean,\n): string => {\n const space = includeSpace ? \" \" : \"\";\n if (value < 1000) {\n return `${value}${space}ms`;\n }\n\n if (value < 60 * 1000) {\n const seconds = value / 1000;\n return seconds % 1 === 0\n ? `${seconds}${space}s`\n : `${seconds.toFixed(1)}${space}s`;\n }\n\n const minutes = value / 60_000;\n return minutes % 1 === 0\n ? `${minutes}${space}m`\n : `${minutes.toFixed(1)}${space}m`;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASA,UAAUA,CAACC,EAAU,EAAU;EAC7C,IAAIA,EAAE,GAAG,CAAC,EAAE;IACV,OAAO,MAAM;EACf;EACA,IAAIA,EAAE,GAAG,IAAI,EAAE;IACb,OAAO,GAAGA,EAAE,CAACC,OAAO,CAAC,CAAC,CAAC,IAAI;EAC7B;EACA,OAAO,GAAG,CAACD,EAAE,GAAG,IAAI,EAAEC,OAAO,CAAC,CAAC,CAAC,GAAG;AACrC;AAEA,OAAO,SAASC,YAAYA,CAACC,GAAW,EAAU;EAChD,IAAIA,GAAG,IAAI,OAAO,EAAE;IAClB,OAAO,GAAG,CAACA,GAAG,GAAG,OAAO,EAAEF,OAAO,CAAC,CAAC,CAAC,GAAG;EACzC;EACA,IAAIE,GAAG,IAAI,IAAI,EAAE;IACf,OAAO,GAAG,CAACA,GAAG,GAAG,IAAI,EAAEF,OAAO,CAAC,CAAC,CAAC,GAAG;EACtC;EACA,OAAOE,GAAG,CAACF,OAAO,CAAC,CAAC,CAAC;AACvB;AAEA,OAAO,SAASG,WAAWA,CAACC,KAAa,EAAU;EACjD,IAAIA,KAAK,GAAG,IAAI,EAAE;IAChB,OAAO,GAAGA,KAAK,GAAG;EACpB;EACA,IAAIA,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE;IACvB,OAAO,GAAG,CAACA,KAAK,GAAG,IAAI,EAAEJ,OAAO,CAAC,CAAC,CAAC,IAAI;EACzC;EACA,OAAO,GAAG,CAACI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,EAAEJ,OAAO,CAAC,CAAC,CAAC,IAAI;AAClD;AAEA,OAAO,SAASK,kBAAkBA,CAACC,SAAiB,EAAU;EAC5D,MAAMC,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGH,SAAS;EACnC,IAAIC,IAAI,GAAG,IAAI,EAAE;IACf,OAAO,UAAU;EACnB;EACA,IAAIA,IAAI,GAAG,KAAK,EAAE;IAChB,OAAO,GAAGG,IAAI,CAACC,KAAK,CAACJ,IAAI,GAAG,IAAI,CAAC,OAAO;EAC1C;EACA,IAAIA,IAAI,GAAG,OAAO,EAAE;IAClB,OAAO,GAAGG,IAAI,CAACC,KAAK,CAACJ,IAAI,GAAG,KAAK,CAAC,OAAO;EAC3C;EACA,OAAO,GAAGG,IAAI,CAACC,KAAK,CAACJ,IAAI,GAAG,OAAO,CAAC,OAAO;AAC7C;AAEA,OAAO,MAAMK,kBAAkB,GAAGA,CAChCC,KAAa,EACbC,YAAqB,KACV;EACX,MAAMC,KAAK,GAAGD,YAAY,GAAG,GAAG,GAAG,EAAE;EACrC,IAAID,KAAK,GAAG,IAAI,EAAE;IAChB,OAAO,GAAGA,KAAK,GAAGE,KAAK,IAAI;EAC7B;EAEA,IAAIF,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE;IACrB,MAAMG,OAAO,GAAGH,KAAK,GAAG,IAAI;IAC5B,OAAOG,OAAO,GAAG,CAAC,KAAK,CAAC,GACpB,GAAGA,OAAO,GAAGD,KAAK,GAAG,GACrB,GAAGC,OAAO,CAAChB,OAAO,CAAC,CAAC,CAAC,GAAGe,KAAK,GAAG;EACtC;EAEA,MAAME,OAAO,GAAGJ,KAAK,GAAG,MAAM;EAC9B,OAAOI,OAAO,GAAG,CAAC,KAAK,CAAC,GACpB,GAAGA,OAAO,GAAGF,KAAK,GAAG,GACrB,GAAGE,OAAO,CAACjB,OAAO,CAAC,CAAC,CAAC,GAAGe,KAAK,GAAG;AACtC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"format.js","names":["formatTime","ms","toFixed","formatNumber","num","formatBytes","bytes","formatRelativeTime","timestamp","diff","Date","now","Math","floor","formatMilliseconds","value","includeSpace","space","seconds","minutes"],"sources":["format.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 function formatTime(ms: number): string {\n if (ms < 1) {\n return \"<1ms\";\n }\n if (ms < 1000) {\n return `${ms.toFixed(0)}ms`;\n }\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nexport function formatNumber(num: number): string {\n if (num >= 1000000) {\n return `${(num / 1000000).toFixed(1)}M`;\n }\n if (num >= 1000) {\n return `${(num / 1000).toFixed(1)}K`;\n }\n return num.toFixed(0);\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes}B`;\n }\n if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)}KB`;\n }\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\nexport function formatRelativeTime(timestamp: number): string {\n const diff = Date.now() - timestamp;\n if (diff < 1000) {\n return \"just now\";\n }\n if (diff < 60000) {\n return `${Math.floor(diff / 1000)}s ago`;\n }\n if (diff < 3600000) {\n return `${Math.floor(diff / 60000)}m ago`;\n }\n return `${Math.floor(diff / 3600000)}h ago`;\n}\n\nexport const formatMilliseconds = (\n value: number,\n includeSpace: boolean\n): string => {\n const space = includeSpace ? \" \" : \"\";\n if (value < 1000) {\n return `${value}${space}ms`;\n }\n\n if (value < 60 * 1000) {\n const seconds = value / 1000;\n return seconds % 1 === 0\n ? `${seconds}${space}s`\n : `${seconds.toFixed(1)}${space}s`;\n }\n\n const minutes = value / 60_000;\n return minutes % 1 === 0\n ? `${minutes}${space}m`\n : `${minutes.toFixed(1)}${space}m`;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASA,UAAUA,CAACC,EAAU,EAAU;EAC7C,IAAIA,EAAE,GAAG,CAAC,EAAE;IACV,OAAO,MAAM;EACf;EACA,IAAIA,EAAE,GAAG,IAAI,EAAE;IACb,OAAO,GAAGA,EAAE,CAACC,OAAO,CAAC,CAAC,CAAC,IAAI;EAC7B;EACA,OAAO,GAAG,CAACD,EAAE,GAAG,IAAI,EAAEC,OAAO,CAAC,CAAC,CAAC,GAAG;AACrC;AAEA,OAAO,SAASC,YAAYA,CAACC,GAAW,EAAU;EAChD,IAAIA,GAAG,IAAI,OAAO,EAAE;IAClB,OAAO,GAAG,CAACA,GAAG,GAAG,OAAO,EAAEF,OAAO,CAAC,CAAC,CAAC,GAAG;EACzC;EACA,IAAIE,GAAG,IAAI,IAAI,EAAE;IACf,OAAO,GAAG,CAACA,GAAG,GAAG,IAAI,EAAEF,OAAO,CAAC,CAAC,CAAC,GAAG;EACtC;EACA,OAAOE,GAAG,CAACF,OAAO,CAAC,CAAC,CAAC;AACvB;AAEA,OAAO,SAASG,WAAWA,CAACC,KAAa,EAAU;EACjD,IAAIA,KAAK,GAAG,IAAI,EAAE;IAChB,OAAO,GAAGA,KAAK,GAAG;EACpB;EACA,IAAIA,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE;IACvB,OAAO,GAAG,CAACA,KAAK,GAAG,IAAI,EAAEJ,OAAO,CAAC,CAAC,CAAC,IAAI;EACzC;EACA,OAAO,GAAG,CAACI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,EAAEJ,OAAO,CAAC,CAAC,CAAC,IAAI;AAClD;AAEA,OAAO,SAASK,kBAAkBA,CAACC,SAAiB,EAAU;EAC5D,MAAMC,IAAI,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGH,SAAS;EACnC,IAAIC,IAAI,GAAG,IAAI,EAAE;IACf,OAAO,UAAU;EACnB;EACA,IAAIA,IAAI,GAAG,KAAK,EAAE;IAChB,OAAO,GAAGG,IAAI,CAACC,KAAK,CAACJ,IAAI,GAAG,IAAI,CAAC,OAAO;EAC1C;EACA,IAAIA,IAAI,GAAG,OAAO,EAAE;IAClB,OAAO,GAAGG,IAAI,CAACC,KAAK,CAACJ,IAAI,GAAG,KAAK,CAAC,OAAO;EAC3C;EACA,OAAO,GAAGG,IAAI,CAACC,KAAK,CAACJ,IAAI,GAAG,OAAO,CAAC,OAAO;AAC7C;AAEA,OAAO,MAAMK,kBAAkB,GAAGA,CAChCC,KAAa,EACbC,YAAqB,KACV;EACX,MAAMC,KAAK,GAAGD,YAAY,GAAG,GAAG,GAAG,EAAE;EACrC,IAAID,KAAK,GAAG,IAAI,EAAE;IAChB,OAAO,GAAGA,KAAK,GAAGE,KAAK,IAAI;EAC7B;EAEA,IAAIF,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE;IACrB,MAAMG,OAAO,GAAGH,KAAK,GAAG,IAAI;IAC5B,OAAOG,OAAO,GAAG,CAAC,KAAK,CAAC,GACpB,GAAGA,OAAO,GAAGD,KAAK,GAAG,GACrB,GAAGC,OAAO,CAAChB,OAAO,CAAC,CAAC,CAAC,GAAGe,KAAK,GAAG;EACtC;EAEA,MAAME,OAAO,GAAGJ,KAAK,GAAG,MAAM;EAC9B,OAAOI,OAAO,GAAG,CAAC,KAAK,CAAC,GACpB,GAAGA,OAAO,GAAGF,KAAK,GAAG,GACrB,GAAGE,OAAO,CAACjB,OAAO,CAAC,CAAC,CAAC,GAAGe,KAAK,GAAG;AACtC,CAAC","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"hookInstaller.js","names":["generateHookInstallationScript","verbose"],"sources":["hookInstaller.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 function generateHookInstallationScript(\n verbose: boolean = false,\n): string {\n return `\n<script type=\"module\">\n // OSDK DevTools Hook Installer\n // This script installs __REACT_DEVTOOLS_GLOBAL_HOOK__ before React initializes\n\n (function installOsdkDevToolsHook() {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return;\n }\n\n // If hook already exists (React DevTools extension), cooperate with it\n if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {\n ${\n verbose\n ? `console.log('[OSDK DevTools] Hook already exists (browser extension detected)');`\n : \"\"\n }\n return;\n }\n\n // Store fiber roots per renderer ID\n const fiberRootsByRenderer = new Map();\n // Renderer registry (closure-scoped so inject() does not depend on \\`this\\`)\n const renderers = new Map();\n\n // Install our hook\n window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {\n // Renderer registry (same Map instance as the closure variable)\n renderers,\n\n // Indicate we support React Fiber architecture\n supportsFiber: true,\n\n // Called by React when a renderer initializes\n inject(renderer) {\n const id = renderers.size + 1;\n renderers.set(id, renderer);\n fiberRootsByRenderer.set(id, new Set());\n\n ${\n verbose\n ? `\n console.log('[OSDK DevTools] React renderer injected:', {\n id,\n version: renderer.version,\n package: renderer.rendererPackageName\n });\n `\n : \"\"\n }\n\n return id;\n },\n\n // Called by React after each commit phase\n onCommitFiberRoot(rendererID, root, priorityLevel) {\n const roots = fiberRootsByRenderer.get(rendererID);\n if (roots) {\n roots.add(root);\n }\n },\n\n // Called by React when a fiber unmounts\n onCommitFiberUnmount(rendererID, fiber) {\n // Optional: track unmounts if needed for GC\n },\n\n // Custom method: Get roots for specific renderer\n getFiberRoots(rendererID) {\n return fiberRootsByRenderer.get(rendererID) || new Set();\n },\n\n // Custom method: Get all roots across all renderers\n getAllFiberRoots() {\n const allRoots = new Set();\n for (const roots of fiberRootsByRenderer.values()) {\n for (const root of roots) {\n allRoots.add(root);\n }\n }\n return allRoots;\n }\n };\n\n ${\n verbose\n ? `console.log('[OSDK DevTools] Hook installed successfully via Vite plugin');`\n : \"\"\n }\n })();\n</script>`;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASA,8BAA8BA,CAC5CC,OAAgB,GAAG,KAAK,EAChB;EACR,OAAO;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QACIA,OAAO,GACH,kFAAkF,GAClF,EAAE;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAEIA,OAAO,GACH;AACR;AACA;AACA;AACA;AACA;AACA,SAAS,GACD,EAAE;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAEIA,OAAO,GACH,6EAA6E,GAC7E,EAAE;AACV;AACA,UACU;AACV","ignoreList":[]}
1
+ {"version":3,"file":"hookInstaller.js","names":["generateHookInstallationScript","verbose"],"sources":["hookInstaller.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 function generateHookInstallationScript(\n verbose: boolean = false\n): string {\n return `\n<script type=\"module\">\n // OSDK DevTools Hook Installer\n // This script installs __REACT_DEVTOOLS_GLOBAL_HOOK__ before React initializes\n\n (function installOsdkDevToolsHook() {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return;\n }\n\n // If hook already exists (React DevTools extension), cooperate with it\n if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {\n ${\n verbose\n ? `console.log('[OSDK DevTools] Hook already exists (browser extension detected)');`\n : \"\"\n }\n return;\n }\n\n // Store fiber roots per renderer ID\n const fiberRootsByRenderer = new Map();\n // Renderer registry (closure-scoped so inject() does not depend on \\`this\\`)\n const renderers = new Map();\n\n // Install our hook\n window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {\n // Renderer registry (same Map instance as the closure variable)\n renderers,\n\n // Indicate we support React Fiber architecture\n supportsFiber: true,\n\n // Called by React when a renderer initializes\n inject(renderer) {\n const id = renderers.size + 1;\n renderers.set(id, renderer);\n fiberRootsByRenderer.set(id, new Set());\n\n ${\n verbose\n ? `\n console.log('[OSDK DevTools] React renderer injected:', {\n id,\n version: renderer.version,\n package: renderer.rendererPackageName\n });\n `\n : \"\"\n }\n\n return id;\n },\n\n // Called by React after each commit phase\n onCommitFiberRoot(rendererID, root, priorityLevel) {\n const roots = fiberRootsByRenderer.get(rendererID);\n if (roots) {\n roots.add(root);\n }\n },\n\n // Called by React when a fiber unmounts\n onCommitFiberUnmount(rendererID, fiber) {\n // Optional: track unmounts if needed for GC\n },\n\n // Custom method: Get roots for specific renderer\n getFiberRoots(rendererID) {\n return fiberRootsByRenderer.get(rendererID) || new Set();\n },\n\n // Custom method: Get all roots across all renderers\n getAllFiberRoots() {\n const allRoots = new Set();\n for (const roots of fiberRootsByRenderer.values()) {\n for (const root of roots) {\n allRoots.add(root);\n }\n }\n return allRoots;\n }\n };\n\n ${\n verbose\n ? `console.log('[OSDK DevTools] Hook installed successfully via Vite plugin');`\n : \"\"\n }\n })();\n</script>`;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASA,8BAA8BA,CAC5CC,OAAgB,GAAG,KAAK,EAChB;EACR,OAAO;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QACQA,OAAO,GACH,kFAAkF,GAClF,EAAE;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAEUA,OAAO,GACH;AACd;AACA;AACA;AACA;AACA;AACA,SAAS,GACK,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAEMA,OAAO,GACH,6EAA6E,GAC7E,EAAE;AACZ;AACA,UACU;AACV","ignoreList":[]}
@@ -14,11 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { dirname, resolve as resolvePath } from "node:path";
18
- import { fileURLToPath } from "node:url";
17
+ import { resolve as resolvePath } from "node:path";
19
18
  import { PLUGIN_NAME } from "./constants.js";
20
19
  import { generateHookInstallationScript } from "./hookInstaller.js";
21
- const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const __dirname = import.meta.dirname;
22
21
  const CSS_PATH = resolvePath(__dirname, "../styles.css");
23
22
  export function osdkDevTools(options = {}) {
24
23
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["dirname","resolve","resolvePath","fileURLToPath","PLUGIN_NAME","generateHookInstallationScript","__dirname","import","meta","url","CSS_PATH","osdkDevTools","options","enabled","process","env","NODE_ENV","verbose","injectCSS","name","enforce","apply","config","command","mode","VITEST","transformIndexHtml","order","handler","html","hookScript","cssTag","injection","transformed","replace","console","log"],"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 { dirname, resolve as resolvePath } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Plugin } from \"vite\";\nimport { PLUGIN_NAME } from \"./constants.js\";\nimport { generateHookInstallationScript } from \"./hookInstaller.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst CSS_PATH = resolvePath(__dirname, \"../styles.css\");\n\nexport interface OsdkDevToolsOptions {\n /**\n * Enable devtools.\n * Default: true in development, false in production\n */\n enabled?: boolean;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n\n /**\n * Automatically inject CSS.\n * Default: true\n */\n injectCSS?: boolean;\n}\n\nexport function osdkDevTools(options: OsdkDevToolsOptions = {}): Plugin {\n const {\n enabled = process.env.NODE_ENV !== \"production\",\n verbose = false,\n injectCSS = true,\n } = options;\n\n return {\n name: PLUGIN_NAME,\n\n enforce: \"pre\",\n\n apply(config, { command }) {\n if (config.mode === \"production\") {\n return false;\n }\n\n if (process.env.VITEST) {\n return false;\n }\n\n if (!enabled) {\n return false;\n }\n\n return command === \"serve\";\n },\n\n transformIndexHtml: {\n order: \"pre\",\n\n handler(html) {\n if (!enabled) return html;\n\n const hookScript = generateHookInstallationScript(verbose);\n\n const registerScript =\n `\\n <script type=\"module\">import '@osdk/react-devtools';</script>`;\n\n let cssTag = \"\";\n if (injectCSS) {\n cssTag = `\\n <link rel=\"stylesheet\" href=\"/@fs${CSS_PATH}\" />`;\n }\n\n const injection = `${hookScript}${registerScript}${cssTag}\\n`;\n let transformed = html.replace(\"</head>\", `${injection}</head>`);\n\n if (transformed === html) {\n transformed = html.replace(\"</body>\", `${injection}</body>`);\n }\n\n if (transformed !== html) {\n if (verbose) {\n // eslint-disable-next-line no-console\n console.log(`[${PLUGIN_NAME}] Injected devtools into HTML`);\n }\n } else if (verbose) {\n // eslint-disable-next-line no-console\n console.log(\n `[${PLUGIN_NAME}] Warning: Could not find </head> or </body> tag for injection`,\n );\n }\n\n return transformed;\n },\n },\n };\n}\n\n// Default export for convenience\nexport default osdkDevTools;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,EAAEC,OAAO,IAAIC,WAAW,QAAQ,WAAW;AAC3D,SAASC,aAAa,QAAQ,UAAU;AAExC,SAASC,WAAW,QAAQ,gBAAgB;AAC5C,SAASC,8BAA8B,QAAQ,oBAAoB;AAEnE,MAAMC,SAAS,GAAGN,OAAO,CAACG,aAAa,CAACI,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC,CAAC;AACzD,MAAMC,QAAQ,GAAGR,WAAW,CAACI,SAAS,EAAE,eAAe,CAAC;AAsBxD,OAAO,SAASK,YAAYA,CAACC,OAA4B,GAAG,CAAC,CAAC,EAAU;EACtE,MAAM;IACJC,OAAO,GAAGC,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY;IAC/CC,OAAO,GAAG,KAAK;IACfC,SAAS,GAAG;EACd,CAAC,GAAGN,OAAO;EAEX,OAAO;IACLO,IAAI,EAAEf,WAAW;IAEjBgB,OAAO,EAAE,KAAK;IAEdC,KAAKA,CAACC,MAAM,EAAE;MAAEC;IAAQ,CAAC,EAAE;MACzB,IAAID,MAAM,CAACE,IAAI,KAAK,YAAY,EAAE;QAChC,OAAO,KAAK;MACd;MAEA,IAAIV,OAAO,CAACC,GAAG,CAACU,MAAM,EAAE;QACtB,OAAO,KAAK;MACd;MAEA,IAAI,CAACZ,OAAO,EAAE;QACZ,OAAO,KAAK;MACd;MAEA,OAAOU,OAAO,KAAK,OAAO;IAC5B,CAAC;IAEDG,kBAAkB,EAAE;MAClBC,KAAK,EAAE,KAAK;MAEZC,OAAOA,CAACC,IAAI,EAAE;QACZ,IAAI,CAAChB,OAAO,EAAE,OAAOgB,IAAI;QAEzB,MAAMC,UAAU,GAAGzB,8BAA8B,CAACY,OAAO,CAAC;QAK1D,IAAIc,MAAM,GAAG,EAAE;QACf,IAAIb,SAAS,EAAE;UACba,MAAM,GAAG,wCAAwCrB,QAAQ,MAAM;QACjE;QAEA,MAAMsB,SAAS,GAAG,GAAGF,UAAU,GAP7B,mEAAmE,GAOlBC,MAAM,IAAI;QAC7D,IAAIE,WAAW,GAAGJ,IAAI,CAACK,OAAO,CAAC,SAAS,EAAE,GAAGF,SAAS,SAAS,CAAC;QAEhE,IAAIC,WAAW,KAAKJ,IAAI,EAAE;UACxBI,WAAW,GAAGJ,IAAI,CAACK,OAAO,CAAC,SAAS,EAAE,GAAGF,SAAS,SAAS,CAAC;QAC9D;QAEA,IAAIC,WAAW,KAAKJ,IAAI,EAAE;UACxB,IAAIZ,OAAO,EAAE;YACX;YACAkB,OAAO,CAACC,GAAG,CAAC,IAAIhC,WAAW,+BAA+B,CAAC;UAC7D;QACF,CAAC,MAAM,IAAIa,OAAO,EAAE;UAClB;UACAkB,OAAO,CAACC,GAAG,CACT,IAAIhC,WAAW,gEACjB,CAAC;QACH;QAEA,OAAO6B,WAAW;MACpB;IACF;EACF,CAAC;AACH;;AAEA;AACA,eAAetB,YAAY","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["resolve","resolvePath","PLUGIN_NAME","generateHookInstallationScript","__dirname","import","meta","dirname","CSS_PATH","osdkDevTools","options","enabled","process","env","NODE_ENV","verbose","injectCSS","name","enforce","apply","config","command","mode","VITEST","transformIndexHtml","order","handler","html","hookScript","cssTag","injection","transformed","replace","console","log"],"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 { dirname, resolve as resolvePath } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type { Plugin } from \"vite\";\n\nimport { PLUGIN_NAME } from \"./constants.js\";\nimport { generateHookInstallationScript } from \"./hookInstaller.js\";\n\nconst __dirname = import.meta.dirname;\nconst CSS_PATH = resolvePath(__dirname, \"../styles.css\");\n\nexport interface OsdkDevToolsOptions {\n /**\n * Enable devtools.\n * Default: true in development, false in production\n */\n enabled?: boolean;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n\n /**\n * Automatically inject CSS.\n * Default: true\n */\n injectCSS?: boolean;\n}\n\nexport function osdkDevTools(options: OsdkDevToolsOptions = {}): Plugin {\n const {\n enabled = process.env.NODE_ENV !== \"production\",\n verbose = false,\n injectCSS = true,\n } = options;\n\n return {\n name: PLUGIN_NAME,\n\n enforce: \"pre\",\n\n apply(config, { command }) {\n if (config.mode === \"production\") {\n return false;\n }\n\n if (process.env.VITEST) {\n return false;\n }\n\n if (!enabled) {\n return false;\n }\n\n return command === \"serve\";\n },\n\n transformIndexHtml: {\n order: \"pre\",\n\n handler(html) {\n if (!enabled) return html;\n\n const hookScript = generateHookInstallationScript(verbose);\n\n const registerScript = `\\n <script type=\"module\">import '@osdk/react-devtools';</script>`;\n\n let cssTag = \"\";\n if (injectCSS) {\n cssTag = `\\n <link rel=\"stylesheet\" href=\"/@fs${CSS_PATH}\" />`;\n }\n\n const injection = `${hookScript}${registerScript}${cssTag}\\n`;\n let transformed = html.replace(\"</head>\", `${injection}</head>`);\n\n if (transformed === html) {\n transformed = html.replace(\"</body>\", `${injection}</body>`);\n }\n\n if (transformed !== html) {\n if (verbose) {\n // eslint-disable-next-line no-console\n console.log(`[${PLUGIN_NAME}] Injected devtools into HTML`);\n }\n } else if (verbose) {\n // eslint-disable-next-line no-console\n console.log(\n `[${PLUGIN_NAME}] Warning: Could not find </head> or </body> tag for injection`\n );\n }\n\n return transformed;\n },\n },\n };\n}\n\n// Default export for convenience\nexport default osdkDevTools;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAkBA,OAAO,IAAIC,WAAW,QAAQ,WAAW;AAK3D,SAASC,WAAW,QAAQ,gBAAgB;AAC5C,SAASC,8BAA8B,QAAQ,oBAAoB;AAEnE,MAAMC,SAAS,GAAGC,MAAM,CAACC,IAAI,CAACC,OAAO;AACrC,MAAMC,QAAQ,GAAGP,WAAW,CAACG,SAAS,EAAE,eAAe,CAAC;AAsBxD,OAAO,SAASK,YAAYA,CAACC,OAA4B,GAAG,CAAC,CAAC,EAAU;EACtE,MAAM;IACJC,OAAO,GAAGC,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY;IAC/CC,OAAO,GAAG,KAAK;IACfC,SAAS,GAAG;EACd,CAAC,GAAGN,OAAO;EAEX,OAAO;IACLO,IAAI,EAAEf,WAAW;IAEjBgB,OAAO,EAAE,KAAK;IAEdC,KAAKA,CAACC,MAAM,EAAE;MAAEC;IAAQ,CAAC,EAAE;MACzB,IAAID,MAAM,CAACE,IAAI,KAAK,YAAY,EAAE;QAChC,OAAO,KAAK;MACd;MAEA,IAAIV,OAAO,CAACC,GAAG,CAACU,MAAM,EAAE;QACtB,OAAO,KAAK;MACd;MAEA,IAAI,CAACZ,OAAO,EAAE;QACZ,OAAO,KAAK;MACd;MAEA,OAAOU,OAAO,KAAK,OAAO;IAC5B,CAAC;IAEDG,kBAAkB,EAAE;MAClBC,KAAK,EAAE,KAAK;MAEZC,OAAOA,CAACC,IAAI,EAAE;QACZ,IAAI,CAAChB,OAAO,EAAE,OAAOgB,IAAI;QAEzB,MAAMC,UAAU,GAAGzB,8BAA8B,CAACY,OAAO,CAAC;QAI1D,IAAIc,MAAM,GAAG,EAAE;QACf,IAAIb,SAAS,EAAE;UACba,MAAM,GAAG,wCAAwCrB,QAAQ,MAAM;QACjE;QAEA,MAAMsB,SAAS,GAAG,GAAGF,UAAU,GAPR,mEAAmE,GAOvCC,MAAM,IAAI;QAC7D,IAAIE,WAAW,GAAGJ,IAAI,CAACK,OAAO,CAAC,SAAS,EAAE,GAAGF,SAAS,SAAS,CAAC;QAEhE,IAAIC,WAAW,KAAKJ,IAAI,EAAE;UACxBI,WAAW,GAAGJ,IAAI,CAACK,OAAO,CAAC,SAAS,EAAE,GAAGF,SAAS,SAAS,CAAC;QAC9D;QAEA,IAAIC,WAAW,KAAKJ,IAAI,EAAE;UACxB,IAAIZ,OAAO,EAAE;YACX;YACAkB,OAAO,CAACC,GAAG,CAAC,IAAIhC,WAAW,+BAA+B,CAAC;UAC7D;QACF,CAAC,MAAM,IAAIa,OAAO,EAAE;UAClB;UACAkB,OAAO,CAACC,GAAG,CACT,IAAIhC,WAAW,gEACjB,CAAC;QACH;QAEA,OAAO6B,WAAW;MACpB;IACF;EACF,CAAC;AACH;;AAEA;AACA,eAAetB,YAAY","ignoreList":[]}
@@ -1 +1 @@
1
- {"mappings":"AAgBA,cAAc,eAAe,OAAQ;AAErC,cAAc,oBAAoB,yBAA0B;AAE5D,OAAO,cAAMA,iBAAiB,QAAQ","names":["DevToolsContext: Context<MonitorStore | null>"],"sources":["../../src/DevToolsContext.ts"],"version":3,"file":"DevToolsContext.d.ts"}
1
+ {"mappings":"AAgBA,cAAc,eAAe,OAAQ;AAGrC,cAAc,oBAAoB,yBAA0B;AAE5D,OAAO,cAAMA,iBAAiB,QAAQ","names":["DevToolsContext: Context<MonitorStore | null>"],"sources":["../../src/DevToolsContext.ts"],"version":3,"file":"DevToolsContext.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAC1B,cAAc,uBAAuB,mBAAoB;AAOzD,iBAAiB,mBAAmB;CAClC,SAAS;AACV;AAED,OAAO,cAAMA,eAAe,MAAM,GAAG","names":["ActionMetrics: React.FC<ActionMetricsProps>"],"sources":["../../../src/components/ActionMetrics.tsx"],"version":3,"file":"ActionMetrics.d.ts"}
1
+ {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAE1B,cAAc,uBAAuB,mBAAoB;AAQzD,iBAAiB,mBAAmB;CAClC,SAAS;AACV;AAED,OAAO,cAAMA,eAAe,MAAM,GAAG","names":["ActionMetrics: React.FC<ActionMetricsProps>"],"sources":["../../../src/components/ActionMetrics.tsx"],"version":3,"file":"ActionMetrics.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAsBA,OAAO,WAAW,OAAQ;AAO1B,cAAc,oBAAoB,0BAA2B;UA+BnD,iBAAiB;CACzB,cAAc;CACd;CACA;CACA,kBAAkBA;AACnB;AAED,OAAO,cAAMC,aAAa,MAAM,GAAG","names":["id: string | undefined","BubbleChart: React.FC<BubbleChartProps>"],"sources":["../../../src/components/BubbleChart.tsx"],"version":3,"file":"BubbleChart.d.ts"}
1
+ {"mappings":"AAsBA,OAAO,WAAW,OAAQ;AAQ1B,cAAc,oBAAoB,0BAA2B;UAgCnD,iBAAiB;CACzB,cAAc;CACd;CACA;CACA,kBAAkBA;AACnB;AAED,OAAO,cAAMC,aAAa,MAAM,GAAG","names":["id: string | undefined","BubbleChart: React.FC<BubbleChartProps>"],"sources":["../../../src/components/BubbleChart.tsx"],"version":3,"file":"BubbleChart.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AA2BA,OAAO,WAAkC,OAAQ;AAEjD,cAAc,oBAAoB,0BAA2B;AAkD7D,iBAAiB,uBAAuB;CACtC,cAAc;AACf;AAgBD,OAAO,cAAMA,mBAAmB,MAAM,GAAG","names":["CacheInspectorTab: React.FC<CacheInspectorTabProps>"],"sources":["../../../src/components/CacheInspectorTab.tsx"],"version":3,"file":"CacheInspectorTab.d.ts"}
1
+ {"mappings":"AA2BA,OAAO,WAAkC,OAAQ;AAGjD,cAAc,oBAAoB,0BAA2B;AAmD7D,iBAAiB,uBAAuB;CACtC,cAAc;AACf;AAgBD,OAAO,cAAMA,mBAAmB,MAAM,GAAG","names":["CacheInspectorTab: React.FC<CacheInspectorTabProps>"],"sources":["../../../src/components/CacheInspectorTab.tsx"],"version":3,"file":"CacheInspectorTab.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAC1B,cAAc,uBAAuB,mBAAoB;AAOzD,iBAAiB,kBAAkB;CACjC,SAAS;AACV;AAED,OAAO,cAAMA,cAAc,MAAM,GAAG","names":["CacheMetrics: React.FC<CacheMetricsProps>"],"sources":["../../../src/components/CacheMetrics.tsx"],"version":3,"file":"CacheMetrics.d.ts"}
1
+ {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAE1B,cAAc,uBAAuB,mBAAoB;AAQzD,iBAAiB,kBAAkB;CACjC,SAAS;AACV;AAED,OAAO,cAAMA,cAAc,MAAM,GAAG","names":["CacheMetrics: React.FC<CacheMetricsProps>"],"sources":["../../../src/components/CacheMetrics.tsx"],"version":3,"file":"CacheMetrics.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AACxC,cAAc,oBAAoB,0BAA2B;AAC7D,cAAc,4BAA4B,oCAAqC;AAG/E,cAAc,aAAa,iBAAkB;AAG7C,iBAAiB,mBAAmB;CAClC;CACA,UAAU;CACV,cAAcA;CACd,eAAe;CACf,QAAQ,MAAM;CACd,SAAS;AACV;AAED,OAAO,cAAMC,eAAe,MAAM,GAAG","names":["ms: number","ComponentCard: React.FC<ComponentCardProps>"],"sources":["../../../src/components/ComponentCard.tsx"],"version":3,"file":"ComponentCard.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AAExC,cAAc,oBAAoB,0BAA2B;AAC7D,cAAc,4BAA4B,oCAAqC;AAE/E,cAAc,aAAa,iBAAkB;AAK7C,iBAAiB,mBAAmB;CAClC;CACA,UAAU;CACV,cAAcA;CACd,eAAe;CACf,QAAQ,MAAM;CACd,SAAS;AACV;AAED,OAAO,cAAMC,eAAe,MAAM,GAAG","names":["ms: number","ComponentCard: React.FC<ComponentCardProps>"],"sources":["../../../src/components/ComponentCard.tsx"],"version":3,"file":"ComponentCard.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAwB,OAAQ;AAOvC,cAAc,oBAAoB,0BAA2B;AAM7D,iBAAiB,gBAAgB;CAC/B,cAAc;AACf;AAED,OAAO,cAAMA,YAAY,MAAM,GAAG","names":["ComputeTab: React.FC<ComputeTabProps>"],"sources":["../../../src/components/ComputeTab.tsx"],"version":3,"file":"ComputeTab.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAwB,OAAQ;AAQvC,cAAc,oBAAoB,0BAA2B;AAO7D,iBAAiB,gBAAgB;CAC/B,cAAc;AACf;AAED,OAAO,cAAMA,YAAY,MAAM,GAAG","names":["ComputeTab: React.FC<ComputeTabProps>"],"sources":["../../../src/components/ComputeTab.tsx"],"version":3,"file":"ComputeTab.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAA8C,OAAQ;UAGnD,uBAAuB;CAC/B,UAAU,MAAM;CAChB;AACD;AAED,OAAO,cAAMA,mBAAmB,MAAM,GAAG","names":["CopyableCodeBlock: React.FC<CopyableCodeBlockProps>"],"sources":["../../../src/components/CopyableCodeBlock.tsx"],"version":3,"file":"CopyableCodeBlock.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAA8C,OAAQ;UAInD,uBAAuB;CAC/B,UAAU,MAAM;CAChB;AACD;AAED,OAAO,cAAMA,mBAAmB,MAAM,GAAG","names":["CopyableCodeBlock: React.FC<CopyableCodeBlockProps>"],"sources":["../../../src/components/CopyableCodeBlock.tsx"],"version":3,"file":"CopyableCodeBlock.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAuD,OAAQ;AAItE,cAAc,oBAAoB,0BAA2B;AAY7D,iBAAiB,kBAAkB;CACjC,cAAc;AACf;AAqJD,OAAO,cAAMA,cAAc,MAAM,GAAG","names":["DebuggingTab: React.FC<DebuggingTabProps>"],"sources":["../../../src/components/DebuggingTab.tsx"],"version":3,"file":"DebuggingTab.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAuD,OAAQ;AAKtE,cAAc,oBAAoB,0BAA2B;AAa7D,iBAAiB,kBAAkB;CACjC,cAAc;AACf;AAoJD,OAAO,cAAMA,cAAc,MAAM,GAAG","names":["DebuggingTab: React.FC<DebuggingTabProps>"],"sources":["../../../src/components/DebuggingTab.tsx"],"version":3,"file":"DebuggingTab.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAwB,OAAQ;AAEvC,cAAc,oBAAoB,0BAA2B;AAC7D,cAAc,4BAA4B,oCAAqC;AA6C/E,iBAAiB,aAAa;CAC5B,SAAS;CACT,cAAcA;CACd,eAAe;AAChB;AASD,OAAO,cAAMC,SAAS,MAAM,GAAG","names":["ms: number","HookRow: React.FC<HookRowProps>"],"sources":["../../../src/components/HookRow.tsx"],"version":3,"file":"HookRow.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAwB,OAAQ;AAGvC,cAAc,oBAAoB,0BAA2B;AAC7D,cAAc,4BAA4B,oCAAqC;AA8C/E,iBAAiB,aAAa;CAC5B,SAAS;CACT,cAAcA;CACd,eAAe;AAChB;AASD,OAAO,cAAMC,SAAS,MAAM,GAAG","names":["ms: number","HookRow: React.FC<HookRowProps>"],"sources":["../../../src/components/HookRow.tsx"],"version":3,"file":"HookRow.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AAExC,cAAc,oBAAoB,0BAA2B;UAInD,qBAAqB;CAC7B,cAAc;AACf;AAED,OAAO,cAAMA,iBAAiB,MAAM,GAAG","names":["ImprovementsTab: React.FC<ImprovementsTabProps>"],"sources":["../../../src/components/ImprovementsTab.tsx"],"version":3,"file":"ImprovementsTab.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AAGxC,cAAc,oBAAoB,0BAA2B;UAKnD,qBAAqB;CAC7B,cAAc;AACf;AAED,OAAO,cAAMA,iBAAiB,MAAM,GAAG","names":["ImprovementsTab: React.FC<ImprovementsTabProps>"],"sources":["../../../src/components/ImprovementsTab.tsx"],"version":3,"file":"ImprovementsTab.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAG1B,iBAAiB,8BAA8B;CAC7C;CACA;CACA;CACA;CACA,UAAU,MAAM;CAChB;CACA;CACA;AACD;AAED,OAAO,cAAMA,0BAA0B,MAAM,GAC3C","names":["InspectorSelectionHeader: React.FC<\n InspectorSelectionHeaderProps\n>"],"sources":["../../../src/components/InspectorSelectionHeader.tsx"],"version":3,"file":"InspectorSelectionHeader.d.ts"}
1
+ {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAI1B,iBAAiB,8BAA8B;CAC7C;CACA;CACA;CACA;CACA,UAAU,MAAM;CAChB;CACA;CACA;AACD;AAED,OAAO,cAAMA,0BAA0B,MAAM,GAC3C","names":["InspectorSelectionHeader: React.FC<\n InspectorSelectionHeaderProps\n>"],"sources":["../../../src/components/InspectorSelectionHeader.tsx"],"version":3,"file":"InspectorSelectionHeader.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAiBA,OAAO,WAAiD,OAAQ;AAGhE,cAAc,oBAAoB,2BAA4B;AAC9D,cACE,mBACA,+BACK,0CAA2C;AAClD,cAAc,oBAAoB,0BAA2B;AAY7D,cAAc,yBAAyB,8BAA+B;AA0CtE,iBAAiB,kBAAkB;CACjC,WAAW;CACX,UAAU,WAAW,aAAa;CAClC,cAAc,YAAY;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAED,iBAAiB,cAAc;CAC7B;CACA;CACA;CACA;CACA;CACA,gBAAgB;CAChB;CACA;AACD;KAEI,iBAAiB,eAAe;CAAE,QAAQ;AAAmB;AA2DlE,YAAY,kBACR;CAAE,MAAM;CAA0B,WAAW;AAA0B,IACvE;CAAE,MAAM;CAAa,OAAO,MAAM;AAAiB,IACnD;CACA,MAAM;CACN,UAAUA,MAAM,MAAM,oBAAoB,MAAM;AACjD,IACC;CAAE,MAAM;CAAoB,MAAM;AAAuB,IACzD;CAAE,MAAM;CAAiB,UAAU,kBAAkB;AAAa,IAClE;CACA,MAAM;CACN,cAAc,kBAAkB;AACjC,IACC;CAAE,MAAM;CAAmB;AAAqB,IAChD;CAAE,MAAM;CAAoB;AAAqB,IACjD;CAAE,MAAM;CAAoB;AAAsB,IAClD;CAAE,MAAM;CAAmB;AAAoB,IAC/C;CAAE,MAAM;CAAqB;AAAsB,IACnD;CAAE,MAAM;CAAqB;AAAsB,IACnD;CAAE,MAAM;CAAsB,OAAO;AAAsB,IAC3D;CAAE,MAAM;CAAwB,WAAW;AAAqB,IAChE;CAAE,MAAM;CAAyB;AAAc,IAC/C;CAAE,MAAM;CAAqB;AAAc,IAC3C;CAAE,MAAM;CAAiB;AAA8B,IACvD;CAAE,MAAM;CAAqB;AAAc,IAC3C;CAAE,MAAM;CAAmB;AAAc,IACzC;CAAE,MAAM;CAA0B,WAAW;AAA0B,IACvE;CAAE,MAAM;CAAa;AAAsB,IAC3C;CAAE,MAAM;CAAyB,QAAQ;AAA2B,IACpE;CAAE,MAAM;CAA8B,QAAQ;AAAmB,IACjE;CAAE,MAAM;CAAiC,WAAW;AAAmB,IACvE;CAAE,MAAM;CAA6B,WAAW;AAAmB,IACnE;CAAE,MAAM;AAAsB,IAC9B;CAAE,MAAM;AAAmB,IAC3B;CAAE,MAAM;AAAkB;UAEpB,0BAA0B;CAClC;CACA;CACA;CACA;CACA;CACA;AACD;AAqID,iBAAiB,kBAAkB;CACjC,cAAc;CACd,QAAQ,UAAU;AACnB;AAED,OAAO,cAAMC,cAAc,MAAM,GAAG","names":["prev: Array<MockWithConfig>","InterceptTab: React.FC<InterceptTabProps>"],"sources":["../../../src/components/InterceptTab.tsx"],"version":3,"file":"InterceptTab.d.ts"}
1
+ {"mappings":"AAiBA,OAAO,WAAiD,OAAQ;AAIhE,cAAc,oBAAoB,2BAA4B;AAC9D,cACE,mBACA,+BACK,0CAA2C;AAClD,cAAc,oBAAoB,0BAA2B;AAW7D,cAAc,yBAAyB,8BAA+B;AA4CtE,iBAAiB,kBAAkB;CACjC,WAAW;CACX,UAAU,WAAW,aAAa;CAClC,cAAc,YAAY;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAED,iBAAiB,cAAc;CAC7B;CACA;CACA;CACA;CACA;CACA,gBAAgB;CAChB;CACA;AACD;KAEI,iBAAiB,eAAe;CAAE,QAAQ;AAAmB;AA2DlE,YAAY,kBACR;CAAE,MAAM;CAA0B,WAAW;AAA0B,IACvE;CAAE,MAAM;CAAa,OAAO,MAAM;AAAiB,IACnD;CACE,MAAM;CACN,UAAUA,MAAM,MAAM,oBAAoB,MAAM;AACjD,IACD;CAAE,MAAM;CAAoB,MAAM;AAAuB,IACzD;CAAE,MAAM;CAAiB,UAAU,kBAAkB;AAAa,IAClE;CACE,MAAM;CACN,cAAc,kBAAkB;AACjC,IACD;CAAE,MAAM;CAAmB;AAAqB,IAChD;CAAE,MAAM;CAAoB;AAAqB,IACjD;CAAE,MAAM;CAAoB;AAAsB,IAClD;CAAE,MAAM;CAAmB;AAAoB,IAC/C;CAAE,MAAM;CAAqB;AAAsB,IACnD;CAAE,MAAM;CAAqB;AAAsB,IACnD;CAAE,MAAM;CAAsB,OAAO;AAAsB,IAC3D;CAAE,MAAM;CAAwB,WAAW;AAAqB,IAChE;CAAE,MAAM;CAAyB;AAAc,IAC/C;CAAE,MAAM;CAAqB;AAAc,IAC3C;CAAE,MAAM;CAAiB;AAA8B,IACvD;CAAE,MAAM;CAAqB;AAAc,IAC3C;CAAE,MAAM;CAAmB;AAAc,IACzC;CAAE,MAAM;CAA0B,WAAW;AAA0B,IACvE;CAAE,MAAM;CAAa;AAAsB,IAC3C;CAAE,MAAM;CAAyB,QAAQ;AAA2B,IACpE;CAAE,MAAM;CAA8B,QAAQ;AAAmB,IACjE;CAAE,MAAM;CAAiC,WAAW;AAAmB,IACvE;CAAE,MAAM;CAA6B,WAAW;AAAmB,IACnE;CAAE,MAAM;AAAsB,IAC9B;CAAE,MAAM;AAAmB,IAC3B;CAAE,MAAM;AAAkB;UAEpB,0BAA0B;CAClC;CACA;CACA;CACA;CACA;CACA;AACD;AAqID,iBAAiB,kBAAkB;CACjC,cAAc;CACd,QAAQ,UAAU;AACnB;AAED,OAAO,cAAMC,cAAc,MAAM,GAAG","names":["prev: Array<MockWithConfig>","InterceptTab: React.FC<InterceptTabProps>"],"sources":["../../../src/components/InterceptTab.tsx"],"version":3,"file":"InterceptTab.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AAIxC,cAAc,aAAa,iBAAkB;AAE7C,iBAAiB,eAAe;CAC9B,OAAO;CACP,oBAAoBA;CACpB,QAAQ,MAAM;AACf;AAoBD,OAAO,cAAMC,WAAW,MAAM,GAAG","names":["componentId: string","IssueCard: React.FC<IssueCardProps>"],"sources":["../../../src/components/IssueCard.tsx"],"version":3,"file":"IssueCard.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AAIxC,cAAc,aAAa,iBAAkB;AAI7C,iBAAiB,eAAe;CAC9B,OAAO;CACP,oBAAoBA;CACpB,QAAQ,MAAM;AACf;AAoBD,OAAO,cAAMC,WAAW,MAAM,GAAG","names":["componentId: string","IssueCard: React.FC<IssueCardProps>"],"sources":["../../../src/components/IssueCard.tsx"],"version":3,"file":"IssueCard.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AACxC,cAAc,uBAAuB,6BAA8B;AAInE,iBAAiB,kBAAkB;CACjC,OAAO;CACP,QAAQ,MAAM;AACf;AAqCD,OAAO,cAAMA,cAAc,MAAM,GAAG","names":["LogEntryCard: React.FC<LogEntryCardProps>"],"sources":["../../../src/components/LogEntryCard.tsx"],"version":3,"file":"LogEntryCard.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAyB,OAAQ;AAExC,cAAc,uBAAuB,6BAA8B;AAKnE,iBAAiB,kBAAkB;CACjC,OAAO;CACP,QAAQ,MAAM;AACf;AAqCD,OAAO,cAAMA,cAAc,MAAM,GAAG","names":["LogEntryCard: React.FC<LogEntryCardProps>"],"sources":["../../../src/components/LogEntryCard.tsx"],"version":3,"file":"LogEntryCard.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AA2BA,OAAO,WAAW,OAAQ;AAC1B,cAAc,oBAAoB,2BAA4B;AAC9D,cAAc,iBAAiB,yBAAyB,mBAAoB;AAE5E,cAAc,yBAAyB,8BAA+B;KAEjE,iBAAiB,eAAe;CAAE,QAAQ;AAAmB;UAExD,gBAAgB;CACxB,mBAAmB;CACnB,aAAa;CACb,UAAU,kBAAkB;CAC5B,cAAc,kBAAkB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA,UAAU,MAAM,SAAS;CACzB,mBAAmB,kBAAkB;CACrC;CACA;AACD;AAED,OAAO,cAAMA,YAAY,MAAM,GAAG;AA8MlC,OAAO,iBAAS,qBAAqBC,WAAW,oBAAoB;CAClE;CACA;CACA,MACI,UACA,YACA,SACA,SACA,aACA;CACJ;AACD;AAiDD,OAAO,iBAAS,2BAA2BA,WAAW,oBAAoB;CACxE;CACA;CACA,cAAc;CACd;CACA;AACD;AA6BD,OAAO,iBAAS,yBACdA,WAAW,mBACXC,oBACC;CACD,MAAM;CACN;AACD,IAAG;CACF,MAAM;CACN;CACA;AACD,IAAG;CACF,MAAM;CACN;AACD;AAiBD,iBAAiB,cAAc;CAC7B,MAAM,eAAe;EAAE,QAAQ;CAAmB;CAClD;CACA;CACA;AACD;AAED,OAAO,cAAMC,UAAU,MAAM,GAAG","names":["MockEditor: React.FC<MockEditorProps>","primitive: SelectedPrimitive","mockData: unknown","MockItem: React.FC<MockItemProps>"],"sources":["../../../src/components/MockEditor.tsx"],"version":3,"file":"MockEditor.d.ts"}
1
+ {"mappings":"AA2BA,OAAO,WAAW,OAAQ;AAE1B,cAAc,oBAAoB,2BAA4B;AAC9D,cAAc,iBAAiB,yBAAyB,mBAAoB;AAC5E,cAAc,yBAAyB,8BAA+B;KAIjE,iBAAiB,eAAe;CAAE,QAAQ;AAAmB;UAExD,gBAAgB;CACxB,mBAAmB;CACnB,aAAa;CACb,UAAU,kBAAkB;CAC5B,cAAc,kBAAkB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA,UAAU,MAAM,SAAS;CACzB,mBAAmB,kBAAkB;CACrC;CACA;AACD;AAED,OAAO,cAAMA,YAAY,MAAM,GAAG;AAkNlC,OAAO,iBAAS,qBAAqBC,WAAW,oBAAoB;CAClE;CACA;CACA,MACI,UACA,YACA,SACA,SACA,aACA;CACJ;AACD;AAiDD,OAAO,iBAAS,2BAA2BA,WAAW,oBAAoB;CACxE;CACA;CACA,cAAc;CACd;CACA;AACD;AA6BD,OAAO,iBAAS,yBACdA,WAAW,mBACXC,oBAEE;CACE,MAAM;CACN;AACD,IACD;CACE,MAAM;CACN;CACA;AACD,IACD;CACE,MAAM;CACN;AACD;AAkBL,iBAAiB,cAAc;CAC7B,MAAM,eAAe;EAAE,QAAQ;CAAmB;CAClD;CACA;CACA;AACD;AAED,OAAO,cAAMC,UAAU,MAAM,GAAG","names":["MockEditor: React.FC<MockEditorProps>","primitive: SelectedPrimitive","mockData: unknown","MockItem: React.FC<MockItemProps>"],"sources":["../../../src/components/MockEditor.tsx"],"version":3,"file":"MockEditor.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAgBA,OAAO,WAAW,OAAQ;AAG1B,iBAAiB,0BAA0B;CACzC,UAAU,MAAM;CAChB,WAAWA,OAAO,OAAOC,WAAW,MAAM;AAC3C;UAES,0BAA0B;CAClC;CACA,OAAO;AACR;AAED,OAAO,cAAM,6BAA6B,MAAM,UAC9C,2BACA,2BACA;CACA,YAAYC,OAAO;CAKnB,OAAO,yBAAyBF,OAAO,QAAQ;CAI/C,kBAAkBA,OAAO,OAAOC,WAAW,MAAM;CAQjD,UAAU,MAAM;AA+BjB","names":["error: Error","errorInfo: React.ErrorInfo","props: MonitorErrorBoundaryProps"],"sources":["../../../src/components/MonitorErrorBoundary.tsx"],"version":3,"file":"MonitorErrorBoundary.d.ts"}
1
+ {"mappings":"AAgBA,OAAO,WAAW,OAAQ;AAI1B,iBAAiB,0BAA0B;CACzC,UAAU,MAAM;CAChB,WAAWA,OAAO,OAAOC,WAAW,MAAM;AAC3C;UAES,0BAA0B;CAClC;CACA,OAAO;AACR;AAED,OAAO,cAAM,6BAA6B,MAAM,UAC9C,2BACA,2BACA;CACA,YAAYC,OAAO;CAKnB,OAAO,yBAAyBF,OAAO,QAAQ;CAI/C,kBAAkBA,OAAO,OAAOC,WAAW,MAAM;CAQjD,UAAU,MAAM;AA6BjB","names":["error: Error","errorInfo: React.ErrorInfo","props: MonitorErrorBoundaryProps"],"sources":["../../../src/components/MonitorErrorBoundary.tsx"],"version":3,"file":"MonitorErrorBoundary.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAkBA,OAAO,WAAuD,OAAQ;AAQtE,cAAc,oBAAoB,0BAA2B;AA6D7D,iBAAiB,qBAAqB;;CAEpC,cAAc;AACf;AAED,OAAO,cAAMA,iBAAiB,MAAM,GAAG;AAmevC,OAAO,cAAMC,qBAAqB,MAAM,GAAG","names":["MonitoringPanel: React.FC<MonitoringPanelProps>","SafeMonitoringPanel: React.FC<MonitoringPanelProps>"],"sources":["../../../src/components/MonitoringPanel.tsx"],"version":3,"file":"MonitoringPanel.d.ts"}
1
+ {"mappings":"AAkBA,OAAO,WAAuD,OAAQ;AAStE,cAAc,oBAAoB,0BAA2B;AAgE7D,iBAAiB,qBAAqB;;CAEpC,cAAc;AACf;AAED,OAAO,cAAMA,iBAAiB,MAAM,GAAG;AAwfvC,OAAO,cAAMC,qBAAqB,MAAM,GAAG","names":["MonitoringPanel: React.FC<MonitoringPanelProps>","SafeMonitoringPanel: React.FC<MonitoringPanelProps>"],"sources":["../../../src/components/MonitoringPanel.tsx"],"version":3,"file":"MonitoringPanel.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAE1B,cAAc,yBAAyB,iCAAkC;AAGzE,iBAAiB,0BAA0B;CACzC;CACA,mBAAmB;AACpB;AAED,OAAO,cAAMA,sBAAsB,MAAM,GAAG","names":["ObjectLoadingMetrics: React.FC<ObjectLoadingMetricsProps>"],"sources":["../../../src/components/ObjectLoadingMetrics.tsx"],"version":3,"file":"ObjectLoadingMetrics.d.ts"}
1
+ {"mappings":"AAiBA,OAAO,WAAW,OAAQ;AAG1B,cAAc,yBAAyB,iCAAkC;AAIzE,iBAAiB,0BAA0B;CACzC;CACA,mBAAmB;AACpB;AAED,OAAO,cAAMA,sBAAsB,MAAM,GAAG","names":["ObjectLoadingMetrics: React.FC<ObjectLoadingMetricsProps>"],"sources":["../../../src/components/ObjectLoadingMetrics.tsx"],"version":3,"file":"ObjectLoadingMetrics.d.ts"}
@@ -1 +1 @@
1
- {"mappings":"AAqBA,OAAO,WAAW,OAAQ;AAC1B,cAAc,oBAAoB,0BAA2B;AAE7D,iBAAiB,0BAA0B;CACzC,cAAc;CACd,UAAU,MAAM;CAChB,WACI,MAAM,cACJA,OAAO,OAAOC,sBAAsB,MAAM;AACjD;UAES,0BAA0B;CAClC,OAAO;AACR;AAED,OAAO,cAAM,6BAA6B,MAAM,UAC9C,2BACA,2BACA;CACA,YAAYC,OAAO;CAKnB,OAAO,yBAAyBF,OAAO,QAAQ;CAI/C,kBAAkBA,OAAO,OAAOG,WAAW,MAAM;CAOjD;CAIA,UAAU,MAAM;AAsBjB","names":["error: Error","reset: () => void","props: OsdkAppErrorBoundaryProps","errorInfo: React.ErrorInfo"],"sources":["../../../src/components/OsdkAppErrorBoundary.tsx"],"version":3,"file":"OsdkAppErrorBoundary.d.ts"}
1
+ {"mappings":"AAqBA,OAAO,WAAW,OAAQ;AAE1B,cAAc,oBAAoB,0BAA2B;AAE7D,iBAAiB,0BAA0B;CACzC,cAAc;CACd,UAAU,MAAM;CAChB,WACI,MAAM,cACJA,OAAO,OAAOC,sBAAsB,MAAM;AACjD;UAES,0BAA0B;CAClC,OAAO;AACR;AAED,OAAO,cAAM,6BAA6B,MAAM,UAC9C,2BACA,2BACA;CACA,YAAYC,OAAO;CAKnB,OAAO,yBAAyBF,OAAO,QAAQ;CAI/C,kBAAkBA,OAAO,OAAOG,WAAW,MAAM;CAOjD;CAIA,UAAU,MAAM;AAwBjB","names":["error: Error","reset: () => void","props: OsdkAppErrorBoundaryProps","errorInfo: React.ErrorInfo"],"sources":["../../../src/components/OsdkAppErrorBoundary.tsx"],"version":3,"file":"OsdkAppErrorBoundary.d.ts"}