sparkforensics-server 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/index.js +8 -4
  2. package/package.json +1 -1
  3. package/public/assets/AutoscalingChurn-9Zo6IMGS.js +1 -0
  4. package/public/assets/CacheUtilization-MBDfMsKC.js +1 -0
  5. package/public/assets/CachingOpportunity-Cfw3wAFa.js +1 -0
  6. package/public/assets/ColdStart-BtS12b6_.js +1 -0
  7. package/public/assets/ConfigAudit-DNPV6EQg.js +1 -0
  8. package/public/assets/CoreUsageArea-BObEeenE.js +1 -0
  9. package/public/assets/Dashboard-CC_BXrNy.js +2 -0
  10. package/public/assets/DisclosureContext-Ds0hcZFn.js +1 -0
  11. package/public/assets/DuplicatePlanSubtree-vN3zqRsi.js +1 -0
  12. package/public/assets/ExecutorUtilization-CZObSLIj.js +1 -0
  13. package/public/assets/GcPressure-ByJlLOua.js +1 -0
  14. package/public/assets/IncompleteRun-MzqV4W8y.js +1 -0
  15. package/public/assets/JobFailures-LbMvAwAb.js +1 -0
  16. package/public/assets/MemoryUtilization-DH4jYvJK.js +1 -0
  17. package/public/assets/OverBroadcast-euk6HKg4.js +1 -0
  18. package/public/assets/PartitionHint-DThaMMRT.js +1 -0
  19. package/public/assets/PartitionSizing-yIN-iZzx.js +1 -0
  20. package/public/assets/PlanExplorer-Dd9WPK4S.js +1 -0
  21. package/public/assets/PlanGraphRoute-NV5mCXRm.js +1 -0
  22. package/public/assets/RetryWaste-CXH4D-xH.js +1 -0
  23. package/public/assets/ShuffleIO-CW7U68ph.js +1 -0
  24. package/public/assets/Skew-PL79TppX.js +1 -0
  25. package/public/assets/SlowHost-GBO73hCi.js +1 -0
  26. package/public/assets/SmallFiles-B5cUjEav.js +1 -0
  27. package/public/assets/SpeculationWaste-mxi3jgb0.js +1 -0
  28. package/public/assets/Spill-CH1bNpxL.js +1 -0
  29. package/public/assets/StageFailed-YvxC11ii.js +1 -0
  30. package/public/assets/StageFindingGroup-B1A0nf-e.js +1 -0
  31. package/public/assets/StageHeader-BMNmUy-s.js +1 -0
  32. package/public/assets/StageShape-DO3mQ6NS.js +1 -0
  33. package/public/assets/StageSlowness-SwRxfAEx.js +1 -0
  34. package/public/assets/Straggler-DHLTiBY-.js +1 -0
  35. package/public/assets/TaskFailures-Bj0QxiOc.js +1 -0
  36. package/public/assets/{TinyTask-Be-pvTjJ.js → TinyTask-COUQQ5bQ.js} +1 -1
  37. package/public/assets/UnderBroadcast-RAUbQ6vw.js +1 -0
  38. package/public/assets/{finding-anchor-vVODA_VC.js → finding-anchor-Dl8mIHiU.js} +1 -1
  39. package/public/assets/impact-sort-Eihua9dY.js +1 -0
  40. package/public/assets/index-BcqTLKFp.css +2 -0
  41. package/public/assets/index-DaC8A2FS.js +13 -0
  42. package/public/assets/{parser-worker-jAP0kWvS.js → parser-worker-CfDvPkwF.js} +9 -9
  43. package/public/assets/react-vendor-BAKt3vny.js +9 -0
  44. package/public/assets/select-DkjFHlXR.js +1 -0
  45. package/public/assets/usePagedRows-Bo-aSztx.js +1 -0
  46. package/public/assets/useRecentFiles-Bb4-ukVz.js +11 -0
  47. package/public/assets/useSortMode-lDedD5a3.js +1 -0
  48. package/public/docs/404.html +4 -3
  49. package/public/docs/assets/{app.C5E-wy6e.js → app.yjczoibf.js} +1 -1
  50. package/public/docs/assets/chunks/@localSearchIndexroot.r9imX8Aq.js +1 -0
  51. package/public/docs/assets/chunks/{VPLocalSearchBox.DtyygpbL.js → VPLocalSearchBox.DOBbPfix.js} +1 -1
  52. package/public/docs/assets/chunks/{theme.DQS9-w_Z.js → theme.DFcAl8Ws.js} +2 -2
  53. package/public/docs/assets/contributor-guide_architecture_board-widgets.md.D0Kkk_r5.js +1 -0
  54. package/public/docs/assets/contributor-guide_architecture_board-widgets.md.D0Kkk_r5.lean.js +1 -0
  55. package/public/docs/assets/contributor-guide_architecture_detector-contract.md.caA46z-u.js +1 -0
  56. package/public/docs/assets/{contributor-guide_architecture_detector-contract.md.CsCytCho.lean.js → contributor-guide_architecture_detector-contract.md.caA46z-u.lean.js} +1 -1
  57. package/public/docs/assets/contributor-guide_architecture_drill-down.md.CdtlKHl-.js +1 -0
  58. package/public/docs/assets/contributor-guide_architecture_impact-estimation.md.BNp14LtL.js +1 -0
  59. package/public/docs/assets/contributor-guide_architecture_impact-estimation.md.BNp14LtL.lean.js +1 -0
  60. package/public/docs/assets/contributor-guide_architecture_index.md.B9yZieYL.js +1 -0
  61. package/public/docs/assets/{contributor-guide_architecture_index.md.3TO9ic6w.lean.js → contributor-guide_architecture_index.md.B9yZieYL.lean.js} +1 -1
  62. package/public/docs/assets/contributor-guide_architecture_overview.md.DBGo-bwn.js +1 -0
  63. package/public/docs/assets/contributor-guide_architecture_overview.md.DBGo-bwn.lean.js +1 -0
  64. package/public/docs/assets/contributor-guide_architecture_state-and-history.md.w4lwybdh.js +1 -0
  65. package/public/docs/assets/{contributor-guide_architecture_state-and-history.md.B8Wc_ZTg.lean.js → contributor-guide_architecture_state-and-history.md.w4lwybdh.lean.js} +1 -1
  66. package/public/docs/assets/contributor-guide_architecture_widget-rendering.md.CcvqxnZI.js +1 -0
  67. package/public/docs/assets/{contributor-guide_architecture_widget-rendering.md.DYwFeyjV.lean.js → contributor-guide_architecture_widget-rendering.md.CcvqxnZI.lean.js} +1 -1
  68. package/public/docs/assets/contributor-guide_architecture_worker-protocol.md.CKeFttKj.js +6 -0
  69. package/public/docs/assets/contributor-guide_architecture_worker-protocol.md.CKeFttKj.lean.js +1 -0
  70. package/public/docs/assets/contributor-guide_contributing.md.CQMvGwFt.js +1 -0
  71. package/public/docs/assets/{contributor-guide_contributing.md.B2E9ni79.lean.js → contributor-guide_contributing.md.CQMvGwFt.lean.js} +1 -1
  72. package/public/docs/assets/contributor-guide_development-setup.md.D9bu4j_c.js +15 -0
  73. package/public/docs/assets/contributor-guide_development-setup.md.D9bu4j_c.lean.js +1 -0
  74. package/public/docs/assets/contributor-guide_testing.md.By6XGR9a.js +1 -0
  75. package/public/docs/assets/{contributor-guide_testing.md.Cnn6gz1C.lean.js → contributor-guide_testing.md.By6XGR9a.lean.js} +1 -1
  76. package/public/docs/assets/{style.DSixAiZE.css → style.tmDhD3c8.css} +1 -1
  77. package/public/docs/assets/tuning-reference_anti-patterns.md.D08Uaod7.js +1 -0
  78. package/public/docs/assets/tuning-reference_anti-patterns.md.D08Uaod7.lean.js +1 -0
  79. package/public/docs/assets/tuning-reference_aqe.md.C1Ae6A8u.js +1 -0
  80. package/public/docs/assets/tuning-reference_aqe.md.C1Ae6A8u.lean.js +1 -0
  81. package/public/docs/assets/tuning-reference_bottleneck-broadcast-sizing.md.6wjKuJNE.js +1 -0
  82. package/public/docs/assets/tuning-reference_bottleneck-broadcast-sizing.md.6wjKuJNE.lean.js +1 -0
  83. package/public/docs/assets/tuning-reference_bottleneck-cold-start.md.BVQbsuHP.js +7 -0
  84. package/public/docs/assets/tuning-reference_bottleneck-cold-start.md.BVQbsuHP.lean.js +1 -0
  85. package/public/docs/assets/tuning-reference_bottleneck-duplicate-plan-subtree.md.DtaYnaiF.js +1 -0
  86. package/public/docs/assets/tuning-reference_bottleneck-duplicate-plan-subtree.md.DtaYnaiF.lean.js +1 -0
  87. package/public/docs/assets/{tuning-reference_bottleneck-failures.md.CAsFf3RR.js → tuning-reference_bottleneck-failures.md.Z1Tdmdd3.js} +2 -2
  88. package/public/docs/assets/tuning-reference_bottleneck-failures.md.Z1Tdmdd3.lean.js +1 -0
  89. package/public/docs/assets/tuning-reference_bottleneck-gc.md.BCnXLf1n.js +6 -0
  90. package/public/docs/assets/tuning-reference_bottleneck-gc.md.BCnXLf1n.lean.js +1 -0
  91. package/public/docs/assets/tuning-reference_bottleneck-job-failure-rate.md.CcvQj2g9.js +8 -0
  92. package/public/docs/assets/tuning-reference_bottleneck-job-failure-rate.md.CcvQj2g9.lean.js +1 -0
  93. package/public/docs/assets/tuning-reference_bottleneck-memory-utilization.md.B-C0-8h-.js +7 -0
  94. package/public/docs/assets/tuning-reference_bottleneck-memory-utilization.md.B-C0-8h-.lean.js +1 -0
  95. package/public/docs/assets/tuning-reference_bottleneck-retry-waste.md.DCnhWiqj.js +1 -0
  96. package/public/docs/assets/tuning-reference_bottleneck-retry-waste.md.DCnhWiqj.lean.js +1 -0
  97. package/public/docs/assets/{tuning-reference_bottleneck-shuffle.md.DDMQVOW6.js → tuning-reference_bottleneck-shuffle.md.B5OMJCd3.js} +2 -2
  98. package/public/docs/assets/tuning-reference_bottleneck-shuffle.md.B5OMJCd3.lean.js +1 -0
  99. package/public/docs/assets/{tuning-reference_bottleneck-skew.md.B0MzhWcX.js → tuning-reference_bottleneck-skew.md.Cvo6NQm_.js} +1 -1
  100. package/public/docs/assets/tuning-reference_bottleneck-skew.md.Cvo6NQm_.lean.js +1 -0
  101. package/public/docs/assets/{tuning-reference_bottleneck-slow-host.md.BlIo6UDW.js → tuning-reference_bottleneck-slow-host.md.ja5qr3wq.js} +1 -1
  102. package/public/docs/assets/tuning-reference_bottleneck-slow-host.md.ja5qr3wq.lean.js +1 -0
  103. package/public/docs/assets/tuning-reference_bottleneck-small-files.md.Crjtb0i2.js +5 -0
  104. package/public/docs/assets/tuning-reference_bottleneck-small-files.md.Crjtb0i2.lean.js +1 -0
  105. package/public/docs/assets/tuning-reference_bottleneck-spill.md.Bl8KtSRg.js +6 -0
  106. package/public/docs/assets/tuning-reference_bottleneck-spill.md.Bl8KtSRg.lean.js +1 -0
  107. package/public/docs/assets/tuning-reference_bottleneck-straggler.md.B0VN8reT.js +7 -0
  108. package/public/docs/assets/tuning-reference_bottleneck-straggler.md.B0VN8reT.lean.js +1 -0
  109. package/public/docs/assets/tuning-reference_bottleneck-tiny-tasks.md.DQCftGhu.js +8 -0
  110. package/public/docs/assets/tuning-reference_bottleneck-tiny-tasks.md.DQCftGhu.lean.js +1 -0
  111. package/public/docs/assets/{tuning-reference_bottleneck-utilization.md.DqC_iGkw.js → tuning-reference_bottleneck-utilization.md.BXDl30f9.js} +1 -1
  112. package/public/docs/assets/tuning-reference_bottleneck-utilization.md.BXDl30f9.lean.js +1 -0
  113. package/public/docs/assets/tuning-reference_caching.md.CcaiMn_7.js +1 -0
  114. package/public/docs/assets/tuning-reference_caching.md.CcaiMn_7.lean.js +1 -0
  115. package/public/docs/assets/tuning-reference_cluster-config.md.DbWG1yZq.js +1 -0
  116. package/public/docs/assets/tuning-reference_cluster-config.md.DbWG1yZq.lean.js +1 -0
  117. package/public/docs/assets/tuning-reference_config.md.YUqSpwFB.js +1 -0
  118. package/public/docs/assets/tuning-reference_config.md.YUqSpwFB.lean.js +1 -0
  119. package/public/docs/assets/tuning-reference_data-formats.md.C5DX5xL4.js +1 -0
  120. package/public/docs/assets/tuning-reference_data-formats.md.C5DX5xL4.lean.js +1 -0
  121. package/public/docs/assets/tuning-reference_index.md.ZVIpQ6Dk.js +1 -0
  122. package/public/docs/assets/tuning-reference_index.md.ZVIpQ6Dk.lean.js +1 -0
  123. package/public/docs/assets/tuning-reference_intro.md.BSSaDlqx.js +1 -0
  124. package/public/docs/assets/tuning-reference_intro.md.BSSaDlqx.lean.js +1 -0
  125. package/public/docs/assets/tuning-reference_joins.md.BVhNCDnE.js +1 -0
  126. package/public/docs/assets/tuning-reference_joins.md.BVhNCDnE.lean.js +1 -0
  127. package/public/docs/assets/tuning-reference_memory-model.md.CfjFdgbl.js +1 -0
  128. package/public/docs/assets/tuning-reference_memory-model.md.CfjFdgbl.lean.js +1 -0
  129. package/public/docs/assets/tuning-reference_metrics.md.C64VNEL4.js +1 -0
  130. package/public/docs/assets/tuning-reference_metrics.md.C64VNEL4.lean.js +1 -0
  131. package/public/docs/assets/tuning-reference_partitioning.md.CtLK0xsS.js +1 -0
  132. package/public/docs/assets/tuning-reference_partitioning.md.CtLK0xsS.lean.js +1 -0
  133. package/public/docs/assets/tuning-reference_pyspark.md.D-92XgF8.js +6 -0
  134. package/public/docs/assets/tuning-reference_pyspark.md.D-92XgF8.lean.js +1 -0
  135. package/public/docs/assets/tuning-reference_shuffle.md.Iq2v1oHJ.js +1 -0
  136. package/public/docs/assets/tuning-reference_shuffle.md.Iq2v1oHJ.lean.js +1 -0
  137. package/public/docs/assets/tuning-reference_spark-architecture.md._qwnE_Sc.js +1 -0
  138. package/public/docs/assets/tuning-reference_spark-architecture.md._qwnE_Sc.lean.js +1 -0
  139. package/public/docs/assets/tuning-reference_table-formats.md.BSYEK-eN.js +1 -0
  140. package/public/docs/assets/tuning-reference_table-formats.md.BSYEK-eN.lean.js +1 -0
  141. package/public/docs/assets/user-guide_alternative-log-retrieval.md.z-8npxNk.js +7 -0
  142. package/public/docs/assets/user-guide_alternative-log-retrieval.md.z-8npxNk.lean.js +1 -0
  143. package/public/docs/assets/user-guide_getting-started.md.BJW5oVhe.js +24 -0
  144. package/public/docs/assets/user-guide_getting-started.md.BJW5oVhe.lean.js +1 -0
  145. package/public/docs/assets/user-guide_mcp-tools.md.DcLiOa9t.js +148 -0
  146. package/public/docs/assets/user-guide_mcp-tools.md.DcLiOa9t.lean.js +1 -0
  147. package/public/docs/assets/user-guide_run-comparison.md.qin0a4IX.js +1 -0
  148. package/public/docs/assets/user-guide_run-comparison.md.qin0a4IX.lean.js +1 -0
  149. package/public/docs/assets/user-guide_understanding-findings.md.DzReyCXb.js +1 -0
  150. package/public/docs/assets/{user-guide_understanding-findings.md.YBBLOwWi.lean.js → user-guide_understanding-findings.md.DzReyCXb.lean.js} +1 -1
  151. package/public/docs/contributor-guide/architecture/board-widgets.html +7 -6
  152. package/public/docs/contributor-guide/architecture/detector-contract.html +7 -6
  153. package/public/docs/contributor-guide/architecture/drill-down.html +7 -6
  154. package/public/docs/contributor-guide/architecture/impact-estimation.html +7 -6
  155. package/public/docs/contributor-guide/architecture/index.html +7 -6
  156. package/public/docs/contributor-guide/architecture/overview.html +7 -6
  157. package/public/docs/contributor-guide/architecture/state-and-history.html +7 -6
  158. package/public/docs/contributor-guide/architecture/widget-rendering.html +7 -6
  159. package/public/docs/contributor-guide/architecture/worker-protocol.html +10 -9
  160. package/public/docs/contributor-guide/contributing.html +7 -6
  161. package/public/docs/contributor-guide/development-setup.html +12 -11
  162. package/public/docs/contributor-guide/testing.html +7 -6
  163. package/public/docs/hashmap.json +1 -1
  164. package/public/docs/index.html +5 -4
  165. package/public/docs/tuning-reference/anti-patterns.html +8 -7
  166. package/public/docs/tuning-reference/aqe.html +8 -7
  167. package/public/docs/tuning-reference/bottleneck-broadcast-sizing.html +8 -7
  168. package/public/docs/tuning-reference/bottleneck-cold-start.html +8 -7
  169. package/public/docs/tuning-reference/bottleneck-duplicate-plan-subtree.html +8 -7
  170. package/public/docs/tuning-reference/bottleneck-failures.html +8 -7
  171. package/public/docs/tuning-reference/bottleneck-gc.html +8 -7
  172. package/public/docs/tuning-reference/bottleneck-job-failure-rate.html +8 -7
  173. package/public/docs/tuning-reference/bottleneck-memory-utilization.html +8 -7
  174. package/public/docs/tuning-reference/bottleneck-retry-waste.html +8 -7
  175. package/public/docs/tuning-reference/bottleneck-shuffle.html +8 -7
  176. package/public/docs/tuning-reference/bottleneck-skew.html +8 -7
  177. package/public/docs/tuning-reference/bottleneck-slow-host.html +8 -7
  178. package/public/docs/tuning-reference/bottleneck-small-files.html +8 -7
  179. package/public/docs/tuning-reference/bottleneck-spill.html +8 -7
  180. package/public/docs/tuning-reference/bottleneck-straggler.html +8 -7
  181. package/public/docs/tuning-reference/bottleneck-tiny-tasks.html +8 -7
  182. package/public/docs/tuning-reference/bottleneck-utilization.html +8 -7
  183. package/public/docs/tuning-reference/caching.html +8 -7
  184. package/public/docs/tuning-reference/cluster-config.html +8 -7
  185. package/public/docs/tuning-reference/config.html +8 -7
  186. package/public/docs/tuning-reference/data-formats.html +8 -7
  187. package/public/docs/tuning-reference/index.html +8 -7
  188. package/public/docs/tuning-reference/intro.html +8 -7
  189. package/public/docs/tuning-reference/joins.html +8 -7
  190. package/public/docs/tuning-reference/memory-model.html +8 -7
  191. package/public/docs/tuning-reference/metrics.html +8 -7
  192. package/public/docs/tuning-reference/partitioning.html +8 -7
  193. package/public/docs/tuning-reference/pyspark.html +8 -7
  194. package/public/docs/tuning-reference/shuffle.html +8 -7
  195. package/public/docs/tuning-reference/spark-architecture.html +8 -7
  196. package/public/docs/tuning-reference/table-formats.html +8 -7
  197. package/public/docs/user-guide/alternative-log-retrieval.html +14 -7
  198. package/public/docs/user-guide/getting-started.html +29 -7
  199. package/public/docs/user-guide/mcp-tools.html +51 -27
  200. package/public/docs/user-guide/run-comparison.html +7 -6
  201. package/public/docs/user-guide/understanding-findings.html +7 -6
  202. package/public/export-template.html +111 -0
  203. package/public/index.html +4 -3
  204. package/vendor-core/allocation.js +106 -0
  205. package/vendor-core/analyzer.js +168 -60
  206. package/vendor-core/check-coverage.js +88 -0
  207. package/vendor-core/cli/budgets.js +54 -27
  208. package/vendor-core/cli/collect-run.js +84 -32
  209. package/vendor-core/cli/regression-budgets.js +83 -0
  210. package/vendor-core/cli/threshold-config.js +28 -0
  211. package/vendor-core/comparison-verdict.js +177 -0
  212. package/vendor-core/core-source-hash.txt +1 -0
  213. package/vendor-core/core-usage-locality.js +56 -2
  214. package/vendor-core/detector-docs.js +58 -0
  215. package/vendor-core/detectors.js +1094 -500
  216. package/vendor-core/docs-config.js +0 -36
  217. package/vendor-core/docs-content/chapters/nav-index.json +31 -0
  218. package/vendor-core/docs-content/detection/cache.md +3 -2
  219. package/vendor-core/docs-content/detection/cfg.md +9 -8
  220. package/vendor-core/docs-content/detection/chrn.md +1 -2
  221. package/vendor-core/docs-content/detection/cold.md +4 -2
  222. package/vendor-core/docs-content/detection/cstor.md +9 -0
  223. package/vendor-core/docs-content/detection/fail.md +3 -2
  224. package/vendor-core/docs-content/detection/gc.md +3 -2
  225. package/vendor-core/docs-content/detection/host.md +2 -1
  226. package/vendor-core/docs-content/detection/local.md +1 -1
  227. package/vendor-core/docs-content/detection/mem.md +5 -2
  228. package/vendor-core/docs-content/detection/plan.md +2 -1
  229. package/vendor-core/docs-content/detection/sfail.md +2 -1
  230. package/vendor-core/docs-content/detection/shape.md +5 -4
  231. package/vendor-core/docs-content/detection/skew.md +3 -1
  232. package/vendor-core/docs-content/detection/slow.md +2 -2
  233. package/vendor-core/docs-content/detection/spec.md +2 -3
  234. package/vendor-core/docs-content/detection/spill.md +1 -1
  235. package/vendor-core/docs-site-config.js +3 -0
  236. package/vendor-core/effective-conf.js +107 -0
  237. package/vendor-core/efficiency-model.js +8 -6
  238. package/vendor-core/event-handlers.js +321 -44
  239. package/vendor-core/event-schemas.js +23 -0
  240. package/vendor-core/evidence-report.js +432 -115
  241. package/vendor-core/export-data.js +79 -6
  242. package/vendor-core/finding-action-label.js +9 -88
  243. package/vendor-core/finding-filter-predicate.js +9 -0
  244. package/vendor-core/finding-generic-recommendation.js +26 -105
  245. package/vendor-core/finding-names.js +28 -45
  246. package/vendor-core/finding-presentation.js +368 -0
  247. package/vendor-core/finding-tag-help.js +110 -0
  248. package/vendor-core/finding-types.js +373 -0
  249. package/vendor-core/findings-of-type.js +11 -0
  250. package/vendor-core/format-utils.js +96 -30
  251. package/vendor-core/html-export.js +51 -0
  252. package/vendor-core/impact-band.js +21 -8
  253. package/vendor-core/impact-estimator.js +25 -520
  254. package/vendor-core/impact-format.js +115 -0
  255. package/vendor-core/impact-model.js +197 -0
  256. package/vendor-core/ingest.js +6 -2
  257. package/vendor-core/intervals.js +13 -0
  258. package/vendor-core/list-runs.js +7 -5
  259. package/vendor-core/load-vendored.js +70 -5
  260. package/vendor-core/mcp-server-factory.js +14 -10
  261. package/vendor-core/mcp-tools.js +105 -45
  262. package/vendor-core/model-assembler.js +35 -1
  263. package/vendor-core/occupancy.js +1 -1
  264. package/vendor-core/parser-worker.js +2 -2
  265. package/vendor-core/plan-graph-model.js +3 -2
  266. package/vendor-core/plan-node-detail.js +1 -1
  267. package/vendor-core/proxy.js +3 -1
  268. package/vendor-core/python-stage.js +25 -0
  269. package/vendor-core/recommendation-rollup.js +70 -3
  270. package/vendor-core/redact.js +96 -37
  271. package/vendor-core/remediation.js +20 -0
  272. package/vendor-core/run-comparison.js +73 -29
  273. package/vendor-core/run-interpretation.js +291 -0
  274. package/vendor-core/run-metrics.js +198 -0
  275. package/vendor-core/run-outcome.js +74 -0
  276. package/vendor-core/run-payload.js +17 -0
  277. package/vendor-core/run-shape.js +40 -0
  278. package/vendor-core/run-totals.js +24 -0
  279. package/vendor-core/run-verdict.js +352 -0
  280. package/vendor-core/scaling-sim.js +4 -5
  281. package/vendor-core/scorecard-estimates.js +63 -0
  282. package/vendor-core/session-snapshot.js +7 -0
  283. package/vendor-core/shs-schemas.js +2 -2
  284. package/vendor-core/spark-memory.js +17 -0
  285. package/vendor-core/sql-stages.js +11 -0
  286. package/vendor-core/stage-plan-nodes.js +18 -0
  287. package/vendor-core/stage-quantiles.js +6 -0
  288. package/vendor-core/threshold-overrides.js +160 -0
  289. package/vendor-core/threshold-summary.js +11 -33
  290. package/vendor-core/types.js +54 -42
  291. package/vendor-core/wall-clock.js +1 -12
  292. package/vendor-core/wasted-core-hours.js +12 -9
  293. package/vendor-core/write-targets.js +312 -0
  294. package/public/assets/AutoscalingChurn-lxZHWIwq.js +0 -1
  295. package/public/assets/CacheUtilization-DuAJ-Lve.js +0 -1
  296. package/public/assets/CachingOpportunity-DC1t7o2_.js +0 -1
  297. package/public/assets/ColdStart-BOYXeiUZ.js +0 -1
  298. package/public/assets/ConfigAudit-MCPrJomC.js +0 -1
  299. package/public/assets/CoreUsageArea-ChNuqGA0.js +0 -1
  300. package/public/assets/Dashboard-VuyUGvZx.js +0 -1
  301. package/public/assets/DuplicatePlanSubtree-JZut9xwq.js +0 -1
  302. package/public/assets/DurationHistogram-_7C1w0l4.js +0 -1
  303. package/public/assets/EmptyState-D_ulfIIi.js +0 -1
  304. package/public/assets/ExecutorUtilization-B08E76jT.js +0 -1
  305. package/public/assets/GcPressure-BZMi2fTx.js +0 -1
  306. package/public/assets/ImpactEstimate-36WxuPdV.js +0 -1
  307. package/public/assets/IncompleteRun-t8JU7HRt.js +0 -1
  308. package/public/assets/JobFailures-CguB1bec.js +0 -1
  309. package/public/assets/MemoryUtilization-DDk8lz9-.js +0 -1
  310. package/public/assets/OverBroadcast-BHXLt6s7.js +0 -1
  311. package/public/assets/PartitionSizing-COj3uwV-.js +0 -1
  312. package/public/assets/PlanExplorer-CnCdEY_i.js +0 -1
  313. package/public/assets/PlanGraphRoute-BesZOW1n.js +0 -1
  314. package/public/assets/RetryWaste-CcU4ctAn.js +0 -1
  315. package/public/assets/RowPagination-D2aIcfGv.js +0 -1
  316. package/public/assets/ShuffleIO-NPHkWbg1.js +0 -1
  317. package/public/assets/Skew-CzztP-C4.js +0 -1
  318. package/public/assets/SlowHost-Dh2KHypN.js +0 -1
  319. package/public/assets/SmallFiles-CgYSuZQw.js +0 -1
  320. package/public/assets/SpeculationWaste-C8J5z1WS.js +0 -1
  321. package/public/assets/Spill-DwTQPZ_L.js +0 -1
  322. package/public/assets/StageFailed-aFeIEh3p.js +0 -1
  323. package/public/assets/StageFindingGroup-DQmAE3uk.js +0 -1
  324. package/public/assets/StageHeader-D6GBbcZp.js +0 -1
  325. package/public/assets/StagePill-CSKyM8Kd.js +0 -1
  326. package/public/assets/StageShape-J6U4cUcM.js +0 -1
  327. package/public/assets/StageSlowness-C5F2v_ZO.js +0 -1
  328. package/public/assets/Straggler-DcP3dFGA.js +0 -1
  329. package/public/assets/TaskFailures-C-vIEheo.js +0 -1
  330. package/public/assets/UnderBroadcast-DfjYGhoK.js +0 -1
  331. package/public/assets/WidgetLeadSummary-BdUUi7L5.js +0 -1
  332. package/public/assets/downsample-WmNM1qc9.js +0 -1
  333. package/public/assets/impact-sort-DxaUheWV.js +0 -1
  334. package/public/assets/inbox-LtbS_kBS.js +0 -1
  335. package/public/assets/index-27MbqTFr.js +0 -11
  336. package/public/assets/index-CWjjbtyo.css +0 -2
  337. package/public/assets/react-vendor-D2TLlSzI.js +0 -9
  338. package/public/assets/select-CC2Lyrmi.js +0 -1
  339. package/public/assets/toggle-group-lmgO21t9.js +0 -1
  340. package/public/assets/usePagedRows-jNUWgVTD.js +0 -1
  341. package/public/assets/useRecentFiles-qH5Ap4xm.js +0 -12
  342. package/public/assets/useSortMode-CvPY99UV.js +0 -1
  343. package/public/docs/assets/chunks/@localSearchIndexroot.CJBoRv1b.js +0 -1
  344. package/public/docs/assets/contributor-guide_architecture_board-widgets.md.9ToZXcTk.js +0 -1
  345. package/public/docs/assets/contributor-guide_architecture_board-widgets.md.9ToZXcTk.lean.js +0 -1
  346. package/public/docs/assets/contributor-guide_architecture_detector-contract.md.CsCytCho.js +0 -1
  347. package/public/docs/assets/contributor-guide_architecture_drill-down.md.Bawx6NgP.js +0 -1
  348. package/public/docs/assets/contributor-guide_architecture_impact-estimation.md.sf9DU2bA.js +0 -1
  349. package/public/docs/assets/contributor-guide_architecture_impact-estimation.md.sf9DU2bA.lean.js +0 -1
  350. package/public/docs/assets/contributor-guide_architecture_index.md.3TO9ic6w.js +0 -1
  351. package/public/docs/assets/contributor-guide_architecture_overview.md.rhfxoGsI.js +0 -1
  352. package/public/docs/assets/contributor-guide_architecture_overview.md.rhfxoGsI.lean.js +0 -1
  353. package/public/docs/assets/contributor-guide_architecture_state-and-history.md.B8Wc_ZTg.js +0 -1
  354. package/public/docs/assets/contributor-guide_architecture_widget-rendering.md.DYwFeyjV.js +0 -1
  355. package/public/docs/assets/contributor-guide_architecture_worker-protocol.md.CBJkwH24.js +0 -6
  356. package/public/docs/assets/contributor-guide_architecture_worker-protocol.md.CBJkwH24.lean.js +0 -1
  357. package/public/docs/assets/contributor-guide_contributing.md.B2E9ni79.js +0 -1
  358. package/public/docs/assets/contributor-guide_development-setup.md.s85j2l8b.js +0 -15
  359. package/public/docs/assets/contributor-guide_development-setup.md.s85j2l8b.lean.js +0 -1
  360. package/public/docs/assets/contributor-guide_testing.md.Cnn6gz1C.js +0 -1
  361. package/public/docs/assets/tuning-reference_anti-patterns.md.Df1YMIHu.js +0 -1
  362. package/public/docs/assets/tuning-reference_anti-patterns.md.Df1YMIHu.lean.js +0 -1
  363. package/public/docs/assets/tuning-reference_aqe.md.BIsCtLzm.js +0 -1
  364. package/public/docs/assets/tuning-reference_aqe.md.BIsCtLzm.lean.js +0 -1
  365. package/public/docs/assets/tuning-reference_bottleneck-broadcast-sizing.md.CEstB3Ia.js +0 -1
  366. package/public/docs/assets/tuning-reference_bottleneck-broadcast-sizing.md.CEstB3Ia.lean.js +0 -1
  367. package/public/docs/assets/tuning-reference_bottleneck-cold-start.md.CEuy-72y.js +0 -7
  368. package/public/docs/assets/tuning-reference_bottleneck-cold-start.md.CEuy-72y.lean.js +0 -1
  369. package/public/docs/assets/tuning-reference_bottleneck-duplicate-plan-subtree.md.CIohQDfn.js +0 -1
  370. package/public/docs/assets/tuning-reference_bottleneck-duplicate-plan-subtree.md.CIohQDfn.lean.js +0 -1
  371. package/public/docs/assets/tuning-reference_bottleneck-failures.md.CAsFf3RR.lean.js +0 -1
  372. package/public/docs/assets/tuning-reference_bottleneck-gc.md.B4T3kJYV.js +0 -6
  373. package/public/docs/assets/tuning-reference_bottleneck-gc.md.B4T3kJYV.lean.js +0 -1
  374. package/public/docs/assets/tuning-reference_bottleneck-job-failure-rate.md.BaJl__1W.js +0 -8
  375. package/public/docs/assets/tuning-reference_bottleneck-job-failure-rate.md.BaJl__1W.lean.js +0 -1
  376. package/public/docs/assets/tuning-reference_bottleneck-memory-utilization.md.DbP-SJZc.js +0 -7
  377. package/public/docs/assets/tuning-reference_bottleneck-memory-utilization.md.DbP-SJZc.lean.js +0 -1
  378. package/public/docs/assets/tuning-reference_bottleneck-retry-waste.md.D5JMjVOt.js +0 -1
  379. package/public/docs/assets/tuning-reference_bottleneck-retry-waste.md.D5JMjVOt.lean.js +0 -1
  380. package/public/docs/assets/tuning-reference_bottleneck-shuffle.md.DDMQVOW6.lean.js +0 -1
  381. package/public/docs/assets/tuning-reference_bottleneck-skew.md.B0MzhWcX.lean.js +0 -1
  382. package/public/docs/assets/tuning-reference_bottleneck-slow-host.md.BlIo6UDW.lean.js +0 -1
  383. package/public/docs/assets/tuning-reference_bottleneck-small-files.md.DHGMTmPs.js +0 -5
  384. package/public/docs/assets/tuning-reference_bottleneck-small-files.md.DHGMTmPs.lean.js +0 -1
  385. package/public/docs/assets/tuning-reference_bottleneck-spill.md.PNH7mITt.js +0 -6
  386. package/public/docs/assets/tuning-reference_bottleneck-spill.md.PNH7mITt.lean.js +0 -1
  387. package/public/docs/assets/tuning-reference_bottleneck-straggler.md.DIbXdAcQ.js +0 -7
  388. package/public/docs/assets/tuning-reference_bottleneck-straggler.md.DIbXdAcQ.lean.js +0 -1
  389. package/public/docs/assets/tuning-reference_bottleneck-tiny-tasks.md.CB05v3zh.js +0 -8
  390. package/public/docs/assets/tuning-reference_bottleneck-tiny-tasks.md.CB05v3zh.lean.js +0 -1
  391. package/public/docs/assets/tuning-reference_bottleneck-utilization.md.DqC_iGkw.lean.js +0 -1
  392. package/public/docs/assets/tuning-reference_caching.md.B7aQ8asB.js +0 -1
  393. package/public/docs/assets/tuning-reference_caching.md.B7aQ8asB.lean.js +0 -1
  394. package/public/docs/assets/tuning-reference_cluster-config.md.CD6vzYtD.js +0 -1
  395. package/public/docs/assets/tuning-reference_cluster-config.md.CD6vzYtD.lean.js +0 -1
  396. package/public/docs/assets/tuning-reference_config.md.UvveiWG3.js +0 -1
  397. package/public/docs/assets/tuning-reference_config.md.UvveiWG3.lean.js +0 -1
  398. package/public/docs/assets/tuning-reference_data-formats.md.bjCAWH3N.js +0 -1
  399. package/public/docs/assets/tuning-reference_data-formats.md.bjCAWH3N.lean.js +0 -1
  400. package/public/docs/assets/tuning-reference_index.md.BQ_NooMV.js +0 -1
  401. package/public/docs/assets/tuning-reference_index.md.BQ_NooMV.lean.js +0 -1
  402. package/public/docs/assets/tuning-reference_intro.md.CobD-lGB.js +0 -1
  403. package/public/docs/assets/tuning-reference_intro.md.CobD-lGB.lean.js +0 -1
  404. package/public/docs/assets/tuning-reference_joins.md.BtKs_CuW.js +0 -1
  405. package/public/docs/assets/tuning-reference_joins.md.BtKs_CuW.lean.js +0 -1
  406. package/public/docs/assets/tuning-reference_memory-model.md.CWhvgevP.js +0 -1
  407. package/public/docs/assets/tuning-reference_memory-model.md.CWhvgevP.lean.js +0 -1
  408. package/public/docs/assets/tuning-reference_metrics.md.mLOh7Apj.js +0 -1
  409. package/public/docs/assets/tuning-reference_metrics.md.mLOh7Apj.lean.js +0 -1
  410. package/public/docs/assets/tuning-reference_partitioning.md.q0zKF_8X.js +0 -1
  411. package/public/docs/assets/tuning-reference_partitioning.md.q0zKF_8X.lean.js +0 -1
  412. package/public/docs/assets/tuning-reference_pyspark.md.DDCfvN9t.js +0 -6
  413. package/public/docs/assets/tuning-reference_pyspark.md.DDCfvN9t.lean.js +0 -1
  414. package/public/docs/assets/tuning-reference_shuffle.md.BZZ7R4Ix.js +0 -1
  415. package/public/docs/assets/tuning-reference_shuffle.md.BZZ7R4Ix.lean.js +0 -1
  416. package/public/docs/assets/tuning-reference_spark-architecture.md.Dwzm5avO.js +0 -1
  417. package/public/docs/assets/tuning-reference_spark-architecture.md.Dwzm5avO.lean.js +0 -1
  418. package/public/docs/assets/tuning-reference_table-formats.md.D6wj-2dX.js +0 -1
  419. package/public/docs/assets/tuning-reference_table-formats.md.D6wj-2dX.lean.js +0 -1
  420. package/public/docs/assets/user-guide_alternative-log-retrieval.md.ZHPSbBkF.js +0 -1
  421. package/public/docs/assets/user-guide_alternative-log-retrieval.md.ZHPSbBkF.lean.js +0 -1
  422. package/public/docs/assets/user-guide_getting-started.md.Cpe0U-eO.js +0 -3
  423. package/public/docs/assets/user-guide_getting-started.md.Cpe0U-eO.lean.js +0 -1
  424. package/public/docs/assets/user-guide_mcp-tools.md.DrphooJv.js +0 -125
  425. package/public/docs/assets/user-guide_mcp-tools.md.DrphooJv.lean.js +0 -1
  426. package/public/docs/assets/user-guide_run-comparison.md.CQc1aoU8.js +0 -1
  427. package/public/docs/assets/user-guide_run-comparison.md.CQc1aoU8.lean.js +0 -1
  428. package/public/docs/assets/user-guide_understanding-findings.md.YBBLOwWi.js +0 -1
  429. /package/public/docs/assets/{contributor-guide_architecture_drill-down.md.Bawx6NgP.lean.js → contributor-guide_architecture_drill-down.md.CdtlKHl-.lean.js} +0 -0
@@ -0,0 +1,312 @@
1
+ // Write targets: every SQL write command in a run's plans, with the path or table it writes to.
2
+ // Read by automation that halts a session when a target leaves its sandbox, so every rule here
3
+ // fails toward "target unknown" (null), never toward a guessed or partial target:
4
+ // - a write node whose target cannot be parsed is still reported, with target null and its raw
5
+ // simpleString;
6
+ // - a target Spark cut short (no delimiter after it, or a "..." marker in it) is unparseable;
7
+ // - a write-like node outside the known list is reported as an unrecognized write;
8
+ // - an execution whose plan is not in the model (or whose start event could not be read) is
9
+ // listed, never skipped, and the count of unreadable log lines is reported.
10
+ // Targets are verbatim from the simpleString: nothing is resolved (relative paths, ${var}
11
+ // placeholders, catalog-relative table names all pass through as the log states them).
12
+ import { walkPlanTree } from './plan-tree-walk.js';
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+ // Write-like detection: a known command, any CamelCase word of the operator name in this set, or a
54
+ // TableAsSelect name.
55
+ const WRITE_WORDS = new Set([
56
+ 'Write', 'Insert', 'Save', 'Overwrite', 'Append', 'Merge', 'Update', 'Delete', 'Truncate', 'Replace', 'Drop',
57
+ 'Load', 'Vacuum', 'Convert', 'Clone', 'Restore', 'Optimize', 'Alter', 'Reorg', 'Rename', 'Call',
58
+ ]);
59
+ // Names that contain no write word of their own: ADD/DROP/RENAME PARTITION (which can name a LOCATION).
60
+ const WRITE_SUBSTRINGS = ['TableAsSelect', 'AddPartition', 'DropPartition', 'RenamePartition', 'RecoverPartitions'];
61
+ // Plan nodes whose name matches a write word but which write no user data: WriteFiles is the child
62
+ // of a write command (the command is the write), the rest are query or streaming-state operators.
63
+ // Any join (SortMergeJoin) is excluded by name in isWriteLike.
64
+ const NOT_WRITES = new Set([
65
+ 'WriteFiles', 'AppendColumns', 'AppendColumnsWithObject', 'MergeRows', 'StateStoreSave',
66
+ 'StateStoreRestore', 'SessionWindowStateStoreSave', 'SessionWindowStateStoreRestore',
67
+ 'UpdateEventTimeWatermarkColumn',
68
+ ]);
69
+
70
+ const IDENT_PART = String.raw`(?:\`(?:[^\`]|\`\`)*\`|[A-Za-z0-9_$]+)`;
71
+ const IDENTIFIER = new RegExp(`^${IDENT_PART}(?:\\.${IDENT_PART})*$`);
72
+ const IDENT_PARTS = new RegExp(IDENT_PART, 'g');
73
+ const TRUNCATION_MARKER = /\.\.\.(?:\s*\d+ more fields)?/;
74
+
75
+ function commandOf(nodeName ) {
76
+ return nodeName.replace(/^Execute\s+/, '').trim().replace(/Exec$/, '');
77
+ }
78
+
79
+ // Only the operator name (the first word) is classified: a scan's node name goes on to print its
80
+ // relation and table, whose identifiers can hold a write word (Scan JDBCRelation(dbo.PriceUpdate)).
81
+ function isWriteLike(command ) {
82
+ if (isKnownWrite(command)) return true;
83
+ const operator = command.split(/\s/, 1)[0];
84
+ if (NOT_WRITES.has(operator) || operator.includes('Join')) return false;
85
+ if (WRITE_SUBSTRINGS.some((part) => operator.includes(part))) return true;
86
+ return (operator.match(/[A-Z][a-z0-9]*/g) ?? []).some((word) => WRITE_WORDS.has(word));
87
+ }
88
+
89
+
90
+
91
+ // Splits at top-level commas, ignoring commas inside (), [], {} and backticks. `terminated` is
92
+ // true when a comma follows the arg: the last arg of a cut-off string is never terminated.
93
+ function splitArgs(args ) {
94
+ const out = [];
95
+ let depth = 0;
96
+ let quoted = false;
97
+ let start = 0;
98
+ for (let i = 0; i < args.length; i++) {
99
+ const c = args[i];
100
+ if (c === '`') quoted = !quoted;
101
+ else if (quoted) continue;
102
+ else if (c === '(' || c === '[' || c === '{') depth++;
103
+ else if (c === ')' || c === ']' || c === '}') depth--;
104
+ else if (c === ',' && depth === 0) {
105
+ out.push({ text: args.slice(start, i).trim(), terminated: true });
106
+ start = i + 1;
107
+ }
108
+ }
109
+ out.push({ text: args.slice(start).trim(), terminated: false });
110
+ return out;
111
+ }
112
+
113
+ // Text after the command name in the simpleString. Empty when the simpleString does not start
114
+ // with the command (so nothing after it can be trusted).
115
+ function argsOf(detail , command ) {
116
+ const m = /^(?:Execute\s+)?(\S+)\s*([\s\S]*)$/.exec(detail.trim());
117
+ if (!m || commandOf(m[1]) !== command) return '';
118
+ return m[2];
119
+ }
120
+
121
+ function isCut(text ) {
122
+ return text === '' || TRUNCATION_MARKER.test(text);
123
+ }
124
+
125
+ // `db`.`t` or db.t -> db.t. A part that itself contains a dot or backtick keeps its quoting.
126
+ function tableName(ident ) {
127
+ if (!IDENTIFIER.test(ident)) return null;
128
+ const parts = (ident.match(IDENT_PARTS) ?? []).map((p) => {
129
+ if (!p.startsWith('`')) return p;
130
+ const inner = p.slice(1, -1).replace(/``/g, '`');
131
+ return /[.`]/.test(inner) ? p : inner;
132
+ });
133
+ return parts.join('.');
134
+ }
135
+
136
+ // First arg of a path-writing command. The next arg must be the boolean that follows it in
137
+ // InsertIntoHadoopFsRelationCommand, or the static-partition map (INSERT OVERWRITE ... PARTITION
138
+ // (dt='x')) that precedes that boolean, which Spark prints as `[dt=x]` (or `Map(dt -> x)`); this also rejects a path Spark printed with ", " inside.
139
+ function parseHadoopFsPath(args ) {
140
+ const [path, second, third] = args;
141
+ const flag = second && /^(Map\(.*\)|\[.*\])$/s.test(second.text) && second.terminated ? third : second;
142
+ if (!path?.terminated || isCut(path.text) || !flag || !/^(true|false)$/.test(flag.text)) return null;
143
+ return { kind: 'path', target: path.text };
144
+ }
145
+
146
+ // A quoted or plain identifier, or the `[Database: d, TableName: t, ...]` form Hive commands print.
147
+ function parseTableArg(args ) {
148
+ const first = args[0];
149
+ if (!first) return null;
150
+ const hive = /^\[Database: ([^,\]]+), TableName: ([^,\]]+)[,\]]/.exec(first.text);
151
+ if (hive && /\]$/.test(first.text)) {
152
+ const name = tableName(`${hive[1].trim()}.${hive[2].trim()}`);
153
+ return name && !isCut(name) ? { kind: 'table', target: name } : null;
154
+ }
155
+ if (!first.terminated || isCut(first.text)) return null;
156
+ const name = tableName(first.text);
157
+ return name ? { kind: 'table', target: name } : null;
158
+ }
159
+
160
+ // Options of `Map(k -> v, k2 -> v2)`, or null when the Map is missing or not closed.
161
+ function parseOptionMap(text ) {
162
+ const m = /^Map\(([\s\S]*)\)$/.exec(text);
163
+ if (!m) return null;
164
+ const body = m[1];
165
+ const keys = [...body.matchAll(/(?:^|, )([A-Za-z0-9_.\-]+) -> /g)];
166
+ const options = new Map ();
167
+ keys.forEach((key, i) => {
168
+ const valueStart = key.index + key[0].length;
169
+ const valueEnd = i + 1 < keys.length ? keys[i + 1].index : body.length;
170
+ options.set(key[1].toLowerCase(), body.slice(valueStart, valueEnd));
171
+ });
172
+ return options;
173
+ }
174
+
175
+ // SaveIntoDataSourceCommand: `<provider>, Map(options), <mode>`. The target is the `path` option or
176
+ // the JDBC `dbtable`/`table` option; a redacted or missing value, or both options, is unparseable.
177
+ function parseSaveIntoDataSource(args ) {
178
+ const [, options, mode] = args;
179
+ if (!options?.terminated || !mode || mode.text === '') return null;
180
+ const map = parseOptionMap(options.text);
181
+ if (!map) return null;
182
+ const path = map.get('path');
183
+ const table = map.get('dbtable') ?? map.get('table');
184
+ if ((path === undefined) === (table === undefined)) return null;
185
+ const value = (path ?? table) ;
186
+ if (isCut(value) || /\*{5,}\(redacted\)/.test(value)) return null;
187
+ return path !== undefined ? { kind: 'path', target: value } : { kind: 'jdbcTable', target: value };
188
+ }
189
+
190
+ // The one target every match of `pattern` names, or null when there is none, when they name
191
+ // different targets, or when one of them is cut: a string that also prints another plan (a
192
+ // subquery) cannot tell which match is written. `pattern` captures the target, then its closing
193
+ // delimiter; a match without the delimiter was cut before it.
194
+ function soleMatch(detail , pattern , normalize ) {
195
+ const targets = new Set ();
196
+ for (const m of detail.matchAll(pattern)) targets.add(m[2] === undefined || isCut(m[1]) ? null : normalize(m[1]));
197
+ const [target] = targets;
198
+ return targets.size === 1 ? target : null;
199
+ }
200
+
201
+ // A V2 name states its catalog only as a leading part (catalog.namespace.table). With two parts or
202
+ // fewer the catalog is implicit, so a database check on the name alone could match another catalog.
203
+ function v2Table(name ) {
204
+ if (!name) return null;
205
+ const parts = name.match(IDENT_PARTS)?.length ?? 0;
206
+ return { kind: parts >= 3 ? 'table' : 'unqualifiedTable', target: name };
207
+ }
208
+
209
+ // DataSource V2 writes print the connector's Write object; Iceberg's is IcebergWrite(table=t, ...).
210
+ function parseV2Write(detail ) {
211
+ return v2Table(soleMatch(detail, /\b\w*Write\(table=([^,()\s]*)([,)])?/g, tableName));
212
+ }
213
+
214
+ // V2 CTAS/RTAS: `<catalog>@<hash>, <identifier>, <query plan>, ...`. The catalog shape is checked
215
+ // so a plan printed in a different layout is not misread.
216
+ function parseV2TableAsSelect(args ) {
217
+ const [catalog, ident] = args;
218
+ if (!catalog?.terminated || !/^[\w.$]+@[0-9a-f]+$/.test(catalog.text)) return null;
219
+ if (!ident?.terminated || isCut(ident.text)) return null;
220
+ return v2Table(tableName(ident.text));
221
+ }
222
+
223
+ // Delta prints a path-based table as delta.`<path>`. Only the command's own first argument is the
224
+ // written table: later arguments print other plans (a source relation, a condition's subquery).
225
+ function parseDeltaPath(args ) {
226
+ const [first] = args;
227
+ const m = first?.terminated ? /^delta\.`([^`]*)`$/.exec(first.text) : null;
228
+ return m && !isCut(m[1]) ? { kind: 'path', target: m[1] } : null;
229
+ }
230
+
231
+ const V2_WRITES = new Set([
232
+ 'AppendData', 'OverwriteByExpression', 'OverwritePartitionsDynamic', 'ReplaceData', 'WriteDelta',
233
+ 'WriteToDataSourceV2',
234
+ // V1-fallback writers (Delta tables): their node names keep the V1 suffix, not ending in Exec.
235
+ 'AppendDataExecV1', 'OverwriteByExpressionExecV1',
236
+ ]);
237
+ const V2_TABLE_AS_SELECT = new Set([
238
+ 'CreateTableAsSelect', 'AtomicCreateTableAsSelect', 'ReplaceTableAsSelect', 'AtomicReplaceTableAsSelect',
239
+ ]);
240
+ const DELTA_COMMANDS = new Set([
241
+ 'WriteIntoDelta', 'WriteIntoDeltaCommand', 'MergeIntoCommand', 'UpdateCommand', 'DeleteCommand',
242
+ 'CreateDeltaTableCommand', 'OptimizeTableCommand', 'RestoreTableCommand', 'DeltaReorgTableCommand',
243
+ ]);
244
+
245
+ const ARG_PARSERS = {
246
+ InsertIntoHadoopFsRelationCommand: parseHadoopFsPath,
247
+ InsertIntoHiveTable: parseTableArg,
248
+ CreateHiveTableAsSelectCommand: parseTableArg,
249
+ OptimizedCreateHiveTableAsSelectCommand: parseTableArg,
250
+ CreateDataSourceTableAsSelectCommand: parseTableArg,
251
+ SaveIntoDataSourceCommand: parseSaveIntoDataSource,
252
+ };
253
+
254
+ function isKnownWrite(command ) {
255
+ return command in ARG_PARSERS || V2_WRITES.has(command) || V2_TABLE_AS_SELECT.has(command) || DELTA_COMMANDS.has(command);
256
+ }
257
+
258
+ // [recognized, parsed target or null] for one write-like node.
259
+ function parseWrite(command , detail ) {
260
+ const argParser = ARG_PARSERS[command];
261
+ if (argParser) return [true, argParser(splitArgs(argsOf(detail, command)))];
262
+ if (V2_WRITES.has(command)) return [true, parseV2Write(detail)];
263
+ if (V2_TABLE_AS_SELECT.has(command)) return [true, parseV2TableAsSelect(splitArgs(argsOf(detail, command)))];
264
+ // A MERGE prints its source relation too, so a delta. path in it may be the source, not the target.
265
+ if (command === 'MergeIntoCommand') return [true, null];
266
+ if (DELTA_COMMANDS.has(command)) return [true, parseDeltaPath(splitArgs(argsOf(detail, command)))];
267
+ return [false, null];
268
+ }
269
+
270
+ function outputRowsOf(node ) {
271
+ const metric = node.metrics?.find((m) => m.name === 'number of output rows');
272
+ return metric !== undefined && Number.isFinite(metric.value) ? metric.value : null;
273
+ }
274
+
275
+ function collectWrites(executionId , root , out ) {
276
+ walkPlanTree(root, (node) => {
277
+ const command = commandOf(node.name);
278
+ if (!isWriteLike(command)) return;
279
+ const detail = node.detail ?? '';
280
+ const [recognized, parsed] = parseWrite(command, detail);
281
+ out.push({
282
+ sqlExecutionId: executionId,
283
+ nodeId: node.id ?? null,
284
+ command,
285
+ recognized,
286
+ kind: parsed?.kind ?? null,
287
+ target: parsed?.target ?? null,
288
+ outputRows: outputRowsOf(node),
289
+ raw: detail !== '' ? detail : node.name,
290
+ });
291
+ }, { dedupe: true });
292
+ }
293
+
294
+
295
+
296
+
297
+
298
+
299
+
300
+ export function extractWriteTargets(sql , input = {}) {
301
+ const writes = [];
302
+ const withoutPlan = new Map ();
303
+ for (const id of input.unreadableSqlExecutions ?? []) if (!sql.get(id)?.planTree) withoutPlan.set(id, 'unreadableStart');
304
+ for (const id of [...sql.keys()].sort((a, b) => a - b)) {
305
+ const planTree = sql.get(id) .planTree;
306
+ if (!planTree) withoutPlan.set(id, withoutPlan.get(id) ?? 'noPlan');
307
+ else collectWrites(id, planTree, writes);
308
+ }
309
+ const executionsWithoutPlan = [...withoutPlan].sort((a, b) => a[0] - b[0])
310
+ .map(([sqlExecutionId, reason]) => ({ sqlExecutionId, reason }));
311
+ return { writes, executionsWithoutPlan, skippedLines: input.skippedLines ?? null };
312
+ }
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{M as t,T as n,f as r,l as i,o as a,s as o,t as s,v as c,w as l}from"./charts-vendor-0VMaLVLN.js";import{p as u}from"./plan-graph-vendor-B0sEms9Z.js";import{T as d,w as f}from"./useRecentFiles-qH5Ap4xm.js";import{A as p,D as m,O as h,i as g}from"./index-27MbqTFr.js";import{t as _}from"./downsample-WmNM1qc9.js";import{t as v}from"./WidgetLeadSummary-BdUUi7L5.js";import{t as y}from"./ImpactEstimate-36WxuPdV.js";var b=e(t(),1),x=u(),S=60,C=6e4,w=220;function T(e,t,n,r,i){if(e.length===0&&t.length===0)return[];let a=Math.max(i,r-n),o=Math.max(1,Math.ceil(a/i)),s=[];for(let e=0;e<o;e++)s.push({tStart:n+e*i,adds:0,removes:0});let c=e=>Math.min(o-1,Math.max(0,Math.floor((e-n)/i)));for(let t of e)s[c(t.timestamp)].adds++;for(let e of t)s[c(e.timestamp)].removes++;return s}function E(e,t){let n=Math.max(1,t-e);return Math.max(C,Math.ceil(n/S))}function D(e){if(e<=0)return 1;let t=10**Math.floor(Math.log10(e)),n=e/t;return(n<=1?1:n<=2?2:n<=5?5:10)*t}function O(e){let t=D(e.reduce((e,t)=>Math.max(e,Math.abs(t.added),Math.abs(t.removed)),0));return{domain:[-t,t],ticks:[-t,-t/2,0,t/2,t]}}function k(e){return Math.abs(e.height)<1?null:(0,x.jsx)(l,{...e})}function A({finding:e}){return(0,x.jsxs)(`div`,{className:`flex flex-col gap-1 transition-colors`,children:[(0,x.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Short-lived executors: `,(0,x.jsxs)(`strong`,{children:[e.value,`%`]})]}),(0,x.jsx)(y,{finding:e}),(0,x.jsxs)(`p`,{className:`flex flex-wrap items-start gap-2 text-sm`,children:[(0,x.jsx)(m,{impactBand:e.impactBand,className:`mt-1.5`}),(0,x.jsxs)(`span`,{children:[e.recommendation,` `,(0,x.jsx)(p,{anchor:`#config-autoscale-bounds`,children:`Tuning executorIdleTimeout and the min/max bounds`}),`.`]})]})]})}var j=(0,b.memo)(function({appModel:e,activeFileId:t,catalog:l=[],defaultCollapsed:u=!0}){let p=(0,b.useMemo)(()=>{let t=e.executors.added,n=e.executors.removed;if(t.length===0&&n.length===0)return{hasEvents:!1,added:t,removed:n};let r=e.app,i=r?.startTime??0,a=r?.endTime??i,o=E(i,a),s=_(T(t,n,i,a,o)).map(e=>({t:`${Math.round((e.tStart-i)/1e3)}s`,added:e.adds,removed:-e.removes}));return{hasEvents:!0,added:t,removed:n,rows:s,yAxisScale:O(s)}},[e,t]);if(!p.hasEvents)return(0,x.jsx)(g,{title:`Autoscaling Churn`,summary:(0,x.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:`No executor add/remove events (static allocation).`}),children:(0,x.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`No executor add/remove events (static allocation).`})});let{added:m,removed:y,rows:S,yAxisScale:C}=p,D=l.find(e=>e.type===`autoscalingChurn`);return(0,x.jsx)(g,{title:`Autoscaling Churn`,impactBand:D?.impactBand,badges:D&&(0,x.jsx)(h,{type:`autoscalingChurn`,impactBand:D.impactBand}),defaultCollapsed:u,summary:(0,x.jsx)(v,{value:`${m.length} added / ${y.length} removed`,context:D?`${D.value}% short-lived executors, ${D.impactBand}`:`executor churn events`}),children:(0,x.jsxs)(`div`,{className:`space-y-2`,children:[D&&(0,x.jsx)(A,{finding:D}),(0,x.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:`executors added / removed over time`}),(0,x.jsx)(d,{ariaLabel:`Executor added and removed counts per time bucket over the run.`,height:w,table:{caption:`Executor added/removed counts by time bucket`,columns:[`Time`,`Executors added`,`Executors removed`],rows:S.map(e=>[e.t,e.added,Math.abs(e.removed)]),align:[`right`,`right`,`right`]},children:(0,x.jsxs)(s,{data:S,children:[(0,x.jsx)(r,{stroke:f.muted,strokeOpacity:.2}),(0,x.jsx)(o,{dataKey:`t`,tick:{fontSize:10}}),(0,x.jsx)(a,{tick:{fontSize:10},width:32,domain:C.domain,ticks:C.ticks}),(0,x.jsx)(c,{formatter:(e,t)=>[Math.abs(Number(e)),t]}),(0,x.jsx)(n,{wrapperStyle:{fontSize:10}}),(0,x.jsx)(i,{dataKey:`added`,name:`Added`,stackId:`churn`,fill:f.clean,shape:k}),(0,x.jsx)(i,{dataKey:`removed`,name:`Removed`,stackId:`churn`,fill:f.muted,shape:k})]})})]})})});export{j as AutoscalingChurn};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{M as t}from"./charts-vendor-0VMaLVLN.js";import{p as n}from"./plan-graph-vendor-B0sEms9Z.js";import{A as r,D as i,O as a,St as o,_ as s,_t as c,b as l,ct as u,ft as d,h as f,ht as p,i as m,k as h,l as g,m as _,v,vt as y,y as b}from"./index-27MbqTFr.js";import{t as x}from"./WidgetLeadSummary-BdUUi7L5.js";import{t as S}from"./ImpactEstimate-36WxuPdV.js";import{t as C}from"./RowPagination-D2aIcfGv.js";import{n as w}from"./finding-anchor-vVODA_VC.js";import{t as T}from"./usePagedRows-jNUWgVTD.js";var E=e(t(),1),D=n(),O=70;function k(e){if(!e)return`—`;let t=[];return e.useMemory&&t.push(`Memory`),e.useDisk&&t.push(`Disk`),e.deserialized?t.push(`Deserialized`):(e.useMemory||e.useDisk)&&t.push(`Serialized`),(e.replication??1)>1&&t.push(`x${e.replication}`),t.join(` · `)||`—`}function A(e){return e.name||`RDD ${e.id}`}function j(e){let t=y(A(e));return t.length<=O?t:`${t.slice(0,O)}…`}function M(e){let t=p(`pct`,c(e));return e.variant===`diskSpillover`?`${t} spilled to disk: ${d(e.diskSize??0)} disk / ${d(e.memorySize??0)} memory`:`${t} cached (${e.numCachedPartitions??0}/${e.numPartitions??0} partitions)`}function N({finding:e}){let t=w([e]),n=e.rddName??`RDD ${e.rddId}`;return(0,D.jsxs)(`div`,{ref:t.ref,tabIndex:t.tabIndex,"data-flashed":t.dataFlashed,className:`space-y-1 transition-colors ${t.flashClassName}`,children:[(0,D.jsxs)(`p`,{className:`flex flex-wrap items-start gap-2`,children:[(0,D.jsx)(i,{impactBand:e.impactBand,className:`mt-1.5`}),(0,D.jsx)(`span`,{children:n})]}),(0,D.jsx)(h,{children:(0,D.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:M(e)})}),(0,D.jsx)(S,{finding:e}),(0,D.jsx)(`p`,{className:`text-sm`,children:e.recommendation})]})}var P=(0,E.memo)(function({appModel:e,catalog:t}){let[n,c]=(0,E.useState)(0),[p,h]=(0,E.useState)(0),y=e.app?.rddInfo,S=(0,E.useMemo)(()=>y?[...y.values()].filter(e=>(e.storageLevel?.useMemory||e.storageLevel?.useDisk)&&(e.numCachedPartitions??0)>0).sort((e,t)=>(t.memorySize??0)+(t.diskSize??0)-((e.memorySize??0)+(e.diskSize??0))):[],[y]),w=(0,E.useMemo)(()=>t.filter(e=>e.type===`cacheUtilization`).sort((e,t)=>u[e.impactBand]-u[t.impactBand]),[t]),O=T(S,n,c),M=g(),P=M?w.findIndex(e=>e===M.finding):null,F=T(w,p,h,P);if(S.length===0)return null;let I=e=>w.filter(t=>t.rddId===e),L=S.reduce((e,t)=>e+(t.memorySize??0)+(t.diskSize??0),0);return(0,D.jsx)(`div`,{"data-widget":`cache-utilization`,children:(0,D.jsxs)(m,{title:`Cache Storage`,impactBand:o(w),badges:(0,D.jsxs)(D.Fragment,{children:[w.length>0?(0,D.jsx)(a,{type:`cacheUtilization`,impactBand:o(w)??`info`}):null,(0,D.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[S.length,` cached RDD`,S.length===1?``:`s`,`, see`,` `,(0,D.jsx)(r,{anchor:`#memory-model`,children:`how Spark accounts cached memory`})]})]}),defaultCollapsed:!0,summary:(0,D.jsx)(x,{value:d(L),context:`cached across memory + disk`}),children:[(0,D.jsxs)(_,{children:[(0,D.jsx)(b,{children:(0,D.jsxs)(l,{children:[(0,D.jsx)(v,{children:`RDD`}),(0,D.jsx)(v,{children:`Storage level`}),(0,D.jsx)(v,{className:`text-right`,children:`Cached partitions`}),(0,D.jsx)(v,{className:`text-right`,children:`Memory`}),(0,D.jsx)(v,{className:`text-right`,children:`Disk`})]})}),(0,D.jsx)(f,{children:O.visible.map(e=>{let t=A(e),n=j(e),r=I(e.id);return(0,D.jsxs)(l,{children:[(0,D.jsxs)(s,{className:`max-w-80 truncate`,title:t===n?void 0:t,children:[n,r.length>0&&(0,D.jsx)(i,{impactBand:o(r)??`info`,className:`ml-1.5`})]}),(0,D.jsx)(s,{children:k(e.storageLevel)}),(0,D.jsxs)(s,{className:`text-right`,children:[e.numCachedPartitions,` / `,e.numPartitions]}),(0,D.jsx)(s,{className:`text-right`,children:d(e.memorySize??0)}),(0,D.jsx)(s,{className:`text-right`,children:d(e.diskSize??0)})]},e.id)})})]}),(0,D.jsx)(C,{page:O.effectivePage,totalPages:O.totalPages,onPrev:()=>c(e=>e-1),onNext:()=>c(e=>e+1)}),w.length>0?(0,D.jsxs)(`div`,{className:`mt-3 space-y-2 text-sm`,children:[F.visible.map(e=>(0,D.jsx)(N,{finding:e},e.id)),(0,D.jsx)(C,{page:F.effectivePage,totalPages:F.totalPages,onPrev:()=>h(e=>e-1),onNext:()=>h(e=>e+1)})]}):null]})})});export{P as CacheUtilization};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{M as t}from"./charts-vendor-0VMaLVLN.js";import{p as n}from"./plan-graph-vendor-B0sEms9Z.js";import{S as r}from"./useRecentFiles-qH5Ap4xm.js";import{Mt as i,O as a,_ as o,b as s,ft as c,h as l,i as u,j as d,k as f,l as p,m,v as h,y as g}from"./index-27MbqTFr.js";import{t as _}from"./WidgetLeadSummary-BdUUi7L5.js";import{t as v}from"./ImpactEstimate-36WxuPdV.js";import{t as y}from"./RowPagination-D2aIcfGv.js";import{n as b}from"./finding-anchor-vVODA_VC.js";import{t as x}from"./usePagedRows-jNUWgVTD.js";var S={name:`git-merge`,size:24,node:[[`circle`,{cx:`18`,cy:`18`,r:`3`,key:`1xkwt0`}],[`circle`,{cx:`6`,cy:`6`,r:`3`,key:`1lh9wr`}],[`path`,{d:`M6 21V9a9 9 0 0 0 9 9`,key:`7kw0sc`}]]};S.node;var C=i(S),w=e(t(),1),T=n();function E({relations:e,operator:t}){let n=t===`union`?`union`:`join`;return(0,T.jsx)(`span`,{className:`inline-flex flex-wrap items-baseline`,children:e.map((e,t)=>(0,T.jsxs)(`span`,{children:[t>0?(0,T.jsxs)(T.Fragment,{children:[` `,(0,T.jsx)(`span`,{className:`mx-1 font-semibold uppercase text-xs tracking-wide text-primary`,children:n}),` `]}):null,e.relation]},e.relation))})}function D({finding:e}){let t=b([e]),n=e.variant===`composite`;return(0,T.jsxs)(s,{ref:t.ref,tabIndex:t.tabIndex,"data-flashed":t.dataFlashed,className:`transition-colors ${t.flashClassName}`,children:[(0,T.jsx)(o,{children:(0,T.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[n?(0,T.jsx)(C,{className:`size-3.5 text-muted-foreground`,"aria-hidden":`true`}):null,n&&e.relations&&e.relations.length>0?(0,T.jsx)(E,{relations:e.relations,operator:e.operator}):(0,T.jsx)(`span`,{children:e.relation}),n?(0,T.jsx)(d,{variant:`outline`,className:`text-xs uppercase border-dashed`,children:e.operator?.toUpperCase()}):(0,T.jsx)(d,{variant:`secondary`,className:`text-xs uppercase`,children:e.format})]})}),(0,T.jsxs)(o,{children:[e.value,` queries`]}),(0,T.jsx)(o,{className:`text-right`,children:c(e.totalReadBytes??0)}),(0,T.jsxs)(o,{children:[(0,T.jsx)(v,{finding:e}),(0,T.jsx)(`p`,{className:`mt-1`,children:e.recommendation}),(0,T.jsx)(f,{children:(0,T.jsx)(r,{confidence:e.confidence,validationRequired:e.validationRequired})})]})]})}var O=(0,w.memo)(function({catalog:e,defaultCollapsed:t=!0}){let[n,r]=(0,w.useState)(0),i=(0,w.useMemo)(()=>e.filter(e=>e.type===`cachingOpportunity`).sort((e,t)=>(t.totalReadBytes??0)-(e.totalReadBytes??0)||(typeof t.value==`number`?t.value:0)-(typeof e.value==`number`?e.value:0)),[e]),o=p(),c=o?i.findIndex(e=>e===o.finding):null,{totalPages:d,effectivePage:v,visible:b}=x(i,n,r,c);if(i.length===0)return null;let S=i[0];return(0,T.jsx)(u,{title:`Caching Opportunities`,impactBand:`info`,badges:(0,T.jsx)(a,{type:`cachingOpportunity`,impactBand:`info`}),defaultCollapsed:t,summary:(0,T.jsx)(_,{value:`${S.value}×`,context:`read by ${S.value} queries: ${S.relation}`}),children:(0,T.jsxs)(`div`,{className:`space-y-3`,children:[(0,T.jsxs)(m,{children:[(0,T.jsx)(g,{children:(0,T.jsxs)(s,{children:[(0,T.jsx)(h,{children:`Relation`}),(0,T.jsx)(h,{children:`Read by`}),(0,T.jsx)(h,{className:`text-right`,children:`Data read`}),(0,T.jsx)(h,{children:`Recommendation`})]})}),(0,T.jsx)(l,{children:b.map((e,t)=>(0,T.jsx)(D,{finding:e},`${e.format}:${e.relation}:${(e.executionIds??[]).join(`,`)}:${t}`))})]}),(0,T.jsx)(f,{children:(0,T.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Reuse is inferred from plan structure, not confirmed by execution. Verify before caching.`})}),(0,T.jsx)(y,{page:v,totalPages:d,onPrev:()=>r(e=>e-1),onNext:()=>r(e=>e+1)})]})})});export{O as CachingOpportunity};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{M as t}from"./charts-vendor-0VMaLVLN.js";import{p as n}from"./plan-graph-vendor-B0sEms9Z.js";import{D as r,O as i,ct as a,i as o,l as s}from"./index-27MbqTFr.js";import{t as c}from"./WidgetLeadSummary-BdUUi7L5.js";import{t as l}from"./ImpactEstimate-36WxuPdV.js";import{t as u}from"./RowPagination-D2aIcfGv.js";import{r as d}from"./impact-sort-DxaUheWV.js";import{n as f}from"./finding-anchor-vVODA_VC.js";import{t as p}from"./usePagedRows-jNUWgVTD.js";import{n as m,t as h}from"./useSortMode-CvPY99UV.js";var g=e(t(),1),_=n();function v(e){return`${e.value}s`}function y({finding:e}){let t=f([e]);return(0,_.jsxs)(`li`,{ref:t.ref,tabIndex:t.tabIndex,"data-flashed":t.dataFlashed,className:`space-y-1 text-sm transition-colors ${t.flashClassName}`,children:[(0,_.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,_.jsx)(r,{impactBand:e.impactBand}),(0,_.jsx)(`strong`,{children:v(e)})]}),(0,_.jsx)(l,{finding:e}),(0,_.jsx)(`p`,{className:`text-muted-foreground pt-1`,children:e.recommendation})]})}var b=(0,g.memo)(function({catalog:e,defaultCollapsed:t=!0}){let{sortMode:n,setSortMode:r,orderBy:l}=h(),[f,b]=(0,g.useState)(!t),[x,S]=(0,g.useState)(0),C=e.filter(e=>e.type===`coldStart`).slice().sort((e,t)=>a[e.impactBand]-a[t.impactBand]),w=l(C,e=>[e],e=>e.stageId??null),T=s(),E=T?w.findIndex(e=>e===T.finding):null,{totalPages:D,effectivePage:O,visible:k}=p(w,x,S,E);return C.length===0?null:(0,_.jsxs)(o,{title:`Cold Start`,impactBand:C[0].impactBand,badges:(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(i,{type:`coldStart`,impactBand:C[0].impactBand}),d(C,C.length,f)?(0,_.jsx)(m,{mode:n,onChange:r}):null]}),open:f,onOpenChange:b,summary:(0,_.jsx)(c,{value:v(C[0]),context:`${C.length} issue${C.length===1?``:`s`} flagged`}),children:[(0,_.jsx)(`ul`,{className:`space-y-2`,children:k.map(e=>(0,_.jsx)(y,{finding:e},e.id))}),(0,_.jsx)(u,{page:O,totalPages:D,onPrev:()=>S(e=>e-1),onNext:()=>S(e=>e+1)})]})});export{b as ColdStart};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{M as t}from"./charts-vendor-0VMaLVLN.js";import{p as n}from"./plan-graph-vendor-B0sEms9Z.js";import{S as r}from"./useRecentFiles-qH5Ap4xm.js";import{A as i,D as a,H as o,N as s,O as c,St as l,ct as u,i as d,k as f,l as p}from"./index-27MbqTFr.js";import{t as m}from"./WidgetLeadSummary-BdUUi7L5.js";import{t as h}from"./ImpactEstimate-36WxuPdV.js";import{t as g}from"./RowPagination-D2aIcfGv.js";import{n as _}from"./finding-anchor-vVODA_VC.js";import{t as v}from"./usePagedRows-jNUWgVTD.js";var y=e(t(),1),b=n();function x({finding:e}){let t=_([e]);return(0,b.jsxs)(`li`,{ref:t.ref,tabIndex:t.tabIndex,"data-flashed":t.dataFlashed,className:`space-y-1 transition-colors ${t.flashClassName}`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsx)(a,{impactBand:e.impactBand}),(0,b.jsx)(`code`,{className:`text-xs`,children:e.property}),(0,b.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`=`}),(0,b.jsx)(`code`,{className:`rounded bg-accent/10 px-1.5 py-0.5 font-mono text-xs text-accent`,children:String(e.value)})]}),(0,b.jsx)(h,{finding:e}),(0,b.jsxs)(`p`,{className:`text-sm`,children:[e.recommendation,e.docAnchor?(0,b.jsxs)(b.Fragment,{children:[` `,(0,b.jsxs)(i,{anchor:e.docAnchor,children:[`Why `,e.property,` matters`]})]}):null]})]})}var S=(0,y.memo)(function({appModel:e,configFindings:t,defaultCollapsed:n=!0}){let[i,a]=(0,y.useState)(0),h=(0,y.useMemo)(()=>(t??o(e.app)).filter(e=>e.type===`configAudit`).slice().sort((e,t)=>u[e.impactBand]-u[t.impactBand]),[t,e]),_=p(),S=_?h.findIndex(e=>e===_.finding):null,{totalPages:C,effectivePage:w,visible:T}=v(h,i,a,S);if(h.length===0){let t=e.evidenceAvailability?.entries.find(e=>e.key===`sparkConfiguration`),n;if(t)n=t.state===`present`?`No misconfigurations detected.`:t.state===`unknown`&&t.reasonCode===`parseIncomplete`?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`span`,{children:[t.summary,` `]}),(0,b.jsx)(f,{children:(0,b.jsx)(r,{evidenceKey:`sparkConfiguration`})})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`span`,{children:`No environment info captured in this log. `}),(0,b.jsx)(f,{children:(0,b.jsx)(r,{evidenceKey:`sparkConfiguration`})})]});else{let t=e.app?.evidenceInputs;n=(t?t.environmentUpdates>0:Object.keys(e.app?.config??{}).length>0||e.app?.resources)?`No misconfigurations detected.`:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`span`,{children:`No environment info captured in this log. `}),(0,b.jsx)(f,{children:(0,b.jsx)(r,{evidenceKey:`sparkConfiguration`})})]})}let i=(0,b.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:n});return(0,b.jsx)(d,{title:`Config Sanity`,compact:!0,summary:i,children:i})}let E=l(h);return(0,b.jsxs)(d,{title:`Config Sanity`,impactBand:E,badges:(0,b.jsx)(c,{type:`configAudit`,impactBand:E??`info`,docAnchor:s(h)}),statusBadge:(0,b.jsx)(f,{children:(0,b.jsx)(r,{evidenceKey:`sparkConfiguration`})}),defaultCollapsed:n,summary:(0,b.jsx)(m,{value:`${h.length}`,context:`misconfiguration${h.length===1?``:`s`} flagged`}),children:[(0,b.jsx)(`ul`,{className:`space-y-4`,children:T.map(e=>(0,b.jsx)(x,{finding:e},e.id))}),(0,b.jsx)(g,{page:w,totalPages:C,onPrev:()=>a(e=>e-1),onNext:()=>a(e=>e+1)})]})});export{S as ConfigAudit};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{M as t,T as n,f as r,n as i,o as a,s as o,u as s,v as c}from"./charts-vendor-0VMaLVLN.js";import{p as l}from"./plan-graph-vendor-B0sEms9Z.js";import{S as u,T as d,w as f}from"./useRecentFiles-qH5Ap4xm.js";import{t as p}from"./inbox-LtbS_kBS.js";import{A as m,D as h,O as g,X as _,i as v,k as y}from"./index-27MbqTFr.js";import{t as b}from"./EmptyState-D_ulfIIi.js";import{t as x}from"./downsample-WmNM1qc9.js";import{t as S}from"./WidgetLeadSummary-BdUUi7L5.js";import{t as C}from"./ImpactEstimate-36WxuPdV.js";import{t as w}from"./RowPagination-D2aIcfGv.js";import{t as T}from"./usePagedRows-jNUWgVTD.js";var E=e(t(),1),D=[`PROCESS_LOCAL`,`NODE_LOCAL`,`RACK_LOCAL`,`NO_PREF`,`ANY`];function O(e,{bucketWidthMs:t=6e4,tiers:n=D}={}){let r=e.filter(e=>(e.completedAt??0)>(e.submittedAt??0)&&(e.executorRunTime??0)>0);if(r.length===0)return{labels:[],series:{}};let i=r.reduce((e,t)=>Math.min(e,t.submittedAt??e),1/0),a=r.reduce((e,t)=>Math.max(e,t.completedAt??e),-1/0),o=Math.max(1,Math.ceil((a-i)/t)),s={};for(let e of n)s[e]=Array(o).fill(0);let c=Array(o).fill(0);for(let e of r){let n=e.completedAt??0,r=e.submittedAt??0,a=n-r,l=(e.executorRunTime??0)/a,u=(e.localityStats??[]).reduce((e,t)=>e+t.count,0)||1,d=new Map((e.localityStats??[]).map(e=>[e.locality,e.count/u]));for(let e=0;e<o;e++){let a=i+e*t,o=a+t,u=Math.min(n,o)-Math.max(r,a);if(u<=0)continue;let f=u/t;for(let[t,n]of d){let r=l*n*f;s[t]?s[t][e]+=r:c[e]+=r}}}c.some(e=>e>0)&&(s.OTHER=c);let l=Array(o).fill(0);for(let e of Object.keys(s))for(let t=0;t<o;t++)l[t]+=s[e][t];let u=l.reduce((e,t)=>Math.max(e,t),0);s.idle=l.map(e=>Math.max(0,u-e));let d=[];for(let e=0;e<o;e++)d.push(i+e*t);return{labels:d,series:s}}var k=l(),A=240,j=60,M={PROCESS_LOCAL:`Process-local`,NODE_LOCAL:`Node-local`,RACK_LOCAL:`Rack-local`,NO_PREF:`No preference`,ANY:`Any`,OTHER:`Other`,idle:`Idle`},N={PROCESS_LOCAL:f.clean,NODE_LOCAL:f.accent,RACK_LOCAL:f.warning,NO_PREF:f.muted,ANY:f.critical,OTHER:f.muted,idle:f.muted},P=`Core Usage by Locality`,F=(0,E.memo)(function({appModel:e,catalog:t,activeFileId:l,defaultCollapsed:F=!0}){let[I,L]=(0,E.useState)(0),R=(0,E.useMemo)(()=>{let t=[...e.stages.values()];if(!t.some(e=>(e.executorRunTime??0)>0&&(e.completedAt??0)>(e.submittedAt??0)))return{hasActivity:!1};let n=e.app,r=n?.startTime??0,i=n?.endTime??r,{labels:a,series:o}=O(t,{bucketWidthMs:Math.max(6e4,Math.ceil(Math.max(1,i-r)/j))}),s=[...D.filter(e=>o[e]),...o.OTHER?[`OTHER`]:[],`idle`],c=a.map((e,t)=>{let n={t:Math.round((e-r)/1e3)};for(let e of s)n[e]=o[e]?.[t]??0;return n}),l=x(c),u=s.filter(e=>e!==`idle`);return{hasActivity:!0,order:s,points:c,sampled:l,peakCores:c.reduce((e,t)=>Math.max(e,u.reduce((e,n)=>e+t[n],0)),0)}},[e,l]),z=(0,E.useMemo)(()=>_([...e.stages.values()],{topN:1/0}),[e,l]),B=t.find(e=>e.type===`coreLocality`),V=t.some(e=>e.type===`memoryUtilization`&&e.variant===`idleCores`),H=z.topStages.filter(e=>e.nonLocalTasks>0),{totalPages:U,effectivePage:W,visible:G}=T(H,I,L);if(!R.hasActivity)return(0,k.jsx)(v,{title:P,summary:(0,k.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:`No stage activity to plot.`}),children:(0,k.jsx)(b,{tone:`neutral`,icon:p,title:`No stage activity to plot.`})});let{order:K,points:q,sampled:J,peakCores:Y}=R;return(0,k.jsx)(v,{title:P,impactBand:B?.impactBand,badges:B?(0,k.jsx)(g,{type:`coreLocality`,impactBand:B.impactBand}):null,defaultCollapsed:F,summary:(0,k.jsx)(S,{value:`${Math.round(Y)} cores`,context:`peak concurrent, by locality`}),children:(0,k.jsxs)(`div`,{className:`space-y-2`,children:[(0,k.jsx)(y,{children:(0,k.jsxs)(`p`,{className:`text-muted-foreground text-xs`,children:[`approximate: stage-level attribution`,B?null:(0,k.jsxs)(k.Fragment,{children:[`, see `,(0,k.jsx)(m,{anchor:`#bottleneck-utilization`,children:`how utilization is measured`})]})]})}),B?(0,k.jsxs)(`p`,{className:`flex flex-wrap items-start gap-2 text-sm`,children:[(0,k.jsx)(h,{impactBand:B.impactBand,className:`mt-1.5`}),(0,k.jsxs)(`span`,{children:[(0,k.jsxs)(`strong`,{children:[B.value,`% non-local`]}),`: `,B.recommendation]})]}):null,B?(0,k.jsx)(C,{finding:B}):null,(0,k.jsx)(y,{children:B?(0,k.jsx)(u,{confidence:B.confidence,validationRequired:B.validationRequired}):null}),(0,k.jsx)(d,{ariaLabel:`Approximate concurrent core usage over time, stacked by task locality tier, with idle capacity shown. See the legend for tier colors.`,height:A,table:{caption:`Concurrent core usage over time by locality tier`,columns:[`Time (s)`,...K.map(e=>M[e]??e)],rows:q.map(e=>[e.t,...K.map(t=>Math.round(e[t]))]),align:Array.from({length:K.length+1},()=>`right`)},children:(0,k.jsxs)(i,{data:J,children:[(0,k.jsx)(r,{vertical:!1,stroke:f.muted,strokeOpacity:.2}),(0,k.jsx)(o,{dataKey:`t`,tick:{fontSize:10},label:{value:`seconds from app start`,position:`insideBottom`,offset:-2,fontSize:10}}),(0,k.jsx)(a,{tick:{fontSize:10},width:36,label:{value:`avg concurrent cores`,angle:-90,position:`insideLeft`,fontSize:10}}),(0,k.jsx)(c,{}),(0,k.jsx)(n,{wrapperStyle:{fontSize:10}}),K.map(e=>(0,k.jsx)(s,{type:`monotone`,dataKey:e,name:M[e]??e,stackId:`cores`,stroke:N[e]??f.muted,fill:N[e]??f.muted,fillOpacity:e===`idle`?.15:.8,isAnimationActive:!1},e))]})}),(0,k.jsx)(y,{children:G.length>0?(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(`ul`,{className:`space-y-1 text-xs text-muted-foreground`,children:G.map(e=>(0,k.jsxs)(`li`,{children:[`Stage `,e.stageId,`: `,Math.round(e.ratio*100),`% non-local (`,e.nonLocalTasks,`/`,e.taskCount,` tasks)`]},e.stageId))}),(0,k.jsx)(w,{page:W,totalPages:U,onPrev:()=>L(e=>e-1),onNext:()=>L(e=>e+1)})]}):null}),(0,k.jsx)(y,{children:V?(0,k.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Idle cores also flagged → see Memory Utilization widget`}):null})]})})});export{F as CoreUsageArea};