mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 10:06:15 -08:00
* docs(performance): plan Xtream benchmark * feat(xtream-mock-server): add deterministic 100k fixture * style(xtream-mock-server): apply repository formatting * fix(xtream-mock-server): harden performance fixture data * feat(xtream-mock-server): add performance control plane * docs(performance): correct Xtream capture plan * fix(xtream-mock-server): harden performance controls * fix(xtream-mock-server): harden control lifecycle * feat(performance): add Xtream preload markers * feat(performance): trace Xtream main phases * feat(performance): mark Xtream store publications * feat(performance): trace Xtream database phases * feat(performance): trace Xtream delete cancellation * feat(performance): capture Xtream phase attribution * feat(performance): mark Sources Xtream refresh * test(performance): define Xtream benchmark evidence contracts * test(performance): add Xtream benchmark runner * test(performance): surface failure evidence writes * test(performance): align database read clock * test(performance): preserve capture failure contracts
74 lines
2.5 KiB
TypeScript
74 lines
2.5 KiB
TypeScript
import { createServer } from 'node:http';
|
|
import {
|
|
createXtreamMockServerShutdown,
|
|
createXtreamMockApp,
|
|
parseXtreamMockServerEnvironment,
|
|
} from './app/server.js';
|
|
|
|
function start(): void {
|
|
let options;
|
|
try {
|
|
options = parseXtreamMockServerEnvironment(process.env);
|
|
} catch (error) {
|
|
const message =
|
|
error instanceof Error ? error.message : 'Invalid configuration';
|
|
console.error(`[xtream-mock] ${message}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const application = createXtreamMockApp(options);
|
|
const server = createServer(application);
|
|
const shutdownServer = createXtreamMockServerShutdown(server, application);
|
|
const displayHost = options.host === '::1' ? '[::1]' : options.host;
|
|
let shuttingDown = false;
|
|
|
|
server.on('error', (error: NodeJS.ErrnoException) => {
|
|
if (error.code === 'EADDRINUSE') {
|
|
console.error(
|
|
`[xtream-mock] Port ${options.port} is already in use.`
|
|
);
|
|
} else {
|
|
console.error('[xtream-mock] Server error:', error.message);
|
|
}
|
|
process.exit(1);
|
|
});
|
|
|
|
server.listen(options.port, options.host, () => {
|
|
const origin = `http://${displayHost}:${options.port}`;
|
|
console.log(`[xtream-mock] Listening on ${origin}`);
|
|
console.log(`[xtream-mock] Direct API: ${origin}/player_api.php`);
|
|
console.log(`[xtream-mock] PWA proxy: ${origin}/xtream`);
|
|
console.log(`[xtream-mock] Health: ${origin}/health`);
|
|
if (options.control?.enabled) {
|
|
console.log('[xtream-mock] Performance control enabled');
|
|
}
|
|
});
|
|
|
|
const shutdown = () => {
|
|
if (!shuttingDown) {
|
|
shuttingDown = true;
|
|
console.log('\n[xtream-mock] Shutting down...');
|
|
}
|
|
void shutdownServer().then(() => process.exit(0));
|
|
};
|
|
|
|
process.on('SIGINT', shutdown);
|
|
process.on('SIGTERM', shutdown);
|
|
process.on('uncaughtException', (error) => {
|
|
console.error('[xtream-mock] Uncaught exception:', error.message);
|
|
process.exit(1);
|
|
});
|
|
process.on('unhandledRejection', (reason) => {
|
|
const message =
|
|
reason instanceof Error ? reason.message : 'Unknown rejection';
|
|
console.error('[xtream-mock] Unhandled rejection:', message);
|
|
process.exit(1);
|
|
});
|
|
process.stdin.resume();
|
|
process.stdin.on('end', () => {
|
|
/* The HTTP server handle intentionally keeps this process alive. */
|
|
});
|
|
}
|
|
|
|
start();
|