@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 @@
|
|
|
1
|
+
{"version":3,"file":"TraceView.cjs","sources":["../../../src/data/traces/TraceView.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { inferColumns } from \"../data-table-utils\";\nimport { DataTable } from \"../DataTable\";\nimport { GoProfileTraceView, StackTraceView } from \"./ProcessRecordViews\";\nimport { ProcessTraceTree } from \"./ProcessTraceTree\";\nimport { SqlTraceTable } from \"./SqlTraceTable\";\nimport { TerminalCastPlayer } from \"./TerminalCastPlayer\";\nimport { TraceHarView } from \"./TraceHarView\";\nimport type {\n GoProfileRecord,\n HttpExchangeRow,\n ProcessNodeRow,\n ProcessSampleRow,\n SqlStatementRow,\n StackRecord,\n TerminalEvent,\n TraceRow,\n} from \"./types\";\n\nexport type TraceViewProps = {\n /** The record kind: `http`, `http_proxy`, `pg_proxy`, `sql_statements`, `terminal`, `process_tree`, `goprof`, `stacks`, or any other. */\n kind: string;\n /** The kind's records, as its stream stores them. */\n rows: TraceRow[];\n /** `process_samples` records of the same root; used by `process_tree` for CPU sparklines. */\n samples?: TraceRow[];\n /** Classes applied to the viewer root. */\n className?: string;\n};\n\n/** Each row of a kind with a dedicated viewer must carry the field that viewer cannot do without. */\nfunction requireField(kind: string, rows: TraceRow[], field: string): void {\n rows.forEach((row, index) => {\n if (row[field] === undefined || row[field] === null) {\n throw new Error(`trace kind \"${kind}\" row ${index} has no \"${field}\"`);\n }\n });\n}\n\nfunction GenericTraceTable({ kind, rows }: { kind: string; rows: TraceRow[] }) {\n const columns = useMemo(() => inferColumns(rows, { literalKeys: true }), [rows]);\n return <DataTable data={rows} columns={columns} autoFilter emptyMessage={`No ${kind} records`} />;\n}\n\nfunction ProcessTraceView({ rows, samples }: { rows: ProcessNodeRow[]; samples: ProcessSampleRow[] | undefined }) {\n const [selectedKey, setSelectedKey] = useState<string | null>(null);\n return <ProcessTraceTree nodes={rows} selectedKey={selectedKey} onSelect={setSelectedKey} {...(samples ? { samples } : {})} />;\n}\n\n/**\n * Renders a trace kind's records with its dedicated viewer: HTTP exchanges in\n * a HAR panel, SQL statements in a table, a terminal session in a cast player,\n * a process tree as a tree, Go profiles as a top-functions profile view per\n * process, stack dumps as one dump per checkpoint per process. Any other kind\n * gets a table over the row keys.\n */\nexport function TraceView({ kind, rows, samples, className }: TraceViewProps) {\n const body = (() => {\n switch (kind) {\n case \"http\":\n case \"http_proxy\":\n requireField(kind, rows, \"request\");\n requireField(kind, rows, \"response\");\n return <TraceHarView rows={rows as HttpExchangeRow[]} />;\n case \"pg_proxy\":\n case \"sql_statements\":\n requireField(kind, rows, \"sql\");\n return <SqlTraceTable rows={rows as SqlStatementRow[]} />;\n case \"terminal\":\n requireField(kind, rows, \"kind\");\n requireField(kind, rows, \"offset\");\n return <TerminalCastPlayer events={rows as TerminalEvent[]} />;\n case \"process_tree\":\n requireField(kind, rows, \"key\");\n if (samples) requireField(\"process_samples\", samples, \"key\");\n return <ProcessTraceView rows={rows as ProcessNodeRow[]} samples={samples as ProcessSampleRow[] | undefined} />;\n case \"goprof\":\n requireField(kind, rows, \"key\");\n requireField(kind, rows, \"checkpointId\");\n return <GoProfileTraceView rows={rows as GoProfileRecord[]} />;\n case \"stacks\":\n requireField(kind, rows, \"key\");\n requireField(kind, rows, \"checkpointId\");\n return <StackTraceView rows={rows as StackRecord[]} />;\n default:\n return <GenericTraceTable kind={kind} rows={rows} />;\n }\n })();\n return <div className={cn(\"flex h-full min-h-0 flex-col\", className)}>{body}</div>;\n}\n"],"names":["useMemo","inferColumns","jsx","DataTable","useState","ProcessTraceTree","TraceHarView","SqlTraceTable","TerminalCastPlayer","GoProfileTraceView","StackTraceView","cn"],"mappings":";;;;;;;;;;;;AAgCA,SAAS,aAAa,MAAc,MAAkB,OAAqB;AACzE,OAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,QAAI,IAAI,KAAK,MAAM,UAAa,IAAI,KAAK,MAAM,MAAM;AACnD,YAAM,IAAI,MAAM,eAAe,IAAI,SAAS,KAAK,YAAY,KAAK,GAAG;AAAA,IACvE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,kBAAkB,EAAE,MAAM,QAA4C;AAC7E,QAAM,UAAUA,MAAAA,QAAQ,MAAMC,eAAAA,aAAa,MAAM,EAAE,aAAa,KAAA,CAAM,GAAG,CAAC,IAAI,CAAC;AAC/E,SAAOC,2BAAAA,IAACC,UAAAA,WAAA,EAAU,MAAM,MAAM,SAAkB,YAAU,MAAC,cAAc,MAAM,IAAI,WAAA,CAAY;AACjG;AAEA,SAAS,iBAAiB,EAAE,MAAM,WAAgF;AAChH,QAAM,CAAC,aAAa,cAAc,IAAIC,MAAAA,SAAwB,IAAI;AAClE,SAAOF,2BAAAA,IAACG,iBAAAA,kBAAA,EAAiB,OAAO,MAAM,aAA0B,UAAU,gBAAiB,GAAI,UAAU,EAAE,QAAA,IAAY,CAAA,EAAC,CAAI;AAC9H;AASO,SAAS,UAAU,EAAE,MAAM,MAAM,SAAS,aAA6B;AAC5E,QAAM,QAAQ,MAAM;AAClB,YAAQ,MAAA;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AACH,qBAAa,MAAM,MAAM,SAAS;AAClC,qBAAa,MAAM,MAAM,UAAU;AACnC,eAAOH,+BAACI,aAAAA,gBAAa,MAAiC;AAAA,MACxD,KAAK;AAAA,MACL,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,eAAOJ,+BAACK,cAAAA,iBAAc,MAAiC;AAAA,MACzD,KAAK;AACH,qBAAa,MAAM,MAAM,MAAM;AAC/B,qBAAa,MAAM,MAAM,QAAQ;AACjC,eAAOL,2BAAAA,IAACM,mBAAAA,oBAAA,EAAmB,QAAQ,KAAA,CAAyB;AAAA,MAC9D,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,YAAI,QAAS,cAAa,mBAAmB,SAAS,KAAK;AAC3D,eAAON,2BAAAA,IAAC,kBAAA,EAAiB,MAAgC,QAAA,CAAoD;AAAA,MAC/G,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,qBAAa,MAAM,MAAM,cAAc;AACvC,eAAOA,+BAACO,mBAAAA,sBAAmB,MAAiC;AAAA,MAC9D,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,qBAAa,MAAM,MAAM,cAAc;AACvC,eAAOP,+BAACQ,mBAAAA,kBAAe,MAA6B;AAAA,MACtD;AACE,eAAOR,2BAAAA,IAAC,mBAAA,EAAkB,MAAY,KAAA,CAAY;AAAA,IAAA;AAAA,EAExD,GAAA;AACA,wCAAQ,OAAA,EAAI,WAAWS,MAAAA,GAAG,gCAAgC,SAAS,GAAI,UAAA,MAAK;AAC9E;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TraceRow } from './types.js';
|
|
2
|
+
export type TraceViewProps = {
|
|
3
|
+
/** The record kind: `http`, `http_proxy`, `pg_proxy`, `sql_statements`, `terminal`, `process_tree`, `goprof`, `stacks`, or any other. */
|
|
4
|
+
kind: string;
|
|
5
|
+
/** The kind's records, as its stream stores them. */
|
|
6
|
+
rows: TraceRow[];
|
|
7
|
+
/** `process_samples` records of the same root; used by `process_tree` for CPU sparklines. */
|
|
8
|
+
samples?: TraceRow[];
|
|
9
|
+
/** Classes applied to the viewer root. */
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Renders a trace kind's records with its dedicated viewer: HTTP exchanges in
|
|
14
|
+
* a HAR panel, SQL statements in a table, a terminal session in a cast player,
|
|
15
|
+
* a process tree as a tree, Go profiles as a top-functions profile view per
|
|
16
|
+
* process, stack dumps as one dump per checkpoint per process. Any other kind
|
|
17
|
+
* gets a table over the row keys.
|
|
18
|
+
*/
|
|
19
|
+
export declare function TraceView({ kind, rows, samples, className }: TraceViewProps): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=TraceView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceView.d.ts","sourceRoot":"","sources":["../../../src/data/traces/TraceView.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAQV,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG;IAC3B,yIAAyI;IACzI,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACrB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAqBF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,cAAc,+BAiC3E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
import { cn } from "../../lib/utils.js";
|
|
4
|
+
import { inferColumns } from "../data-table-utils.js";
|
|
5
|
+
import { DataTable } from "../DataTable.js";
|
|
6
|
+
import { StackTraceView, GoProfileTraceView } from "./ProcessRecordViews.js";
|
|
7
|
+
import { ProcessTraceTree } from "./ProcessTraceTree.js";
|
|
8
|
+
import { SqlTraceTable } from "./SqlTraceTable.js";
|
|
9
|
+
import { TerminalCastPlayer } from "./TerminalCastPlayer.js";
|
|
10
|
+
import { TraceHarView } from "./TraceHarView.js";
|
|
11
|
+
function requireField(kind, rows, field) {
|
|
12
|
+
rows.forEach((row, index) => {
|
|
13
|
+
if (row[field] === void 0 || row[field] === null) {
|
|
14
|
+
throw new Error(`trace kind "${kind}" row ${index} has no "${field}"`);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function GenericTraceTable({ kind, rows }) {
|
|
19
|
+
const columns = useMemo(() => inferColumns(rows, { literalKeys: true }), [rows]);
|
|
20
|
+
return /* @__PURE__ */ jsx(DataTable, { data: rows, columns, autoFilter: true, emptyMessage: `No ${kind} records` });
|
|
21
|
+
}
|
|
22
|
+
function ProcessTraceView({ rows, samples }) {
|
|
23
|
+
const [selectedKey, setSelectedKey] = useState(null);
|
|
24
|
+
return /* @__PURE__ */ jsx(ProcessTraceTree, { nodes: rows, selectedKey, onSelect: setSelectedKey, ...samples ? { samples } : {} });
|
|
25
|
+
}
|
|
26
|
+
function TraceView({ kind, rows, samples, className }) {
|
|
27
|
+
const body = (() => {
|
|
28
|
+
switch (kind) {
|
|
29
|
+
case "http":
|
|
30
|
+
case "http_proxy":
|
|
31
|
+
requireField(kind, rows, "request");
|
|
32
|
+
requireField(kind, rows, "response");
|
|
33
|
+
return /* @__PURE__ */ jsx(TraceHarView, { rows });
|
|
34
|
+
case "pg_proxy":
|
|
35
|
+
case "sql_statements":
|
|
36
|
+
requireField(kind, rows, "sql");
|
|
37
|
+
return /* @__PURE__ */ jsx(SqlTraceTable, { rows });
|
|
38
|
+
case "terminal":
|
|
39
|
+
requireField(kind, rows, "kind");
|
|
40
|
+
requireField(kind, rows, "offset");
|
|
41
|
+
return /* @__PURE__ */ jsx(TerminalCastPlayer, { events: rows });
|
|
42
|
+
case "process_tree":
|
|
43
|
+
requireField(kind, rows, "key");
|
|
44
|
+
if (samples) requireField("process_samples", samples, "key");
|
|
45
|
+
return /* @__PURE__ */ jsx(ProcessTraceView, { rows, samples });
|
|
46
|
+
case "goprof":
|
|
47
|
+
requireField(kind, rows, "key");
|
|
48
|
+
requireField(kind, rows, "checkpointId");
|
|
49
|
+
return /* @__PURE__ */ jsx(GoProfileTraceView, { rows });
|
|
50
|
+
case "stacks":
|
|
51
|
+
requireField(kind, rows, "key");
|
|
52
|
+
requireField(kind, rows, "checkpointId");
|
|
53
|
+
return /* @__PURE__ */ jsx(StackTraceView, { rows });
|
|
54
|
+
default:
|
|
55
|
+
return /* @__PURE__ */ jsx(GenericTraceTable, { kind, rows });
|
|
56
|
+
}
|
|
57
|
+
})();
|
|
58
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex h-full min-h-0 flex-col", className), children: body });
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
TraceView
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=TraceView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceView.js","sources":["../../../src/data/traces/TraceView.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { inferColumns } from \"../data-table-utils\";\nimport { DataTable } from \"../DataTable\";\nimport { GoProfileTraceView, StackTraceView } from \"./ProcessRecordViews\";\nimport { ProcessTraceTree } from \"./ProcessTraceTree\";\nimport { SqlTraceTable } from \"./SqlTraceTable\";\nimport { TerminalCastPlayer } from \"./TerminalCastPlayer\";\nimport { TraceHarView } from \"./TraceHarView\";\nimport type {\n GoProfileRecord,\n HttpExchangeRow,\n ProcessNodeRow,\n ProcessSampleRow,\n SqlStatementRow,\n StackRecord,\n TerminalEvent,\n TraceRow,\n} from \"./types\";\n\nexport type TraceViewProps = {\n /** The record kind: `http`, `http_proxy`, `pg_proxy`, `sql_statements`, `terminal`, `process_tree`, `goprof`, `stacks`, or any other. */\n kind: string;\n /** The kind's records, as its stream stores them. */\n rows: TraceRow[];\n /** `process_samples` records of the same root; used by `process_tree` for CPU sparklines. */\n samples?: TraceRow[];\n /** Classes applied to the viewer root. */\n className?: string;\n};\n\n/** Each row of a kind with a dedicated viewer must carry the field that viewer cannot do without. */\nfunction requireField(kind: string, rows: TraceRow[], field: string): void {\n rows.forEach((row, index) => {\n if (row[field] === undefined || row[field] === null) {\n throw new Error(`trace kind \"${kind}\" row ${index} has no \"${field}\"`);\n }\n });\n}\n\nfunction GenericTraceTable({ kind, rows }: { kind: string; rows: TraceRow[] }) {\n const columns = useMemo(() => inferColumns(rows, { literalKeys: true }), [rows]);\n return <DataTable data={rows} columns={columns} autoFilter emptyMessage={`No ${kind} records`} />;\n}\n\nfunction ProcessTraceView({ rows, samples }: { rows: ProcessNodeRow[]; samples: ProcessSampleRow[] | undefined }) {\n const [selectedKey, setSelectedKey] = useState<string | null>(null);\n return <ProcessTraceTree nodes={rows} selectedKey={selectedKey} onSelect={setSelectedKey} {...(samples ? { samples } : {})} />;\n}\n\n/**\n * Renders a trace kind's records with its dedicated viewer: HTTP exchanges in\n * a HAR panel, SQL statements in a table, a terminal session in a cast player,\n * a process tree as a tree, Go profiles as a top-functions profile view per\n * process, stack dumps as one dump per checkpoint per process. Any other kind\n * gets a table over the row keys.\n */\nexport function TraceView({ kind, rows, samples, className }: TraceViewProps) {\n const body = (() => {\n switch (kind) {\n case \"http\":\n case \"http_proxy\":\n requireField(kind, rows, \"request\");\n requireField(kind, rows, \"response\");\n return <TraceHarView rows={rows as HttpExchangeRow[]} />;\n case \"pg_proxy\":\n case \"sql_statements\":\n requireField(kind, rows, \"sql\");\n return <SqlTraceTable rows={rows as SqlStatementRow[]} />;\n case \"terminal\":\n requireField(kind, rows, \"kind\");\n requireField(kind, rows, \"offset\");\n return <TerminalCastPlayer events={rows as TerminalEvent[]} />;\n case \"process_tree\":\n requireField(kind, rows, \"key\");\n if (samples) requireField(\"process_samples\", samples, \"key\");\n return <ProcessTraceView rows={rows as ProcessNodeRow[]} samples={samples as ProcessSampleRow[] | undefined} />;\n case \"goprof\":\n requireField(kind, rows, \"key\");\n requireField(kind, rows, \"checkpointId\");\n return <GoProfileTraceView rows={rows as GoProfileRecord[]} />;\n case \"stacks\":\n requireField(kind, rows, \"key\");\n requireField(kind, rows, \"checkpointId\");\n return <StackTraceView rows={rows as StackRecord[]} />;\n default:\n return <GenericTraceTable kind={kind} rows={rows} />;\n }\n })();\n return <div className={cn(\"flex h-full min-h-0 flex-col\", className)}>{body}</div>;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAgCA,SAAS,aAAa,MAAc,MAAkB,OAAqB;AACzE,OAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,QAAI,IAAI,KAAK,MAAM,UAAa,IAAI,KAAK,MAAM,MAAM;AACnD,YAAM,IAAI,MAAM,eAAe,IAAI,SAAS,KAAK,YAAY,KAAK,GAAG;AAAA,IACvE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,kBAAkB,EAAE,MAAM,QAA4C;AAC7E,QAAM,UAAU,QAAQ,MAAM,aAAa,MAAM,EAAE,aAAa,KAAA,CAAM,GAAG,CAAC,IAAI,CAAC;AAC/E,SAAO,oBAAC,WAAA,EAAU,MAAM,MAAM,SAAkB,YAAU,MAAC,cAAc,MAAM,IAAI,WAAA,CAAY;AACjG;AAEA,SAAS,iBAAiB,EAAE,MAAM,WAAgF;AAChH,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,IAAI;AAClE,SAAO,oBAAC,kBAAA,EAAiB,OAAO,MAAM,aAA0B,UAAU,gBAAiB,GAAI,UAAU,EAAE,QAAA,IAAY,CAAA,EAAC,CAAI;AAC9H;AASO,SAAS,UAAU,EAAE,MAAM,MAAM,SAAS,aAA6B;AAC5E,QAAM,QAAQ,MAAM;AAClB,YAAQ,MAAA;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AACH,qBAAa,MAAM,MAAM,SAAS;AAClC,qBAAa,MAAM,MAAM,UAAU;AACnC,eAAO,oBAAC,gBAAa,MAAiC;AAAA,MACxD,KAAK;AAAA,MACL,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,eAAO,oBAAC,iBAAc,MAAiC;AAAA,MACzD,KAAK;AACH,qBAAa,MAAM,MAAM,MAAM;AAC/B,qBAAa,MAAM,MAAM,QAAQ;AACjC,eAAO,oBAAC,oBAAA,EAAmB,QAAQ,KAAA,CAAyB;AAAA,MAC9D,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,YAAI,QAAS,cAAa,mBAAmB,SAAS,KAAK;AAC3D,eAAO,oBAAC,kBAAA,EAAiB,MAAgC,QAAA,CAAoD;AAAA,MAC/G,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,qBAAa,MAAM,MAAM,cAAc;AACvC,eAAO,oBAAC,sBAAmB,MAAiC;AAAA,MAC9D,KAAK;AACH,qBAAa,MAAM,MAAM,KAAK;AAC9B,qBAAa,MAAM,MAAM,cAAc;AACvC,eAAO,oBAAC,kBAAe,MAA6B;AAAA,MACtD;AACE,eAAO,oBAAC,mBAAA,EAAkB,MAAY,KAAA,CAAY;AAAA,IAAA;AAAA,EAExD,GAAA;AACA,6BAAQ,OAAA,EAAI,WAAW,GAAG,gCAAgC,SAAS,GAAI,UAAA,MAAK;AAC9E;"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
7
|
+
const react = require("react");
|
|
8
|
+
const TraceView = require("./TraceView.cjs");
|
|
9
|
+
const UNSERVED = "This run's trace store is not served, so its windows cannot be opened.";
|
|
10
|
+
const MAX_SUMMARY_CHIPS = 6;
|
|
11
|
+
const windowKey = (window) => `${window.run_id}:${window.kind}:${window.stream}:${window.afterSeq ?? 0}`;
|
|
12
|
+
const isScalar = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
13
|
+
function SummaryChips({ summary }) {
|
|
14
|
+
const entries = Object.entries(summary ?? {}).filter(([key, value]) => key !== "count" && isScalar(value)).slice(0, MAX_SUMMARY_CHIPS);
|
|
15
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: entries.map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground", "data-summary-chip": key, children: [
|
|
16
|
+
key,
|
|
17
|
+
": ",
|
|
18
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono", children: String(value) })
|
|
19
|
+
] }, key)) });
|
|
20
|
+
}
|
|
21
|
+
class ViewerBoundary extends react.Component {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
__publicField(this, "state", {});
|
|
25
|
+
}
|
|
26
|
+
static getDerivedStateFromError(error) {
|
|
27
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
28
|
+
}
|
|
29
|
+
render() {
|
|
30
|
+
if (this.state.error) {
|
|
31
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-xs text-red-700 dark:text-red-400", role: "alert", children: this.state.error });
|
|
32
|
+
}
|
|
33
|
+
return this.props.children;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function WindowViewer({
|
|
37
|
+
window,
|
|
38
|
+
fetchRecords
|
|
39
|
+
}) {
|
|
40
|
+
const [rows, setRows] = react.useState(null);
|
|
41
|
+
const [error, setError] = react.useState(void 0);
|
|
42
|
+
react.useEffect(() => {
|
|
43
|
+
const abort = new AbortController();
|
|
44
|
+
fetchRecords(window, abort.signal).then(setRows, (reason) => {
|
|
45
|
+
if (!abort.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason));
|
|
46
|
+
});
|
|
47
|
+
return () => abort.abort();
|
|
48
|
+
}, [window.run_id, window.kind, window.stream, window.afterSeq, window.toSeq]);
|
|
49
|
+
if (error) {
|
|
50
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap border-t border-border px-2 py-1.5 text-xs text-red-700 dark:text-red-400", role: "alert", children: error });
|
|
51
|
+
}
|
|
52
|
+
if (!rows) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border px-2 py-1.5 text-xs text-muted-foreground", children: "Loading records..." });
|
|
53
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border", style: { height: 420 }, children: /* @__PURE__ */ jsxRuntime.jsx(ViewerBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(TraceView.TraceView, { kind: window.kind, rows }) }) });
|
|
54
|
+
}
|
|
55
|
+
function WindowRow({
|
|
56
|
+
window,
|
|
57
|
+
mount,
|
|
58
|
+
formats,
|
|
59
|
+
fetchRecords,
|
|
60
|
+
exportUrl,
|
|
61
|
+
openUrl
|
|
62
|
+
}) {
|
|
63
|
+
const [open, setOpen] = react.useState(false);
|
|
64
|
+
const linkClass = "text-xs text-primary hover:underline";
|
|
65
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded border border-border", "data-trace-kind": window.kind, children: [
|
|
66
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 px-2 py-1.5 text-sm", children: [
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-medium text-foreground", children: window.kind }),
|
|
68
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
69
|
+
window.count,
|
|
70
|
+
" ",
|
|
71
|
+
window.count === 1 ? "record" : "records"
|
|
72
|
+
] }),
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(SummaryChips, { summary: window.summary }),
|
|
74
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
75
|
+
mount && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { className: linkClass, href: openUrl(window), target: "_blank", rel: "noreferrer", children: "Open in query" }),
|
|
77
|
+
formats.map((format) => /* @__PURE__ */ jsxRuntime.jsx("a", { className: linkClass, href: exportUrl(window, format.name), download: true, children: format.name.toUpperCase() }, format.name)),
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: linkClass, onClick: () => setOpen(!open), children: open ? "Hide" : "View" })
|
|
79
|
+
] })
|
|
80
|
+
] }),
|
|
81
|
+
window.error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap px-2 pb-1.5 text-xs text-red-700 dark:text-red-400", children: window.error }),
|
|
82
|
+
open && mount && /* @__PURE__ */ jsxRuntime.jsx(WindowViewer, { window, fetchRecords })
|
|
83
|
+
] });
|
|
84
|
+
}
|
|
85
|
+
function TraceWindowList({ windows, resolve, formats, fetchRecords, exportUrl, openUrl, error }) {
|
|
86
|
+
const sources = windows.map((window) => resolve(window));
|
|
87
|
+
const unavailable = [
|
|
88
|
+
...new Set(sources.filter((source) => !source.mount).map((source) => source.unavailable || UNSERVED))
|
|
89
|
+
];
|
|
90
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
91
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Traces" }),
|
|
92
|
+
unavailable.map((reason) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
className: "mb-2 rounded border border-amber-300 bg-amber-50 px-2 py-1 text-xs text-amber-800 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-300",
|
|
96
|
+
role: "status",
|
|
97
|
+
children: reason
|
|
98
|
+
},
|
|
99
|
+
reason
|
|
100
|
+
)),
|
|
101
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: windows.map((window, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
WindowRow,
|
|
103
|
+
{
|
|
104
|
+
window,
|
|
105
|
+
mount: sources[index].mount,
|
|
106
|
+
formats: formats(window.kind),
|
|
107
|
+
fetchRecords,
|
|
108
|
+
exportUrl,
|
|
109
|
+
openUrl
|
|
110
|
+
},
|
|
111
|
+
windowKey(window)
|
|
112
|
+
)) }),
|
|
113
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-xs text-red-700 dark:text-red-400", children: error })
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
exports.TraceWindowList = TraceWindowList;
|
|
117
|
+
//# sourceMappingURL=TraceWindowList.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceWindowList.cjs","sources":["../../../src/data/traces/TraceWindowList.tsx"],"sourcesContent":["import { Component, useEffect, useState, type ReactNode } from \"react\";\nimport { TraceView } from \"./TraceView\";\nimport type { TraceRow } from \"./types\";\n\n/** A window of a trace stream a fixture armed: the records after `afterSeq` through `toSeq` (0 = unbounded) of one kind's stream. */\nexport type TraceWindow = {\n kind: string;\n stream: string;\n afterSeq?: number;\n toSeq?: number;\n /** The run whose trace store holds the window. */\n run_id: string;\n count: number;\n /** The kind's summary of the window, shown as chips. */\n summary?: Record<string, unknown>;\n /** Why the window could not be read. */\n error?: string;\n};\n\n/** Where a window's run serves its store, or why it does not. */\nexport type TraceWindowSource = {\n /** Where the store is served; absent when it is not. */\n mount?: string;\n /** Why a store that was kept is not served (for example pruned since). */\n unavailable?: string;\n};\n\nexport type TraceWindowListProps = {\n windows: TraceWindow[];\n /** Resolves the store of a window's run. */\n resolve: (window: TraceWindow) => TraceWindowSource;\n /** The export formats of a kind, for example `[{ name: \"har\" }]`. */\n formats: (kind: string) => Array<{ name: string }>;\n /** Reads a window's records for the inline viewer. Must reject on failure and honour `signal`. */\n fetchRecords: (window: TraceWindow, signal: AbortSignal) => Promise<TraceRow[]>;\n /** Download URL of a window in one export format. */\n exportUrl: (window: TraceWindow, format: string) => string;\n /** URL of the query app opened at exactly this window. */\n openUrl: (window: TraceWindow) => string;\n /** A failure that applies to the whole list, such as the export formats not loading. */\n error?: string;\n};\n\nconst UNSERVED = \"This run's trace store is not served, so its windows cannot be opened.\";\nconst MAX_SUMMARY_CHIPS = 6;\n\nconst windowKey = (window: TraceWindow) => `${window.run_id}:${window.kind}:${window.stream}:${window.afterSeq ?? 0}`;\n\nconst isScalar = (value: unknown) => typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\";\n\nfunction SummaryChips({ summary }: { summary: Record<string, unknown> | undefined }) {\n const entries = Object.entries(summary ?? {})\n .filter(([key, value]) => key !== \"count\" && isScalar(value))\n .slice(0, MAX_SUMMARY_CHIPS);\n return (\n <>\n {entries.map(([key, value]) => (\n <span key={key} className=\"rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\" data-summary-chip={key}>\n {key}: <span className=\"font-mono\">{String(value)}</span>\n </span>\n ))}\n </>\n );\n}\n\n/** Keeps a viewer that refuses its records (TraceView throws on a row its kind's viewer cannot render) from taking the whole list down. */\nclass ViewerBoundary extends Component<{ children: ReactNode }, { error?: string }> {\n override state: { error?: string } = {};\n\n static getDerivedStateFromError(error: unknown) {\n return { error: error instanceof Error ? error.message : String(error) };\n }\n\n override render() {\n if (this.state.error) {\n return (\n <div className=\"px-2 py-1.5 text-xs text-red-700 dark:text-red-400\" role=\"alert\">\n {this.state.error}\n </div>\n );\n }\n return this.props.children;\n }\n}\n\nfunction WindowViewer({\n window,\n fetchRecords,\n}: {\n window: TraceWindow;\n fetchRecords: TraceWindowListProps[\"fetchRecords\"];\n}) {\n const [rows, setRows] = useState<TraceRow[] | null>(null);\n const [error, setError] = useState<string | undefined>(undefined);\n useEffect(() => {\n const abort = new AbortController();\n fetchRecords(window, abort.signal).then(setRows, (reason: unknown) => {\n if (!abort.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason));\n });\n return () => abort.abort();\n // The window is identified by its coordinates; the host may rebuild the object each render.\n }, [window.run_id, window.kind, window.stream, window.afterSeq, window.toSeq]);\n if (error) {\n return (\n <div className=\"whitespace-pre-wrap border-t border-border px-2 py-1.5 text-xs text-red-700 dark:text-red-400\" role=\"alert\">\n {error}\n </div>\n );\n }\n if (!rows) return <div className=\"border-t border-border px-2 py-1.5 text-xs text-muted-foreground\">Loading records...</div>;\n return (\n <div className=\"border-t border-border\" style={{ height: 420 }}>\n <ViewerBoundary>\n <TraceView kind={window.kind} rows={rows} />\n </ViewerBoundary>\n </div>\n );\n}\n\nfunction WindowRow({\n window,\n mount,\n formats,\n fetchRecords,\n exportUrl,\n openUrl,\n}: {\n window: TraceWindow;\n mount: string | undefined;\n formats: Array<{ name: string }>;\n} & Pick<TraceWindowListProps, \"fetchRecords\" | \"exportUrl\" | \"openUrl\">) {\n const [open, setOpen] = useState(false);\n const linkClass = \"text-xs text-primary hover:underline\";\n return (\n <div className=\"rounded border border-border\" data-trace-kind={window.kind}>\n <div className=\"flex flex-wrap items-center gap-2 px-2 py-1.5 text-sm\">\n <span className=\"font-mono font-medium text-foreground\">{window.kind}</span>\n <span className=\"text-xs text-muted-foreground\">\n {window.count} {window.count === 1 ? \"record\" : \"records\"}\n </span>\n <SummaryChips summary={window.summary} />\n <span className=\"flex-1\" />\n {mount && (\n <>\n <a className={linkClass} href={openUrl(window)} target=\"_blank\" rel=\"noreferrer\">\n Open in query\n </a>\n {formats.map((format) => (\n <a key={format.name} className={linkClass} href={exportUrl(window, format.name)} download>\n {format.name.toUpperCase()}\n </a>\n ))}\n <button type=\"button\" className={linkClass} onClick={() => setOpen(!open)}>\n {open ? \"Hide\" : \"View\"}\n </button>\n </>\n )}\n </div>\n {window.error && (\n <div className=\"whitespace-pre-wrap px-2 pb-1.5 text-xs text-red-700 dark:text-red-400\">{window.error}</div>\n )}\n {open && mount && <WindowViewer window={window} fetchRecords={fetchRecords} />}\n </div>\n );\n}\n\n/**\n * One fixture's trace windows: what each captured (kind, record count, summary\n * chips), a link into the query app at exactly that window, per-format export\n * downloads and an inline viewer of its records. Windows of a run whose store\n * is not served say why, once per reason. Props-only: the host resolves stores\n * and builds the URLs.\n */\nexport function TraceWindowList({ windows, resolve, formats, fetchRecords, exportUrl, openUrl, error }: TraceWindowListProps) {\n const sources = windows.map((window) => resolve(window));\n const unavailable = [\n ...new Set(sources.filter((source) => !source.mount).map((source) => source.unavailable || UNSERVED)),\n ];\n return (\n <div>\n <h3 className=\"mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">Traces</h3>\n {unavailable.map((reason) => (\n <div\n key={reason}\n className=\"mb-2 rounded border border-amber-300 bg-amber-50 px-2 py-1 text-xs text-amber-800 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-300\"\n role=\"status\"\n >\n {reason}\n </div>\n ))}\n <div className=\"space-y-2\">\n {windows.map((window, index) => (\n <WindowRow\n key={windowKey(window)}\n window={window}\n mount={sources[index]!.mount}\n formats={formats(window.kind)}\n fetchRecords={fetchRecords}\n exportUrl={exportUrl}\n openUrl={openUrl}\n />\n ))}\n </div>\n {error && <div className=\"mt-1 text-xs text-red-700 dark:text-red-400\">{error}</div>}\n </div>\n );\n}\n"],"names":["jsx","Fragment","jsxs","Component","useState","useEffect","TraceView"],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { TraceRow } from './types.js';
|
|
2
|
+
/** A window of a trace stream a fixture armed: the records after `afterSeq` through `toSeq` (0 = unbounded) of one kind's stream. */
|
|
3
|
+
export type TraceWindow = {
|
|
4
|
+
kind: string;
|
|
5
|
+
stream: string;
|
|
6
|
+
afterSeq?: number;
|
|
7
|
+
toSeq?: number;
|
|
8
|
+
/** The run whose trace store holds the window. */
|
|
9
|
+
run_id: string;
|
|
10
|
+
count: number;
|
|
11
|
+
/** The kind's summary of the window, shown as chips. */
|
|
12
|
+
summary?: Record<string, unknown>;
|
|
13
|
+
/** Why the window could not be read. */
|
|
14
|
+
error?: string;
|
|
15
|
+
};
|
|
16
|
+
/** Where a window's run serves its store, or why it does not. */
|
|
17
|
+
export type TraceWindowSource = {
|
|
18
|
+
/** Where the store is served; absent when it is not. */
|
|
19
|
+
mount?: string;
|
|
20
|
+
/** Why a store that was kept is not served (for example pruned since). */
|
|
21
|
+
unavailable?: string;
|
|
22
|
+
};
|
|
23
|
+
export type TraceWindowListProps = {
|
|
24
|
+
windows: TraceWindow[];
|
|
25
|
+
/** Resolves the store of a window's run. */
|
|
26
|
+
resolve: (window: TraceWindow) => TraceWindowSource;
|
|
27
|
+
/** The export formats of a kind, for example `[{ name: "har" }]`. */
|
|
28
|
+
formats: (kind: string) => Array<{
|
|
29
|
+
name: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Reads a window's records for the inline viewer. Must reject on failure and honour `signal`. */
|
|
32
|
+
fetchRecords: (window: TraceWindow, signal: AbortSignal) => Promise<TraceRow[]>;
|
|
33
|
+
/** Download URL of a window in one export format. */
|
|
34
|
+
exportUrl: (window: TraceWindow, format: string) => string;
|
|
35
|
+
/** URL of the query app opened at exactly this window. */
|
|
36
|
+
openUrl: (window: TraceWindow) => string;
|
|
37
|
+
/** A failure that applies to the whole list, such as the export formats not loading. */
|
|
38
|
+
error?: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* One fixture's trace windows: what each captured (kind, record count, summary
|
|
42
|
+
* chips), a link into the query app at exactly that window, per-format export
|
|
43
|
+
* downloads and an inline viewer of its records. Windows of a run whose store
|
|
44
|
+
* is not served say why, once per reason. Props-only: the host resolves stores
|
|
45
|
+
* and builds the URLs.
|
|
46
|
+
*/
|
|
47
|
+
export declare function TraceWindowList({ windows, resolve, formats, fetchRecords, exportUrl, openUrl, error }: TraceWindowListProps): import("react").JSX.Element;
|
|
48
|
+
//# sourceMappingURL=TraceWindowList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceWindowList.d.ts","sourceRoot":"","sources":["../../../src/data/traces/TraceWindowList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,qIAAqI;AACrI,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,4CAA4C;IAC5C,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,iBAAiB,CAAC;IACpD,qEAAqE;IACrE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,kGAAkG;IAClG,YAAY,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChF,qDAAqD;IACrD,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,0DAA0D;IAC1D,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC;IACzC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA6HF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,oBAAoB,+BAiC3H"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
5
|
+
import { useState, useEffect, Component } from "react";
|
|
6
|
+
import { TraceView } from "./TraceView.js";
|
|
7
|
+
const UNSERVED = "This run's trace store is not served, so its windows cannot be opened.";
|
|
8
|
+
const MAX_SUMMARY_CHIPS = 6;
|
|
9
|
+
const windowKey = (window) => `${window.run_id}:${window.kind}:${window.stream}:${window.afterSeq ?? 0}`;
|
|
10
|
+
const isScalar = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
11
|
+
function SummaryChips({ summary }) {
|
|
12
|
+
const entries = Object.entries(summary ?? {}).filter(([key, value]) => key !== "count" && isScalar(value)).slice(0, MAX_SUMMARY_CHIPS);
|
|
13
|
+
return /* @__PURE__ */ jsx(Fragment, { children: entries.map(([key, value]) => /* @__PURE__ */ jsxs("span", { className: "rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground", "data-summary-chip": key, children: [
|
|
14
|
+
key,
|
|
15
|
+
": ",
|
|
16
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: String(value) })
|
|
17
|
+
] }, key)) });
|
|
18
|
+
}
|
|
19
|
+
class ViewerBoundary extends Component {
|
|
20
|
+
constructor() {
|
|
21
|
+
super(...arguments);
|
|
22
|
+
__publicField(this, "state", {});
|
|
23
|
+
}
|
|
24
|
+
static getDerivedStateFromError(error) {
|
|
25
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
26
|
+
}
|
|
27
|
+
render() {
|
|
28
|
+
if (this.state.error) {
|
|
29
|
+
return /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs text-red-700 dark:text-red-400", role: "alert", children: this.state.error });
|
|
30
|
+
}
|
|
31
|
+
return this.props.children;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function WindowViewer({
|
|
35
|
+
window,
|
|
36
|
+
fetchRecords
|
|
37
|
+
}) {
|
|
38
|
+
const [rows, setRows] = useState(null);
|
|
39
|
+
const [error, setError] = useState(void 0);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const abort = new AbortController();
|
|
42
|
+
fetchRecords(window, abort.signal).then(setRows, (reason) => {
|
|
43
|
+
if (!abort.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason));
|
|
44
|
+
});
|
|
45
|
+
return () => abort.abort();
|
|
46
|
+
}, [window.run_id, window.kind, window.stream, window.afterSeq, window.toSeq]);
|
|
47
|
+
if (error) {
|
|
48
|
+
return /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap border-t border-border px-2 py-1.5 text-xs text-red-700 dark:text-red-400", role: "alert", children: error });
|
|
49
|
+
}
|
|
50
|
+
if (!rows) return /* @__PURE__ */ jsx("div", { className: "border-t border-border px-2 py-1.5 text-xs text-muted-foreground", children: "Loading records..." });
|
|
51
|
+
return /* @__PURE__ */ jsx("div", { className: "border-t border-border", style: { height: 420 }, children: /* @__PURE__ */ jsx(ViewerBoundary, { children: /* @__PURE__ */ jsx(TraceView, { kind: window.kind, rows }) }) });
|
|
52
|
+
}
|
|
53
|
+
function WindowRow({
|
|
54
|
+
window,
|
|
55
|
+
mount,
|
|
56
|
+
formats,
|
|
57
|
+
fetchRecords,
|
|
58
|
+
exportUrl,
|
|
59
|
+
openUrl
|
|
60
|
+
}) {
|
|
61
|
+
const [open, setOpen] = useState(false);
|
|
62
|
+
const linkClass = "text-xs text-primary hover:underline";
|
|
63
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded border border-border", "data-trace-kind": window.kind, children: [
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 px-2 py-1.5 text-sm", children: [
|
|
65
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium text-foreground", children: window.kind }),
|
|
66
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
67
|
+
window.count,
|
|
68
|
+
" ",
|
|
69
|
+
window.count === 1 ? "record" : "records"
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsx(SummaryChips, { summary: window.summary }),
|
|
72
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
73
|
+
mount && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
74
|
+
/* @__PURE__ */ jsx("a", { className: linkClass, href: openUrl(window), target: "_blank", rel: "noreferrer", children: "Open in query" }),
|
|
75
|
+
formats.map((format) => /* @__PURE__ */ jsx("a", { className: linkClass, href: exportUrl(window, format.name), download: true, children: format.name.toUpperCase() }, format.name)),
|
|
76
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: linkClass, onClick: () => setOpen(!open), children: open ? "Hide" : "View" })
|
|
77
|
+
] })
|
|
78
|
+
] }),
|
|
79
|
+
window.error && /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap px-2 pb-1.5 text-xs text-red-700 dark:text-red-400", children: window.error }),
|
|
80
|
+
open && mount && /* @__PURE__ */ jsx(WindowViewer, { window, fetchRecords })
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
function TraceWindowList({ windows, resolve, formats, fetchRecords, exportUrl, openUrl, error }) {
|
|
84
|
+
const sources = windows.map((window) => resolve(window));
|
|
85
|
+
const unavailable = [
|
|
86
|
+
...new Set(sources.filter((source) => !source.mount).map((source) => source.unavailable || UNSERVED))
|
|
87
|
+
];
|
|
88
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
89
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Traces" }),
|
|
90
|
+
unavailable.map((reason) => /* @__PURE__ */ jsx(
|
|
91
|
+
"div",
|
|
92
|
+
{
|
|
93
|
+
className: "mb-2 rounded border border-amber-300 bg-amber-50 px-2 py-1 text-xs text-amber-800 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-300",
|
|
94
|
+
role: "status",
|
|
95
|
+
children: reason
|
|
96
|
+
},
|
|
97
|
+
reason
|
|
98
|
+
)),
|
|
99
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: windows.map((window, index) => /* @__PURE__ */ jsx(
|
|
100
|
+
WindowRow,
|
|
101
|
+
{
|
|
102
|
+
window,
|
|
103
|
+
mount: sources[index].mount,
|
|
104
|
+
formats: formats(window.kind),
|
|
105
|
+
fetchRecords,
|
|
106
|
+
exportUrl,
|
|
107
|
+
openUrl
|
|
108
|
+
},
|
|
109
|
+
windowKey(window)
|
|
110
|
+
)) }),
|
|
111
|
+
error && /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-red-700 dark:text-red-400", children: error })
|
|
112
|
+
] });
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
TraceWindowList
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=TraceWindowList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceWindowList.js","sources":["../../../src/data/traces/TraceWindowList.tsx"],"sourcesContent":["import { Component, useEffect, useState, type ReactNode } from \"react\";\nimport { TraceView } from \"./TraceView\";\nimport type { TraceRow } from \"./types\";\n\n/** A window of a trace stream a fixture armed: the records after `afterSeq` through `toSeq` (0 = unbounded) of one kind's stream. */\nexport type TraceWindow = {\n kind: string;\n stream: string;\n afterSeq?: number;\n toSeq?: number;\n /** The run whose trace store holds the window. */\n run_id: string;\n count: number;\n /** The kind's summary of the window, shown as chips. */\n summary?: Record<string, unknown>;\n /** Why the window could not be read. */\n error?: string;\n};\n\n/** Where a window's run serves its store, or why it does not. */\nexport type TraceWindowSource = {\n /** Where the store is served; absent when it is not. */\n mount?: string;\n /** Why a store that was kept is not served (for example pruned since). */\n unavailable?: string;\n};\n\nexport type TraceWindowListProps = {\n windows: TraceWindow[];\n /** Resolves the store of a window's run. */\n resolve: (window: TraceWindow) => TraceWindowSource;\n /** The export formats of a kind, for example `[{ name: \"har\" }]`. */\n formats: (kind: string) => Array<{ name: string }>;\n /** Reads a window's records for the inline viewer. Must reject on failure and honour `signal`. */\n fetchRecords: (window: TraceWindow, signal: AbortSignal) => Promise<TraceRow[]>;\n /** Download URL of a window in one export format. */\n exportUrl: (window: TraceWindow, format: string) => string;\n /** URL of the query app opened at exactly this window. */\n openUrl: (window: TraceWindow) => string;\n /** A failure that applies to the whole list, such as the export formats not loading. */\n error?: string;\n};\n\nconst UNSERVED = \"This run's trace store is not served, so its windows cannot be opened.\";\nconst MAX_SUMMARY_CHIPS = 6;\n\nconst windowKey = (window: TraceWindow) => `${window.run_id}:${window.kind}:${window.stream}:${window.afterSeq ?? 0}`;\n\nconst isScalar = (value: unknown) => typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\";\n\nfunction SummaryChips({ summary }: { summary: Record<string, unknown> | undefined }) {\n const entries = Object.entries(summary ?? {})\n .filter(([key, value]) => key !== \"count\" && isScalar(value))\n .slice(0, MAX_SUMMARY_CHIPS);\n return (\n <>\n {entries.map(([key, value]) => (\n <span key={key} className=\"rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\" data-summary-chip={key}>\n {key}: <span className=\"font-mono\">{String(value)}</span>\n </span>\n ))}\n </>\n );\n}\n\n/** Keeps a viewer that refuses its records (TraceView throws on a row its kind's viewer cannot render) from taking the whole list down. */\nclass ViewerBoundary extends Component<{ children: ReactNode }, { error?: string }> {\n override state: { error?: string } = {};\n\n static getDerivedStateFromError(error: unknown) {\n return { error: error instanceof Error ? error.message : String(error) };\n }\n\n override render() {\n if (this.state.error) {\n return (\n <div className=\"px-2 py-1.5 text-xs text-red-700 dark:text-red-400\" role=\"alert\">\n {this.state.error}\n </div>\n );\n }\n return this.props.children;\n }\n}\n\nfunction WindowViewer({\n window,\n fetchRecords,\n}: {\n window: TraceWindow;\n fetchRecords: TraceWindowListProps[\"fetchRecords\"];\n}) {\n const [rows, setRows] = useState<TraceRow[] | null>(null);\n const [error, setError] = useState<string | undefined>(undefined);\n useEffect(() => {\n const abort = new AbortController();\n fetchRecords(window, abort.signal).then(setRows, (reason: unknown) => {\n if (!abort.signal.aborted) setError(reason instanceof Error ? reason.message : String(reason));\n });\n return () => abort.abort();\n // The window is identified by its coordinates; the host may rebuild the object each render.\n }, [window.run_id, window.kind, window.stream, window.afterSeq, window.toSeq]);\n if (error) {\n return (\n <div className=\"whitespace-pre-wrap border-t border-border px-2 py-1.5 text-xs text-red-700 dark:text-red-400\" role=\"alert\">\n {error}\n </div>\n );\n }\n if (!rows) return <div className=\"border-t border-border px-2 py-1.5 text-xs text-muted-foreground\">Loading records...</div>;\n return (\n <div className=\"border-t border-border\" style={{ height: 420 }}>\n <ViewerBoundary>\n <TraceView kind={window.kind} rows={rows} />\n </ViewerBoundary>\n </div>\n );\n}\n\nfunction WindowRow({\n window,\n mount,\n formats,\n fetchRecords,\n exportUrl,\n openUrl,\n}: {\n window: TraceWindow;\n mount: string | undefined;\n formats: Array<{ name: string }>;\n} & Pick<TraceWindowListProps, \"fetchRecords\" | \"exportUrl\" | \"openUrl\">) {\n const [open, setOpen] = useState(false);\n const linkClass = \"text-xs text-primary hover:underline\";\n return (\n <div className=\"rounded border border-border\" data-trace-kind={window.kind}>\n <div className=\"flex flex-wrap items-center gap-2 px-2 py-1.5 text-sm\">\n <span className=\"font-mono font-medium text-foreground\">{window.kind}</span>\n <span className=\"text-xs text-muted-foreground\">\n {window.count} {window.count === 1 ? \"record\" : \"records\"}\n </span>\n <SummaryChips summary={window.summary} />\n <span className=\"flex-1\" />\n {mount && (\n <>\n <a className={linkClass} href={openUrl(window)} target=\"_blank\" rel=\"noreferrer\">\n Open in query\n </a>\n {formats.map((format) => (\n <a key={format.name} className={linkClass} href={exportUrl(window, format.name)} download>\n {format.name.toUpperCase()}\n </a>\n ))}\n <button type=\"button\" className={linkClass} onClick={() => setOpen(!open)}>\n {open ? \"Hide\" : \"View\"}\n </button>\n </>\n )}\n </div>\n {window.error && (\n <div className=\"whitespace-pre-wrap px-2 pb-1.5 text-xs text-red-700 dark:text-red-400\">{window.error}</div>\n )}\n {open && mount && <WindowViewer window={window} fetchRecords={fetchRecords} />}\n </div>\n );\n}\n\n/**\n * One fixture's trace windows: what each captured (kind, record count, summary\n * chips), a link into the query app at exactly that window, per-format export\n * downloads and an inline viewer of its records. Windows of a run whose store\n * is not served say why, once per reason. Props-only: the host resolves stores\n * and builds the URLs.\n */\nexport function TraceWindowList({ windows, resolve, formats, fetchRecords, exportUrl, openUrl, error }: TraceWindowListProps) {\n const sources = windows.map((window) => resolve(window));\n const unavailable = [\n ...new Set(sources.filter((source) => !source.mount).map((source) => source.unavailable || UNSERVED)),\n ];\n return (\n <div>\n <h3 className=\"mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">Traces</h3>\n {unavailable.map((reason) => (\n <div\n key={reason}\n className=\"mb-2 rounded border border-amber-300 bg-amber-50 px-2 py-1 text-xs text-amber-800 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-300\"\n role=\"status\"\n >\n {reason}\n </div>\n ))}\n <div className=\"space-y-2\">\n {windows.map((window, index) => (\n <WindowRow\n key={windowKey(window)}\n window={window}\n mount={sources[index]!.mount}\n formats={formats(window.kind)}\n fetchRecords={fetchRecords}\n exportUrl={exportUrl}\n openUrl={openUrl}\n />\n ))}\n </div>\n {error && <div className=\"mt-1 text-xs text-red-700 dark:text-red-400\">{error}</div>}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const NO_EXIT_CODE = -1;
|
|
4
|
+
const IGNORED_EVENT_TYPES = /* @__PURE__ */ new Set(["i", "m"]);
|
|
5
|
+
function parseJson(text, what) {
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(text);
|
|
8
|
+
} catch (cause) {
|
|
9
|
+
throw new Error(`cast ${what} is not valid JSON: ${cause.message}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function parseHeader(line) {
|
|
13
|
+
const header = parseJson(line, "header");
|
|
14
|
+
if (header === null || typeof header !== "object" || Array.isArray(header)) {
|
|
15
|
+
throw new Error("cast header is not a JSON object");
|
|
16
|
+
}
|
|
17
|
+
if (header.version !== 2) throw new Error(`cast header: only asciinema version 2 is supported, got ${String(header.version)}`);
|
|
18
|
+
if (typeof header.width !== "number" || typeof header.height !== "number") {
|
|
19
|
+
throw new Error("cast header has no numeric width and height");
|
|
20
|
+
}
|
|
21
|
+
return { ...header, width: header.width, height: header.height };
|
|
22
|
+
}
|
|
23
|
+
function parseResize(data, lineNumber) {
|
|
24
|
+
const match = typeof data === "string" ? /^(\d+)x(\d+)$/.exec(data) : null;
|
|
25
|
+
if (!match) throw new Error(`cast line ${lineNumber}: resize data must be "<width>x<height>", got ${JSON.stringify(data)}`);
|
|
26
|
+
return { width: Number(match[1]), height: Number(match[2]) };
|
|
27
|
+
}
|
|
28
|
+
function parseCast(text) {
|
|
29
|
+
const lines = text.split("\n").filter((line) => line.trim() !== "");
|
|
30
|
+
const [headerLine, ...eventLines] = lines;
|
|
31
|
+
if (headerLine === void 0) throw new Error("cast text is empty");
|
|
32
|
+
const header = parseHeader(headerLine);
|
|
33
|
+
let size = { width: header.width, height: header.height };
|
|
34
|
+
const events = [];
|
|
35
|
+
let lastOffset = 0;
|
|
36
|
+
eventLines.forEach((line, index) => {
|
|
37
|
+
const lineNumber = index + 2;
|
|
38
|
+
let entry;
|
|
39
|
+
try {
|
|
40
|
+
entry = JSON.parse(line);
|
|
41
|
+
} catch (cause) {
|
|
42
|
+
throw new Error(`cast line ${lineNumber} is not valid JSON: ${cause.message}`);
|
|
43
|
+
}
|
|
44
|
+
if (!Array.isArray(entry) || entry.length < 3 || typeof entry[0] !== "number" || typeof entry[1] !== "string") {
|
|
45
|
+
throw new Error(`cast line ${lineNumber} is not a [seconds, type, data] event`);
|
|
46
|
+
}
|
|
47
|
+
const [offset, type, data] = entry;
|
|
48
|
+
lastOffset = Math.max(lastOffset, offset);
|
|
49
|
+
if (IGNORED_EVENT_TYPES.has(type)) return;
|
|
50
|
+
if (type === "o") {
|
|
51
|
+
events.push({ offset, kind: "o", data: String(data), ...size });
|
|
52
|
+
} else if (type === "r") {
|
|
53
|
+
size = parseResize(data, lineNumber);
|
|
54
|
+
events.push({ offset, kind: "r", data: "", ...size });
|
|
55
|
+
} else {
|
|
56
|
+
throw new Error(`cast line ${lineNumber}: unknown event type "${type}"`);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const extras = header._gavel;
|
|
60
|
+
if (!extras) return events;
|
|
61
|
+
const duration = header.duration ?? lastOffset;
|
|
62
|
+
const snapshots = extras.snapshots ?? [];
|
|
63
|
+
for (const [milliseconds, screen] of snapshots) {
|
|
64
|
+
events.push({ offset: milliseconds / 1e3, kind: "snapshot", data: screen, ...size });
|
|
65
|
+
}
|
|
66
|
+
if (snapshots.length === 0 && extras.final !== void 0) {
|
|
67
|
+
events.push({ offset: duration, kind: "snapshot", data: extras.final, ...size });
|
|
68
|
+
}
|
|
69
|
+
events.push({
|
|
70
|
+
offset: duration,
|
|
71
|
+
kind: "exit",
|
|
72
|
+
data: "",
|
|
73
|
+
...size,
|
|
74
|
+
...extras.exit_code !== void 0 && extras.exit_code !== NO_EXIT_CODE ? { exitCode: extras.exit_code } : {},
|
|
75
|
+
...extras.truncated ? { truncated: true } : {},
|
|
76
|
+
...header.command ? { command: header.command } : {}
|
|
77
|
+
});
|
|
78
|
+
return events;
|
|
79
|
+
}
|
|
80
|
+
exports.parseCast = parseCast;
|
|
81
|
+
//# sourceMappingURL=cast.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast.cjs","sources":["../../../src/data/traces/cast.ts"],"sourcesContent":["import type { TerminalEvent } from \"./types\";\n\ntype CastHeader = {\n version?: number;\n width?: number;\n height?: number;\n duration?: number;\n command?: string;\n /** Gavel's extras on top of asciinema v2; players ignore keys they do not know. */\n _gavel?: {\n exit_code?: number;\n snapshots?: [number, string][];\n final?: string;\n truncated?: boolean;\n };\n};\n\nconst NO_EXIT_CODE = -1;\n/** Events asciinema defines that draw nothing on the screen. */\nconst IGNORED_EVENT_TYPES = new Set([\"i\", \"m\"]);\n\nfunction parseJson(text: string, what: string): unknown {\n try {\n return JSON.parse(text);\n } catch (cause) {\n throw new Error(`cast ${what} is not valid JSON: ${(cause as Error).message}`);\n }\n}\n\nfunction parseHeader(line: string): CastHeader & { width: number; height: number } {\n const header = parseJson(line, \"header\") as CastHeader | null;\n if (header === null || typeof header !== \"object\" || Array.isArray(header)) {\n throw new Error(\"cast header is not a JSON object\");\n }\n if (header.version !== 2) throw new Error(`cast header: only asciinema version 2 is supported, got ${String(header.version)}`);\n if (typeof header.width !== \"number\" || typeof header.height !== \"number\") {\n throw new Error(\"cast header has no numeric width and height\");\n }\n return { ...header, width: header.width, height: header.height };\n}\n\nfunction parseResize(data: unknown, lineNumber: number): { width: number; height: number } {\n const match = typeof data === \"string\" ? /^(\\d+)x(\\d+)$/.exec(data) : null;\n if (!match) throw new Error(`cast line ${lineNumber}: resize data must be \"<width>x<height>\", got ${JSON.stringify(data)}`);\n return { width: Number(match[1]), height: Number(match[2]) };\n}\n\n/**\n * Parses an asciinema v2 cast (a header object, then one `[seconds, type, data]`\n * array per line) into the terminal events `TerminalCastPlayer` replays. The\n * `_gavel` header extras a commons-db export carries become the `snapshot` and\n * `exit` events a live capture records.\n */\nexport function parseCast(text: string): TerminalEvent[] {\n const lines = text.split(\"\\n\").filter((line) => line.trim() !== \"\");\n const [headerLine, ...eventLines] = lines;\n if (headerLine === undefined) throw new Error(\"cast text is empty\");\n\n const header = parseHeader(headerLine);\n let size = { width: header.width, height: header.height };\n const events: TerminalEvent[] = [];\n let lastOffset = 0;\n\n eventLines.forEach((line, index) => {\n const lineNumber = index + 2;\n let entry: unknown;\n try {\n entry = JSON.parse(line);\n } catch (cause) {\n throw new Error(`cast line ${lineNumber} is not valid JSON: ${(cause as Error).message}`);\n }\n if (!Array.isArray(entry) || entry.length < 3 || typeof entry[0] !== \"number\" || typeof entry[1] !== \"string\") {\n throw new Error(`cast line ${lineNumber} is not a [seconds, type, data] event`);\n }\n const [offset, type, data] = entry as [number, string, unknown];\n lastOffset = Math.max(lastOffset, offset);\n if (IGNORED_EVENT_TYPES.has(type)) return;\n if (type === \"o\") {\n events.push({ offset, kind: \"o\", data: String(data), ...size });\n } else if (type === \"r\") {\n size = parseResize(data, lineNumber);\n events.push({ offset, kind: \"r\", data: \"\", ...size });\n } else {\n throw new Error(`cast line ${lineNumber}: unknown event type \"${type}\"`);\n }\n });\n\n const extras = header._gavel;\n if (!extras) return events;\n\n const duration = header.duration ?? lastOffset;\n const snapshots = extras.snapshots ?? [];\n for (const [milliseconds, screen] of snapshots) {\n events.push({ offset: milliseconds / 1000, kind: \"snapshot\", data: screen, ...size });\n }\n if (snapshots.length === 0 && extras.final !== undefined) {\n events.push({ offset: duration, kind: \"snapshot\", data: extras.final, ...size });\n }\n events.push({\n offset: duration,\n kind: \"exit\",\n data: \"\",\n ...size,\n ...(extras.exit_code !== undefined && extras.exit_code !== NO_EXIT_CODE ? { exitCode: extras.exit_code } : {}),\n ...(extras.truncated ? { truncated: true } : {}),\n ...(header.command ? { command: header.command } : {}),\n });\n return events;\n}\n"],"names":[],"mappings":"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"}
|