@casoon/auditmysite
Version:
Professional website analysis suite with robust accessibility testing, Core Web Vitals performance monitoring, SEO analysis, and content optimization insights. Features isolated browser contexts, retry mechanisms, and comprehensive API endpoints for profe
230 lines • 6.81 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamingReporter = void 0;
/**
* Streaming Reporter for Real-time Tauri Integration
* Outputs NDJSON (Newline Delimited JSON) for efficient parsing
*/
class StreamingReporter {
constructor(outputStream, sessionId, config = {
enabled: true,
chunkSize: 10,
bufferTimeout: 1000,
includeDetailedResults: true,
compressResults: false
}) {
this.sequenceNumber = 0;
this.resultBuffer = [];
this.outputStream = outputStream;
this.sessionId = sessionId;
this.config = config;
this.startTime = Date.now();
}
/**
* Initialize streaming session
*/
init(totalPages, config) {
const event = {
type: 'init',
sessionId: this.sessionId,
timestamp: new Date().toISOString(),
data: {
sessionId: this.sessionId,
config: this.config,
totalPages
}
};
this.writeEvent(event);
}
/**
* Report progress updates
*/
reportProgress(data) {
const timeElapsed = Date.now() - this.startTime;
const percentage = Math.round((data.current / data.total) * 100);
// Calculate estimated remaining time
let estimatedRemaining;
if (data.current > 0 && data.stage === 'testing_pages') {
const avgTimePerPage = timeElapsed / data.current;
estimatedRemaining = Math.round(avgTimePerPage * (data.total - data.current));
}
const event = {
type: 'progress',
sessionId: this.sessionId,
timestamp: new Date().toISOString(),
data: {
...data,
timeElapsed,
estimatedRemaining,
percentage
}
};
this.writeEvent(event);
}
/**
* Report individual page result
*/
reportPageResult(result, processingTime) {
const chunkId = this.generateChunkId();
const streamingMeta = {
processedAt: new Date().toISOString(),
processingTime,
chunkId,
sequenceNumber: ++this.sequenceNumber
};
const enhancedResult = {
...result,
streamingMeta
};
if (this.config.includeDetailedResults) {
const event = {
type: 'page_result',
sessionId: this.sessionId,
timestamp: new Date().toISOString(),
data: enhancedResult
};
this.writeEvent(event);
}
// Add to buffer for batch processing if needed
this.resultBuffer.push(enhancedResult);
this.maybeFlushBuffer();
}
/**
* Report summary data
*/
reportSummary(summary) {
const event = {
type: 'summary',
sessionId: this.sessionId,
timestamp: new Date().toISOString(),
data: summary
};
this.writeEvent(event);
}
/**
* Report errors
*/
reportError(error, url, stage = 'unknown', recoverable = false) {
const event = {
type: 'error',
sessionId: this.sessionId,
timestamp: new Date().toISOString(),
data: {
error,
url,
recoverable,
stage
}
};
this.writeEvent(event);
}
/**
* Report completion
*/
complete(summary, totalPages, successfulPages) {
// Flush any remaining buffer
this.flushBuffer();
const totalTime = Date.now() - this.startTime;
const event = {
type: 'complete',
sessionId: this.sessionId,
timestamp: new Date().toISOString(),
data: {
totalTime,
totalPages,
successfulPages,
failedPages: totalPages - successfulPages,
summary
}
};
this.writeEvent(event);
}
/**
* Get real-time metrics
*/
getRealTimeMetrics() {
const timeElapsed = Date.now() - this.startTime;
const pagesPerSecond = this.sequenceNumber / (timeElapsed / 1000);
const memoryUsage = process.memoryUsage().heapUsed;
return {
pagesPerSecond,
memoryUsage,
timeElapsed
};
}
/**
* Write event to output stream in NDJSON format
*/
writeEvent(event) {
try {
const jsonLine = JSON.stringify(event) + '\n';
// Compress if configured and data is large
if (this.config.compressResults && jsonLine.length > 1024 * 10) { // > 10KB
// Could implement compression here if needed
}
this.outputStream.write(jsonLine, 'utf8');
}
catch (error) {
console.error('Failed to write stream event:', error);
}
}
/**
* Generate unique chunk ID
*/
generateChunkId() {
return `${this.sessionId}-${Date.now()}-${this.sequenceNumber}`;
}
/**
* Maybe flush buffer based on configuration
*/
maybeFlushBuffer() {
if (this.resultBuffer.length >= this.config.chunkSize) {
this.flushBuffer();
}
else if (!this.bufferTimeout) {
this.bufferTimeout = setTimeout(() => {
this.flushBuffer();
}, this.config.bufferTimeout);
}
}
/**
* Flush result buffer
*/
flushBuffer() {
if (this.bufferTimeout) {
clearTimeout(this.bufferTimeout);
this.bufferTimeout = undefined;
}
if (this.resultBuffer.length === 0)
return;
// Could emit a batch event if needed for efficiency
// For now, individual page results are already emitted
this.resultBuffer = [];
}
/**
* Create streaming reporter from options
*/
static create(sessionId, outputStream = process.stdout, options = {}) {
const config = {
enabled: true,
chunkSize: 10,
bufferTimeout: 1000,
includeDetailedResults: true,
compressResults: false,
...options
};
return new StreamingReporter(outputStream, sessionId, config);
}
/**
* Cleanup resources
*/
cleanup() {
if (this.bufferTimeout) {
clearTimeout(this.bufferTimeout);
this.bufferTimeout = undefined;
}
this.flushBuffer();
}
}
exports.StreamingReporter = StreamingReporter;
//# sourceMappingURL=streaming-reporter.js.map