lacis 0.2.2 → 0.2.4

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.
@@ -1 +1 @@
1
- export{I as bunAdapter,J as getAdapter,H as netlifyAdapter,F as nodeAdapter,G as vercelAdapter}from'../chunk-GWLL6W5O.js';
1
+ export{I as bunAdapter,J as getAdapter,H as netlifyAdapter,F as nodeAdapter,G as vercelAdapter}from'../chunk-QZ3VOPKR.js';
@@ -0,0 +1,26 @@
1
+ import F from'path';import Le from'fs/promises';import j from'cluster';import ue,{IncomingMessage,ServerResponse}from'http';import Ve from'https';import*as q from'os';import q__default from'os';import {EventEmitter}from'events';import {Socket}from'net';var O={beforeRequest:[],afterRequest:[],onError:[]},T=new Map;function re(t,e){return O[t].push(e),{remove:()=>{let r=O[t].indexOf(e);r!==-1&&O[t].splice(r,1);}}}function dt(t,e,r){let n=t==="/"?"/":t.replace(/\/+$/,"");return T.has(n)||T.set(n,{beforeRequest:[],afterRequest:[],onError:[]}),T.get(n)[e].push(r),{remove:()=>{if(T.has(n)){let s=T.get(n),a=s[e].indexOf(r);a!==-1&&s[e].splice(a,1);}}}}function je(t){let r=(t==="/"?"/":t.replace(/\/+$/,"")).split("/").filter(Boolean),n={beforeRequest:[...O.beforeRequest],afterRequest:[...O.afterRequest],onError:[...O.onError]},o="";if(T.has("/")){let s=T.get("/");n.beforeRequest.push(...s.beforeRequest),n.afterRequest.push(...s.afterRequest),n.onError.push(...s.onError);}for(let s of r)if(o+="/"+s,T.has(o)){let a=T.get(o);n.beforeRequest.push(...a.beforeRequest),n.afterRequest.push(...a.afterRequest),n.onError.push(...a.onError);}return n}function x(){return O.beforeRequest.length>0||O.afterRequest.length>0||O.onError.length>0?true:T.size>0}async function _(t,e,r,n){let o=e.url?.split("?")[0]||"/",s=je(o);if(s[t].length===0)return true;for(let a of s[t])try{if(await a(e,r,n)===!1)return !1}catch(l){if(t!=="onError")try{for(let i of s.onError)await i(e,r,{error:l,phase:t});}catch(i){console.error("Error in error handler:",i);}return false}return true}async function ye(t){T.clear();async function e(r,n=""){try{let o=await Le.readdir(r,{withFileTypes:!0}),s=o.find(a=>a.name==="+middleware.ts"||a.name==="+middleware.js");if(s){let a=F.join(r,s.name);try{let i=await import(`${F.resolve(a)}?update=${Date.now()}`);if(T.has(n)||T.set(n,{beforeRequest:[],afterRequest:[],onError:[]}),i.beforeRequest){let d=Array.isArray(i.beforeRequest)?i.beforeRequest:[i.beforeRequest];T.get(n).beforeRequest.push(...d);}if(i.afterRequest){let d=Array.isArray(i.afterRequest)?i.afterRequest:[i.afterRequest];T.get(n).afterRequest.push(...d);}if(i.onError){let d=Array.isArray(i.onError)?i.onError:[i.onError];T.get(n).onError.push(...d);}}catch(l){console.error(`Error loading middleware for ${n}:`,l);}}for(let a of o)a.isDirectory()&&await e(F.join(r,a.name),`${n==="/"?"":n}/${a.name}`);}catch(o){console.error(`Error scanning directory ${r}:`,o);}}await e(t,"/");}function ut(){return T}function ct(){O.beforeRequest=[],O.afterRequest=[],O.onError=[],T.clear();}function P(t){if(t)for(let e of ["beforeRequest","afterRequest","onError"]){let r=t[e];if(r){let n=Array.isArray(r)?r:[r];for(let o of n)re(e,o);}}}function Ue(t,e){return !e||e==="*"?true:typeof e=="string"?t===e:Array.isArray(e)?e.includes(t):e instanceof RegExp?e.test(t):typeof e=="function"?e(t):false}function De(t){let e=(t.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", "),r=(t.allowedHeaders??["Content-Type","Authorization"]).join(", "),n=t.exposedHeaders?.join(", "),o=t.maxAge!=null?String(t.maxAge):null,s=!t.origin||t.origin==="*";return async(a,l)=>{let i=a.getHeader("origin");if(!i||!Ue(i,t.origin))return;let d=s&&!t.credentials;if(l.setHeader("Access-Control-Allow-Origin",d?"*":i),d||l.setHeader("Vary","Origin"),t.credentials&&l.setHeader("Access-Control-Allow-Credentials","true"),n&&l.setHeader("Access-Control-Expose-Headers",n),a.method==="OPTIONS")return l.setHeader("Access-Control-Allow-Methods",e),l.setHeader("Access-Control-Allow-Headers",r),o&&l.setHeader("Access-Control-Max-Age",o),l.status(204),l.end(),false}}function I(t){t&&re("beforeRequest",De(t));}function g(...t){j.isPrimary&&console.log(...t);}function We(t){let e=t.match(/^\[(\w+)(\??)]/);return e?{name:e[1],isParam:true,isOptional:e[2]==="?"}:{name:t,isParam:false,isOptional:false}}var Fe=1e3,ze=100,se=class{rootNode;cachedRoutes;routeCount;lastLoaded;verbose;constructor(){this.rootNode=this.createNode(),this.cachedRoutes=new Map,this.routeCount=0,this.lastLoaded=0,this.verbose=false;}createNode(){return {handlers:Object.create(null),staticChildren:new Map,paramChild:null,wildcardHandler:null,isEndpoint:false}}addRoute(e,r,n){let o=r.split("/").filter(Boolean),s=this.rootNode;for(let a of o){let l=We(a);if(l.isParam){if(!s.paramChild)s.paramChild={name:l.name,node:this.createNode(),isOptional:l.isOptional};else if(s.paramChild.name!==l.name)throw new Error(`Route conflict: param name "[${l.name}]" conflicts with existing "[${s.paramChild.name}]" at the same path position. Use the same param name for all methods at this level.`);s=s.paramChild.node;}else {if(a==="*")return s.wildcardHandler||(s.wildcardHandler=Object.create(null)),s.wildcardHandler[e]=n,this.cachedRoutes.clear(),this;s.staticChildren.has(a)||s.staticChildren.set(a,this.createNode()),s=s.staticChildren.get(a);}}return s.isEndpoint=true,s.handlers[e]||this.routeCount++,s.handlers[e]=n,this.cachedRoutes.clear(),this}findRoute(e,r){let n=r==="/"?"/":r.replace(/\/+$/,""),o=e+":"+n,s=this.cachedRoutes.get(o);if(s)return s;let a=n==="/"?[]:n.split("/").filter(Boolean),l=Object.create(null),i=this.traverse(this.rootNode,a,e,l,0)??{handler:null,params:Object.create(null)};if(this.cachedRoutes.size>=Fe){let d=0;for(let c of this.cachedRoutes.keys())if(this.cachedRoutes.delete(c),++d>=ze)break}return this.cachedRoutes.set(o,i),i}traverse(e,r,n,o,s){if(s===r.length){if(e.isEndpoint){let d=e.handlers[n]??(n==="HEAD"?e.handlers.GET:void 0)??e.handlers[""];if(d)return {handler:d,params:{...o}};let c=Object.keys(e.handlers).filter(p=>p!=="");return {handler:null,params:{},allowedMethods:c}}let i=e.paramChild;if(i?.isOptional&&i.node.isEndpoint){let d=i.node.handlers[n]??(n==="HEAD"?i.node.handlers.GET:void 0)??i.node.handlers[""];if(d)return {handler:d,params:{...o}}}return null}let a=r[s],l=e.staticChildren.get(a);if(l){let i=this.traverse(l,r,n,o,s+1);if(i)return i}if(e.paramChild){let{name:i,node:d}=e.paramChild;o[i]=a;let c=this.traverse(d,r,n,o,s+1);if(c)return c;delete o[i];}if(e.wildcardHandler){let i=e.wildcardHandler[n]??e.wildcardHandler[""],d=r.slice(s).join("/");if(i)return {handler:i,params:{...o,"*":d}};let c=Object.keys(e.wildcardHandler).filter(p=>p!=="");if(c.length>0)return {handler:null,params:{...o,"*":d},allowedMethods:c}}return null}async loadRoutes(e){this.rootNode=this.createNode(),this.cachedRoutes.clear(),this.routeCount=0,await ye(e);let r=this;async function n(o,s=[]){try{let a=await Le.readdir(o,{withFileTypes:!0}),l=a.find(i=>!i.isDirectory()&&(i.name==="index.ts"||i.name==="index.js"));if(l)try{let d=await import(`${F.resolve(F.join(o,l.name))}?update=${Date.now()}`),c=["GET","POST","PUT","DELETE","PATCH"],p="/"+s.join("/"),m=!1;for(let S of c)typeof d[S]=="function"&&(r.addRoute(S,p,d[S]),m=!0);!m&&typeof d.default=="function"&&r.addRoute("GET",p,d.default),r.verbose&&g(`Route loaded: ${p}`);}catch(i){console.error(`Error loading index in ${o}:`,i);}for(let i of a)if(i.isDirectory()){let d=i.name.match(/^\[(\w+)(\??)]/),c=d?`[${d[1]}${d[2]}]`:i.name;await n(F.join(o,i.name),[...s,c]);}}catch(a){console.error(`Error scanning directory ${o}:`,a);}}return await n(e),this.lastLoaded=Date.now(),this.verbose&&g(`Loading completed: ${this.routeCount} routes`),true}getRoutes(){let e=[];return this.collectRoutes(this.rootNode,[],e),e}collectRoutes(e,r,n){if(e.isEndpoint){let o=r.length===0?"/":"/"+r.join("/");for(let[s,a]of Object.entries(e.handlers))s!==""&&n.push({method:s,path:o,handler:a});}for(let[o,s]of e.staticChildren)this.collectRoutes(s,[...r,o],n);if(e.paramChild){let{name:o,isOptional:s,node:a}=e.paramChild;this.collectRoutes(a,[...r,s?`:${o}?`:`:${o}`],n);}if(e.wildcardHandler){let o="/"+[...r,"*"].join("/");for(let[s,a]of Object.entries(e.wildcardHandler))s!==""&&n.push({method:s,path:o,handler:a});}}getStats(){return {routeCount:this.routeCount,lastLoaded:this.lastLoaded,uptime:Date.now()-this.lastLoaded,cacheSize:this.cachedRoutes.size}}setVerbose(e){return this.verbose=e,this}reset(){this.rootNode=this.createNode(),this.cachedRoutes=new Map,this.routeCount=0;}},D=new se;function z(t){return t&&typeof t=="object"&&"error"in t}function J(t){for(let{path:e,handlers:r}of t){let n=e.replace(/:(\w+\??)/g,(o,s)=>s.endsWith("?")?`[${s.slice(0,-1)}?]`:`[${s}]`);for(let[o,s]of Object.entries(r))typeof s=="function"&&D.addRoute(o,n,s);}}async function V(t){return D.loadRoutes(t)}function L(t,e="GET"){let r=D.findRoute(e,t);return r.handler?{handler:r.handler,params:r.params}:r.allowedMethods?.length?{error:"Method Not Allowed",status:405,allowedMethods:r.allowedMethods}:null}function St(t){return F.resolve(process.cwd(),t||process.env.ROUTES_DIR||"routes")}function vt(){return D.getStats()}function bt(t){D.setVerbose(t);}function Et(){D.reset();}function Re(t,e={},r={},n){let o=false,s=0,a={},l=[],i=[],d=[],c=null;r.onMessage&&l.push(r.onMessage),r.onClose&&i.push(r.onClose),r.onError&&d.push(r.onError),r.onEvent&&Object.entries(r.onEvent).forEach(([f,h])=>{a[f]||(a[f]=[]),a[f].push(h);});let p=e.reconnectInterval||3e3,m=e.maxRetries||3,S=e.disableReconnect||false,y=e.body,w=e.contentType||(y?"application/json":void 0),u=e.method||(y?"POST":"GET");if(typeof t!="string"){let f=t;return o=true,f.on("data",h=>{C(h.toString());}),f.on("end",()=>{o=false;}),f.on("error",h=>{o=false,console.error("SSE Error:",h);}),b()}if(typeof t=="string")return new Promise((f,h)=>{A().then(()=>f(b())).catch(h);});function C(f){let h=f,v=h.split(`
2
+
3
+ `);h=v.pop()||"";for(let M of v){let $=M.split(`
4
+ `),R="",E="";for(let k of $)k.startsWith("event:")?E=k.slice(6).trim():k.startsWith("data:")&&(R=k.slice(5).trim());if(R)try{let k=JSON.parse(R);E&&a[E]?a[E].forEach(B=>B(k)):l.forEach(B=>B(k));}catch{E&&a[E]?a[E].forEach(k=>k(R)):l.forEach(k=>k(R));}}}function b(){return {onMessage(f){return l.push(f),this},onEvent(f,h){return a[f]||(a[f]=[]),a[f].push(h),this},onClose(f){return i.push(f),this},close(){c&&(c.destroy(),c=null),o=false,i.forEach(f=>f());}}}async function A(){if(!o){o=true;try{await H();}catch(f){!S&&s<m?(s++,setTimeout(()=>{A();},p)):d.forEach(h=>h(f));}}}async function H(){return new Promise((f,h)=>{let v=new URL(t);e.params&&(typeof e.params=="object"?Object.entries(e.params).forEach(([R,E])=>{v.searchParams.append(R,String(E));}):typeof e.params=="string"&&new URLSearchParams(e.params).forEach((E,k)=>{v.searchParams.append(k,E);}));let M={hostname:v.hostname,port:v.port||(v.protocol==="https:"?443:80),path:v.pathname+v.search,method:u,headers:{Accept:"text/event-stream",...n?.headers||{},"Cache-Control":"no-cache",Connection:"keep-alive",...w&&{"Content-Type":w},...y&&typeof y=="string"&&{"Content-Length":Buffer.byteLength(y).toString()},...y&&typeof y!="string"&&{"Content-Length":Buffer.byteLength(JSON.stringify(y)).toString()}}};c=(v.protocol==="https:"?Ve:ue).request(M,R=>{if(R.statusCode!==200){o=false,h(new Error(`Server responded with status: ${R.statusCode}`));return}R.setEncoding("utf8"),R.on("data",C),R.on("end",()=>{o=false,c?.destroy(),c=null,i.forEach(E=>E()),f(null);}),R.on("close",()=>{o=false,c?.destroy(),c=null,i.forEach(E=>E()),f(null);}),R.on("error",E=>{o=false,c?.destroy(),c=null,i.forEach(k=>k()),h(E);});}),c.on("error",R=>{o=false,c?.destroy(),c=null,h(R);}),y&&(typeof y=="string"?c.write(y):c.write(JSON.stringify(y))),c.end();})}return b()}function we(t,e){let r=e?.headers?.["Cache-Control"]||"no-cache",n=e?.headers?.Connection||"keep-alive",o=e?.timeout||3e5;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":r,Connection:n,...e?.headers||{}});let s=setTimeout(()=>{t.end();},o);return t.on("close",()=>{clearTimeout(s);}),s}function Ce(t,e){return t.writableEnded?false:t.write(`data: ${e}
5
+
6
+ `)}function Se(t,e){return t.writableEnded?false:t.write(`data: ${JSON.stringify(e)}
7
+
8
+ `)}function ve(t,e,r){return t.writableEnded?false:(t.write(`event: ${e}
9
+ `),t.write(`data: ${JSON.stringify(r)}
10
+
11
+ `))}function be(t,e){return t.writableEnded?false:t.write(`: ${e}
12
+
13
+ `)}function Ee(t,e){return t.writableEnded?false:t.write(`id: ${e}
14
+
15
+ `)}function Me(t,e){return t.writableEnded?false:t.write(`retry: ${e}
16
+
17
+ `)}function Te(t,e="Connection closed"){t.write(`: ${e}
18
+
19
+ `),t.end();}function xe(t,e,r,n=500,o){t.writeHead(n,{"Content-Type":"text/event-stream"}),t.write(`event: ${e}
20
+ `);let s={message:r,code:n,details:o||null};t.write(`data: ${JSON.stringify(s)}
21
+
22
+ `),t.end();}var Ge=10485760,K=class{_parsed=null;_raw;constructor(e){this._raw=e;}_parse(){if(this._parsed!==null)return this._parsed;if(this._parsed={},!this._raw)return this._parsed;for(let e of this._raw.split(";")){let r=e.indexOf("=");if(r===-1)continue;let n=e.slice(0,r).trim(),o=e.slice(r+1).trim();if(n){let s=o.startsWith('"')&&o.endsWith('"')?o.slice(1,-1):o;try{this._parsed[n]=decodeURIComponent(s);}catch{this._parsed[n]=s;}}}return this._parsed}get(e){return this._parse()[e]}all(){return {...this._parse()}}},X=class{_pending=[];set(e,r,n={}){return this._pending.push({name:e,value:r,opts:n}),this}delete(e,r={}){return this.set(e,"",{...r,maxAge:0,expires:new Date(0)})}serialize(){return this._pending.map(({name:e,value:r,opts:n})=>{let o=`${e}=${encodeURIComponent(r)}`,s=n.path!==void 0?n.path:"/";return s&&(o+=`; Path=${s}`),n.domain&&(o+=`; Domain=${n.domain}`),n.maxAge!=null&&(o+=`; Max-Age=${n.maxAge}`),n.expires&&(o+=`; Expires=${n.expires.toUTCString()}`),n.httpOnly&&(o+="; HttpOnly"),n.secure&&(o+="; Secure"),n.sameSite&&(o+=`; SameSite=${n.sameSite}`),o})}};function _e(t){if(typeof t.get=="function")return t.get("cookie")??void 0;let e=t.cookie;return Array.isArray(e)?e.join("; "):e}function N(t){return class extends t{_zreqCookies;getHeader(e){let r=this.headers;if(typeof r.get=="function")return r.get(e)??void 0;let n=r[e.toLowerCase()];return Array.isArray(n)?n[0]:n}get cookies(){return this._zreqCookies||(this._zreqCookies=new K(_e(this.headers))),this._zreqCookies}json(){return this.body().then(e=>JSON.parse(e.toString()))}form(){return new Promise((e,r)=>{let n=this.headers,o=typeof n.get=="function"?n.get("content-type")??"":n["content-type"]??"";if(!o.startsWith("multipart/form-data")){r(new Error("Content-Type is not multipart/form-data"));return}let s=o.match(/boundary=(.+)$/);if(!s){r(new Error("Boundary not found"));return}let a=s[1].trim();this.body().then(l=>{let i={},d=Buffer.from(`--${a}`),c=[],p=0,m;for(;(m=l.indexOf(d,p))!==-1;)c.push(l.subarray(p,m)),p=m+d.length;c.push(l.subarray(p));for(let S=1;S<c.length-1;S++){let y=c[S].subarray(2),w=y.indexOf(`\r
23
+ \r
24
+ `);if(w===-1)continue;let u=y.subarray(0,w).toString(),C=y.subarray(w+4,y.length-2),b=u.match(/Content-Disposition: form-data; name="([^"]+)"(?:; filename="([^"]+)")?/i);if(b)if(b[2]){let A=u.match(/Content-Type:\s*([^\r\n]+)/i);i[b[1]]={filename:b[2],mimetype:A?A[1].trim():"application/octet-stream",data:C,size:C.length};}else i[b[1]]=C.toString("utf-8");}e(i);}).catch(r);})}createSSEClient(e,r){return Re(this,e,r)}}}function Y(){let t=[],e=0,r=false;return new Promise((n,o)=>{this.on("data",s=>{if(e+=s.length,e>Ge){r=true,this.destroy(),o(Object.assign(new Error("Payload Too Large"),{code:413}));return}t.push(s);}).on("end",()=>{r||(r=true,n(Buffer.concat(t)));}).on("error",s=>{r||(r=true,o(s));});})}function ke(t,e){let r=t.serialize();r.length>0&&!e.headersSent&&e.setHeader("Set-Cookie",r);}function W(t){return class extends t{_zresCookies;get cookies(){return this._zresCookies||(this._zresCookies=new X),this._zresCookies}end(e){return this._zresCookies&&ke(this._zresCookies,this),super.end(e)}status(e){return this.statusCode=e,this}send(e){return typeof e=="string"?(this.setHeader("Content-Type","text/plain"),this.end(e)):this.json(e),this}json(e){return this.setHeader("Content-Type","application/json"),this.end(JSON.stringify(e)),this}initSSE(e){return we(this,e)}sseSend(e){Ce(this,e);}sseJson(e){Se(this,e);}sseEvent(e,r){ve(this,e,r);}sseComment(e){be(this,e);}sseId(e){Ee(this,e);}sseRetry(e){Me(this,e);}sseClose(e){Te(this,e);}sseError(e,r,n=500,o){xe(this,e,r,n,o);}}}var ne=class{params={};headers={};body(){return Y.call(this)}},G=N(ne).prototype,oe=class{statusCode=200;headersSent=false;setHeader(e,r){}end(e){}write(e){}},Ke=W(oe).prototype;function Z(t){t.body=Y,t.json=G.json,t.form=G.form,t.getHeader=G.getHeader,t.createSSEClient=G.createSSEClient,t.cookies=new K(_e(t.headers));}function Q(t){let e=Ke;t.status=e.status,t.send=e.send,t.json=e.json,t.initSSE=e.initSSE,t.sseSend=e.sseSend,t.sseJson=e.sseJson,t.sseEvent=e.sseEvent,t.sseComment=e.sseComment,t.sseId=e.sseId,t.sseRetry=e.sseRetry,t.sseClose=e.sseClose,t.sseError=e.sseError;let r=new X;t.cookies=r;let n=t.end.bind(t);t.end=function(...o){return ke(r,this),n(...o)};}var ee=null;function Ye(t={}){let e=new EventEmitter,r={sampleInterval:t.sampleInterval||5e3,reportInterval:t.reportInterval||6e4,resetInterval:t.resetInterval||1440*60*1e3,enableHistogram:t.enableHistogram!==void 0?t.enableHistogram:true,logToConsole:t.logToConsole!==void 0?t.logToConsole:true,thresholds:{cpu:t.thresholds?.cpu||80,memory:t.thresholds?.memory||80,responseTime:t.thresholds?.responseTime||1e3,errorRate:t.thresholds?.errorRate||5}},n=Date.now(),o={requestCount:0,activeRequests:0,errorCount:0,responseTimes:[],responseTimesBucket:Array(100).fill(0),statusCodes:{},lastReport:n,lastReset:n},s=d(),a=[],l=process.cpuUsage(),i={cpu:false,memory:false,responseTime:false,errorRate:false};function d(){return {timestamp:Date.now(),uptime:process.uptime(),requestCount:0,activeRequests:0,errorCount:0,responseTimes:{min:0,max:0,avg:0,count:0,sum:0},statusCodes:{},memory:process.memoryUsage(),cpu:{usage:0,system:0,user:0},systemLoad:q.loadavg(),systemMemory:{total:q.totalmem(),free:q.freemem(),used:q.totalmem()-q.freemem()}}}function c(){let f=o.responseTimes;if(f.length===0)return {min:0,max:0,avg:0,count:0,sum:0};let h=1/0,v=-1/0,M=0;for(let E of f)h=Math.min(h,E),v=Math.max(v,E),M+=E;let $=M/f.length,R={min:h,max:v,avg:$,count:f.length,sum:M};if(r.enableHistogram){let E=[...f].sort((k,B)=>k-B);R.p50=E[Math.floor(E.length*.5)],R.p90=E[Math.floor(E.length*.9)],R.p99=E[Math.floor(E.length*.99)];}return R}function p(){let f=Date.now(),h=process.uptime(),v=process.memoryUsage(),M=process.cpuUsage(l);l=process.cpuUsage();let R=(M.user+M.system)/1e3/r.sampleInterval*100;s={timestamp:f,uptime:h,requestCount:o.requestCount,activeRequests:o.activeRequests,errorCount:o.errorCount,responseTimes:c(),statusCodes:{...o.statusCodes},memory:v,cpu:{usage:R,system:M.system,user:M.user},systemLoad:q.loadavg(),systemMemory:{total:q.totalmem(),free:q.freemem(),used:q.totalmem()-q.freemem()}},a.push({...s}),a.length>100&&a.shift(),y(),j.isWorker&&process.send&&process.send({type:"metrics",metrics:s});}function m(){if(!r.logToConsole||j.isPrimary===false)return;let f={rss:(s.memory.rss/1024/1024).toFixed(2),heapTotal:(s.memory.heapTotal/1024/1024).toFixed(2),heapUsed:(s.memory.heapUsed/1024/1024).toFixed(2)},h=Date.now()-o.lastReport,v=(s.requestCount/(h/1e3)).toFixed(2),M=s.requestCount?(s.errorCount/s.requestCount*100).toFixed(2):"0.00";g(`
25
+ \u{1F4CA} Server Performance Metrics \u{1F4CA}`),g(`Uptime: ${w(s.uptime)}`),g(`Load: ${s.systemLoad[0].toFixed(2)}, ${s.systemLoad[1].toFixed(2)}, ${s.systemLoad[2].toFixed(2)}`),g(`Requests: ${s.requestCount} total, ${v} req/sec`),g(`Active Requests: ${s.activeRequests}`),g(`Errors: ${s.errorCount} (${M}%)`),s.responseTimes.count>0&&(g(`Response Times: avg ${s.responseTimes.avg.toFixed(2)}ms, min ${s.responseTimes.min}ms, max ${s.responseTimes.max}ms`),s.responseTimes.p50&&g(`Response Time Percentiles: p50 ${s.responseTimes.p50}ms, p90 ${s.responseTimes.p90}ms, p99 ${s.responseTimes.p99}ms`)),g(`Memory: ${f.rss}MB (RSS), ${f.heapUsed}MB / ${f.heapTotal}MB (Heap)`),g(`CPU Usage: ${s.cpu.usage.toFixed(2)}%`),Object.keys(s.statusCodes).length>0&&(g("Status Codes:"),Object.entries(s.statusCodes).sort(([$],[R])=>parseInt($)-parseInt(R)).forEach(([$,R])=>{g(` ${$}: ${R}`);})),g(""),o.lastReport=Date.now();}function S(){let f=Date.now();o.requestCount=0,o.activeRequests=0,o.errorCount=0,o.responseTimes=[],o.responseTimesBucket=Array(100).fill(0),o.statusCodes={},o.lastReport=f,o.lastReset=f,g("\u{1F504} Performance metrics have been reset");}function y(){let f=s.memory.heapUsed/s.memory.heapTotal*100,h=s.requestCount?s.errorCount/s.requestCount*100:0,v=s.responseTimes.avg;s.cpu.usage>r.thresholds.cpu&&!i.cpu?(i.cpu=true,e.emit("alarm","cpu",`High CPU usage: ${s.cpu.usage.toFixed(2)}%`)):s.cpu.usage<=r.thresholds.cpu&&i.cpu&&(i.cpu=false,e.emit("alarm-clear","cpu",`CPU usage returned to normal: ${s.cpu.usage.toFixed(2)}%`)),f>r.thresholds.memory&&!i.memory?(i.memory=true,e.emit("alarm","memory",`High memory usage: ${f.toFixed(2)}%`)):f<=r.thresholds.memory&&i.memory&&(i.memory=false,e.emit("alarm-clear","memory",`Memory usage returned to normal: ${f.toFixed(2)}%`)),v>r.thresholds.responseTime&&!i.responseTime?(i.responseTime=true,e.emit("alarm","responseTime",`High response time: ${v.toFixed(2)}ms`)):v<=r.thresholds.responseTime&&i.responseTime&&(i.responseTime=false,e.emit("alarm-clear","responseTime",`Response time returned to normal: ${v.toFixed(2)}ms`)),h>r.thresholds.errorRate&&!i.errorRate?(i.errorRate=true,e.emit("alarm","errorRate",`High error rate: ${h.toFixed(2)}%`)):h<=r.thresholds.errorRate&&i.errorRate&&(i.errorRate=false,e.emit("alarm-clear","errorRate",`Error rate returned to normal: ${h.toFixed(2)}%`));}function w(f){let h=Math.floor(f/86400),v=Math.floor(f%86400/3600),M=Math.floor(f%3600/60),$=Math.floor(f%60),R=[];return h>0&&R.push(`${h}d`),v>0&&R.push(`${v}h`),M>0&&R.push(`${M}m`),($>0||R.length===0)&&R.push(`${$}s`),R.join(" ")}function u(){let f=setInterval(p,r.sampleInterval),h=setInterval(m,r.reportInterval),v=setInterval(S,r.resetInterval);return {stop:()=>{clearInterval(f),clearInterval(h),clearInterval(v);}}}function C(){let f=Date.now();return o.activeRequests++,{end:(h,v=false)=>{let M=Date.now()-f;return o.activeRequests--,o.requestCount++,o.responseTimes.push(M),o.responseTimes.length>1e3&&o.responseTimes.shift(),o.statusCodes[h]=(o.statusCodes[h]||0)+1,(v||h>=500)&&o.errorCount++,M}}}function b(){return !Object.values(i).some(f=>f)}function A(){let f=s.memory.heapUsed/s.memory.heapTotal*100,h=s.requestCount?s.errorCount/s.requestCount*100:0;return {status:b()?"healthy":"unhealthy",uptime:s.uptime,responseTimes:{avg:s.responseTimes.avg,p90:s.responseTimes.p90||null,p99:s.responseTimes.p99||null},memory:{usedMB:Math.round(s.memory.heapUsed/1024/1024),totalMB:Math.round(s.memory.heapTotal/1024/1024),percent:f.toFixed(2)},cpu:s.cpu.usage.toFixed(2),requests:{total:s.requestCount,active:s.activeRequests,errors:s.errorCount,errorRate:h.toFixed(2)},alerts:Object.entries(i).filter(([v,M])=>M).map(([v])=>v)}}let H=u();return {trackRequest:C,getMetrics:()=>({...s}),getMetricsHistory:()=>[...a],getHealthMetrics:A,isHealthy:b,stop:H.stop,on:e.on.bind(e),once:e.once.bind(e),off:e.off.bind(e)}}function qe(t){if(!ee){let e=Ye(t),r=e.stop;e.stop=()=>{r(),ee=null;},ee=e;}return ee}function ie(t={}){let e=t.reportInterval??5e3,r={workers:new Map,workerIds:[]};function n(){if(!j.isWorker)return;let d=process.cpuUsage(),c=()=>{if(!process.send)return;let p=process.memoryUsage(),m=process.cpuUsage(d);d=process.cpuUsage();let S=(m.user+m.system)/(e*1e3),y={type:"stats",stats:{pid:process.pid,load:S,lastUsed:Date.now(),memoryUsage:p}};process.send(y);};c(),setInterval(c,e).unref();}function o(){let d=j.fork();r.workers.set(d.id,{pid:d.process.pid,load:0,lastUsed:Date.now(),memoryUsage:{rss:0,heapTotal:0,heapUsed:0,external:0,arrayBuffers:0}}),r.workerIds.push(d.id),g(`Worker ${d.process.pid} started`);}let s=false,a=[];function l(d=q.cpus().length){if(!j.isPrimary)return n();g(`\u{1F9F5} Launching ${d} workers...`);for(let c=0;c<d;c++)o();j.on("message",(c,p)=>{if(p.type==="stats"&&"stats"in p){let m=r.workers.get(c.id);m&&Object.assign(m,p.stats);}}),j.on("exit",(c,p,m)=>{if(r.workers.delete(c.id),r.workerIds=r.workerIds.filter(S=>S!==c.id),s){a.forEach(S=>S());return}g(`Worker ${c.process.pid} died (${m||p}). Restarting...`),setTimeout(()=>o(),1e3);});}function i(d){s=true;let c=Object.keys(j.workers??{});if(c.length===0){d?.();return}let p=c.length;a.push(()=>{p--,p===0&&d?.();});for(let m of c)j.workers?.[m]?.kill();}return {start:l,shutdown:i,getWorkerStats:()=>Array.from(r.workers.entries()),getActiveWorkerCount:()=>r.workerIds.length}}var ae=class extends ue.IncomingMessage{params={};body=Y},le=class extends N(ae){},de=class extends W(ue.ServerResponse){},$e={name:"node",createHandler:t=>{if(typeof t!="string")throw new Error("nodeAdapter requires a routesDir string, not a ServerlessConfig.");let e=t;return async(r={})=>{let{port:n=3e3,defaultHeaders:o,isDev:s,cluster:a,monitoring:l={enabled:false}}=r,i=null;s&&l.enabled&&(i=qe({sampleInterval:l.sampleInterval||5e3,reportInterval:l.reportInterval||6e4,thresholds:l.thresholds,logToConsole:true}),j.isPrimary&&(g("\u{1F4CA} Development performance monitoring enabled"),i.on("alarm",(c,p)=>{g(`\u26A0\uFE0F ALERT: ${p}`);}),i.on("alarm-clear",(c,p)=>{g(`\u2705 RESOLVED: ${p}`);})));let d=o?Object.entries(o):[];if(a?.enabled&&j.isPrimary){let c=a.workers??q__default.cpus().length,p=r.httpsOptions?"https":"http";if(g(`\u{1F9F5} Starting server with ${c} workers`),j.schedulingPolicy!==void 0)try{j.schedulingPolicy=j.SCHED_RR;}catch{}let m=ie();return m.start(c),g(`\u{1F680} Server running at ${p}://localhost:${n}/`+(s?" (dev)":"")),s&&i&&g(`\u{1F4CA} Performance monitoring available at http://localhost:${n}/health`),{close:S=>{i&&i.stop(),m.shutdown(S);}}}if(j.isWorker||!a?.enabled){await V(e),I(r.cors),P(r.middleware);let c=async(w,u,C)=>{try{if(s&&i&&w.url==="/health"){u.setHeader("Content-Type","application/json"),u.end(JSON.stringify(i.getHealthMetrics())),C?.end(200);return}let b=w.url||"/",A=b.indexOf("?"),H=A===-1?b:b.slice(0,A);if(x()&&(await _("beforeRequest",w,u)===!1||u.headersSent)){C?.end(u.statusCode||204);return}let f=L(H,w.method||"GET");if(!f){x()&&await _("onError",w,u),u.status(404).json({error:"Route not found"}),C?.end(404);return}if("error"in f){let h=f.status||500;u.status(h).json({error:f.error}),C?.end(h,!0);return}w.params=f.params,await f.handler(w,u),x()&&await _("afterRequest",w,u),u.headersSent||u.end(),C?.end(u.statusCode||200);}catch(b){s&&console.error("Error:",b),u.headersSent||u.status(500).json({error:"Internal Server Error"}),x()&&await _("onError",w,u),C?.end(u.statusCode||500,true);}},p=(w,u)=>{let C=s&&i?i.trackRequest():null;if(d.length>0)for(let b=0;b<d.length;b++)u.setHeader(d[b][0],d[b][1]);c(w,u,C).catch(b=>{s&&console.error("Fatal error:",b),u.headersSent||(u.statusCode=500,u.end("Server Error")),C?.end(500,true);});},m={IncomingMessage:le,ServerResponse:de},S=r.httpsOptions?Ve.createServer({...m,...r.httpsOptions},p):ue.createServer(m,p);S.on("clientError",(w,u)=>{u.destroyed||u.destroy();});let y=r.httpsOptions?"https":"http";return j.isWorker&&ie().start(),S.listen(n,()=>{a?.enabled?s&&g(`Worker ${process.pid} is listening on port ${n}`):(g(`\u{1F680} Server running at ${y}://localhost:${n}/`+(s?" (dev)":"")),s&&i&&g(`\u{1F4CA} Performance monitoring available at http://localhost:${n}/health`));}),S}return null}}};var Oe={name:"vercel",createHandler:t=>{if(typeof t=="string")throw new Error("vercelAdapter.createHandler() requires a ServerlessConfig object, not a routesDir string. Import your routes manifest and pass { routes } instead.");let e=null,r=()=>e||(e=(async()=>{J(t.routes),I(t.cors),P(t.middleware);})(),e);return async(n,o)=>{await r(),Z(n),Q(o);let s=n,a=o;try{if(x()&&(await _("beforeRequest",s,a)===!1||a.headersSent))return;let l=L(s.url??"/",s.method??"GET");if(!l){a.status(404).json({error:"Route not found"});return}if(z(l)){a.status(l.status??500).json({error:l.error});return}s.params=l.params,await l.handler(s,a),x()&&await _("afterRequest",s,a);}catch(l){console.error("[lacis/vercel] Handler error:",l),x()&&await _("onError",s,a,{error:l}),a.headersSent||a.status(500).json({error:"Internal server error"});}}}};function ce(t,e,r,n){let o=Object.keys(r).length>0;return {statusCode:t,headers:e,...o?{multiValueHeaders:r}:{},body:n}}var Pe={name:"netlify",createHandler:t=>{if(typeof t=="string")throw new Error("netlifyAdapter.createHandler() requires a ServerlessConfig object. Run `lacis build` to generate routes/_manifest.ts and pass { routes } instead.");let e=null,r=()=>e||(e=(async()=>{J(t.routes),I(t.cors),P(t.middleware);})(),e);return async(n,o)=>{await r();let s=n.queryStringParameters?"?"+new URLSearchParams(n.queryStringParameters).toString():"",a=n.path+s,l=new IncomingMessage(new Socket);l.url=a,l.method=n.httpMethod,l.headers=n.headers,n.body&&l.push(Buffer.from(n.body,"utf-8")),l.push(null);let i="",d={},c={},p=false,m=new ServerResponse(l);m.writeHead=function(u,C){return m.statusCode=u,C&&(d={...d,...C}),this},m.setHeader=function(u,C){let b=u.toLowerCase();return Array.isArray(C)?(c[b]=C.map(String),d[b]=String(C[0])):d[b]=String(C),this},m.getHeader=function(u){return d[u.toLowerCase()]},m.end=function(u){return p=true,u!==void 0&&(i=typeof u=="string"?u:u.toString()),this},Object.defineProperty(m,"headersSent",{get:()=>p}),Z(l),Q(m);let S=l,y=m,w=L(n.path,n.httpMethod);if(!w)return {statusCode:404,body:JSON.stringify({error:"Route not found"})};if(z(w))return {statusCode:w.status??500,body:JSON.stringify({error:w.error})};try{return x()&&(await _("beforeRequest",S,y)===!1||p)||(S.params=w.params,await w.handler(S,y),x()&&await _("afterRequest",S,y)),ce(y.statusCode,d,c,i)}catch(u){return console.error("[lacis/netlify] Handler error:",u),x()&&await _("onError",S,y,{error:u}),p?ce(y.statusCode,d,c,i):{statusCode:500,body:JSON.stringify({error:"Internal server error"})}}}}};var nt=10485760,ot=new TextEncoder,pe=class{params={};url;method;headers;socket={setTimeout:e=>{}};connection;_req;constructor(e,r,n,o){this._req=e,this.url=r+n,this.method=e.method,this.headers=e.headers,this.connection={remoteAddress:o};}setTimeout(e){}text(){return this._req.text()}body(){return this._req.arrayBuffer().then(e=>{if(e.byteLength>nt)throw Object.assign(new Error("Payload Too Large"),{code:413});return Buffer.from(e)})}},he=class extends N(pe){json(){return this._req.json()}},me=class{statusCode=200;headersSent=false;get finished(){return this.headersSent}get writableEnded(){return this.headersSent}_body=null;_headers=null;_sseReadable=null;_sseWriter=null;_sseWindowClosed=false;_listeners=null;on(e,r){return (e==="finish"||e==="close")&&(this._listeners||(this._listeners=[]),this._listeners.push(r)),this}once(e,r){return this.on(e,r)}emit(e){if((e==="finish"||e==="close")&&this._listeners)for(let r=0;r<this._listeners.length;r++)this._listeners[r]();return true}setHeader(e,r){if(this._headers||(this._headers=[]),Array.isArray(r))for(let n of r)this._headers.push(e,n);else this._headers.push(e,r);return this}getHeader(e){if(!this._headers)return;let r=e.toLowerCase();for(let n=0;n<this._headers.length;n+=2)if(this._headers[n].toLowerCase()===r)return this._headers[n+1]}removeHeader(e){if(!this._headers)return this;let r=e.toLowerCase();for(let n=0;n<this._headers.length;n+=2)if(this._headers[n].toLowerCase()===r){this._headers.splice(n,2);break}return this}hasHeader(e){if(!this._headers)return false;let r=e.toLowerCase();for(let n=0;n<this._headers.length;n+=2)if(this._headers[n].toLowerCase()===r)return true;return false}writeHead(e,r){if(this.statusCode=e,r)for(let[n,o]of Object.entries(r))this.setHeader(n,o);return this}write(e){return this._sseWriter?(this._sseWriter.write(ot.encode(String(e))),true):(this._body=(this._body??"")+e,true)}end(e){if(e!==void 0&&this.write(e),this._sseWriter&&this._sseWriter.close(),this.headersSent=true,this._listeners)for(let r=0;r<this._listeners.length;r++)this._listeners[r]();return this}_initSseStream(){if(this._sseWindowClosed)throw new Error("[lacis/bun] initSSE() must be called synchronously before any `await` in your handler.");let{readable:e,writable:r}=new TransformStream;this._sseReadable=e,this._sseWriter=r.getWriter();}_closeSseWindow(){this._sseWindowClosed=true;}},ge=class extends W(me){initSSE(e){return this._initSseStream(),super.initSSE(e)}},Ie={name:"bun",createHandler:t=>{if(typeof t!="string")throw new Error("bunAdapter requires a routesDir string, not a ServerlessConfig.");let e=t;return async(r={})=>{let{isDev:n,port:o=3e3,defaultHeaders:s,cluster:a}=r,l=parseInt(process.env.LACIS_BUN_WORKER??"0"),i=l>0;if(a?.enabled&&!i){let p=a.workers??q__default.cpus().length;g(`\u{1F9F5} Starting Bun server with ${p} workers (reusePort)`);let m=Array.from({length:p},()=>Bun.spawn(process.argv,{env:{...process.env,LACIS_BUN_WORKER:String(process.pid)},stdout:"ignore",stderr:"inherit"}));return g(`\u{1F680} Server running at http://localhost:${o}/`),{close:S=>{for(let y of m)y.kill();S?.();}}}if(i){let p=setInterval(()=>{try{process.kill(l,0);}catch{clearInterval(p),process.exit(0);}},2e3);p.unref();}g("\u{1F680} Bun high-performance mode enabled"),await V(e),I(r.cors),P(r.middleware);let d=s?Object.entries(s):[],c=Bun.serve({port:o,reusePort:i,async fetch(p,m){let S=new URL(p.url),y=S.pathname,w=new he(p,y,S.search,m?.requestIP(p)?.address??""),u=new ge;try{for(let H=0;H<d.length;H++)u.setHeader(d[H][0],d[H][1]);if(x()&&(!await _("beforeRequest",w,u)||u.headersSent))return fe(u);let C=L(y,p.method);if(!C)return x()&&await _("onError",w,u),new Response(JSON.stringify({error:"Route not found"}),{status:404,headers:{"Content-Type":"application/json"}});if("error"in C)return x()&&await _("onError",w,u),new Response(JSON.stringify({error:C.error}),{status:C.status||500,headers:{"Content-Type":"application/json"}});w.params=C.params;let b=null,A=(async()=>{await C.handler(w,u),x()&&await _("afterRequest",w,u),u.headersSent||u.end();})().catch(H=>{b=H,n&&console.error("Server error:",H),u._sseReadable&&!u.headersSent&&u.end();});return u._closeSseWindow(),u._sseReadable?fe(u,u._sseReadable):(await A,b&&!u.headersSent?new Response(JSON.stringify({error:"Internal Server Error"}),{status:500,headers:{"Content-Type":"application/json"}}):fe(u))}catch(C){return n&&console.error("Server error:",C),new Response(JSON.stringify({error:"Internal Server Error"}),{status:500,headers:{"Content-Type":"application/json"}})}}});return g(`\u{1F680} Server started on http://localhost:${o}${n?" (dev)":""}`),{close:()=>{c.stop();}}}}};function fe(t,e){let r=e??t._body;if(!t._headers)return new Response(r,{status:t.statusCode});let n=new Headers;for(let o=0;o<t._headers.length;o+=2){let s=t._headers[o],a=t._headers[o+1];s.toLowerCase()==="set-cookie"?n.append(s,a):n.set(s,a);}return new Response(r,{status:t.statusCode,headers:n})}var it={node:$e,vercel:Oe,netlify:Pe,bun:Ie};function br(t="node"){let e=it[t];if(!e)throw new Error(`Platform "${t}" not supported`);return e}
26
+ export{be as A,Ee as B,Me as C,Te as D,xe as E,$e as F,Oe as G,Pe as H,Ie as I,br as J,re as a,dt as b,je as c,x as d,_ as e,ye as f,ut as g,ct as h,P as i,g as j,D as k,z as l,J as m,V as n,L as o,St as p,vt as q,bt as r,Et as s,De as t,I as u,Re as v,we as w,Ce as x,Se as y,ve as z};
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import {k as k$1,n,j,J}from'./chunk-GWLL6W5O.js';export{a as addMiddleware,b as addPathMiddleware,c as collectMiddleware,t as createCorsMiddleware,v as createSSEClient,o as findRoute,g as getPathMiddlewares,q as getRouterStats,p as getRoutesDir,d as hasMiddlewares,w as initSSE,l as isRouteError,f as loadMiddlewares,n as loadRoutes,u as registerCorsConfig,i as registerMiddlewareConfig,m as registerRoutes,h as resetMiddlewares,s as resetRouter,k as router,e as runMiddlewares,x as send,z as sendEvent,y as sendJson,r as setVerboseLogging,D as sseClose,A as sseComment,E as sseEventError,B as sseId,C as sseRetry}from'./chunk-GWLL6W5O.js';import O from'cluster';var g={port:3e3,isDev:process.env.NODE_ENV==="development",timeout:3e4,cluster:{enabled:true,workers:void 0},platform:"node"};function le(e={}){return {...g,...e}}async function S(e,r){let t=await e["~standard"].validate(r);return t.issues?{success:false,issues:t.issues}:{success:true,data:t.value}}function E(e){return Array.from(e).map(r=>({message:r.message,path:r.path?Array.from(r.path).map(t=>typeof t=="object"&&"key"in t?t.key:t):void 0}))}function ye(e){let r=async(t,n)=>{if(e.params){let a=await S(e.params,t.params??{});if(!a.success){n.status(400).json({error:"Validation failed",issues:E(a.issues)});return}t.params=a.data;}if(e.query){let a=await S(e.query,t.query??{});if(!a.success){n.status(400).json({error:"Validation failed",issues:E(a.issues)});return}t.query=a.data;}if(e.body){let a;try{a=await t.json();}catch{n.status(400).json({error:"Invalid JSON body"});return}let s=await S(e.body,a);if(!s.success){n.status(400).json({error:"Validation failed",issues:E(s.issues)});return}t.body=s.data;}await e.handler(t,n);};return r._defineHandler=e,r}async function R(e){let r=e?.["~standard"]?.vendor;if(!r)return null;try{if(r==="zod"){let t=await import('zod');if(typeof t.toJSONSchema=="function")return t.toJSONSchema(e);let n=await import('zod-to-json-schema');return (n.zodToJsonSchema??n.default)(e,{target:"openApi3"})}if(r==="valibot"){let t=await import('@valibot/to-json-schema');return (t.toJsonSchema??t.default)(e)}if(r==="arktype")return e.toJsonSchema()}catch{j(`[openapi] no converter found for "${r}" \u2014 install the matching json-schema package`);}return null}function k(e){return e.replace(/:(\w+)\??/g,"{$1}")}async function N(e,r){let t={responses:{200:{description:"Success"}}};r.meta?.summary&&(t.summary=r.meta.summary),r.meta?.description&&(t.description=r.meta.description),r.meta?.tags&&(t.tags=r.meta.tags),r.meta?.deprecated&&(t.deprecated=r.meta.deprecated);let n=[];if(r.params){let a=await R(r.params);if(a?.properties)for(let[s,o]of Object.entries(a.properties))n.push({name:s,in:"path",required:true,schema:o});}if(r.query){let a=await R(r.query);if(a?.properties){let s=a.required??[];for(let[o,i]of Object.entries(a.properties))n.push({name:o,in:"query",required:s.includes(o),schema:i});}}if(n.length>0&&(t.parameters=n),r.body){let a=await R(r.body);a&&(t.requestBody={required:true,content:{"application/json":{schema:a}}});}return t}async function h(e){let r=k$1.getRoutes(),t={};for(let{method:n,path:a,handler:s}of r){let o=s._defineHandler,i=k(a);t[i]||(t[i]={}),t[i][n.toLowerCase()]=o?await N(n,o):{responses:{200:{description:"Success"}}};}return {openapi:"3.1.0",info:e.info,paths:t}}var y=null,v=false,C=false;async function we(e,r=g){let{platform:t="node"}=r,n$1=r.isDev&&O.isPrimary&&!process.env.LACIS_BUN_WORKER;try{if(await n(e),r.openapi){let i=await h(r.openapi),m=r.openapi.path??"/openapi.json";k$1.addRoute("GET",m,(l,c)=>c.json(i)),n$1&&j(`OpenAPI doc available at ${m}`);}n$1&&(j("\u{1F680} Serveur d\xE9marr\xE9"),j(`\u{1F4C2} Routes charg\xE9es depuis: ${e}`)),r.isDev&&n$1&&j("\u{1F525} Mode de d\xE9veloppement activ\xE9");let s=J(t).createHandler(e),o;switch(t){case "node":o=await s(r),y=o;break;case "bun":o=s(r);break;case "vercel":case "netlify":o=s;break;default:throw new Error(`Plateforme "${t}" non support\xE9e`)}return I(),o}catch(a){throw n$1&&j("\u274C Erreur lors de la cr\xE9ation du serveur:",a),a}}function I(){if(!O.isPrimary||C)return;C=true;let e=async r=>{v||(v=true,j(`
1
+ import {k as k$1,n,j,J}from'./chunk-QZ3VOPKR.js';export{a as addMiddleware,b as addPathMiddleware,c as collectMiddleware,t as createCorsMiddleware,v as createSSEClient,o as findRoute,g as getPathMiddlewares,q as getRouterStats,p as getRoutesDir,d as hasMiddlewares,w as initSSE,l as isRouteError,f as loadMiddlewares,n as loadRoutes,u as registerCorsConfig,i as registerMiddlewareConfig,m as registerRoutes,h as resetMiddlewares,s as resetRouter,k as router,e as runMiddlewares,x as send,z as sendEvent,y as sendJson,r as setVerboseLogging,D as sseClose,A as sseComment,E as sseEventError,B as sseId,C as sseRetry}from'./chunk-QZ3VOPKR.js';import O from'cluster';var g={port:3e3,isDev:process.env.NODE_ENV==="development",timeout:3e4,cluster:{enabled:true,workers:void 0},platform:"node"};function le(e={}){return {...g,...e}}async function S(e,r){let t=await e["~standard"].validate(r);return t.issues?{success:false,issues:t.issues}:{success:true,data:t.value}}function E(e){return Array.from(e).map(r=>({message:r.message,path:r.path?Array.from(r.path).map(t=>typeof t=="object"&&"key"in t?t.key:t):void 0}))}function ye(e){let r=async(t,n)=>{if(e.params){let a=await S(e.params,t.params??{});if(!a.success){n.status(400).json({error:"Validation failed",issues:E(a.issues)});return}t.params=a.data;}if(e.query){let a=await S(e.query,t.query??{});if(!a.success){n.status(400).json({error:"Validation failed",issues:E(a.issues)});return}t.query=a.data;}if(e.body){let a;try{a=await t.json();}catch{n.status(400).json({error:"Invalid JSON body"});return}let s=await S(e.body,a);if(!s.success){n.status(400).json({error:"Validation failed",issues:E(s.issues)});return}t.body=s.data;}await e.handler(t,n);};return r._defineHandler=e,r}async function R(e){let r=e?.["~standard"]?.vendor;if(!r)return null;try{if(r==="zod"){let t=await import('zod');if(typeof t.toJSONSchema=="function")return t.toJSONSchema(e);let n=await import('zod-to-json-schema');return (n.zodToJsonSchema??n.default)(e,{target:"openApi3"})}if(r==="valibot"){let t=await import('@valibot/to-json-schema');return (t.toJsonSchema??t.default)(e)}if(r==="arktype")return e.toJsonSchema()}catch{j(`[openapi] no converter found for "${r}" \u2014 install the matching json-schema package`);}return null}function k(e){return e.replace(/:(\w+)\??/g,"{$1}")}async function N(e,r){let t={responses:{200:{description:"Success"}}};r.meta?.summary&&(t.summary=r.meta.summary),r.meta?.description&&(t.description=r.meta.description),r.meta?.tags&&(t.tags=r.meta.tags),r.meta?.deprecated&&(t.deprecated=r.meta.deprecated);let n=[];if(r.params){let a=await R(r.params);if(a?.properties)for(let[s,o]of Object.entries(a.properties))n.push({name:s,in:"path",required:true,schema:o});}if(r.query){let a=await R(r.query);if(a?.properties){let s=a.required??[];for(let[o,i]of Object.entries(a.properties))n.push({name:o,in:"query",required:s.includes(o),schema:i});}}if(n.length>0&&(t.parameters=n),r.body){let a=await R(r.body);a&&(t.requestBody={required:true,content:{"application/json":{schema:a}}});}return t}async function h(e){let r=k$1.getRoutes(),t={};for(let{method:n,path:a,handler:s}of r){let o=s._defineHandler,i=k(a);t[i]||(t[i]={}),t[i][n.toLowerCase()]=o?await N(n,o):{responses:{200:{description:"Success"}}};}return {openapi:"3.1.0",info:e.info,paths:t}}var y=null,v=false,C=false;async function we(e,r=g){let{platform:t="node"}=r,n$1=r.isDev&&O.isPrimary&&!process.env.LACIS_BUN_WORKER;try{if(await n(e),r.openapi){let i=await h(r.openapi),m=r.openapi.path??"/openapi.json";k$1.addRoute("GET",m,(l,c)=>c.json(i)),n$1&&j(`OpenAPI doc available at ${m}`);}n$1&&(j("\u{1F680} Serveur d\xE9marr\xE9"),j(`\u{1F4C2} Routes charg\xE9es depuis: ${e}`)),r.isDev&&n$1&&j("\u{1F525} Mode de d\xE9veloppement activ\xE9");let s=J(t).createHandler(e),o;switch(t){case "node":o=await s(r),y=o;break;case "bun":o=s(r);break;case "vercel":case "netlify":o=s;break;default:throw new Error(`Plateforme "${t}" non support\xE9e`)}return I(),o}catch(a){throw n$1&&j("\u274C Erreur lors de la cr\xE9ation du serveur:",a),a}}function I(){if(!O.isPrimary||C)return;C=true;let e=async r=>{v||(v=true,j(`
2
2
  Signal ${r} re\xE7u, arr\xEAt en cours...`),y&&typeof y.close=="function"&&await new Promise(t=>{y.close(()=>t()),setTimeout(()=>{j("Fermeture forc\xE9e apr\xE8s d\xE9lai"),t();},3e3);}),process.exit(0));};process.on("SIGINT",()=>e("SIGINT")),process.on("SIGTERM",()=>e("SIGTERM")),process.on("SIGHUP",()=>e("SIGHUP"));}var p={OK:200,CREATED:201,NO_CONTENT:204,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,CONFLICT:409,UNPROCESSABLE_ENTITY:422,TOO_MANY_REQUESTS:429,INTERNAL_SERVER_ERROR:500,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504},P={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",409:"Conflict",422:"Unprocessable Entity",429:"Too Many Requests",500:"Internal Server Error",503:"Service Unavailable",504:"Gateway Timeout"};function u(e){let r=e.code||p.INTERNAL_SERVER_ERROR,t=e.message||P[r]||"Unknown Error",n=e.name||`HttpError${r}`,a=new Error(t);return Error.captureStackTrace?.(a,u),{name:n,code:r,message:t,details:e.details,expose:e.expose!==void 0?e.expose:r<500,log:e.log!==void 0?e.log:r>=500,stack:a.stack}}function q(e){let r={error:e.message,code:e.code};return e.expose&&e.details?{...r,details:e.details}:r}function w(e,r){r.headersSent||(r.statusCode=e.code,r.setHeader("Content-Type","application/json"),r.end(JSON.stringify(q(e)))),e.log&&D(e);}function D(e){let r={name:e.name,message:e.message,code:e.code,details:e.details,stack:e.stack};e.code>=500?j("\u274C ERROR:",JSON.stringify(r,null,2)):j("\u26A0\uFE0F WARNING:",JSON.stringify(r,null,2));}function Ae(e,r){return u({name:"BadRequestError",code:p.BAD_REQUEST,message:e,details:r})}function ke(e,r){return u({name:"UnauthorizedError",code:p.UNAUTHORIZED,message:e,details:r})}function Ne(e,r){return u({name:"ForbiddenError",code:p.FORBIDDEN,message:e,details:r})}function Ie(e,r){return u({name:"NotFoundError",code:p.NOT_FOUND,message:e,details:r})}function Pe(e,r){return u({name:"MethodNotAllowedError",code:p.METHOD_NOT_ALLOWED,message:e,details:r})}function qe(e,r){return u({name:"ConflictError",code:p.CONFLICT,message:e,details:r})}function De(e,r){return u({name:"ValidationError",code:p.UNPROCESSABLE_ENTITY,message:e,details:r,expose:true})}function x(e,r){return u({name:"RateLimitError",code:p.TOO_MANY_REQUESTS,message:e,details:r})}function L(e,r){return u({name:"InternalServerError",code:p.INTERNAL_SERVER_ERROR,message:e,details:r})}function M(e,r){return u({name:"ServiceUnavailableError",code:p.SERVICE_UNAVAILABLE,message:e,details:r})}function U(e,r){return u({name:"GatewayTimeoutError",code:p.GATEWAY_TIMEOUT,message:e,details:r})}function Le(e){if(e&&typeof e=="object"&&typeof e.code=="number"&&"message"in e)return e;let r=e?.message||"Unknown error occurred",t=e?.stack?{stack:e.stack}:void 0,n=e?.code||e?.statusCode;return n==="ECONNREFUSED"||n==="ENOTFOUND"?M(`Service connection failed: ${r}`,t):n==="ETIMEDOUT"?U(`Request timed out: ${r}`,t):typeof n=="number"&&n>=400&&n<600?u({code:n,message:r,details:t}):L(r,t)}function Me(e){return !!(e&&typeof e=="object"&&typeof e.code=="number"&&"message"in e&&"name"in e)}function Be(e={}){let r=e.windowMs??6e4,t=e.max??100,n=e.message??"Too Many Requests",a=e.keyGenerator??(o=>{let i=o.headers["x-forwarded-for"];return (typeof i=="string"?i.split(",")[0].trim():o.socket?.remoteAddress)??"unknown"}),s=new Map;return (o,i)=>{let m=a(o),l=Date.now(),c=s.get(m);(!c||l>=c.resetAt)&&(c={count:0,resetAt:l+r},s.set(m,c)),c.count++;let H=Math.max(0,t-c.count),A=Math.ceil(c.resetAt/1e3);if(i.setHeader("X-RateLimit-Limit",String(t)),i.setHeader("X-RateLimit-Remaining",String(H)),i.setHeader("X-RateLimit-Reset",String(A)),c.count>t)return i.setHeader("Retry-After",String(Math.ceil((c.resetAt-l)/1e3))),w(x(n),i),false}}export{p as HTTP_STATUS,h as buildOpenApiDoc,Ae as createBadRequestError,qe as createConflictError,Ne as createForbiddenError,U as createGatewayTimeoutError,u as createHttpError,L as createInternalServerError,Pe as createMethodNotAllowedError,Ie as createNotFoundError,Be as createRateLimit,x as createRateLimitError,we as createServer,M as createServiceUnavailableError,ke as createUnauthorizedError,De as createValidationError,g as defaultConfig,ye as defineHandler,le as getConfig,Me as isHttpError,D as logError,Le as normalizeError,w as sendError};
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "lacis",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Zero-dependency TypeScript web framework",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/getlacis/lacis"
9
+ },
5
10
  "type": "module",
6
11
  "module": "index.ts",
7
12
  "main": "./dist/index.js",
@@ -37,18 +42,6 @@
37
42
  "zod": "^4.4.3",
38
43
  "zod-to-json-schema": "^3.25.2"
39
44
  },
40
- "peerDependencies": {
41
- "@types/node": ">=18",
42
- "typescript": "^5.0.0"
43
- },
44
- "peerDependenciesMeta": {
45
- "typescript": {
46
- "optional": true
47
- },
48
- "@types/node": {
49
- "optional": true
50
- }
51
- },
52
45
  "bin": {
53
46
  "lacis": "dist/cli/index.js"
54
47
  },
@@ -1,26 +0,0 @@
1
- import F from'path';import Le from'fs/promises';import L from'cluster';import ue,{IncomingMessage,ServerResponse}from'http';import Ve from'https';import*as q from'os';import q__default from'os';import {EventEmitter}from'events';import {Socket}from'net';var $={beforeRequest:[],afterRequest:[],onError:[]},T=new Map;function re(t,e){return $[t].push(e),{remove:()=>{let r=$[t].indexOf(e);r!==-1&&$[t].splice(r,1);}}}function dt(t,e,r){let n=t==="/"?"/":t.replace(/\/+$/,"");return T.has(n)||T.set(n,{beforeRequest:[],afterRequest:[],onError:[]}),T.get(n)[e].push(r),{remove:()=>{if(T.has(n)){let s=T.get(n),i=s[e].indexOf(r);i!==-1&&s[e].splice(i,1);}}}}function je(t){let r=(t==="/"?"/":t.replace(/\/+$/,"")).split("/").filter(Boolean),n={beforeRequest:[...$.beforeRequest],afterRequest:[...$.afterRequest],onError:[...$.onError]},o="";if(T.has("/")){let s=T.get("/");n.beforeRequest.push(...s.beforeRequest),n.afterRequest.push(...s.afterRequest),n.onError.push(...s.onError);}for(let s of r)if(o+="/"+s,T.has(o)){let i=T.get(o);n.beforeRequest.push(...i.beforeRequest),n.afterRequest.push(...i.afterRequest),n.onError.push(...i.onError);}return n}function _(){return $.beforeRequest.length>0||$.afterRequest.length>0||$.onError.length>0?true:T.size>0}async function k(t,e,r,n){let o=e.url?.split("?")[0]||"/",s=je(o);if(s[t].length===0)return true;for(let i of s[t])try{if(await i(e,r,n)===!1)return !1}catch(l){if(t!=="onError")try{for(let a of s.onError)await a(e,r,{error:l,phase:t});}catch(a){console.error("Error in error handler:",a);}return false}return true}async function ye(t){T.clear();async function e(r,n=""){try{let o=await Le.readdir(r,{withFileTypes:!0}),s=o.find(i=>i.name==="+middleware.ts"||i.name==="+middleware.js");if(s){let i=F.join(r,s.name);try{let a=await import(`${F.resolve(i)}?update=${Date.now()}`);if(T.has(n)||T.set(n,{beforeRequest:[],afterRequest:[],onError:[]}),a.beforeRequest){let d=Array.isArray(a.beforeRequest)?a.beforeRequest:[a.beforeRequest];T.get(n).beforeRequest.push(...d);}if(a.afterRequest){let d=Array.isArray(a.afterRequest)?a.afterRequest:[a.afterRequest];T.get(n).afterRequest.push(...d);}if(a.onError){let d=Array.isArray(a.onError)?a.onError:[a.onError];T.get(n).onError.push(...d);}}catch(l){console.error(`Error loading middleware for ${n}:`,l);}}for(let i of o)i.isDirectory()&&await e(F.join(r,i.name),`${n==="/"?"":n}/${i.name}`);}catch(o){console.error(`Error scanning directory ${r}:`,o);}}await e(t,"/");}function ut(){return T}function ct(){$.beforeRequest=[],$.afterRequest=[],$.onError=[],T.clear();}function O(t){if(t)for(let e of ["beforeRequest","afterRequest","onError"]){let r=t[e];if(r){let n=Array.isArray(r)?r:[r];for(let o of n)re(e,o);}}}function Ue(t,e){return !e||e==="*"?true:typeof e=="string"?t===e:Array.isArray(e)?e.includes(t):e instanceof RegExp?e.test(t):typeof e=="function"?e(t):false}function De(t){let e=(t.methods??["GET","POST","PUT","DELETE","PATCH","OPTIONS"]).join(", "),r=(t.allowedHeaders??["Content-Type","Authorization"]).join(", "),n=t.exposedHeaders?.join(", "),o=t.maxAge!=null?String(t.maxAge):null,s=!t.origin||t.origin==="*";return async(i,l)=>{let a=i.getHeader("origin");if(!a||!Ue(a,t.origin))return;let d=s&&!t.credentials;if(l.setHeader("Access-Control-Allow-Origin",d?"*":a),d||l.setHeader("Vary","Origin"),t.credentials&&l.setHeader("Access-Control-Allow-Credentials","true"),n&&l.setHeader("Access-Control-Expose-Headers",n),i.method==="OPTIONS")return l.setHeader("Access-Control-Allow-Methods",e),l.setHeader("Access-Control-Allow-Headers",r),o&&l.setHeader("Access-Control-Max-Age",o),l.status(204),l.end(),false}}function P(t){t&&re("beforeRequest",De(t));}function R(...t){L.isPrimary&&console.log(...t);}function We(t){let e=t.match(/^\[(\w+)(\??)]/);return e?{name:e[1],isParam:true,isOptional:e[2]==="?"}:{name:t,isParam:false,isOptional:false}}var Fe=1e3,ze=100,se=class{rootNode;cachedRoutes;routeCount;lastLoaded;verbose;constructor(){this.rootNode=this.createNode(),this.cachedRoutes=new Map,this.routeCount=0,this.lastLoaded=0,this.verbose=false;}createNode(){return {handlers:Object.create(null),staticChildren:new Map,paramChild:null,wildcardHandler:null,isEndpoint:false}}addRoute(e,r,n){let o=r.split("/").filter(Boolean),s=this.rootNode;for(let i of o){let l=We(i);if(l.isParam){if(!s.paramChild)s.paramChild={name:l.name,node:this.createNode(),isOptional:l.isOptional};else if(s.paramChild.name!==l.name)throw new Error(`Route conflict: param name "[${l.name}]" conflicts with existing "[${s.paramChild.name}]" at the same path position. Use the same param name for all methods at this level.`);s=s.paramChild.node;}else {if(i==="*")return s.wildcardHandler||(s.wildcardHandler=Object.create(null)),s.wildcardHandler[e]=n,this.cachedRoutes.clear(),this;s.staticChildren.has(i)||s.staticChildren.set(i,this.createNode()),s=s.staticChildren.get(i);}}return s.isEndpoint=true,s.handlers[e]||this.routeCount++,s.handlers[e]=n,this.cachedRoutes.clear(),this}findRoute(e,r){let n=r==="/"?"/":r.replace(/\/+$/,""),o=e+":"+n,s=this.cachedRoutes.get(o);if(s)return s;let i=n==="/"?[]:n.split("/").filter(Boolean),l=Object.create(null),a=this.traverse(this.rootNode,i,e,l,0)??{handler:null,params:Object.create(null)};if(this.cachedRoutes.size>=Fe){let d=0;for(let u of this.cachedRoutes.keys())if(this.cachedRoutes.delete(u),++d>=ze)break}return this.cachedRoutes.set(o,a),a}traverse(e,r,n,o,s){if(s===r.length){if(e.isEndpoint){let d=e.handlers[n]??(n==="HEAD"?e.handlers.GET:void 0)??e.handlers[""];if(d)return {handler:d,params:{...o}};let u=Object.keys(e.handlers).filter(p=>p!=="");return {handler:null,params:{},allowedMethods:u}}let a=e.paramChild;if(a?.isOptional&&a.node.isEndpoint){let d=a.node.handlers[n]??(n==="HEAD"?a.node.handlers.GET:void 0)??a.node.handlers[""];if(d)return {handler:d,params:{...o}}}return null}let i=r[s],l=e.staticChildren.get(i);if(l){let a=this.traverse(l,r,n,o,s+1);if(a)return a}if(e.paramChild){let{name:a,node:d}=e.paramChild;o[a]=i;let u=this.traverse(d,r,n,o,s+1);if(u)return u;delete o[a];}if(e.wildcardHandler){let a=e.wildcardHandler[n]??e.wildcardHandler[""],d=r.slice(s).join("/");if(a)return {handler:a,params:{...o,"*":d}};let u=Object.keys(e.wildcardHandler).filter(p=>p!=="");if(u.length>0)return {handler:null,params:{...o,"*":d},allowedMethods:u}}return null}async loadRoutes(e){this.rootNode=this.createNode(),this.cachedRoutes.clear(),this.routeCount=0,await ye(e);let r=this;async function n(o,s=[]){try{let i=await Le.readdir(o,{withFileTypes:!0}),l=i.find(a=>!a.isDirectory()&&(a.name==="index.ts"||a.name==="index.js"));if(l)try{let d=await import(`${F.resolve(F.join(o,l.name))}?update=${Date.now()}`),u=["GET","POST","PUT","DELETE","PATCH"],p="/"+s.join("/"),g=!1;for(let C of u)typeof d[C]=="function"&&(r.addRoute(C,p,d[C]),g=!0);!g&&typeof d.default=="function"&&r.addRoute("GET",p,d.default),r.verbose&&R(`Route loaded: ${p}`);}catch(a){console.error(`Error loading index in ${o}:`,a);}for(let a of i)if(a.isDirectory()){let d=a.name.match(/^\[(\w+)(\??)]/),u=d?`[${d[1]}${d[2]}]`:a.name;await n(F.join(o,a.name),[...s,u]);}}catch(i){console.error(`Error scanning directory ${o}:`,i);}}return await n(e),this.lastLoaded=Date.now(),this.verbose&&R(`Loading completed: ${this.routeCount} routes`),true}getRoutes(){let e=[];return this.collectRoutes(this.rootNode,[],e),e}collectRoutes(e,r,n){if(e.isEndpoint){let o=r.length===0?"/":"/"+r.join("/");for(let[s,i]of Object.entries(e.handlers))s!==""&&n.push({method:s,path:o,handler:i});}for(let[o,s]of e.staticChildren)this.collectRoutes(s,[...r,o],n);if(e.paramChild){let{name:o,isOptional:s,node:i}=e.paramChild;this.collectRoutes(i,[...r,s?`:${o}?`:`:${o}`],n);}if(e.wildcardHandler){let o="/"+[...r,"*"].join("/");for(let[s,i]of Object.entries(e.wildcardHandler))s!==""&&n.push({method:s,path:o,handler:i});}}getStats(){return {routeCount:this.routeCount,lastLoaded:this.lastLoaded,uptime:Date.now()-this.lastLoaded,cacheSize:this.cachedRoutes.size}}setVerbose(e){return this.verbose=e,this}reset(){this.rootNode=this.createNode(),this.cachedRoutes=new Map,this.routeCount=0;}},U=new se;function z(t){return t&&typeof t=="object"&&"error"in t}function J(t){for(let{path:e,handlers:r}of t){let n=e.replace(/:(\w+\??)/g,(o,s)=>s.endsWith("?")?`[${s.slice(0,-1)}?]`:`[${s}]`);for(let[o,s]of Object.entries(r))typeof s=="function"&&U.addRoute(o,n,s);}}async function V(t){return U.loadRoutes(t)}function I(t,e="GET"){let r=U.findRoute(e,t);return r.handler?{handler:r.handler,params:r.params}:r.allowedMethods?.length?{error:"Method Not Allowed",status:405,allowedMethods:r.allowedMethods}:null}function St(t){return F.resolve(process.cwd(),t||process.env.ROUTES_DIR||"routes")}function vt(){return U.getStats()}function bt(t){U.setVerbose(t);}function Et(){U.reset();}function Re(t,e={},r={},n){let o=false,s=0,i={},l=[],a=[],d=[],u=null;r.onMessage&&l.push(r.onMessage),r.onClose&&a.push(r.onClose),r.onError&&d.push(r.onError),r.onEvent&&Object.entries(r.onEvent).forEach(([c,m])=>{i[c]||(i[c]=[]),i[c].push(m);});let p=e.reconnectInterval||3e3,g=e.maxRetries||3,C=e.disableReconnect||false,y=e.body,h=e.contentType||(y?"application/json":void 0),f=e.method||(y?"POST":"GET");if(typeof t!="string"){let c=t;return o=true,c.on("data",m=>{b(m.toString());}),c.on("end",()=>{o=false;}),c.on("error",m=>{o=false,console.error("SSE Error:",m);}),v()}if(typeof t=="string")return new Promise((c,m)=>{x().then(()=>c(v())).catch(m);});function b(c){let m=c,S=m.split(`
2
-
3
- `);m=S.pop()||"";for(let M of S){let A=M.split(`
4
- `),w="",E="";for(let H of A)H.startsWith("event:")?E=H.slice(6).trim():H.startsWith("data:")&&(w=H.slice(5).trim());if(w)try{let H=JSON.parse(w);E&&i[E]?i[E].forEach(B=>B(H)):l.forEach(B=>B(H));}catch{E&&i[E]?i[E].forEach(H=>H(w)):l.forEach(H=>H(w));}}}function v(){return {onMessage(c){return l.push(c),this},onEvent(c,m){return i[c]||(i[c]=[]),i[c].push(m),this},onClose(c){return a.push(c),this},close(){u&&(u.destroy(),u=null),o=false,a.forEach(c=>c());}}}async function x(){if(!o){o=true;try{await D();}catch(c){!C&&s<g?(s++,setTimeout(()=>{x();},p)):d.forEach(m=>m(c));}}}async function D(){return new Promise((c,m)=>{let S=new URL(t);e.params&&(typeof e.params=="object"?Object.entries(e.params).forEach(([w,E])=>{S.searchParams.append(w,String(E));}):typeof e.params=="string"&&new URLSearchParams(e.params).forEach((E,H)=>{S.searchParams.append(H,E);}));let M={hostname:S.hostname,port:S.port||(S.protocol==="https:"?443:80),path:S.pathname+S.search,method:f,headers:{Accept:"text/event-stream",...n?.headers||{},"Cache-Control":"no-cache",Connection:"keep-alive",...h&&{"Content-Type":h},...y&&typeof y=="string"&&{"Content-Length":Buffer.byteLength(y).toString()},...y&&typeof y!="string"&&{"Content-Length":Buffer.byteLength(JSON.stringify(y)).toString()}}};u=(S.protocol==="https:"?Ve:ue).request(M,w=>{if(w.statusCode!==200){o=false,m(new Error(`Server responded with status: ${w.statusCode}`));return}w.setEncoding("utf8"),w.on("data",b),w.on("end",()=>{o=false,u?.destroy(),u=null,a.forEach(E=>E()),c(null);}),w.on("close",()=>{o=false,u?.destroy(),u=null,a.forEach(E=>E()),c(null);}),w.on("error",E=>{o=false,u?.destroy(),u=null,a.forEach(H=>H()),m(E);});}),u.on("error",w=>{o=false,u?.destroy(),u=null,m(w);}),y&&(typeof y=="string"?u.write(y):u.write(JSON.stringify(y))),u.end();})}return v()}function we(t,e){let r=e?.headers?.["Cache-Control"]||"no-cache",n=e?.headers?.Connection||"keep-alive",o=e?.timeout||3e5;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":r,Connection:n,...e?.headers||{}});let s=setTimeout(()=>{t.end();},o);return t.on("close",()=>{clearTimeout(s);}),s}function Ce(t,e){return t.writableEnded?false:t.write(`data: ${e}
5
-
6
- `)}function Se(t,e){return t.writableEnded?false:t.write(`data: ${JSON.stringify(e)}
7
-
8
- `)}function ve(t,e,r){return t.writableEnded?false:(t.write(`event: ${e}
9
- `),t.write(`data: ${JSON.stringify(r)}
10
-
11
- `))}function be(t,e){return t.writableEnded?false:t.write(`: ${e}
12
-
13
- `)}function Ee(t,e){return t.writableEnded?false:t.write(`id: ${e}
14
-
15
- `)}function Me(t,e){return t.writableEnded?false:t.write(`retry: ${e}
16
-
17
- `)}function xe(t,e="Connection closed"){t.write(`: ${e}
18
-
19
- `),t.end();}function Te(t,e,r,n=500,o){t.writeHead(n,{"Content-Type":"text/event-stream"}),t.write(`event: ${e}
20
- `);let s={message:r,code:n,details:o||null};t.write(`data: ${JSON.stringify(s)}
21
-
22
- `),t.end();}var Ge=10485760,K=class{_parsed=null;_raw;constructor(e){this._raw=e;}_parse(){if(this._parsed!==null)return this._parsed;if(this._parsed={},!this._raw)return this._parsed;for(let e of this._raw.split(";")){let r=e.indexOf("=");if(r===-1)continue;let n=e.slice(0,r).trim(),o=e.slice(r+1).trim();if(n){let s=o.startsWith('"')&&o.endsWith('"')?o.slice(1,-1):o;try{this._parsed[n]=decodeURIComponent(s);}catch{this._parsed[n]=s;}}}return this._parsed}get(e){return this._parse()[e]}all(){return {...this._parse()}}},X=class{_pending=[];set(e,r,n={}){return this._pending.push({name:e,value:r,opts:n}),this}delete(e,r={}){return this.set(e,"",{...r,maxAge:0,expires:new Date(0)})}serialize(){return this._pending.map(({name:e,value:r,opts:n})=>{let o=`${e}=${encodeURIComponent(r)}`,s=n.path!==void 0?n.path:"/";return s&&(o+=`; Path=${s}`),n.domain&&(o+=`; Domain=${n.domain}`),n.maxAge!=null&&(o+=`; Max-Age=${n.maxAge}`),n.expires&&(o+=`; Expires=${n.expires.toUTCString()}`),n.httpOnly&&(o+="; HttpOnly"),n.secure&&(o+="; Secure"),n.sameSite&&(o+=`; SameSite=${n.sameSite}`),o})}};function _e(t){if(typeof t.get=="function")return t.get("cookie")??void 0;let e=t.cookie;return Array.isArray(e)?e.join("; "):e}function N(t){return class extends t{_zreqCookies;getHeader(e){let r=this.headers;if(typeof r.get=="function")return r.get(e)??void 0;let n=r[e.toLowerCase()];return Array.isArray(n)?n[0]:n}get cookies(){return this._zreqCookies||(this._zreqCookies=new K(_e(this.headers))),this._zreqCookies}json(){return this.body().then(e=>JSON.parse(e.toString()))}form(){return new Promise((e,r)=>{let n=this.headers,o=typeof n.get=="function"?n.get("content-type")??"":n["content-type"]??"";if(!o.startsWith("multipart/form-data")){r(new Error("Content-Type is not multipart/form-data"));return}let s=o.match(/boundary=(.+)$/);if(!s){r(new Error("Boundary not found"));return}let i=s[1].trim();this.body().then(l=>{let a={},d=Buffer.from(`--${i}`),u=[],p=0,g;for(;(g=l.indexOf(d,p))!==-1;)u.push(l.subarray(p,g)),p=g+d.length;u.push(l.subarray(p));for(let C=1;C<u.length-1;C++){let y=u[C].subarray(2),h=y.indexOf(`\r
23
- \r
24
- `);if(h===-1)continue;let f=y.subarray(0,h).toString(),b=y.subarray(h+4,y.length-2),v=f.match(/Content-Disposition: form-data; name="([^"]+)"(?:; filename="([^"]+)")?/i);if(v)if(v[2]){let x=f.match(/Content-Type:\s*([^\r\n]+)/i);a[v[1]]={filename:v[2],mimetype:x?x[1].trim():"application/octet-stream",data:b,size:b.length};}else a[v[1]]=b.toString("utf-8");}e(a);}).catch(r);})}createSSEClient(e,r){return Re(this,e,r)}}}function Y(){let t=[],e=0,r=false;return new Promise((n,o)=>{this.on("data",s=>{if(e+=s.length,e>Ge){r=true,this.destroy(),o(Object.assign(new Error("Payload Too Large"),{code:413}));return}t.push(s);}).on("end",()=>{r||(r=true,n(Buffer.concat(t)));}).on("error",s=>{r||(r=true,o(s));});})}function ke(t,e){let r=t.serialize();r.length>0&&!e.headersSent&&e.setHeader("Set-Cookie",r);}function W(t){return class extends t{_zresCookies;get cookies(){return this._zresCookies||(this._zresCookies=new X),this._zresCookies}end(e){return this._zresCookies&&ke(this._zresCookies,this),super.end(e)}status(e){return this.statusCode=e,this}send(e){return typeof e=="string"?(this.setHeader("Content-Type","text/plain"),this.end(e)):this.json(e),this}json(e){return this.setHeader("Content-Type","application/json"),this.end(JSON.stringify(e)),this}initSSE(e){return we(this,e)}sseSend(e){Ce(this,e);}sseJson(e){Se(this,e);}sseEvent(e,r){ve(this,e,r);}sseComment(e){be(this,e);}sseId(e){Ee(this,e);}sseRetry(e){Me(this,e);}sseClose(e){xe(this,e);}sseError(e,r,n=500,o){Te(this,e,r,n,o);}}}var ne=class{params={};headers={};body(){return Y.call(this)}},G=N(ne).prototype,oe=class{statusCode=200;headersSent=false;setHeader(e,r){}end(e){}write(e){}},Ke=W(oe).prototype;function Z(t){t.body=Y,t.json=G.json,t.form=G.form,t.getHeader=G.getHeader,t.createSSEClient=G.createSSEClient,t.cookies=new K(_e(t.headers));}function Q(t){let e=Ke;t.status=e.status,t.send=e.send,t.json=e.json,t.initSSE=e.initSSE,t.sseSend=e.sseSend,t.sseJson=e.sseJson,t.sseEvent=e.sseEvent,t.sseComment=e.sseComment,t.sseId=e.sseId,t.sseRetry=e.sseRetry,t.sseClose=e.sseClose,t.sseError=e.sseError;let r=new X;t.cookies=r;let n=t.end.bind(t);t.end=function(...o){return ke(r,this),n(...o)};}var ee=null;function Ye(t={}){let e=new EventEmitter,r={sampleInterval:t.sampleInterval||5e3,reportInterval:t.reportInterval||6e4,resetInterval:t.resetInterval||1440*60*1e3,enableHistogram:t.enableHistogram!==void 0?t.enableHistogram:true,logToConsole:t.logToConsole!==void 0?t.logToConsole:true,thresholds:{cpu:t.thresholds?.cpu||80,memory:t.thresholds?.memory||80,responseTime:t.thresholds?.responseTime||1e3,errorRate:t.thresholds?.errorRate||5}},n=Date.now(),o={requestCount:0,activeRequests:0,errorCount:0,responseTimes:[],responseTimesBucket:Array(100).fill(0),statusCodes:{},lastReport:n,lastReset:n},s=d(),i=[],l=process.cpuUsage(),a={cpu:false,memory:false,responseTime:false,errorRate:false};function d(){return {timestamp:Date.now(),uptime:process.uptime(),requestCount:0,activeRequests:0,errorCount:0,responseTimes:{min:0,max:0,avg:0,count:0,sum:0},statusCodes:{},memory:process.memoryUsage(),cpu:{usage:0,system:0,user:0},systemLoad:q.loadavg(),systemMemory:{total:q.totalmem(),free:q.freemem(),used:q.totalmem()-q.freemem()}}}function u(){let c=o.responseTimes;if(c.length===0)return {min:0,max:0,avg:0,count:0,sum:0};let m=1/0,S=-1/0,M=0;for(let E of c)m=Math.min(m,E),S=Math.max(S,E),M+=E;let A=M/c.length,w={min:m,max:S,avg:A,count:c.length,sum:M};if(r.enableHistogram){let E=[...c].sort((H,B)=>H-B);w.p50=E[Math.floor(E.length*.5)],w.p90=E[Math.floor(E.length*.9)],w.p99=E[Math.floor(E.length*.99)];}return w}function p(){let c=Date.now(),m=process.uptime(),S=process.memoryUsage(),M=process.cpuUsage(l);l=process.cpuUsage();let w=(M.user+M.system)/1e3/r.sampleInterval*100;s={timestamp:c,uptime:m,requestCount:o.requestCount,activeRequests:o.activeRequests,errorCount:o.errorCount,responseTimes:u(),statusCodes:{...o.statusCodes},memory:S,cpu:{usage:w,system:M.system,user:M.user},systemLoad:q.loadavg(),systemMemory:{total:q.totalmem(),free:q.freemem(),used:q.totalmem()-q.freemem()}},i.push({...s}),i.length>100&&i.shift(),y(),L.isWorker&&process.send&&process.send({type:"metrics",metrics:s});}function g(){if(!r.logToConsole||L.isPrimary===false)return;let c={rss:(s.memory.rss/1024/1024).toFixed(2),heapTotal:(s.memory.heapTotal/1024/1024).toFixed(2),heapUsed:(s.memory.heapUsed/1024/1024).toFixed(2)},m=Date.now()-o.lastReport,S=(s.requestCount/(m/1e3)).toFixed(2),M=s.requestCount?(s.errorCount/s.requestCount*100).toFixed(2):"0.00";R(`
25
- \u{1F4CA} Server Performance Metrics \u{1F4CA}`),R(`Uptime: ${h(s.uptime)}`),R(`Load: ${s.systemLoad[0].toFixed(2)}, ${s.systemLoad[1].toFixed(2)}, ${s.systemLoad[2].toFixed(2)}`),R(`Requests: ${s.requestCount} total, ${S} req/sec`),R(`Active Requests: ${s.activeRequests}`),R(`Errors: ${s.errorCount} (${M}%)`),s.responseTimes.count>0&&(R(`Response Times: avg ${s.responseTimes.avg.toFixed(2)}ms, min ${s.responseTimes.min}ms, max ${s.responseTimes.max}ms`),s.responseTimes.p50&&R(`Response Time Percentiles: p50 ${s.responseTimes.p50}ms, p90 ${s.responseTimes.p90}ms, p99 ${s.responseTimes.p99}ms`)),R(`Memory: ${c.rss}MB (RSS), ${c.heapUsed}MB / ${c.heapTotal}MB (Heap)`),R(`CPU Usage: ${s.cpu.usage.toFixed(2)}%`),Object.keys(s.statusCodes).length>0&&(R("Status Codes:"),Object.entries(s.statusCodes).sort(([A],[w])=>parseInt(A)-parseInt(w)).forEach(([A,w])=>{R(` ${A}: ${w}`);})),R(""),o.lastReport=Date.now();}function C(){let c=Date.now();o.requestCount=0,o.activeRequests=0,o.errorCount=0,o.responseTimes=[],o.responseTimesBucket=Array(100).fill(0),o.statusCodes={},o.lastReport=c,o.lastReset=c,R("\u{1F504} Performance metrics have been reset");}function y(){let c=s.memory.heapUsed/s.memory.heapTotal*100,m=s.requestCount?s.errorCount/s.requestCount*100:0,S=s.responseTimes.avg;s.cpu.usage>r.thresholds.cpu&&!a.cpu?(a.cpu=true,e.emit("alarm","cpu",`High CPU usage: ${s.cpu.usage.toFixed(2)}%`)):s.cpu.usage<=r.thresholds.cpu&&a.cpu&&(a.cpu=false,e.emit("alarm-clear","cpu",`CPU usage returned to normal: ${s.cpu.usage.toFixed(2)}%`)),c>r.thresholds.memory&&!a.memory?(a.memory=true,e.emit("alarm","memory",`High memory usage: ${c.toFixed(2)}%`)):c<=r.thresholds.memory&&a.memory&&(a.memory=false,e.emit("alarm-clear","memory",`Memory usage returned to normal: ${c.toFixed(2)}%`)),S>r.thresholds.responseTime&&!a.responseTime?(a.responseTime=true,e.emit("alarm","responseTime",`High response time: ${S.toFixed(2)}ms`)):S<=r.thresholds.responseTime&&a.responseTime&&(a.responseTime=false,e.emit("alarm-clear","responseTime",`Response time returned to normal: ${S.toFixed(2)}ms`)),m>r.thresholds.errorRate&&!a.errorRate?(a.errorRate=true,e.emit("alarm","errorRate",`High error rate: ${m.toFixed(2)}%`)):m<=r.thresholds.errorRate&&a.errorRate&&(a.errorRate=false,e.emit("alarm-clear","errorRate",`Error rate returned to normal: ${m.toFixed(2)}%`));}function h(c){let m=Math.floor(c/86400),S=Math.floor(c%86400/3600),M=Math.floor(c%3600/60),A=Math.floor(c%60),w=[];return m>0&&w.push(`${m}d`),S>0&&w.push(`${S}h`),M>0&&w.push(`${M}m`),(A>0||w.length===0)&&w.push(`${A}s`),w.join(" ")}function f(){let c=setInterval(p,r.sampleInterval),m=setInterval(g,r.reportInterval),S=setInterval(C,r.resetInterval);return {stop:()=>{clearInterval(c),clearInterval(m),clearInterval(S);}}}function b(){let c=Date.now();return o.activeRequests++,{end:(m,S=false)=>{let M=Date.now()-c;return o.activeRequests--,o.requestCount++,o.responseTimes.push(M),o.responseTimes.length>1e3&&o.responseTimes.shift(),o.statusCodes[m]=(o.statusCodes[m]||0)+1,(S||m>=500)&&o.errorCount++,M}}}function v(){return !Object.values(a).some(c=>c)}function x(){let c=s.memory.heapUsed/s.memory.heapTotal*100,m=s.requestCount?s.errorCount/s.requestCount*100:0;return {status:v()?"healthy":"unhealthy",uptime:s.uptime,responseTimes:{avg:s.responseTimes.avg,p90:s.responseTimes.p90||null,p99:s.responseTimes.p99||null},memory:{usedMB:Math.round(s.memory.heapUsed/1024/1024),totalMB:Math.round(s.memory.heapTotal/1024/1024),percent:c.toFixed(2)},cpu:s.cpu.usage.toFixed(2),requests:{total:s.requestCount,active:s.activeRequests,errors:s.errorCount,errorRate:m.toFixed(2)},alerts:Object.entries(a).filter(([S,M])=>M).map(([S])=>S)}}let D=f();return {trackRequest:b,getMetrics:()=>({...s}),getMetricsHistory:()=>[...i],getHealthMetrics:x,isHealthy:v,stop:D.stop,on:e.on.bind(e),once:e.once.bind(e),off:e.off.bind(e)}}function qe(t){if(!ee){let e=Ye(t),r=e.stop;e.stop=()=>{r(),ee=null;},ee=e;}return ee}function ae(t={}){let e=t.reportInterval??5e3,r={workers:new Map,workerIds:[]};function n(){if(!L.isWorker)return;let d=process.cpuUsage(),u=()=>{if(!process.send)return;let p=process.memoryUsage(),g=process.cpuUsage(d);d=process.cpuUsage();let C=(g.user+g.system)/(e*1e3),y={type:"stats",stats:{pid:process.pid,load:C,lastUsed:Date.now(),memoryUsage:p}};process.send(y);};u(),setInterval(u,e).unref();}function o(){let d=L.fork();r.workers.set(d.id,{pid:d.process.pid,load:0,lastUsed:Date.now(),memoryUsage:{rss:0,heapTotal:0,heapUsed:0,external:0,arrayBuffers:0}}),r.workerIds.push(d.id),R(`Worker ${d.process.pid} started`);}let s=false,i=[];function l(d=q.cpus().length){if(!L.isPrimary)return n();R(`\u{1F9F5} Launching ${d} workers...`);for(let u=0;u<d;u++)o();L.on("message",(u,p)=>{if(p.type==="stats"&&"stats"in p){let g=r.workers.get(u.id);g&&Object.assign(g,p.stats);}}),L.on("exit",(u,p,g)=>{if(r.workers.delete(u.id),r.workerIds=r.workerIds.filter(C=>C!==u.id),s){i.forEach(C=>C());return}R(`Worker ${u.process.pid} died (${g||p}). Restarting...`),setTimeout(()=>o(),1e3);});}function a(d){s=true;let u=Object.keys(L.workers??{});if(u.length===0){d?.();return}let p=u.length;i.push(()=>{p--,p===0&&d?.();});for(let g of u)L.workers?.[g]?.kill();}return {start:l,shutdown:a,getWorkerStats:()=>Array.from(r.workers.entries()),getActiveWorkerCount:()=>r.workerIds.length}}var ie=class extends ue.IncomingMessage{params={};body=Y},le=class extends N(ie){},de=class extends W(ue.ServerResponse){},$e={name:"node",createHandler:t=>{if(typeof t!="string")throw new Error("nodeAdapter requires a routesDir string, not a ServerlessConfig.");let e=t;return async(r={})=>{let{port:n=3e3,defaultHeaders:o,isDev:s,cluster:i,monitoring:l={enabled:false}}=r,a=null;s&&l.enabled&&(a=qe({sampleInterval:l.sampleInterval||5e3,reportInterval:l.reportInterval||6e4,thresholds:l.thresholds,logToConsole:true}),L.isPrimary&&(R("\u{1F4CA} Development performance monitoring enabled"),a.on("alarm",(u,p)=>{R(`\u26A0\uFE0F ALERT: ${p}`);}),a.on("alarm-clear",(u,p)=>{R(`\u2705 RESOLVED: ${p}`);})));let d=o?Object.entries(o):[];if(i?.enabled&&L.isPrimary){let u=i.workers??q__default.cpus().length,p=r.httpsOptions?"https":"http";if(R(`\u{1F9F5} Starting server with ${u} workers`),L.schedulingPolicy!==void 0)try{L.schedulingPolicy=L.SCHED_RR;}catch{}let g=ae();return g.start(u),R(`\u{1F680} Server running at ${p}://localhost:${n}/`+(s?" (dev)":"")),s&&a&&R(`\u{1F4CA} Performance monitoring available at http://localhost:${n}/health`),{close:C=>{a&&a.stop(),g.shutdown(C);}}}if(L.isWorker||!i?.enabled){await V(e),P(r.cors),O(r.middleware);let u=async(h,f,b)=>{try{if(s&&a&&h.url==="/health"){f.setHeader("Content-Type","application/json"),f.end(JSON.stringify(a.getHealthMetrics())),b?.end(200);return}let v=h.url||"/",x=v.indexOf("?"),D=x===-1?v:v.slice(0,x);if(_()&&(await k("beforeRequest",h,f)===!1||f.headersSent)){b?.end(f.statusCode||204);return}let c=I(D,h.method||"GET");if(!c){_()&&await k("onError",h,f),f.status(404).json({error:"Route not found"}),b?.end(404);return}if("error"in c){let m=c.status||500;f.status(m).json({error:c.error}),b?.end(m,!0);return}h.params=c.params,await c.handler(h,f),_()&&await k("afterRequest",h,f),f.headersSent||f.end(),b?.end(f.statusCode||200);}catch(v){s&&console.error("Error:",v),f.headersSent||f.status(500).json({error:"Internal Server Error"}),_()&&await k("onError",h,f),b?.end(f.statusCode||500,true);}},p=(h,f)=>{let b=s&&a?a.trackRequest():null;if(d.length>0)for(let v=0;v<d.length;v++)f.setHeader(d[v][0],d[v][1]);u(h,f,b).catch(v=>{s&&console.error("Fatal error:",v),f.headersSent||(f.statusCode=500,f.end("Server Error")),b?.end(500,true);});},g={IncomingMessage:le,ServerResponse:de},C=r.httpsOptions?Ve.createServer({...g,...r.httpsOptions},p):ue.createServer(g,p);C.on("clientError",(h,f)=>{f.destroyed||f.destroy();});let y=r.httpsOptions?"https":"http";return L.isWorker&&ae().start(),C.listen(n,()=>{i?.enabled?s&&R(`Worker ${process.pid} is listening on port ${n}`):(R(`\u{1F680} Server running at ${y}://localhost:${n}/`+(s?" (dev)":"")),s&&a&&R(`\u{1F4CA} Performance monitoring available at http://localhost:${n}/health`));}),C}return null}}};var Oe={name:"vercel",createHandler:t=>{if(typeof t=="string")throw new Error("vercelAdapter.createHandler() requires a ServerlessConfig object, not a routesDir string. Import your routes manifest and pass { routes } instead.");let e=null,r=()=>e||(e=(async()=>{J(t.routes),P(t.cors),O(t.middleware);})(),e);return async(n,o)=>{await r(),Z(n),Q(o);let s=n,i=o;try{if(_()&&(await k("beforeRequest",s,i)===!1||i.headersSent))return;let l=I(s.url??"/",s.method??"GET");if(!l){i.status(404).json({error:"Route not found"});return}if(z(l)){i.status(l.status??500).json({error:l.error});return}s.params=l.params,await l.handler(s,i),_()&&await k("afterRequest",s,i);}catch(l){console.error("[lacis/vercel] Handler error:",l),_()&&await k("onError",s,i,{error:l}),i.headersSent||i.status(500).json({error:"Internal server error"});}}}};function ce(t,e,r,n){let o=Object.keys(r).length>0;return {statusCode:t,headers:e,...o?{multiValueHeaders:r}:{},body:n}}var Pe={name:"netlify",createHandler:t=>{if(typeof t=="string")throw new Error("netlifyAdapter.createHandler() requires a ServerlessConfig object. Run `lacis build` to generate routes/_manifest.ts and pass { routes } instead.");let e=null,r=()=>e||(e=(async()=>{J(t.routes),P(t.cors),O(t.middleware);})(),e);return async(n,o)=>{await r();let s=n.queryStringParameters?"?"+new URLSearchParams(n.queryStringParameters).toString():"",i=n.path+s,l=new IncomingMessage(new Socket);l.url=i,l.method=n.httpMethod,l.headers=n.headers,n.body&&l.push(Buffer.from(n.body,"utf-8")),l.push(null);let a="",d={},u={},p=false,g=new ServerResponse(l);g.writeHead=function(f,b){return g.statusCode=f,b&&(d={...d,...b}),this},g.setHeader=function(f,b){let v=f.toLowerCase();return Array.isArray(b)?(u[v]=b.map(String),d[v]=String(b[0])):d[v]=String(b),this},g.getHeader=function(f){return d[f.toLowerCase()]},g.end=function(f){return p=true,f!==void 0&&(a=typeof f=="string"?f:f.toString()),this},Object.defineProperty(g,"headersSent",{get:()=>p}),Z(l),Q(g);let C=l,y=g,h=I(n.path,n.httpMethod);if(!h)return {statusCode:404,body:JSON.stringify({error:"Route not found"})};if(z(h))return {statusCode:h.status??500,body:JSON.stringify({error:h.error})};try{return _()&&(await k("beforeRequest",C,y)===!1||p)||(C.params=h.params,await h.handler(C,y),_()&&await k("afterRequest",C,y)),ce(y.statusCode,d,u,a)}catch(f){return console.error("[lacis/netlify] Handler error:",f),_()&&await k("onError",C,y,{error:f}),p?ce(y.statusCode,d,u,a):{statusCode:500,body:JSON.stringify({error:"Internal server error"})}}}}};var nt=10485760,ot=new TextEncoder,pe=class{params={};url;method;headers;socket={setTimeout:e=>{}};connection;_req;constructor(e,r,n){this._req=e,this.url=r+n,this.method=e.method,this.headers=e.headers,this.connection={remoteAddress:e.headers.get("x-forwarded-for")??"127.0.0.1"};}setTimeout(e){}text(){return this._req.text()}body(){return this._req.arrayBuffer().then(e=>{if(e.byteLength>nt)throw Object.assign(new Error("Payload Too Large"),{code:413});return Buffer.from(e)})}},he=class extends N(pe){json(){return this._req.json()}},me=class{statusCode=200;headersSent=false;get finished(){return this.headersSent}get writableEnded(){return this.headersSent}_body=null;_headers=null;_sseReadable=null;_sseWriter=null;_sseWindowClosed=false;_listeners=null;on(e,r){return (e==="finish"||e==="close")&&(this._listeners||(this._listeners=[]),this._listeners.push(r)),this}once(e,r){return this.on(e,r)}emit(e){if((e==="finish"||e==="close")&&this._listeners)for(let r=0;r<this._listeners.length;r++)this._listeners[r]();return true}setHeader(e,r){if(this._headers||(this._headers=[]),Array.isArray(r))for(let n of r)this._headers.push(e,n);else this._headers.push(e,r);return this}getHeader(e){if(!this._headers)return;let r=e.toLowerCase();for(let n=0;n<this._headers.length;n+=2)if(this._headers[n].toLowerCase()===r)return this._headers[n+1]}removeHeader(e){if(!this._headers)return this;let r=e.toLowerCase();for(let n=0;n<this._headers.length;n+=2)if(this._headers[n].toLowerCase()===r){this._headers.splice(n,2);break}return this}hasHeader(e){if(!this._headers)return false;let r=e.toLowerCase();for(let n=0;n<this._headers.length;n+=2)if(this._headers[n].toLowerCase()===r)return true;return false}writeHead(e,r){if(this.statusCode=e,r)for(let[n,o]of Object.entries(r))this.setHeader(n,o);return this}write(e){return this._sseWriter?(this._sseWriter.write(ot.encode(String(e))),true):(this._body=(this._body??"")+e,true)}end(e){if(e!==void 0&&this.write(e),this._sseWriter&&this._sseWriter.close(),this.headersSent=true,this._listeners)for(let r=0;r<this._listeners.length;r++)this._listeners[r]();return this}_initSseStream(){if(this._sseWindowClosed)throw new Error("[lacis/bun] initSSE() must be called synchronously before any `await` in your handler.");let{readable:e,writable:r}=new TransformStream;this._sseReadable=e,this._sseWriter=r.getWriter();}_closeSseWindow(){this._sseWindowClosed=true;}},ge=class extends W(me){initSSE(e){return this._initSseStream(),super.initSSE(e)}},Ie={name:"bun",createHandler:t=>{if(typeof t!="string")throw new Error("bunAdapter requires a routesDir string, not a ServerlessConfig.");let e=t;return async(r={})=>{let{isDev:n,port:o=3e3,defaultHeaders:s,cluster:i}=r,l=parseInt(process.env.LACIS_BUN_WORKER??"0"),a=l>0;if(i?.enabled&&!a){let p=i.workers??q__default.cpus().length;R(`\u{1F9F5} Starting Bun server with ${p} workers (reusePort)`);let g=Array.from({length:p},()=>Bun.spawn(process.argv,{env:{...process.env,LACIS_BUN_WORKER:String(process.pid)},stdout:"ignore",stderr:"inherit"}));return R(`\u{1F680} Server running at http://localhost:${o}/`),{close:C=>{for(let y of g)y.kill();C?.();}}}if(a){let p=setInterval(()=>{try{process.kill(l,0);}catch{clearInterval(p),process.exit(0);}},2e3);p.unref();}R("\u{1F680} Bun high-performance mode enabled"),await V(e),P(r.cors),O(r.middleware);let d=s?Object.entries(s):[],u=Bun.serve({port:o,reusePort:a,async fetch(p){let g=new URL(p.url),C=g.pathname,y=new he(p,C,g.search),h=new ge;try{for(let x=0;x<d.length;x++)h.setHeader(d[x][0],d[x][1]);if(_()&&(!await k("beforeRequest",y,h)||h.headersSent))return fe(h);let f=I(C,p.method);if(!f)return _()&&await k("onError",y,h),new Response(JSON.stringify({error:"Route not found"}),{status:404,headers:{"Content-Type":"application/json"}});if("error"in f)return _()&&await k("onError",y,h),new Response(JSON.stringify({error:f.error}),{status:f.status||500,headers:{"Content-Type":"application/json"}});y.params=f.params;let b=null,v=(async()=>{await f.handler(y,h),_()&&await k("afterRequest",y,h),h.headersSent||h.end();})().catch(x=>{b=x,n&&console.error("Server error:",x),h._sseReadable&&!h.headersSent&&h.end();});return h._closeSseWindow(),h._sseReadable?fe(h,h._sseReadable):(await v,b&&!h.headersSent?new Response(JSON.stringify({error:"Internal Server Error"}),{status:500,headers:{"Content-Type":"application/json"}}):fe(h))}catch(f){return n&&console.error("Server error:",f),new Response(JSON.stringify({error:"Internal Server Error"}),{status:500,headers:{"Content-Type":"application/json"}})}}});return R(`\u{1F680} Server started on http://localhost:${o}${n?" (dev)":""}`),{close:()=>{u.stop();}}}}};function fe(t,e){let r=e??t._body;if(!t._headers)return new Response(r,{status:t.statusCode});let n=new Headers;for(let o=0;o<t._headers.length;o+=2){let s=t._headers[o],i=t._headers[o+1];s.toLowerCase()==="set-cookie"?n.append(s,i):n.set(s,i);}return new Response(r,{status:t.statusCode,headers:n})}var at={node:$e,vercel:Oe,netlify:Pe,bun:Ie};function br(t="node"){let e=at[t];if(!e)throw new Error(`Platform "${t}" not supported`);return e}
26
- export{be as A,Ee as B,Me as C,xe as D,Te as E,$e as F,Oe as G,Pe as H,Ie as I,br as J,re as a,dt as b,je as c,_ as d,k as e,ye as f,ut as g,ct as h,O as i,R as j,U as k,z as l,J as m,V as n,I as o,St as p,vt as q,bt as r,Et as s,De as t,P as u,Re as v,we as w,Ce as x,Se as y,ve as z};