Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 36 additions & 11 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,25 +430,50 @@ tddCmd
globalOptions
);

// Set up cleanup on process signals
// Track cleanup state to prevent double cleanup
let isCleaningUp = false;
const handleCleanup = async () => {
if (isCleaningUp) return;
isCleaningUp = true;
await cleanup();
};

process.once('SIGINT', () => {
handleCleanup().then(() => process.exit(1));
});
// Set up cleanup on process signals
const sigintHandler = () => {
handleCleanup().then(() => process.exit(result?.exitCode || 0));
};
const sigtermHandler = () => {
handleCleanup().then(() => process.exit(result?.exitCode || 0));
};

process.once('SIGTERM', () => {
handleCleanup().then(() => process.exit(1));
});
process.once('SIGINT', sigintHandler);
process.once('SIGTERM', sigtermHandler);

if (result && !result.success && result.exitCode > 0) {
await cleanup();
process.exit(result.exitCode);
// If there are comparisons, keep server running for review
const hasComparisons = result?.comparisons?.length > 0;
if (hasComparisons) {
output.print(
` ${colors.brand.textTertiary('→')} Press ${colors.white('Enter')} to stop server`
);
output.blank();

// Wait for user to press Enter
await new Promise(resolve => {
process.stdin.setRawMode?.(false);
process.stdin.resume();
process.stdin.once('data', () => {
process.stdin.pause();
resolve();
});
});
}

await cleanup();
// Remove signal handlers before normal cleanup to prevent double cleanup
process.off('SIGINT', sigintHandler);
process.off('SIGTERM', sigtermHandler);

await handleCleanup();
process.exit(result?.exitCode || 0);
});

program
Expand Down
4 changes: 4 additions & 0 deletions src/reporter/src/api/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export const tdd = {
* @returns {Promise<Object|null>}
*/
async getReportData() {
// In static mode, return embedded data directly without fetching
if (isStaticMode() && window.VIZZLY_REPORTER_DATA) {
return window.VIZZLY_REPORTER_DATA;
}
return fetchJson('/api/report-data');
},

Expand Down
23 changes: 19 additions & 4 deletions src/reporter/src/hooks/queries/use-tdd-queries.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { tdd } from '../../api/client.js';
import { useMemo } from 'react';
import { isStaticMode, tdd } from '../../api/client.js';
import { queryKeys } from '../../lib/query-keys.js';
import { SSE_STATE, useReportDataSSE } from '../use-sse.js';

export function useReportData(options = {}) {
// Check if we're in static mode with embedded data
// Memoize to ensure consistency within the hook's lifecycle
const staticMode = useMemo(() => isStaticMode(), []);
const staticData = useMemo(
() => (staticMode ? window.VIZZLY_REPORTER_DATA : undefined),
[staticMode]
);

// Use SSE for real-time updates (handles static mode internally)
const { state: sseState } = useReportDataSSE({
enabled: options.polling !== false,
enabled: options.polling !== false && !staticMode,
});

// SSE is connected - it updates the cache directly, no polling needed
Expand All @@ -16,8 +25,14 @@ export function useReportData(options = {}) {
return useQuery({
queryKey: queryKeys.reportData(),
queryFn: tdd.getReportData,
// Only poll as fallback when SSE is not connected
refetchInterval: options.polling !== false && !sseConnected ? 2000 : false,
// In static mode, provide initial data and disable refetching
initialData: staticData,
// Only poll as fallback when SSE is not connected and not in static mode
refetchInterval:
!staticMode && options.polling !== false && !sseConnected ? 2000 : false,
// Don't refetch in static mode
refetchOnMount: !staticMode,
refetchOnWindowFocus: !staticMode,
...options,
});
}
Expand Down