import http from 'node:http';import{pathToFileURL}from'node:url';import{makeMetrics}from'./metrics.mjs'; export function createDemo(){ const m=makeMetrics(); const api=http.createServer(async(req,res)=>{ const url=new URL(req.url,'http://localhost'); if(req.method!=='GET'){res.writeHead(405,{Allow:'GET'}).end();return;} if(url.pathname==='/health'){res.writeHead(200,{'Content-Type':'application/json'}).end('{"ok":true}');return;} const route=['/api/orders','/api/report'].includes(url.pathname)?url.pathname:'unmatched'; const start=performance.now();m.inFlight.inc();let completed=false; function finish(){if(completed)return;completed=true;m.inFlight.dec();m.requests.inc({route,method:'GET',status:String(res.statusCode)});m.duration.observe({route,method:'GET'},(performance.now()-start)/1000);} res.once('finish',finish);res.once('close',()=>{if(!res.writableFinished){res.statusCode=499;finish();}}); const delay=Number(url.searchParams.get('delay')||20); if(!Number.isInteger(delay)||delay<0||delay>1000){res.writeHead(400,{'Content-Type':'application/json'}).end('{"error":"delay must be 0..1000 ms"}');return;} await new Promise(r=>setTimeout(r,delay));if(res.destroyed)return; const status=route==='unmatched'?404:url.searchParams.get('fail')==='1'?500:200; res.writeHead(status,{'Content-Type':'application/json','Cache-Control':'no-store'}).end(JSON.stringify({ok:status===200,route,items:status===200?[{id:'D-1042',amountMinor:125000}]:[],demo:true})); }); const metrics=http.createServer(async(req,res)=>{if(req.method!=='GET'||req.url!=='/metrics'){res.writeHead(404).end();return;}try{res.writeHead(200,{'Content-Type':m.registry.contentType,'Cache-Control':'no-store'}).end(await m.registry.metrics());}catch{res.writeHead(500).end('Metrics unavailable');}}); return{api,metrics,...m}; } if(import.meta.url===pathToFileURL(process.argv[1]||'').href){ const demo=createDemo(),host=process.env.HOST||'127.0.0.1',port=Number(process.env.PORT||8290),metricsPort=Number(process.env.METRICS_PORT||8291); demo.api.listen(port,host,()=>console.log('Demo API: '+host+':'+port));demo.metrics.listen(metricsPort,host,()=>console.log('Private metrics: '+host+':'+metricsPort+'/metrics')); for(const signal of ['SIGINT','SIGTERM'])process.on(signal,()=>{demo.api.close();demo.metrics.close();setTimeout(()=>process.exit(0),1500).unref();}); }