@flanksource/clicky-ui 0.3.48 → 0.3.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/connections/ConnectionsPage.cjs +219 -0
- package/dist/connections/ConnectionsPage.cjs.map +1 -0
- package/dist/connections/ConnectionsPage.d.ts +23 -0
- package/dist/connections/ConnectionsPage.d.ts.map +1 -0
- package/dist/connections/ConnectionsPage.js +219 -0
- package/dist/connections/ConnectionsPage.js.map +1 -0
- package/dist/connections/connectionActionStatus.cjs +43 -0
- package/dist/connections/connectionActionStatus.cjs.map +1 -0
- package/dist/connections/connectionActionStatus.d.ts +5 -0
- package/dist/connections/connectionActionStatus.d.ts.map +1 -0
- package/dist/connections/connectionActionStatus.js +43 -0
- package/dist/connections/connectionActionStatus.js.map +1 -0
- package/dist/connections/connectionActionTypes.cjs +24 -0
- package/dist/connections/connectionActionTypes.cjs.map +1 -0
- package/dist/connections/connectionActionTypes.d.ts +36 -0
- package/dist/connections/connectionActionTypes.d.ts.map +1 -0
- package/dist/connections/connectionActionTypes.js +24 -0
- package/dist/connections/connectionActionTypes.js.map +1 -0
- package/dist/connections/connectionActions.cjs +11 -0
- package/dist/connections/connectionActions.cjs.map +1 -0
- package/dist/connections/connectionActions.d.ts +15 -0
- package/dist/connections/connectionActions.d.ts.map +1 -0
- package/dist/connections/connectionActions.js +11 -0
- package/dist/connections/connectionActions.js.map +1 -0
- package/dist/connections/connectionDashboard.cjs +185 -0
- package/dist/connections/connectionDashboard.cjs.map +1 -0
- package/dist/connections/connectionDashboard.d.ts +25 -0
- package/dist/connections/connectionDashboard.d.ts.map +1 -0
- package/dist/connections/connectionDashboard.js +185 -0
- package/dist/connections/connectionDashboard.js.map +1 -0
- package/dist/connections/connectionDashboardModel.cjs +43 -0
- package/dist/connections/connectionDashboardModel.cjs.map +1 -0
- package/dist/connections/connectionDashboardModel.d.ts +75 -0
- package/dist/connections/connectionDashboardModel.d.ts.map +1 -0
- package/dist/connections/connectionDashboardModel.js +43 -0
- package/dist/connections/connectionDashboardModel.js.map +1 -0
- package/dist/connections/connectionDashboardRenderer.cjs +21 -0
- package/dist/connections/connectionDashboardRenderer.cjs.map +1 -0
- package/dist/connections/connectionDashboardRenderer.d.ts +15 -0
- package/dist/connections/connectionDashboardRenderer.d.ts.map +1 -0
- package/dist/connections/connectionDashboardRenderer.js +21 -0
- package/dist/connections/connectionDashboardRenderer.js.map +1 -0
- package/dist/connections/connectionDashboardRow.cjs +169 -0
- package/dist/connections/connectionDashboardRow.cjs.map +1 -0
- package/dist/connections/connectionDashboardRow.d.ts +12 -0
- package/dist/connections/connectionDashboardRow.d.ts.map +1 -0
- package/dist/connections/connectionDashboardRow.js +169 -0
- package/dist/connections/connectionDashboardRow.js.map +1 -0
- package/dist/connections/connectionErrorView.cjs +8 -0
- package/dist/connections/connectionErrorView.cjs.map +1 -0
- package/dist/connections/connectionErrorView.d.ts +4 -0
- package/dist/connections/connectionErrorView.d.ts.map +1 -0
- package/dist/connections/connectionErrorView.js +8 -0
- package/dist/connections/connectionErrorView.js.map +1 -0
- package/dist/connections/connectionHealth.cjs +82 -0
- package/dist/connections/connectionHealth.cjs.map +1 -0
- package/dist/connections/connectionHealth.d.ts +33 -0
- package/dist/connections/connectionHealth.d.ts.map +1 -0
- package/dist/connections/connectionHealth.js +82 -0
- package/dist/connections/connectionHealth.js.map +1 -0
- package/dist/connections/connectionLogging.cjs +29 -0
- package/dist/connections/connectionLogging.cjs.map +1 -0
- package/dist/connections/connectionLogging.d.ts +11 -0
- package/dist/connections/connectionLogging.d.ts.map +1 -0
- package/dist/connections/connectionLogging.js +29 -0
- package/dist/connections/connectionLogging.js.map +1 -0
- package/dist/connections/connectionLoggingField.cjs +37 -0
- package/dist/connections/connectionLoggingField.cjs.map +1 -0
- package/dist/connections/connectionLoggingField.d.ts +12 -0
- package/dist/connections/connectionLoggingField.d.ts.map +1 -0
- package/dist/connections/connectionLoggingField.js +37 -0
- package/dist/connections/connectionLoggingField.js.map +1 -0
- package/dist/connections/connectionLoggingModel.cjs +16 -0
- package/dist/connections/connectionLoggingModel.cjs.map +1 -0
- package/dist/connections/connectionLoggingModel.d.ts +6 -0
- package/dist/connections/connectionLoggingModel.d.ts.map +1 -0
- package/dist/connections/connectionLoggingModel.js +16 -0
- package/dist/connections/connectionLoggingModel.js.map +1 -0
- package/dist/connections/connectionResolveView.cjs +24 -0
- package/dist/connections/connectionResolveView.cjs.map +1 -0
- package/dist/connections/connectionResolveView.d.ts +5 -0
- package/dist/connections/connectionResolveView.d.ts.map +1 -0
- package/dist/connections/connectionResolveView.js +24 -0
- package/dist/connections/connectionResolveView.js.map +1 -0
- package/dist/connections/connectionTestButton.cjs +58 -0
- package/dist/connections/connectionTestButton.cjs.map +1 -0
- package/dist/connections/connectionTestButton.d.ts +6 -0
- package/dist/connections/connectionTestButton.d.ts.map +1 -0
- package/dist/connections/connectionTestButton.js +58 -0
- package/dist/connections/connectionTestButton.js.map +1 -0
- package/dist/connections/connectionTestView.cjs +12 -0
- package/dist/connections/connectionTestView.cjs.map +1 -0
- package/dist/connections/connectionTestView.d.ts +5 -0
- package/dist/connections/connectionTestView.d.ts.map +1 -0
- package/dist/connections/connectionTestView.js +12 -0
- package/dist/connections/connectionTestView.js.map +1 -0
- package/dist/connections/connectionsPageModel.cjs +33 -0
- package/dist/connections/connectionsPageModel.cjs.map +1 -0
- package/dist/connections/connectionsPageModel.d.ts +24 -0
- package/dist/connections/connectionsPageModel.d.ts.map +1 -0
- package/dist/connections/connectionsPageModel.js +33 -0
- package/dist/connections/connectionsPageModel.js.map +1 -0
- package/dist/connections/iconProvider.cjs +20 -0
- package/dist/connections/iconProvider.cjs.map +1 -0
- package/dist/connections/iconProvider.d.ts +7 -0
- package/dist/connections/iconProvider.d.ts.map +1 -0
- package/dist/connections/iconProvider.js +20 -0
- package/dist/connections/iconProvider.js.map +1 -0
- package/dist/connections.cjs +45 -0
- package/dist/connections.cjs.map +1 -0
- package/dist/connections.d.ts +34 -0
- package/dist/connections.d.ts.map +1 -0
- package/dist/connections.js +45 -0
- package/dist/connections.js.map +1 -0
- package/dist/data/DataTable.cjs +18 -8
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +4 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +18 -8
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/TaskManager.cjs +183 -159
- package/dist/data/TaskManager.cjs.map +1 -1
- package/dist/data/TaskManager.d.ts +3 -1
- package/dist/data/TaskManager.d.ts.map +1 -1
- package/dist/data/TaskManager.js +185 -161
- package/dist/data/TaskManager.js.map +1 -1
- package/dist/data/TaskManagerButton.cjs +1 -0
- package/dist/data/TaskManagerButton.cjs.map +1 -1
- package/dist/data/TaskManagerButton.js +1 -0
- package/dist/data/TaskManagerButton.js.map +1 -1
- package/dist/data/TaskProgress.cjs +13 -7
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts +3 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +13 -7
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +52 -295
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +47 -290
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
- package/dist/data/diagnostics/MetricTile.cjs +44 -0
- package/dist/data/diagnostics/MetricTile.cjs.map +1 -0
- package/dist/data/diagnostics/MetricTile.d.ts +13 -0
- package/dist/data/diagnostics/MetricTile.d.ts.map +1 -0
- package/dist/data/diagnostics/MetricTile.js +44 -0
- package/dist/data/diagnostics/MetricTile.js.map +1 -0
- package/dist/data/diagnostics/StackDumpView.cjs +227 -0
- package/dist/data/diagnostics/StackDumpView.cjs.map +1 -0
- package/dist/data/diagnostics/StackDumpView.d.ts +53 -0
- package/dist/data/diagnostics/StackDumpView.d.ts.map +1 -0
- package/dist/data/diagnostics/StackDumpView.js +227 -0
- package/dist/data/diagnostics/StackDumpView.js.map +1 -0
- package/dist/data/diagnostics/fixtures.d.ts +1 -0
- package/dist/data/diagnostics/fixtures.d.ts.map +1 -1
- package/dist/data/diagnostics/metric-tone.cjs +18 -0
- package/dist/data/diagnostics/metric-tone.cjs.map +1 -0
- package/dist/data/diagnostics/metric-tone.d.ts +6 -0
- package/dist/data/diagnostics/metric-tone.d.ts.map +1 -0
- package/dist/data/diagnostics/metric-tone.js +18 -0
- package/dist/data/diagnostics/metric-tone.js.map +1 -0
- package/dist/data/diagnostics/stacktrace.cjs +44 -0
- package/dist/data/diagnostics/stacktrace.cjs.map +1 -1
- package/dist/data/diagnostics/stacktrace.d.ts +7 -0
- package/dist/data/diagnostics/stacktrace.d.ts.map +1 -1
- package/dist/data/diagnostics/stacktrace.js +44 -0
- package/dist/data/diagnostics/stacktrace.js.map +1 -1
- package/dist/data/diagnostics/types.d.ts +2 -8
- package/dist/data/diagnostics/types.d.ts.map +1 -1
- package/dist/data/lint/LintDetail.cjs +339 -0
- package/dist/data/lint/LintDetail.cjs.map +1 -0
- package/dist/data/lint/LintDetail.d.ts +17 -0
- package/dist/data/lint/LintDetail.d.ts.map +1 -0
- package/dist/data/lint/LintDetail.js +339 -0
- package/dist/data/lint/LintDetail.js.map +1 -0
- package/dist/data/lint/LintFilterBar.cjs +103 -0
- package/dist/data/lint/LintFilterBar.cjs.map +1 -0
- package/dist/data/lint/LintFilterBar.d.ts +16 -0
- package/dist/data/lint/LintFilterBar.d.ts.map +1 -0
- package/dist/data/lint/LintFilterBar.js +103 -0
- package/dist/data/lint/LintFilterBar.js.map +1 -0
- package/dist/data/lint/LintResults.cjs +144 -0
- package/dist/data/lint/LintResults.cjs.map +1 -0
- package/dist/data/lint/LintResults.d.ts +39 -0
- package/dist/data/lint/LintResults.d.ts.map +1 -0
- package/dist/data/lint/LintResults.fixtures.d.ts +10 -0
- package/dist/data/lint/LintResults.fixtures.d.ts.map +1 -0
- package/dist/data/lint/LintResults.js +144 -0
- package/dist/data/lint/LintResults.js.map +1 -0
- package/dist/data/lint/LintTreeNode.cjs +66 -0
- package/dist/data/lint/LintTreeNode.cjs.map +1 -0
- package/dist/data/lint/LintTreeNode.d.ts +7 -0
- package/dist/data/lint/LintTreeNode.d.ts.map +1 -0
- package/dist/data/lint/LintTreeNode.js +66 -0
- package/dist/data/lint/LintTreeNode.js.map +1 -0
- package/dist/data/lint/actions.cjs +195 -0
- package/dist/data/lint/actions.cjs.map +1 -0
- package/dist/data/lint/actions.d.ts +29 -0
- package/dist/data/lint/actions.d.ts.map +1 -0
- package/dist/data/lint/actions.js +195 -0
- package/dist/data/lint/actions.js.map +1 -0
- package/dist/data/lint/grouping-options.cjs +14 -0
- package/dist/data/lint/grouping-options.cjs.map +1 -0
- package/dist/data/lint/grouping-options.d.ts +9 -0
- package/dist/data/lint/grouping-options.d.ts.map +1 -0
- package/dist/data/lint/grouping-options.js +14 -0
- package/dist/data/lint/grouping-options.js.map +1 -0
- package/dist/data/lint/grouping.cjs +450 -0
- package/dist/data/lint/grouping.cjs.map +1 -0
- package/dist/data/lint/grouping.d.ts +10 -0
- package/dist/data/lint/grouping.d.ts.map +1 -0
- package/dist/data/lint/grouping.js +450 -0
- package/dist/data/lint/grouping.js.map +1 -0
- package/dist/data/lint/index.d.ts +10 -0
- package/dist/data/lint/index.d.ts.map +1 -0
- package/dist/data/lint/paths.cjs +35 -0
- package/dist/data/lint/paths.cjs.map +1 -0
- package/dist/data/lint/paths.d.ts +13 -0
- package/dist/data/lint/paths.d.ts.map +1 -0
- package/dist/data/lint/paths.js +35 -0
- package/dist/data/lint/paths.js.map +1 -0
- package/dist/data/lint/stats.cjs +76 -0
- package/dist/data/lint/stats.cjs.map +1 -0
- package/dist/data/lint/stats.d.ts +19 -0
- package/dist/data/lint/stats.d.ts.map +1 -0
- package/dist/data/lint/stats.js +76 -0
- package/dist/data/lint/stats.js.map +1 -0
- package/dist/data/lint/types.cjs +16 -0
- package/dist/data/lint/types.cjs.map +1 -0
- package/dist/data/lint/types.d.ts +93 -0
- package/dist/data/lint/types.d.ts.map +1 -0
- package/dist/data/lint/types.js +16 -0
- package/dist/data/lint/types.js.map +1 -0
- package/dist/data/test-runner/TestAttemptDetail.cjs +113 -0
- package/dist/data/test-runner/TestAttemptDetail.cjs.map +1 -0
- package/dist/data/test-runner/TestAttemptDetail.d.ts +19 -0
- package/dist/data/test-runner/TestAttemptDetail.d.ts.map +1 -0
- package/dist/data/test-runner/TestAttemptDetail.js +113 -0
- package/dist/data/test-runner/TestAttemptDetail.js.map +1 -0
- package/dist/data/test-runner/TestAttempts.cjs +36 -0
- package/dist/data/test-runner/TestAttempts.cjs.map +1 -0
- package/dist/data/test-runner/TestAttempts.d.ts +5 -0
- package/dist/data/test-runner/TestAttempts.d.ts.map +1 -0
- package/dist/data/test-runner/TestAttempts.js +36 -0
- package/dist/data/test-runner/TestAttempts.js.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.cjs +13 -3
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +14 -4
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.cjs +9 -29
- package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.d.ts +6 -6
- package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.js +9 -29
- package/dist/data/test-runner/TestFailureDetail.js.map +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs +33 -0
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
- package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunSummary.js +34 -1
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +3 -0
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +8 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +3 -0
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +3 -1
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
- package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
- package/dist/data/test-runner/TestTreeNode.js +3 -1
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +9 -1
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +5 -0
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +9 -1
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/attempts.cjs +62 -0
- package/dist/data/test-runner/attempts.cjs.map +1 -0
- package/dist/data/test-runner/attempts.d.ts +13 -0
- package/dist/data/test-runner/attempts.d.ts.map +1 -0
- package/dist/data/test-runner/attempts.js +62 -0
- package/dist/data/test-runner/attempts.js.map +1 -0
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +6 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +5 -1
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +2 -0
- package/dist/data/test-runner/marks.cjs.map +1 -1
- package/dist/data/test-runner/marks.d.ts.map +1 -1
- package/dist/data/test-runner/marks.js +2 -0
- package/dist/data/test-runner/marks.js.map +1 -1
- package/dist/data/test-runner/process-metrics.cjs +15 -0
- package/dist/data/test-runner/process-metrics.cjs.map +1 -0
- package/dist/data/test-runner/process-metrics.d.ts +22 -0
- package/dist/data/test-runner/process-metrics.d.ts.map +1 -0
- package/dist/data/test-runner/process-metrics.js +15 -0
- package/dist/data/test-runner/process-metrics.js.map +1 -0
- package/dist/data/test-runner/status.cjs +11 -3
- package/dist/data/test-runner/status.cjs.map +1 -1
- package/dist/data/test-runner/status.d.ts +3 -1
- package/dist/data/test-runner/status.d.ts.map +1 -1
- package/dist/data/test-runner/status.js +11 -3
- package/dist/data/test-runner/status.js.map +1 -1
- package/dist/data/test-runner/types.d.ts +14 -0
- package/dist/data/test-runner/types.d.ts.map +1 -1
- package/dist/data/traces/GoProfileView.cjs +176 -0
- package/dist/data/traces/GoProfileView.cjs.map +1 -0
- package/dist/data/traces/GoProfileView.d.ts +30 -0
- package/dist/data/traces/GoProfileView.d.ts.map +1 -0
- package/dist/data/traces/GoProfileView.js +176 -0
- package/dist/data/traces/GoProfileView.js.map +1 -0
- package/dist/data/traces/ProcessFacetTable.cjs +79 -0
- package/dist/data/traces/ProcessFacetTable.cjs.map +1 -0
- package/dist/data/traces/ProcessFacetTable.d.ts +21 -0
- package/dist/data/traces/ProcessFacetTable.d.ts.map +1 -0
- package/dist/data/traces/ProcessFacetTable.js +79 -0
- package/dist/data/traces/ProcessFacetTable.js.map +1 -0
- package/dist/data/traces/ProcessRecordViews.cjs +41 -0
- package/dist/data/traces/ProcessRecordViews.cjs.map +1 -0
- package/dist/data/traces/ProcessRecordViews.d.ts +16 -0
- package/dist/data/traces/ProcessRecordViews.d.ts.map +1 -0
- package/dist/data/traces/ProcessRecordViews.js +41 -0
- package/dist/data/traces/ProcessRecordViews.js.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.cjs +316 -0
- package/dist/data/traces/ProcessTraceDetail.cjs.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.d.ts +39 -0
- package/dist/data/traces/ProcessTraceDetail.d.ts.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.js +316 -0
- package/dist/data/traces/ProcessTraceDetail.js.map +1 -0
- package/dist/data/traces/ProcessTraceTree.cjs +135 -0
- package/dist/data/traces/ProcessTraceTree.cjs.map +1 -0
- package/dist/data/traces/ProcessTraceTree.d.ts +41 -0
- package/dist/data/traces/ProcessTraceTree.d.ts.map +1 -0
- package/dist/data/traces/ProcessTraceTree.js +135 -0
- package/dist/data/traces/ProcessTraceTree.js.map +1 -0
- package/dist/data/traces/Sparkline.cjs +45 -0
- package/dist/data/traces/Sparkline.cjs.map +1 -0
- package/dist/data/traces/Sparkline.d.ts +29 -0
- package/dist/data/traces/Sparkline.d.ts.map +1 -0
- package/dist/data/traces/Sparkline.js +45 -0
- package/dist/data/traces/Sparkline.js.map +1 -0
- package/dist/data/traces/SqlTraceTable.cjs +104 -0
- package/dist/data/traces/SqlTraceTable.cjs.map +1 -0
- package/dist/data/traces/SqlTraceTable.d.ts +19 -0
- package/dist/data/traces/SqlTraceTable.d.ts.map +1 -0
- package/dist/data/traces/SqlTraceTable.js +104 -0
- package/dist/data/traces/SqlTraceTable.js.map +1 -0
- package/dist/data/traces/TerminalCastPlayer.cjs +162 -0
- package/dist/data/traces/TerminalCastPlayer.cjs.map +1 -0
- package/dist/data/traces/TerminalCastPlayer.js +162 -0
- package/dist/data/traces/TerminalCastPlayer.js.map +1 -0
- package/dist/data/traces/TraceHarView.cjs +15 -0
- package/dist/data/traces/TraceHarView.cjs.map +1 -0
- package/dist/data/traces/TraceHarView.js +15 -0
- package/dist/data/traces/TraceHarView.js.map +1 -0
- package/dist/data/traces/TraceView.cjs +63 -0
- package/dist/data/traces/TraceView.cjs.map +1 -0
- package/dist/data/traces/TraceView.d.ts +20 -0
- package/dist/data/traces/TraceView.d.ts.map +1 -0
- package/dist/data/traces/TraceView.js +63 -0
- package/dist/data/traces/TraceView.js.map +1 -0
- package/dist/data/traces/TraceWindowList.cjs +117 -0
- package/dist/data/traces/TraceWindowList.cjs.map +1 -0
- package/dist/data/traces/TraceWindowList.d.ts +48 -0
- package/dist/data/traces/TraceWindowList.d.ts.map +1 -0
- package/dist/data/traces/TraceWindowList.js +117 -0
- package/dist/data/traces/TraceWindowList.js.map +1 -0
- package/dist/data/traces/cast.cjs +81 -0
- package/dist/data/traces/cast.cjs.map +1 -0
- package/dist/data/traces/cast.js +81 -0
- package/dist/data/traces/cast.js.map +1 -0
- package/dist/data/traces/fixtures.d.ts +25 -1
- package/dist/data/traces/fixtures.d.ts.map +1 -1
- package/dist/data/traces/har-adapter.cjs +83 -0
- package/dist/data/traces/har-adapter.cjs.map +1 -0
- package/dist/data/traces/har-adapter.js +83 -0
- package/dist/data/traces/har-adapter.js.map +1 -0
- package/dist/data/traces/index.d.ts +19 -0
- package/dist/data/traces/index.d.ts.map +1 -0
- package/dist/data/traces/process-facets.cjs +48 -0
- package/dist/data/traces/process-facets.cjs.map +1 -0
- package/dist/data/traces/process-facets.d.ts +38 -0
- package/dist/data/traces/process-facets.d.ts.map +1 -0
- package/dist/data/traces/process-facets.js +48 -0
- package/dist/data/traces/process-facets.js.map +1 -0
- package/dist/data/traces/process-tree.cjs +85 -0
- package/dist/data/traces/process-tree.cjs.map +1 -0
- package/dist/data/traces/process-tree.d.ts +40 -0
- package/dist/data/traces/process-tree.d.ts.map +1 -0
- package/dist/data/traces/process-tree.js +85 -0
- package/dist/data/traces/process-tree.js.map +1 -0
- package/dist/data/traces/profile-aggregate.cjs +78 -0
- package/dist/data/traces/profile-aggregate.cjs.map +1 -0
- package/dist/data/traces/profile-aggregate.d.ts +41 -0
- package/dist/data/traces/profile-aggregate.d.ts.map +1 -0
- package/dist/data/traces/profile-aggregate.js +78 -0
- package/dist/data/traces/profile-aggregate.js.map +1 -0
- package/dist/data/traces/sql-trace.cjs +39 -0
- package/dist/data/traces/sql-trace.cjs.map +1 -0
- package/dist/data/traces/sql-trace.d.ts +31 -0
- package/dist/data/traces/sql-trace.d.ts.map +1 -0
- package/dist/data/traces/sql-trace.js +39 -0
- package/dist/data/traces/sql-trace.js.map +1 -0
- package/dist/data/traces/stack-checkpoints.cjs +22 -0
- package/dist/data/traces/stack-checkpoints.cjs.map +1 -0
- package/dist/data/traces/stack-checkpoints.d.ts +18 -0
- package/dist/data/traces/stack-checkpoints.d.ts.map +1 -0
- package/dist/data/traces/stack-checkpoints.js +22 -0
- package/dist/data/traces/stack-checkpoints.js.map +1 -0
- package/dist/data/traces/terminal-screen.cjs +270 -0
- package/dist/data/traces/terminal-screen.cjs.map +1 -0
- package/dist/data/traces/terminal-screen.js +270 -0
- package/dist/data/traces/terminal-screen.js.map +1 -0
- package/dist/data/traces/terminal-timeline.cjs +48 -0
- package/dist/data/traces/terminal-timeline.cjs.map +1 -0
- package/dist/data/traces/terminal-timeline.js +48 -0
- package/dist/data/traces/terminal-timeline.js.map +1 -0
- package/dist/data/traces/types.d.ts +121 -8
- package/dist/data/traces/types.d.ts.map +1 -1
- package/dist/data/verification/adapters.cjs +1 -0
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +1 -0
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.cjs.map +1 -1
- package/dist/data/version-info.js +3 -3
- package/dist/data/version-info.js.map +1 -1
- package/dist/data.cjs +105 -5
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +5 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +101 -1
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +107 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +101 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo } from "react";
|
|
3
|
+
import { Switch } from "../../components/Switch.js";
|
|
4
|
+
import { cn } from "../../lib/utils.js";
|
|
5
|
+
import { Badge } from "../Badge.js";
|
|
6
|
+
import { CodeBlock } from "../CodeBlock.js";
|
|
7
|
+
import { DataTable } from "../DataTable.js";
|
|
8
|
+
import { JsonView } from "../JsonView.js";
|
|
9
|
+
import { groupStatements, formatStatementDuration } from "./sql-trace.js";
|
|
10
|
+
const COLUMNS = [
|
|
11
|
+
{ key: "startedAt", label: "Time", kind: "timestamp", shrink: true },
|
|
12
|
+
{
|
|
13
|
+
key: "op",
|
|
14
|
+
label: "Op",
|
|
15
|
+
shrink: true,
|
|
16
|
+
filterable: true,
|
|
17
|
+
render: (value) => /* @__PURE__ */ jsx(Badge, { variant: "soft", tone: "neutral", size: "xs", className: "font-mono", children: String(value) })
|
|
18
|
+
},
|
|
19
|
+
{ key: "tables", label: "Tables", kind: "tags", shrink: true },
|
|
20
|
+
{
|
|
21
|
+
key: "sql",
|
|
22
|
+
label: "SQL",
|
|
23
|
+
grow: true,
|
|
24
|
+
render: (_value, row) => /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-density-2", children: [
|
|
25
|
+
/* @__PURE__ */ jsx(CodeBlock, { inline: true, language: "sql", source: row.sql }),
|
|
26
|
+
row.count > 1 ? /* @__PURE__ */ jsx("span", { title: `${row.count} executions`, children: /* @__PURE__ */ jsx(Badge, { variant: "soft", tone: "info", size: "xs", children: `×${row.count}` }) }) : null
|
|
27
|
+
] })
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: "durationMs",
|
|
31
|
+
label: "Duration",
|
|
32
|
+
align: "right",
|
|
33
|
+
shrink: true,
|
|
34
|
+
render: (value, row) => /* @__PURE__ */ jsx("span", { className: "tabular-nums", title: row.count > 1 ? `${row.count} executions in total` : void 0, children: formatStatementDuration(Number(value)) }),
|
|
35
|
+
sortValue: (value) => Number(value)
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: "rows",
|
|
39
|
+
label: "Rows",
|
|
40
|
+
align: "right",
|
|
41
|
+
shrink: true,
|
|
42
|
+
render: (value) => Number(value) < 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "—" }) : /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: String(value) }),
|
|
43
|
+
sortValue: (value) => Number(value)
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "error",
|
|
47
|
+
label: "Error",
|
|
48
|
+
grow: true,
|
|
49
|
+
render: (value, row) => value ? /* @__PURE__ */ jsxs("span", { className: "truncate text-destructive", title: String(value), children: [
|
|
50
|
+
String(value),
|
|
51
|
+
row.count > 1 ? ` (${row.failed} of ${row.count} failed)` : ""
|
|
52
|
+
] }) : null
|
|
53
|
+
}
|
|
54
|
+
];
|
|
55
|
+
function StatementDetails({ row }) {
|
|
56
|
+
var _a;
|
|
57
|
+
const [first] = row.occurrences;
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-density-3", children: [
|
|
59
|
+
/* @__PURE__ */ jsx(CodeBlock, { language: "sql", source: row.sql, copyable: true }),
|
|
60
|
+
row.error ? /* @__PURE__ */ jsxs("div", { children: [
|
|
61
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 font-semibold text-foreground", children: "Error" }),
|
|
62
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap break-all text-destructive", children: row.error })
|
|
63
|
+
] }) : null,
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
|
|
65
|
+
first.connection,
|
|
66
|
+
" · ",
|
|
67
|
+
first.driver,
|
|
68
|
+
((_a = first.truncated) == null ? void 0 : _a.length) ? ` · truncated: ${first.truncated.join(", ")}` : ""
|
|
69
|
+
] }),
|
|
70
|
+
row.count > 1 ? /* @__PURE__ */ jsx("ul", { className: "space-y-1 text-xs", "aria-label": "Executions", children: row.occurrences.map((occurrence, index) => /* @__PURE__ */ jsxs("li", { className: cn("flex items-baseline gap-density-3", occurrence.error && "text-destructive"), children: [
|
|
71
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums text-muted-foreground", children: occurrence.startedAt }),
|
|
72
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: formatStatementDuration(occurrence.durationMs) }),
|
|
73
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: occurrence.rows < 0 ? "— rows" : `${occurrence.rows} rows` }),
|
|
74
|
+
occurrence.args ? /* @__PURE__ */ jsx("code", { className: "font-mono", children: JSON.stringify(occurrence.args) }) : null,
|
|
75
|
+
occurrence.error ? /* @__PURE__ */ jsx("span", { children: occurrence.error }) : null
|
|
76
|
+
] }, index)) }) : first.args ? /* @__PURE__ */ jsxs("div", { children: [
|
|
77
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 font-semibold text-foreground", children: "Arguments" }),
|
|
78
|
+
/* @__PURE__ */ jsx(JsonView, { data: first.args })
|
|
79
|
+
] }) : null
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
function SqlTraceTable({ rows, groupRepeated = true, emptyLabel = "No SQL statements recorded", className }) {
|
|
83
|
+
const [group, setGroup] = useState(groupRepeated);
|
|
84
|
+
const displayRows = useMemo(() => groupStatements(rows, { group }), [rows, group]);
|
|
85
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 flex-col gap-density-2", className), children: [
|
|
86
|
+
/* @__PURE__ */ jsx(Switch, { checked: group, onChange: setGroup, label: "Group repeated statements", className: "self-start px-density-2" }),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
DataTable,
|
|
89
|
+
{
|
|
90
|
+
data: displayRows,
|
|
91
|
+
columns: COLUMNS,
|
|
92
|
+
autoFilter: true,
|
|
93
|
+
emptyMessage: emptyLabel,
|
|
94
|
+
globalFilterPlaceholder: "Filter SQL, table, or error…",
|
|
95
|
+
getRowId: (row) => row.id,
|
|
96
|
+
renderExpandedRow: (row) => /* @__PURE__ */ jsx(StatementDetails, { row })
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
] });
|
|
100
|
+
}
|
|
101
|
+
export {
|
|
102
|
+
SqlTraceTable
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=SqlTraceTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlTraceTable.js","sources":["../../../src/data/traces/SqlTraceTable.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { Switch } from \"../../components/Switch\";\nimport { cn } from \"../../lib/utils\";\nimport { Badge } from \"../Badge\";\nimport { CodeBlock } from \"../CodeBlock\";\nimport { DataTable, type DataTableColumn } from \"../DataTable\";\nimport { JsonView } from \"../JsonView\";\nimport { formatStatementDuration, groupStatements, type SqlDisplayRow } from \"./sql-trace\";\nimport type { SqlStatementRow } from \"./types\";\n\nexport type SqlTraceTableProps = {\n /** `pg_proxy` / `sql_statements` trace records. */\n rows: SqlStatementRow[];\n /** Start with statements sharing a `repeatKey` collapsed into one counted row. Defaults to true. */\n groupRepeated?: boolean;\n /** Shown when there are no statements. */\n emptyLabel?: string;\n /** Classes applied to the table root. */\n className?: string;\n};\n\nconst COLUMNS: DataTableColumn<SqlDisplayRow>[] = [\n { key: \"startedAt\", label: \"Time\", kind: \"timestamp\", shrink: true },\n {\n key: \"op\",\n label: \"Op\",\n shrink: true,\n filterable: true,\n render: (value) => (\n <Badge variant=\"soft\" tone=\"neutral\" size=\"xs\" className=\"font-mono\">\n {String(value)}\n </Badge>\n ),\n },\n { key: \"tables\", label: \"Tables\", kind: \"tags\", shrink: true },\n {\n key: \"sql\",\n label: \"SQL\",\n grow: true,\n render: (_value, row) => (\n <span className=\"flex min-w-0 items-center gap-density-2\">\n <CodeBlock inline language=\"sql\" source={row.sql} />\n {row.count > 1 ? (\n <span title={`${row.count} executions`}>\n <Badge variant=\"soft\" tone=\"info\" size=\"xs\">\n {`×${row.count}`}\n </Badge>\n </span>\n ) : null}\n </span>\n ),\n },\n {\n key: \"durationMs\",\n label: \"Duration\",\n align: \"right\",\n shrink: true,\n render: (value, row) => (\n <span className=\"tabular-nums\" title={row.count > 1 ? `${row.count} executions in total` : undefined}>\n {formatStatementDuration(Number(value))}\n </span>\n ),\n sortValue: (value) => Number(value),\n },\n {\n key: \"rows\",\n label: \"Rows\",\n align: \"right\",\n shrink: true,\n render: (value) => (Number(value) < 0 ? <span className=\"text-muted-foreground\">—</span> : <span className=\"tabular-nums\">{String(value)}</span>),\n sortValue: (value) => Number(value),\n },\n {\n key: \"error\",\n label: \"Error\",\n grow: true,\n render: (value, row) =>\n value ? (\n <span className=\"truncate text-destructive\" title={String(value)}>\n {String(value)}\n {row.count > 1 ? ` (${row.failed} of ${row.count} failed)` : \"\"}\n </span>\n ) : null,\n },\n];\n\nfunction StatementDetails({ row }: { row: SqlDisplayRow }) {\n const [first] = row.occurrences as [SqlStatementRow, ...SqlStatementRow[]];\n return (\n <div className=\"space-y-density-3\">\n <CodeBlock language=\"sql\" source={row.sql} copyable />\n {row.error ? (\n <div>\n <div className=\"mb-1 font-semibold text-foreground\">Error</div>\n <pre className=\"whitespace-pre-wrap break-all text-destructive\">{row.error}</pre>\n </div>\n ) : null}\n <div className=\"text-xs text-muted-foreground\">\n {first.connection} · {first.driver}\n {first.truncated?.length ? ` · truncated: ${first.truncated.join(\", \")}` : \"\"}\n </div>\n {row.count > 1 ? (\n <ul className=\"space-y-1 text-xs\" aria-label=\"Executions\">\n {row.occurrences.map((occurrence, index) => (\n <li key={index} className={cn(\"flex items-baseline gap-density-3\", occurrence.error && \"text-destructive\")}>\n <span className=\"tabular-nums text-muted-foreground\">{occurrence.startedAt}</span>\n <span className=\"tabular-nums\">{formatStatementDuration(occurrence.durationMs)}</span>\n <span className=\"tabular-nums\">{occurrence.rows < 0 ? \"— rows\" : `${occurrence.rows} rows`}</span>\n {occurrence.args ? <code className=\"font-mono\">{JSON.stringify(occurrence.args)}</code> : null}\n {occurrence.error ? <span>{occurrence.error}</span> : null}\n </li>\n ))}\n </ul>\n ) : first.args ? (\n <div>\n <div className=\"mb-1 font-semibold text-foreground\">Arguments</div>\n <JsonView data={first.args} />\n </div>\n ) : null}\n </div>\n );\n}\n\n/**\n * `pg_proxy` / `sql_statements` records as a DataTable: time, op, tables, SQL,\n * duration, rows and error. Statements that differ only by their values share a\n * `repeatKey` and collapse into one row with a count badge and their total\n * duration; the switch above the table shows each execution instead.\n */\nexport function SqlTraceTable({ rows, groupRepeated = true, emptyLabel = \"No SQL statements recorded\", className }: SqlTraceTableProps) {\n const [group, setGroup] = useState(groupRepeated);\n const displayRows = useMemo(() => groupStatements(rows, { group }), [rows, group]);\n return (\n <div className={cn(\"flex h-full min-h-0 flex-col gap-density-2\", className)}>\n <Switch checked={group} onChange={setGroup} label=\"Group repeated statements\" className=\"self-start px-density-2\" />\n <DataTable\n data={displayRows}\n columns={COLUMNS}\n autoFilter\n emptyMessage={emptyLabel}\n globalFilterPlaceholder=\"Filter SQL, table, or error…\"\n getRowId={(row) => row.id}\n renderExpandedRow={(row) => <StatementDetails row={row} />}\n />\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const button = require("../../components/button.cjs");
|
|
6
|
+
const SegmentedControl = require("../../components/SegmentedControl.cjs");
|
|
7
|
+
const utils = require("../../lib/utils.cjs");
|
|
8
|
+
const AnsiHtml = require("../AnsiHtml.cjs");
|
|
9
|
+
const Badge = require("../Badge.cjs");
|
|
10
|
+
const Icon = require("../Icon.cjs");
|
|
11
|
+
const cast = require("./cast.cjs");
|
|
12
|
+
const terminalScreen = require("./terminal-screen.cjs");
|
|
13
|
+
const terminalTimeline = require("./terminal-timeline.cjs");
|
|
14
|
+
const UiPause = require("../../icons/components/UiPause.cjs");
|
|
15
|
+
const UiPlay = require("../../icons/components/UiPlay.cjs");
|
|
16
|
+
const UiSkipForward = require("../../icons/components/UiSkipForward.cjs");
|
|
17
|
+
const TICK_MS = 50;
|
|
18
|
+
const SPEEDS = ["1", "2", "4"];
|
|
19
|
+
const SPEED_OPTIONS = SPEEDS.map((speed) => ({ id: speed, label: `${speed}x` }));
|
|
20
|
+
const VIEW_OPTIONS = [
|
|
21
|
+
{ id: "replay", label: "Replay" },
|
|
22
|
+
{ id: "settled", label: "Settled screen" }
|
|
23
|
+
];
|
|
24
|
+
function resolveEvents(events, castText) {
|
|
25
|
+
if (events === void 0 === (castText === void 0)) {
|
|
26
|
+
throw new Error("TerminalCastPlayer takes either events or castText, not both or neither");
|
|
27
|
+
}
|
|
28
|
+
return events ?? cast.parseCast(castText);
|
|
29
|
+
}
|
|
30
|
+
function seconds(value) {
|
|
31
|
+
return `${value.toFixed(1)}s`;
|
|
32
|
+
}
|
|
33
|
+
function ExitBadge({ exit }) {
|
|
34
|
+
if (exit.exitCode === void 0) return /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { variant: "outline", tone: "neutral", size: "sm", children: "exited" });
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { variant: "soft", tone: exit.exitCode === 0 ? "success" : "danger", size: "sm", className: "font-mono", children: `exit ${exit.exitCode}` });
|
|
36
|
+
}
|
|
37
|
+
function useReplayScreen(timeline, position) {
|
|
38
|
+
const cache = react.useRef(void 0);
|
|
39
|
+
const count = terminalTimeline.stepCountAt(timeline.steps, position);
|
|
40
|
+
return react.useMemo(() => {
|
|
41
|
+
var _a;
|
|
42
|
+
const previous = ((_a = cache.current) == null ? void 0 : _a.timeline) === timeline ? cache.current.replay : void 0;
|
|
43
|
+
const replay = terminalTimeline.replayTo(previous, timeline, count);
|
|
44
|
+
cache.current = { timeline, replay };
|
|
45
|
+
return { ansi: terminalScreen.screenToAnsi(replay.screen), cols: replay.screen.width, rows: replay.screen.height };
|
|
46
|
+
}, [timeline, count]);
|
|
47
|
+
}
|
|
48
|
+
function TerminalCastPlayer({
|
|
49
|
+
events,
|
|
50
|
+
castText,
|
|
51
|
+
autoPlay = false,
|
|
52
|
+
emptyLabel = "No terminal output recorded",
|
|
53
|
+
className
|
|
54
|
+
}) {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
const timeline = react.useMemo(() => terminalTimeline.buildTimeline(resolveEvents(events, castText)), [events, castText]);
|
|
57
|
+
const [position, setPosition] = react.useState(0);
|
|
58
|
+
const [playing, setPlaying] = react.useState(autoPlay);
|
|
59
|
+
const [speed, setSpeed] = react.useState("1");
|
|
60
|
+
const [view, setView] = react.useState("replay");
|
|
61
|
+
const replay = useReplayScreen(timeline, position);
|
|
62
|
+
react.useEffect(() => {
|
|
63
|
+
if (!playing) return;
|
|
64
|
+
let last = Date.now();
|
|
65
|
+
const timer = setInterval(() => {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
const elapsed = (now - last) / 1e3;
|
|
68
|
+
last = now;
|
|
69
|
+
setPosition((current) => Math.min(timeline.duration, current + elapsed * Number(speed)));
|
|
70
|
+
}, TICK_MS);
|
|
71
|
+
return () => clearInterval(timer);
|
|
72
|
+
}, [playing, speed, timeline.duration]);
|
|
73
|
+
react.useEffect(() => {
|
|
74
|
+
if (playing && position >= timeline.duration) setPlaying(false);
|
|
75
|
+
}, [playing, position, timeline.duration]);
|
|
76
|
+
if (timeline.steps.length === 0 && timeline.settled === void 0) {
|
|
77
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-density-6 text-center text-muted-foreground text-sm", children: emptyLabel });
|
|
78
|
+
}
|
|
79
|
+
const hasSettled = timeline.settled !== void 0;
|
|
80
|
+
const showSettled = view === "settled" && hasSettled;
|
|
81
|
+
const play = () => {
|
|
82
|
+
if (position >= timeline.duration) setPosition(0);
|
|
83
|
+
setPlaying(true);
|
|
84
|
+
};
|
|
85
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex min-h-0 flex-col gap-density-2", className), children: [
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-density-2 text-xs text-muted-foreground", children: [
|
|
87
|
+
((_a = timeline.exit) == null ? void 0 : _a.command) ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-foreground", children: timeline.exit.command }) : null,
|
|
88
|
+
timeline.exit ? /* @__PURE__ */ jsxRuntime.jsx(ExitBadge, { exit: timeline.exit }) : null,
|
|
89
|
+
((_b = timeline.exit) == null ? void 0 : _b.truncated) ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: "Size caps or a full buffer stopped some output events being recorded", children: /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { variant: "soft", tone: "warning", size: "sm", children: "output truncated" }) }) : null,
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums", children: `${timeline.width}x${timeline.height}` }),
|
|
91
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
92
|
+
hasSettled && timeline.steps.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(SegmentedControl.SegmentedControl, { size: "sm", "aria-label": "Screen view", value: view, options: VIEW_OPTIONS, onChange: setView }) : null
|
|
93
|
+
] }),
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
95
|
+
"div",
|
|
96
|
+
{
|
|
97
|
+
role: "region",
|
|
98
|
+
"aria-label": "Terminal screen",
|
|
99
|
+
"data-cols": showSettled ? void 0 : replay.cols,
|
|
100
|
+
className: "overflow-auto rounded border bg-black p-density-2",
|
|
101
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
AnsiHtml.AnsiHtml,
|
|
103
|
+
{
|
|
104
|
+
text: showSettled ? timeline.settled : replay.ansi,
|
|
105
|
+
className: "font-mono text-xs leading-5 whitespace-pre text-gray-100"
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
timeline.steps.length > 0 && !showSettled ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-density-2", children: [
|
|
111
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112
|
+
button.Button,
|
|
113
|
+
{
|
|
114
|
+
variant: "ghost",
|
|
115
|
+
size: "icon",
|
|
116
|
+
"aria-label": playing ? "Pause" : "Play",
|
|
117
|
+
onClick: playing ? () => setPlaying(false) : play,
|
|
118
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: playing ? UiPause.UiPause : UiPlay.UiPlay })
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
122
|
+
"input",
|
|
123
|
+
{
|
|
124
|
+
type: "range",
|
|
125
|
+
"aria-label": "Seek",
|
|
126
|
+
className: "min-w-0 flex-1 accent-primary",
|
|
127
|
+
min: 0,
|
|
128
|
+
max: timeline.duration,
|
|
129
|
+
step: "any",
|
|
130
|
+
value: position,
|
|
131
|
+
onChange: (event) => setPosition(Number(event.target.value))
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: `${seconds(position)} / ${seconds(timeline.duration)}` }),
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
136
|
+
SegmentedControl.SegmentedControl,
|
|
137
|
+
{
|
|
138
|
+
size: "sm",
|
|
139
|
+
"aria-label": "Playback speed",
|
|
140
|
+
value: speed,
|
|
141
|
+
options: SPEED_OPTIONS,
|
|
142
|
+
onChange: setSpeed
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
146
|
+
button.Button,
|
|
147
|
+
{
|
|
148
|
+
variant: "ghost",
|
|
149
|
+
size: "icon",
|
|
150
|
+
"aria-label": "Jump to end",
|
|
151
|
+
onClick: () => {
|
|
152
|
+
setPlaying(false);
|
|
153
|
+
setPosition(timeline.duration);
|
|
154
|
+
},
|
|
155
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSkipForward.UiSkipForward })
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
] }) : null
|
|
159
|
+
] });
|
|
160
|
+
}
|
|
161
|
+
exports.TerminalCastPlayer = TerminalCastPlayer;
|
|
162
|
+
//# sourceMappingURL=TerminalCastPlayer.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TerminalCastPlayer.cjs","sources":["../../../src/data/traces/TerminalCastPlayer.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { SegmentedControl } from \"../../components/SegmentedControl\";\nimport { UiPause, UiPlay, UiSkipForward } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport { AnsiHtml } from \"../AnsiHtml\";\nimport { Badge } from \"../Badge\";\nimport { Icon } from \"../Icon\";\nimport { parseCast } from \"./cast\";\nimport { screenToAnsi } from \"./terminal-screen\";\nimport {\n buildTimeline,\n replayTo,\n stepCountAt,\n type ScreenReplay,\n type TerminalTimeline,\n} from \"./terminal-timeline\";\nimport type { TerminalEvent } from \"./types\";\n\nconst TICK_MS = 50;\nconst SPEEDS = [\"1\", \"2\", \"4\"] as const;\ntype Speed = (typeof SPEEDS)[number];\ntype View = \"replay\" | \"settled\";\n\nconst SPEED_OPTIONS = SPEEDS.map((speed) => ({ id: speed, label: `${speed}x` }));\nconst VIEW_OPTIONS: { id: View; label: string }[] = [\n { id: \"replay\", label: \"Replay\" },\n { id: \"settled\", label: \"Settled screen\" },\n];\n\nexport type TerminalCastPlayerProps = {\n /** `terminal` trace records. Give this or `castText`. */\n events?: TerminalEvent[];\n /** An asciinema v2 cast, such as a downloaded `.cast`. Give this or `events`. */\n castText?: string;\n /** Start playing on mount. */\n autoPlay?: boolean;\n /** Shown when the session recorded no events. */\n emptyLabel?: string;\n /** Classes applied to the player root. */\n className?: string;\n};\n\nfunction resolveEvents(events: TerminalEvent[] | undefined, castText: string | undefined): TerminalEvent[] {\n if ((events === undefined) === (castText === undefined)) {\n throw new Error(\"TerminalCastPlayer takes either events or castText, not both or neither\");\n }\n return events ?? parseCast(castText!);\n}\n\nfunction seconds(value: number): string {\n return `${value.toFixed(1)}s`;\n}\n\nfunction ExitBadge({ exit }: { exit: TerminalEvent }) {\n if (exit.exitCode === undefined) return <Badge variant=\"outline\" tone=\"neutral\" size=\"sm\">exited</Badge>;\n return (\n <Badge variant=\"soft\" tone={exit.exitCode === 0 ? \"success\" : \"danger\"} size=\"sm\" className=\"font-mono\">\n {`exit ${exit.exitCode}`}\n </Badge>\n );\n}\n\n/** Feeds the timeline to a screen as the position moves, reusing the screen while moving forward. */\nfunction useReplayScreen(timeline: TerminalTimeline, position: number) {\n const cache = useRef<{ timeline: TerminalTimeline; replay: ScreenReplay } | undefined>(undefined);\n const count = stepCountAt(timeline.steps, position);\n return useMemo(() => {\n const previous = cache.current?.timeline === timeline ? cache.current.replay : undefined;\n const replay = replayTo(previous, timeline, count);\n cache.current = { timeline, replay };\n return { ansi: screenToAnsi(replay.screen), cols: replay.screen.width, rows: replay.screen.height };\n }, [timeline, count]);\n}\n\n/**\n * Replays a `terminal` trace: output events over time with play/pause, a\n * scrubber, 1x/2x/4x speed and jump-to-end, honouring resizes. A downloaded\n * asciinema cast renders the same way through `castText`. When the capture\n * settled a screen, it is offered as the \"Settled screen\" view.\n */\nexport function TerminalCastPlayer({\n events,\n castText,\n autoPlay = false,\n emptyLabel = \"No terminal output recorded\",\n className,\n}: TerminalCastPlayerProps) {\n const timeline = useMemo(() => buildTimeline(resolveEvents(events, castText)), [events, castText]);\n const [position, setPosition] = useState(0);\n const [playing, setPlaying] = useState(autoPlay);\n const [speed, setSpeed] = useState<Speed>(\"1\");\n const [view, setView] = useState<View>(\"replay\");\n const replay = useReplayScreen(timeline, position);\n\n useEffect(() => {\n if (!playing) return;\n let last = Date.now();\n const timer = setInterval(() => {\n const now = Date.now();\n const elapsed = (now - last) / 1000;\n last = now;\n setPosition((current) => Math.min(timeline.duration, current + elapsed * Number(speed)));\n }, TICK_MS);\n return () => clearInterval(timer);\n }, [playing, speed, timeline.duration]);\n\n useEffect(() => {\n if (playing && position >= timeline.duration) setPlaying(false);\n }, [playing, position, timeline.duration]);\n\n if (timeline.steps.length === 0 && timeline.settled === undefined) {\n return <div className=\"p-density-6 text-center text-muted-foreground text-sm\">{emptyLabel}</div>;\n }\n\n const hasSettled = timeline.settled !== undefined;\n const showSettled = view === \"settled\" && hasSettled;\n const play = () => {\n if (position >= timeline.duration) setPosition(0);\n setPlaying(true);\n };\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-density-2\", className)}>\n <div className=\"flex flex-wrap items-center gap-density-2 text-xs text-muted-foreground\">\n {timeline.exit?.command ? <code className=\"font-mono text-foreground\">{timeline.exit.command}</code> : null}\n {timeline.exit ? <ExitBadge exit={timeline.exit} /> : null}\n {timeline.exit?.truncated ? (\n <span title=\"Size caps or a full buffer stopped some output events being recorded\">\n <Badge variant=\"soft\" tone=\"warning\" size=\"sm\">output truncated</Badge>\n </span>\n ) : null}\n <span className=\"tabular-nums\">{`${timeline.width}x${timeline.height}`}</span>\n <span className=\"flex-1\" />\n {hasSettled && timeline.steps.length > 0 ? (\n <SegmentedControl size=\"sm\" aria-label=\"Screen view\" value={view} options={VIEW_OPTIONS} onChange={setView} />\n ) : null}\n </div>\n\n <div\n role=\"region\"\n aria-label=\"Terminal screen\"\n data-cols={showSettled ? undefined : replay.cols}\n className=\"overflow-auto rounded border bg-black p-density-2\"\n >\n <AnsiHtml\n text={showSettled ? timeline.settled! : replay.ansi}\n className=\"font-mono text-xs leading-5 whitespace-pre text-gray-100\"\n />\n </div>\n\n {timeline.steps.length > 0 && !showSettled ? (\n <div className=\"flex items-center gap-density-2\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={playing ? \"Pause\" : \"Play\"}\n onClick={playing ? () => setPlaying(false) : play}\n >\n <Icon icon={playing ? UiPause : UiPlay} />\n </Button>\n <input\n type=\"range\"\n aria-label=\"Seek\"\n className=\"min-w-0 flex-1 accent-primary\"\n min={0}\n max={timeline.duration}\n step=\"any\"\n value={position}\n onChange={(event) => setPosition(Number(event.target.value))}\n />\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {`${seconds(position)} / ${seconds(timeline.duration)}`}\n </span>\n <SegmentedControl\n size=\"sm\"\n aria-label=\"Playback speed\"\n value={speed}\n options={SPEED_OPTIONS}\n onChange={setSpeed}\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Jump to end\"\n onClick={() => {\n setPlaying(false);\n setPosition(timeline.duration);\n }}\n >\n <Icon icon={UiSkipForward} />\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"names":["parseCast","jsx","Badge","useRef","stepCountAt","useMemo","replayTo","screenToAnsi","buildTimeline","useState","useEffect","cn","jsxs","SegmentedControl","AnsiHtml","Button","Icon","UiPause","UiPlay","UiSkipForward"],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState, useEffect, useRef } from "react";
|
|
3
|
+
import { Button } from "../../components/button.js";
|
|
4
|
+
import { SegmentedControl } from "../../components/SegmentedControl.js";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
import { AnsiHtml } from "../AnsiHtml.js";
|
|
7
|
+
import { Badge } from "../Badge.js";
|
|
8
|
+
import { Icon } from "../Icon.js";
|
|
9
|
+
import { parseCast } from "./cast.js";
|
|
10
|
+
import { screenToAnsi } from "./terminal-screen.js";
|
|
11
|
+
import { buildTimeline, stepCountAt, replayTo } from "./terminal-timeline.js";
|
|
12
|
+
import { UiPause } from "../../icons/components/UiPause.js";
|
|
13
|
+
import { UiPlay } from "../../icons/components/UiPlay.js";
|
|
14
|
+
import { UiSkipForward } from "../../icons/components/UiSkipForward.js";
|
|
15
|
+
const TICK_MS = 50;
|
|
16
|
+
const SPEEDS = ["1", "2", "4"];
|
|
17
|
+
const SPEED_OPTIONS = SPEEDS.map((speed) => ({ id: speed, label: `${speed}x` }));
|
|
18
|
+
const VIEW_OPTIONS = [
|
|
19
|
+
{ id: "replay", label: "Replay" },
|
|
20
|
+
{ id: "settled", label: "Settled screen" }
|
|
21
|
+
];
|
|
22
|
+
function resolveEvents(events, castText) {
|
|
23
|
+
if (events === void 0 === (castText === void 0)) {
|
|
24
|
+
throw new Error("TerminalCastPlayer takes either events or castText, not both or neither");
|
|
25
|
+
}
|
|
26
|
+
return events ?? parseCast(castText);
|
|
27
|
+
}
|
|
28
|
+
function seconds(value) {
|
|
29
|
+
return `${value.toFixed(1)}s`;
|
|
30
|
+
}
|
|
31
|
+
function ExitBadge({ exit }) {
|
|
32
|
+
if (exit.exitCode === void 0) return /* @__PURE__ */ jsx(Badge, { variant: "outline", tone: "neutral", size: "sm", children: "exited" });
|
|
33
|
+
return /* @__PURE__ */ jsx(Badge, { variant: "soft", tone: exit.exitCode === 0 ? "success" : "danger", size: "sm", className: "font-mono", children: `exit ${exit.exitCode}` });
|
|
34
|
+
}
|
|
35
|
+
function useReplayScreen(timeline, position) {
|
|
36
|
+
const cache = useRef(void 0);
|
|
37
|
+
const count = stepCountAt(timeline.steps, position);
|
|
38
|
+
return useMemo(() => {
|
|
39
|
+
var _a;
|
|
40
|
+
const previous = ((_a = cache.current) == null ? void 0 : _a.timeline) === timeline ? cache.current.replay : void 0;
|
|
41
|
+
const replay = replayTo(previous, timeline, count);
|
|
42
|
+
cache.current = { timeline, replay };
|
|
43
|
+
return { ansi: screenToAnsi(replay.screen), cols: replay.screen.width, rows: replay.screen.height };
|
|
44
|
+
}, [timeline, count]);
|
|
45
|
+
}
|
|
46
|
+
function TerminalCastPlayer({
|
|
47
|
+
events,
|
|
48
|
+
castText,
|
|
49
|
+
autoPlay = false,
|
|
50
|
+
emptyLabel = "No terminal output recorded",
|
|
51
|
+
className
|
|
52
|
+
}) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
const timeline = useMemo(() => buildTimeline(resolveEvents(events, castText)), [events, castText]);
|
|
55
|
+
const [position, setPosition] = useState(0);
|
|
56
|
+
const [playing, setPlaying] = useState(autoPlay);
|
|
57
|
+
const [speed, setSpeed] = useState("1");
|
|
58
|
+
const [view, setView] = useState("replay");
|
|
59
|
+
const replay = useReplayScreen(timeline, position);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!playing) return;
|
|
62
|
+
let last = Date.now();
|
|
63
|
+
const timer = setInterval(() => {
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
const elapsed = (now - last) / 1e3;
|
|
66
|
+
last = now;
|
|
67
|
+
setPosition((current) => Math.min(timeline.duration, current + elapsed * Number(speed)));
|
|
68
|
+
}, TICK_MS);
|
|
69
|
+
return () => clearInterval(timer);
|
|
70
|
+
}, [playing, speed, timeline.duration]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (playing && position >= timeline.duration) setPlaying(false);
|
|
73
|
+
}, [playing, position, timeline.duration]);
|
|
74
|
+
if (timeline.steps.length === 0 && timeline.settled === void 0) {
|
|
75
|
+
return /* @__PURE__ */ jsx("div", { className: "p-density-6 text-center text-muted-foreground text-sm", children: emptyLabel });
|
|
76
|
+
}
|
|
77
|
+
const hasSettled = timeline.settled !== void 0;
|
|
78
|
+
const showSettled = view === "settled" && hasSettled;
|
|
79
|
+
const play = () => {
|
|
80
|
+
if (position >= timeline.duration) setPosition(0);
|
|
81
|
+
setPlaying(true);
|
|
82
|
+
};
|
|
83
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex min-h-0 flex-col gap-density-2", className), children: [
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-density-2 text-xs text-muted-foreground", children: [
|
|
85
|
+
((_a = timeline.exit) == null ? void 0 : _a.command) ? /* @__PURE__ */ jsx("code", { className: "font-mono text-foreground", children: timeline.exit.command }) : null,
|
|
86
|
+
timeline.exit ? /* @__PURE__ */ jsx(ExitBadge, { exit: timeline.exit }) : null,
|
|
87
|
+
((_b = timeline.exit) == null ? void 0 : _b.truncated) ? /* @__PURE__ */ jsx("span", { title: "Size caps or a full buffer stopped some output events being recorded", children: /* @__PURE__ */ jsx(Badge, { variant: "soft", tone: "warning", size: "sm", children: "output truncated" }) }) : null,
|
|
88
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: `${timeline.width}x${timeline.height}` }),
|
|
89
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
90
|
+
hasSettled && timeline.steps.length > 0 ? /* @__PURE__ */ jsx(SegmentedControl, { size: "sm", "aria-label": "Screen view", value: view, options: VIEW_OPTIONS, onChange: setView }) : null
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
role: "region",
|
|
96
|
+
"aria-label": "Terminal screen",
|
|
97
|
+
"data-cols": showSettled ? void 0 : replay.cols,
|
|
98
|
+
className: "overflow-auto rounded border bg-black p-density-2",
|
|
99
|
+
children: /* @__PURE__ */ jsx(
|
|
100
|
+
AnsiHtml,
|
|
101
|
+
{
|
|
102
|
+
text: showSettled ? timeline.settled : replay.ansi,
|
|
103
|
+
className: "font-mono text-xs leading-5 whitespace-pre text-gray-100"
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
timeline.steps.length > 0 && !showSettled ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-density-2", children: [
|
|
109
|
+
/* @__PURE__ */ jsx(
|
|
110
|
+
Button,
|
|
111
|
+
{
|
|
112
|
+
variant: "ghost",
|
|
113
|
+
size: "icon",
|
|
114
|
+
"aria-label": playing ? "Pause" : "Play",
|
|
115
|
+
onClick: playing ? () => setPlaying(false) : play,
|
|
116
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: playing ? UiPause : UiPlay })
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
"input",
|
|
121
|
+
{
|
|
122
|
+
type: "range",
|
|
123
|
+
"aria-label": "Seek",
|
|
124
|
+
className: "min-w-0 flex-1 accent-primary",
|
|
125
|
+
min: 0,
|
|
126
|
+
max: timeline.duration,
|
|
127
|
+
step: "any",
|
|
128
|
+
value: position,
|
|
129
|
+
onChange: (event) => setPosition(Number(event.target.value))
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: `${seconds(position)} / ${seconds(timeline.duration)}` }),
|
|
133
|
+
/* @__PURE__ */ jsx(
|
|
134
|
+
SegmentedControl,
|
|
135
|
+
{
|
|
136
|
+
size: "sm",
|
|
137
|
+
"aria-label": "Playback speed",
|
|
138
|
+
value: speed,
|
|
139
|
+
options: SPEED_OPTIONS,
|
|
140
|
+
onChange: setSpeed
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
/* @__PURE__ */ jsx(
|
|
144
|
+
Button,
|
|
145
|
+
{
|
|
146
|
+
variant: "ghost",
|
|
147
|
+
size: "icon",
|
|
148
|
+
"aria-label": "Jump to end",
|
|
149
|
+
onClick: () => {
|
|
150
|
+
setPlaying(false);
|
|
151
|
+
setPosition(timeline.duration);
|
|
152
|
+
},
|
|
153
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiSkipForward })
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
] }) : null
|
|
157
|
+
] });
|
|
158
|
+
}
|
|
159
|
+
export {
|
|
160
|
+
TerminalCastPlayer
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=TerminalCastPlayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TerminalCastPlayer.js","sources":["../../../src/data/traces/TerminalCastPlayer.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { SegmentedControl } from \"../../components/SegmentedControl\";\nimport { UiPause, UiPlay, UiSkipForward } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport { AnsiHtml } from \"../AnsiHtml\";\nimport { Badge } from \"../Badge\";\nimport { Icon } from \"../Icon\";\nimport { parseCast } from \"./cast\";\nimport { screenToAnsi } from \"./terminal-screen\";\nimport {\n buildTimeline,\n replayTo,\n stepCountAt,\n type ScreenReplay,\n type TerminalTimeline,\n} from \"./terminal-timeline\";\nimport type { TerminalEvent } from \"./types\";\n\nconst TICK_MS = 50;\nconst SPEEDS = [\"1\", \"2\", \"4\"] as const;\ntype Speed = (typeof SPEEDS)[number];\ntype View = \"replay\" | \"settled\";\n\nconst SPEED_OPTIONS = SPEEDS.map((speed) => ({ id: speed, label: `${speed}x` }));\nconst VIEW_OPTIONS: { id: View; label: string }[] = [\n { id: \"replay\", label: \"Replay\" },\n { id: \"settled\", label: \"Settled screen\" },\n];\n\nexport type TerminalCastPlayerProps = {\n /** `terminal` trace records. Give this or `castText`. */\n events?: TerminalEvent[];\n /** An asciinema v2 cast, such as a downloaded `.cast`. Give this or `events`. */\n castText?: string;\n /** Start playing on mount. */\n autoPlay?: boolean;\n /** Shown when the session recorded no events. */\n emptyLabel?: string;\n /** Classes applied to the player root. */\n className?: string;\n};\n\nfunction resolveEvents(events: TerminalEvent[] | undefined, castText: string | undefined): TerminalEvent[] {\n if ((events === undefined) === (castText === undefined)) {\n throw new Error(\"TerminalCastPlayer takes either events or castText, not both or neither\");\n }\n return events ?? parseCast(castText!);\n}\n\nfunction seconds(value: number): string {\n return `${value.toFixed(1)}s`;\n}\n\nfunction ExitBadge({ exit }: { exit: TerminalEvent }) {\n if (exit.exitCode === undefined) return <Badge variant=\"outline\" tone=\"neutral\" size=\"sm\">exited</Badge>;\n return (\n <Badge variant=\"soft\" tone={exit.exitCode === 0 ? \"success\" : \"danger\"} size=\"sm\" className=\"font-mono\">\n {`exit ${exit.exitCode}`}\n </Badge>\n );\n}\n\n/** Feeds the timeline to a screen as the position moves, reusing the screen while moving forward. */\nfunction useReplayScreen(timeline: TerminalTimeline, position: number) {\n const cache = useRef<{ timeline: TerminalTimeline; replay: ScreenReplay } | undefined>(undefined);\n const count = stepCountAt(timeline.steps, position);\n return useMemo(() => {\n const previous = cache.current?.timeline === timeline ? cache.current.replay : undefined;\n const replay = replayTo(previous, timeline, count);\n cache.current = { timeline, replay };\n return { ansi: screenToAnsi(replay.screen), cols: replay.screen.width, rows: replay.screen.height };\n }, [timeline, count]);\n}\n\n/**\n * Replays a `terminal` trace: output events over time with play/pause, a\n * scrubber, 1x/2x/4x speed and jump-to-end, honouring resizes. A downloaded\n * asciinema cast renders the same way through `castText`. When the capture\n * settled a screen, it is offered as the \"Settled screen\" view.\n */\nexport function TerminalCastPlayer({\n events,\n castText,\n autoPlay = false,\n emptyLabel = \"No terminal output recorded\",\n className,\n}: TerminalCastPlayerProps) {\n const timeline = useMemo(() => buildTimeline(resolveEvents(events, castText)), [events, castText]);\n const [position, setPosition] = useState(0);\n const [playing, setPlaying] = useState(autoPlay);\n const [speed, setSpeed] = useState<Speed>(\"1\");\n const [view, setView] = useState<View>(\"replay\");\n const replay = useReplayScreen(timeline, position);\n\n useEffect(() => {\n if (!playing) return;\n let last = Date.now();\n const timer = setInterval(() => {\n const now = Date.now();\n const elapsed = (now - last) / 1000;\n last = now;\n setPosition((current) => Math.min(timeline.duration, current + elapsed * Number(speed)));\n }, TICK_MS);\n return () => clearInterval(timer);\n }, [playing, speed, timeline.duration]);\n\n useEffect(() => {\n if (playing && position >= timeline.duration) setPlaying(false);\n }, [playing, position, timeline.duration]);\n\n if (timeline.steps.length === 0 && timeline.settled === undefined) {\n return <div className=\"p-density-6 text-center text-muted-foreground text-sm\">{emptyLabel}</div>;\n }\n\n const hasSettled = timeline.settled !== undefined;\n const showSettled = view === \"settled\" && hasSettled;\n const play = () => {\n if (position >= timeline.duration) setPosition(0);\n setPlaying(true);\n };\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-density-2\", className)}>\n <div className=\"flex flex-wrap items-center gap-density-2 text-xs text-muted-foreground\">\n {timeline.exit?.command ? <code className=\"font-mono text-foreground\">{timeline.exit.command}</code> : null}\n {timeline.exit ? <ExitBadge exit={timeline.exit} /> : null}\n {timeline.exit?.truncated ? (\n <span title=\"Size caps or a full buffer stopped some output events being recorded\">\n <Badge variant=\"soft\" tone=\"warning\" size=\"sm\">output truncated</Badge>\n </span>\n ) : null}\n <span className=\"tabular-nums\">{`${timeline.width}x${timeline.height}`}</span>\n <span className=\"flex-1\" />\n {hasSettled && timeline.steps.length > 0 ? (\n <SegmentedControl size=\"sm\" aria-label=\"Screen view\" value={view} options={VIEW_OPTIONS} onChange={setView} />\n ) : null}\n </div>\n\n <div\n role=\"region\"\n aria-label=\"Terminal screen\"\n data-cols={showSettled ? undefined : replay.cols}\n className=\"overflow-auto rounded border bg-black p-density-2\"\n >\n <AnsiHtml\n text={showSettled ? timeline.settled! : replay.ansi}\n className=\"font-mono text-xs leading-5 whitespace-pre text-gray-100\"\n />\n </div>\n\n {timeline.steps.length > 0 && !showSettled ? (\n <div className=\"flex items-center gap-density-2\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={playing ? \"Pause\" : \"Play\"}\n onClick={playing ? () => setPlaying(false) : play}\n >\n <Icon icon={playing ? UiPause : UiPlay} />\n </Button>\n <input\n type=\"range\"\n aria-label=\"Seek\"\n className=\"min-w-0 flex-1 accent-primary\"\n min={0}\n max={timeline.duration}\n step=\"any\"\n value={position}\n onChange={(event) => setPosition(Number(event.target.value))}\n />\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {`${seconds(position)} / ${seconds(timeline.duration)}`}\n </span>\n <SegmentedControl\n size=\"sm\"\n aria-label=\"Playback speed\"\n value={speed}\n options={SPEED_OPTIONS}\n onChange={setSpeed}\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Jump to end\"\n onClick={() => {\n setPlaying(false);\n setPosition(timeline.duration);\n }}\n >\n <Icon icon={UiSkipForward} />\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const HarPanel = require("../har/HarPanel.cjs");
|
|
6
|
+
const harAdapter = require("./har-adapter.cjs");
|
|
7
|
+
function TraceHarView({ rows, emptyLabel = "No HTTP exchanges recorded", ...panel }) {
|
|
8
|
+
const entries = react.useMemo(
|
|
9
|
+
() => rows.map((row, index) => harAdapter.exchangeToHarEntry(row, { id: `${row.startedAt}#${index}` })),
|
|
10
|
+
[rows]
|
|
11
|
+
);
|
|
12
|
+
return /* @__PURE__ */ jsxRuntime.jsx(HarPanel.HarPanel, { entries, emptyLabel, ...panel });
|
|
13
|
+
}
|
|
14
|
+
exports.TraceHarView = TraceHarView;
|
|
15
|
+
//# sourceMappingURL=TraceHarView.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceHarView.cjs","sources":["../../../src/data/traces/TraceHarView.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { HarPanel, type HarPanelProps } from \"../har/HarPanel\";\nimport { exchangeToHarEntry } from \"./har-adapter\";\nimport type { HttpExchangeRow } from \"./types\";\n\nexport type TraceHarViewProps = Omit<HarPanelProps, \"entries\"> & {\n /** `http` / `http_proxy` trace records. */\n rows: HttpExchangeRow[];\n};\n\n/**\n * `http` / `http_proxy` trace records rendered by the shared HarPanel. Bodies\n * the store parsed into structure are shown as JSON; a tunnelled CONNECT shows\n * its bytes in and out where a body would be.\n */\nexport function TraceHarView({ rows, emptyLabel = \"No HTTP exchanges recorded\", ...panel }: TraceHarViewProps) {\n const entries = useMemo(\n () => rows.map((row, index) => exchangeToHarEntry(row, { id: `${row.startedAt}#${index}` })),\n [rows],\n );\n return <HarPanel entries={entries} emptyLabel={emptyLabel} {...panel} />;\n}\n"],"names":["useMemo","exchangeToHarEntry","jsx","HarPanel"],"mappings":";;;;;;AAeO,SAAS,aAAa,EAAE,MAAM,aAAa,8BAA8B,GAAG,SAA4B;AAC7G,QAAM,UAAUA,MAAAA;AAAAA,IACd,MAAM,KAAK,IAAI,CAAC,KAAK,UAAUC,WAAAA,mBAAmB,KAAK,EAAE,IAAI,GAAG,IAAI,SAAS,IAAI,KAAK,GAAA,CAAI,CAAC;AAAA,IAC3F,CAAC,IAAI;AAAA,EAAA;AAEP,SAAOC,2BAAAA,IAACC,SAAAA,UAAA,EAAS,SAAkB,YAAyB,GAAG,OAAO;AACxE;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { HarPanel } from "../har/HarPanel.js";
|
|
4
|
+
import { exchangeToHarEntry } from "./har-adapter.js";
|
|
5
|
+
function TraceHarView({ rows, emptyLabel = "No HTTP exchanges recorded", ...panel }) {
|
|
6
|
+
const entries = useMemo(
|
|
7
|
+
() => rows.map((row, index) => exchangeToHarEntry(row, { id: `${row.startedAt}#${index}` })),
|
|
8
|
+
[rows]
|
|
9
|
+
);
|
|
10
|
+
return /* @__PURE__ */ jsx(HarPanel, { entries, emptyLabel, ...panel });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
TraceHarView
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=TraceHarView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceHarView.js","sources":["../../../src/data/traces/TraceHarView.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { HarPanel, type HarPanelProps } from \"../har/HarPanel\";\nimport { exchangeToHarEntry } from \"./har-adapter\";\nimport type { HttpExchangeRow } from \"./types\";\n\nexport type TraceHarViewProps = Omit<HarPanelProps, \"entries\"> & {\n /** `http` / `http_proxy` trace records. */\n rows: HttpExchangeRow[];\n};\n\n/**\n * `http` / `http_proxy` trace records rendered by the shared HarPanel. Bodies\n * the store parsed into structure are shown as JSON; a tunnelled CONNECT shows\n * its bytes in and out where a body would be.\n */\nexport function TraceHarView({ rows, emptyLabel = \"No HTTP exchanges recorded\", ...panel }: TraceHarViewProps) {\n const entries = useMemo(\n () => rows.map((row, index) => exchangeToHarEntry(row, { id: `${row.startedAt}#${index}` })),\n [rows],\n );\n return <HarPanel entries={entries} emptyLabel={emptyLabel} {...panel} />;\n}\n"],"names":[],"mappings":";;;;AAeO,SAAS,aAAa,EAAE,MAAM,aAAa,8BAA8B,GAAG,SAA4B;AAC7G,QAAM,UAAU;AAAA,IACd,MAAM,KAAK,IAAI,CAAC,KAAK,UAAU,mBAAmB,KAAK,EAAE,IAAI,GAAG,IAAI,SAAS,IAAI,KAAK,GAAA,CAAI,CAAC;AAAA,IAC3F,CAAC,IAAI;AAAA,EAAA;AAEP,SAAO,oBAAC,UAAA,EAAS,SAAkB,YAAyB,GAAG,OAAO;AACxE;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const utils = require("../../lib/utils.cjs");
|
|
6
|
+
const dataTableUtils = require("../data-table-utils.cjs");
|
|
7
|
+
const DataTable = require("../DataTable.cjs");
|
|
8
|
+
const ProcessRecordViews = require("./ProcessRecordViews.cjs");
|
|
9
|
+
const ProcessTraceTree = require("./ProcessTraceTree.cjs");
|
|
10
|
+
const SqlTraceTable = require("./SqlTraceTable.cjs");
|
|
11
|
+
const TerminalCastPlayer = require("./TerminalCastPlayer.cjs");
|
|
12
|
+
const TraceHarView = require("./TraceHarView.cjs");
|
|
13
|
+
function requireField(kind, rows, field) {
|
|
14
|
+
rows.forEach((row, index) => {
|
|
15
|
+
if (row[field] === void 0 || row[field] === null) {
|
|
16
|
+
throw new Error(`trace kind "${kind}" row ${index} has no "${field}"`);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function GenericTraceTable({ kind, rows }) {
|
|
21
|
+
const columns = react.useMemo(() => dataTableUtils.inferColumns(rows, { literalKeys: true }), [rows]);
|
|
22
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DataTable.DataTable, { data: rows, columns, autoFilter: true, emptyMessage: `No ${kind} records` });
|
|
23
|
+
}
|
|
24
|
+
function ProcessTraceView({ rows, samples }) {
|
|
25
|
+
const [selectedKey, setSelectedKey] = react.useState(null);
|
|
26
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ProcessTraceTree.ProcessTraceTree, { nodes: rows, selectedKey, onSelect: setSelectedKey, ...samples ? { samples } : {} });
|
|
27
|
+
}
|
|
28
|
+
function TraceView({ kind, rows, samples, className }) {
|
|
29
|
+
const body = (() => {
|
|
30
|
+
switch (kind) {
|
|
31
|
+
case "http":
|
|
32
|
+
case "http_proxy":
|
|
33
|
+
requireField(kind, rows, "request");
|
|
34
|
+
requireField(kind, rows, "response");
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TraceHarView.TraceHarView, { rows });
|
|
36
|
+
case "pg_proxy":
|
|
37
|
+
case "sql_statements":
|
|
38
|
+
requireField(kind, rows, "sql");
|
|
39
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SqlTraceTable.SqlTraceTable, { rows });
|
|
40
|
+
case "terminal":
|
|
41
|
+
requireField(kind, rows, "kind");
|
|
42
|
+
requireField(kind, rows, "offset");
|
|
43
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TerminalCastPlayer.TerminalCastPlayer, { events: rows });
|
|
44
|
+
case "process_tree":
|
|
45
|
+
requireField(kind, rows, "key");
|
|
46
|
+
if (samples) requireField("process_samples", samples, "key");
|
|
47
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ProcessTraceView, { rows, samples });
|
|
48
|
+
case "goprof":
|
|
49
|
+
requireField(kind, rows, "key");
|
|
50
|
+
requireField(kind, rows, "checkpointId");
|
|
51
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ProcessRecordViews.GoProfileTraceView, { rows });
|
|
52
|
+
case "stacks":
|
|
53
|
+
requireField(kind, rows, "key");
|
|
54
|
+
requireField(kind, rows, "checkpointId");
|
|
55
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ProcessRecordViews.StackTraceView, { rows });
|
|
56
|
+
default:
|
|
57
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GenericTraceTable, { kind, rows });
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("flex h-full min-h-0 flex-col", className), children: body });
|
|
61
|
+
}
|
|
62
|
+
exports.TraceView = TraceView;
|
|
63
|
+
//# sourceMappingURL=TraceView.cjs.map
|