scutivion 0.0.1 → 0.0.2
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.
- package/README.md +31 -45
- package/index.d.ts +25 -4
- package/package.json +22 -4
- package/Core/ContextPool.js +0 -1
- package/Core/CoreEngine.js +0 -1
- package/Core/HookSystem.js +0 -1
- package/Plugins/FileStreamingPlugin.js +0 -1
- package/Plugins/FrameworkPlugin.js +0 -1
- package/Plugins/ObservabilityPlugin.js +0 -1
- package/Plugins/ResponseCompressionPlugin.js +0 -1
- package/Plugins/SecurityPlugin.js +0 -1
- package/Plugins/StructuredLoggingPlugin.js +0 -1
- package/Protocols/HTTP2ProtocolAdapter.js +0 -1
- package/Protocols/HTTPProtocolAdapter.js +0 -1
- package/Protocols/TCPProtocolAdapter.js +0 -1
- package/Protocols/UDPProtocolAdapter.js +0 -1
- package/Protocols/WebSocketProtocolAdapter.js +0 -1
- package/Router/TrieRouter.js +0 -1
- package/index.js +0 -1
package/README.md
CHANGED
|
@@ -205,38 +205,40 @@ Run with `node examples/<file>.js`.
|
|
|
205
205
|
High-Level Architecture Diagram (Scutivion)
|
|
206
206
|
|
|
207
207
|
```
|
|
208
|
-
+-------------------+
|
|
209
|
-
| Protocol Adapters | | Core Engine
|
|
210
|
-
| | |
|
|
211
|
-
| - HTTP/2 Advanced |---->| - Unified Handler
|
|
212
|
-
| (Push, HPACK) | | - Context Pool
|
|
213
|
-
| - WS Binary/Frag | | - Hook Execution
|
|
214
|
-
| - TCP Framing | | - Service DI
|
|
215
|
-
| - UDP Low-Latency | | - Cluster Mode
|
|
216
|
-
+-------------------+ | - Graceful Shutdown|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
|
229
|
-
|
|
|
230
|
-
| -
|
|
231
|
-
| -
|
|
232
|
-
|
|
208
|
+
+-------------------+ +--------------------+ +-------------------+
|
|
209
|
+
| Protocol Adapters | | Core Engine | | Router |
|
|
210
|
+
| | | | | |
|
|
211
|
+
| - HTTP/2 Advanced |---->| - Unified Handler |---->| - Precompiled |
|
|
212
|
+
| (Push, HPACK) | | - Context Pool | | Static Routes |
|
|
213
|
+
| - WS Binary/Frag | | - Hook Execution | | - Radix Tree |
|
|
214
|
+
| - TCP Framing | | - Service DI | | Dynamic Routes |
|
|
215
|
+
| - UDP Low-Latency | | - Cluster Mode | +-------------------+
|
|
216
|
+
+-------------------+ | - Graceful Shutdown|
|
|
217
|
+
+--------------------+
|
|
218
|
+
+-------------------+
|
|
219
|
+
+--------------------+ | Buffer Pool |
|
|
220
|
+
| Hook System | | |
|
|
221
|
+
| | | - Zero-Copy Reuse |
|
|
222
|
+
| - onRequest | | - TCP/WS Buffers |
|
|
223
|
+
| - onResponse | +-------------------+
|
|
224
|
+
| - onError |
|
|
225
|
+
+--------------------+
|
|
226
|
+
|
|
227
|
+
+-------------------+ +-------------------+ +-------------------+
|
|
228
|
+
| Plugin System | | Advanced Features | | Observability |
|
|
229
|
+
| | | | | |
|
|
230
|
+
| - Security | | - Compression | | - Health Checks |
|
|
231
|
+
| (Rate/CORS/CSRF)| | - Streaming | | - Metrics |
|
|
232
|
+
| - Logging | | - UDP Support | | - Circuit Breaker |
|
|
233
|
+
| - Custom Plugins | +-------------------+ +-------------------+
|
|
234
|
+
+-------------------+
|
|
233
235
|
|
|
234
236
|
+-------------------+ +-------------------+
|
|
235
|
-
| Context Pool | |
|
|
237
|
+
| Context Pool | | Memory Management |
|
|
236
238
|
| | | |
|
|
237
|
-
| - Plain Objects | | -
|
|
238
|
-
| - Reuse/Reset | | -
|
|
239
|
-
| - Cluster-Shared | | -
|
|
239
|
+
| - Plain Objects | | - Buffer Pools |
|
|
240
|
+
| - Reuse/Reset | | - Zero-Copy TCP/WS|
|
|
241
|
+
| - Cluster-Shared | | - Minimal GC |
|
|
240
242
|
+-------------------+ +-------------------+
|
|
241
243
|
```
|
|
242
244
|
|
|
@@ -262,21 +264,6 @@ Run `node benchmarks/benchmark.js` to compare with Fastify and Express.
|
|
|
262
264
|
|
|
263
265
|
Expected: Higher throughput, lower latency than Fastify due to no middleware.
|
|
264
266
|
|
|
265
|
-
## Publishing to NPM
|
|
266
|
-
|
|
267
|
-
1. Ensure `package.json` has unique name and version.
|
|
268
|
-
2. Login to NPM: `npm login`
|
|
269
|
-
3. Publish: `npm publish`
|
|
270
|
-
4. For scoped packages: `npm init --scope=@yourorg`
|
|
271
|
-
|
|
272
|
-
## Trade-offs and Limitations
|
|
273
|
-
|
|
274
|
-
- Minimal: Manual body parsing, no built-in security (use plugins).
|
|
275
|
-
- TCP Framing: 4-byte length-prefixed, not for complex protocols.
|
|
276
|
-
- WS: Text frames only, no binary/advanced fragmentation.
|
|
277
|
-
- Error Handling: Basic logging, no auto-recovery.
|
|
278
|
-
- Cluster: Manual load balancing if not using built-in.
|
|
279
|
-
|
|
280
267
|
## Examples
|
|
281
268
|
|
|
282
269
|
- **REST API** (`examples/rest.js`): GET/POST with JSON, cluster support.
|
|
@@ -314,7 +301,6 @@ app.registerPlugin(new LoggingPlugin(console.log));
|
|
|
314
301
|
## Documentation
|
|
315
302
|
|
|
316
303
|
- **JSDoc**: Auto-generated in `docs/api.html`.
|
|
317
|
-
- **Tutorials**: `docs/tutorials.md`.
|
|
318
304
|
|
|
319
305
|
## Contributing
|
|
320
306
|
|
package/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface Context {
|
|
|
9
9
|
params: string[];
|
|
10
10
|
query: Record<string, string>;
|
|
11
11
|
body?: any;
|
|
12
|
+
requestBody?: any;
|
|
13
|
+
rawBody?: Buffer;
|
|
12
14
|
socket?: Socket;
|
|
13
15
|
protocol?: string;
|
|
14
16
|
method?: string;
|
|
@@ -16,9 +18,11 @@ export interface Context {
|
|
|
16
18
|
headers: Record<string, string>;
|
|
17
19
|
statusCode: number;
|
|
18
20
|
responseHeaders: Record<string, string>;
|
|
19
|
-
responseBody?:
|
|
21
|
+
responseBody?: any;
|
|
20
22
|
error?: Error;
|
|
21
23
|
custom: Record<string, any>;
|
|
24
|
+
schema?: any;
|
|
25
|
+
[key: string]: any; // For decorators
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
export interface Service {
|
|
@@ -46,9 +50,10 @@ export class LifecycleHookSystem {
|
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
export class UnifiedEngineCore extends EventEmitter {
|
|
49
|
-
constructor(options?: { poolSize?: number });
|
|
53
|
+
constructor(options?: { poolSize?: number; cluster?: boolean });
|
|
50
54
|
registerService(name: string, service: Service): void;
|
|
51
|
-
|
|
55
|
+
decorate(type: 'context' | 'request' | 'response', name: string, value: any): void;
|
|
56
|
+
route(method: string, path: string, handler: HandlerFunction | { schema?: any; handler: HandlerFunction }): void;
|
|
52
57
|
hook(
|
|
53
58
|
hookName: "onRequest" | "onResponse" | "onError",
|
|
54
59
|
fn: HookFunction
|
|
@@ -93,6 +98,22 @@ export class UDPProtocolAdapter {
|
|
|
93
98
|
close(): void;
|
|
94
99
|
}
|
|
95
100
|
|
|
101
|
+
export class JSONValidationPlugin extends FrameworkPlugin {
|
|
102
|
+
constructor();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export class ContentParsingPlugin extends FrameworkPlugin {
|
|
106
|
+
constructor(options?: { json?: boolean; form?: boolean; multipart?: boolean });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export class ErrorHandlingPlugin extends FrameworkPlugin {
|
|
110
|
+
constructor();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export class DecoratorPlugin extends FrameworkPlugin {
|
|
114
|
+
constructor();
|
|
115
|
+
}
|
|
116
|
+
|
|
96
117
|
export class FrameworkPlugin {
|
|
97
118
|
constructor(name: string);
|
|
98
119
|
registerService(name: string, service: Service): void;
|
|
@@ -104,7 +125,7 @@ export class FrameworkPlugin {
|
|
|
104
125
|
}
|
|
105
126
|
|
|
106
127
|
export class StructuredLoggingPlugin extends FrameworkPlugin {
|
|
107
|
-
constructor();
|
|
128
|
+
constructor(logger?: any);
|
|
108
129
|
}
|
|
109
130
|
|
|
110
131
|
export class SecurityPlugin extends FrameworkPlugin {
|
package/package.json
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scutivion",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Scutivion: Futuristic high-performance Node.js framework inspired by UY Scuti, the largest supergiant star. Shield-like protection for hyperscale applications.",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/",
|
|
9
|
+
"index.d.ts"
|
|
10
|
+
],
|
|
7
11
|
"author": "Muhammad Imam Rozali <muh.imamrozali@gmail.com>",
|
|
8
12
|
"contributors": [],
|
|
9
13
|
"license": "MIT",
|
|
10
14
|
"keywords": [
|
|
15
|
+
"scutivion",
|
|
11
16
|
"nodejs",
|
|
12
17
|
"framework",
|
|
13
18
|
"high-performance",
|
|
14
|
-
"native"
|
|
19
|
+
"native",
|
|
20
|
+
"http",
|
|
21
|
+
"http2",
|
|
22
|
+
"websocket",
|
|
23
|
+
"tcp",
|
|
24
|
+
"udp",
|
|
25
|
+
"cluster",
|
|
26
|
+
"zero-copy",
|
|
27
|
+
"hooks",
|
|
28
|
+
"plugins",
|
|
29
|
+
"minimal",
|
|
30
|
+
"unified",
|
|
31
|
+
"radix-router",
|
|
32
|
+
"buffer-pool"
|
|
15
33
|
],
|
|
16
34
|
"engines": {
|
|
17
35
|
"node": ">=14.0.0"
|
|
@@ -24,4 +42,4 @@
|
|
|
24
42
|
"url": "https://github.com/imamrozali/scutivion/issues"
|
|
25
43
|
},
|
|
26
44
|
"homepage": "https://github.com/imamrozali/scutivion#readme"
|
|
27
|
-
}
|
|
45
|
+
}
|
package/Core/ContextPool.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class ContextObjectPool{constructor(size=1e3){this.pool=[];this.bufferPool=[];this.size=size;for(let i=0;i<size;i++){this.pool.push(this.createContext());this.bufferPool.push(Buffer.alloc(4096))}}createContext(){return{req:null,res:null,params:[],query:{},body:null,socket:null,protocol:null,method:null,url:null,headers:{},statusCode:200,responseHeaders:{},responseBody:null,error:null,custom:{}}}acquire(){return this.pool.pop()||this.createContext()}release(ctx){ctx.req=null;ctx.res=null;ctx.params.length=0;ctx.query={};ctx.body=null;ctx.socket=null;ctx.protocol=null;ctx.method=null;ctx.url=null;ctx.headers={};ctx.statusCode=200;ctx.responseHeaders={};ctx.responseBody=null;ctx.error=null;ctx.custom={};if(this.pool.length<this.size){this.pool.push(ctx)}}acquireBuffer(){return this.bufferPool.pop()||Buffer.alloc(4096)}releaseBuffer(buf){if(this.bufferPool.length<this.size){this.bufferPool.push(buf)}}}module.exports=ContextObjectPool;
|
package/Core/CoreEngine.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const{EventEmitter:EventEmitter}=require("events");const TrieRouter=require("../Router/TrieRouter");class UnifiedEngineCore extends EventEmitter{constructor(options={}){super();this.router=new TrieRouter;this.hooks=new(require("./HookSystem"));this.contextPool=new(require("./ContextPool"))(options.poolSize||1e3);this.services={};this.protocols={};this.circuitBreaker={failures:0,threshold:5,timeout:1e4,lastFailure:0};this.isShuttingDown=false;process.on("SIGTERM",()=>this.shutdown());process.on("SIGINT",()=>this.shutdown())}registerService(name,service){this.services[name]=service}route(method,path,handler){this.router.insert(method,path,handler)}hook(hookName,fn){this.hooks.register(hookName,fn)}async handleRequest(protocol,rawReq,rawRes,socket=null){if(this.isShuttingDown)return;try{this.checkCircuitBreaker();const ctx=this.contextPool.acquire();ctx.protocol=protocol;ctx.req=rawReq;ctx.res=rawRes;ctx.socket=socket;if(protocol==="http"||protocol==="http2"){ctx.method=rawReq.method;ctx.url=rawReq.url;ctx.headers=rawReq.headers}this.hooks.execute("onRequest",ctx);if(ctx.method&&ctx.url){const path=ctx.url.split("?")[0];const handler=this.router.lookup(ctx.method,path,ctx.params);if(handler){try{handler(ctx)}catch(err){ctx.error=err;this.hooks.execute("onError",ctx)}}else{ctx.statusCode=404}}this.hooks.execute("onResponse",ctx);this.emit("response",ctx);this.contextPool.release(ctx)}catch(err){console.error("Request handling error:",err);this.recordFailure()}}listen(protocol,port,options={}){const adapter=this.protocols[protocol];if(!adapter)throw new Error(`Protocol ${protocol} not registered`);adapter.listen(this,port,options)}registerProtocol(name,adapter){this.protocols[name]=adapter}checkCircuitBreaker(){if(this.circuitBreaker.failures>=this.circuitBreaker.threshold){const now=Date.now();if(now-this.circuitBreaker.lastFailure<this.circuitBreaker.timeout){throw new Error("Circuit breaker open")}else{this.circuitBreaker.failures=0}}}recordFailure(){this.circuitBreaker.failures++;this.circuitBreaker.lastFailure=Date.now()}async shutdown(){if(this.isShuttingDown)return;this.isShuttingDown=true;console.log("Shutting down gracefully...");for(const adapter of Object.values(this.protocols)){if(adapter.close)adapter.close()}this.contextPool=null;process.exit(0)}}module.exports=UnifiedEngineCore;
|
package/Core/HookSystem.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class LifecycleHookSystem{constructor(){this.onRequest=[];this.onResponse=[];this.onError=[]}register(hookName,fn){if(this[hookName]){this[hookName].push(fn)}}execute(hookName,ctx){const hooks=this[hookName];if(!hooks)return;for(const hook of hooks){try{hook(ctx)}catch(err){if(hookName!=="onError"){this.execute("onError",{...ctx,error:err})}}}}async executeInline(hookName,ctx){const hooks=this[hookName];if(!hooks)return;for(const hook of hooks){await hook(ctx)}}}module.exports=LifecycleHookSystem;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const FrameworkPlugin=require("./FrameworkPlugin");const fs=require("fs");class FileStreamingPlugin extends FrameworkPlugin{constructor(){super("streaming")}async apply(core){core.route("POST","/upload",async ctx=>{ctx.responseBody=JSON.stringify({uploaded:true})})}}module.exports=FileStreamingPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class FrameworkPlugin{constructor(name){this.name=name;this.services={};this.hooks={}}registerService(name,service){this.services[name]=service}registerHook(hookName,fn){if(!this.hooks[hookName])this.hooks[hookName]=[];this.hooks[hookName].push(fn)}apply(core){for(const[name,service]of Object.entries(this.services)){core.registerService(name,service)}for(const[hookName,fns]of Object.entries(this.hooks)){for(const fn of fns){core.hook(hookName,fn)}}}}module.exports=FrameworkPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const FrameworkPlugin=require("./FrameworkPlugin");class ObservabilityPlugin extends FrameworkPlugin{constructor(){super("observability");this.metrics={requests:0,errors:0}}async apply(core){core.route("GET","/health",async ctx=>{ctx.responseBody=JSON.stringify({status:"ok",uptime:process.uptime()})});core.route("GET","/metrics",async ctx=>{ctx.responseBody=JSON.stringify(this.metrics)});core.hook("onRequest",()=>this.metrics.requests++);core.hook("onError",()=>this.metrics.errors++)}}module.exports=ObservabilityPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const FrameworkPlugin=require("./FrameworkPlugin");const zlib=require("zlib");class ResponseCompressionPlugin extends FrameworkPlugin{constructor(){super("compression")}async apply(core){core.hook("onResponse",async ctx=>{if(ctx.responseBody&&ctx.headers["accept-encoding"]?.includes("gzip")){ctx.responseBody=await new Promise((resolve,reject)=>{zlib.gzip(Buffer.from(ctx.responseBody),(err,result)=>{if(err)reject(err);else resolve(result)})});ctx.headers["content-encoding"]="gzip"}})}}module.exports=ResponseCompressionPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const FrameworkPlugin=require("./FrameworkPlugin");class SecurityPlugin extends FrameworkPlugin{constructor(options={}){super("security");this.rateLimit=options.rateLimit||1e3;this.requests=new Map}async apply(core){core.hook("onRequest",async ctx=>{const ip=ctx.socket?.remoteAddress||"unknown";const now=Date.now();if(!this.requests.has(ip))this.requests.set(ip,[]);const times=this.requests.get(ip).filter(t=>now-t<6e4);if(times.length>=this.rateLimit){ctx.statusCode=429;ctx.responseBody="Rate limit exceeded";return}times.push(now);this.requests.set(ip,times)})}}module.exports=SecurityPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const FrameworkPlugin=require("./FrameworkPlugin");class StructuredLoggingPlugin extends FrameworkPlugin{constructor(){super("logging");this.registerHook("onRequest",ctx=>{console.log(`${ctx.method} ${ctx.url}`)});this.registerHook("onResponse",ctx=>{console.log(`Response ${ctx.statusCode}`)});this.registerHook("onError",ctx=>{console.error(`Error: ${ctx.error.message}`)})}}module.exports=StructuredLoggingPlugin;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const http2=require("http2");class HTTP2ProtocolAdapter{constructor(options={}){this.server=http2.createServer(options)}async listen(core,port){this.server.on("stream",async(stream,headers)=>{const ctx=core.pool.acquire();ctx.stream=stream;ctx.pushStream=(pushHeaders,callback)=>stream.pushStream(pushHeaders,callback);await core.handleRequest("http2",{method:headers[":method"],url:headers[":path"],headers:headers},{respond:resHeaders=>stream.respond(resHeaders),end:data=>stream.end(data)})})}close(){this.server.close()}}module.exports=HTTP2ProtocolAdapter;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const http=require("http");const http2=require("http2");class HTTPProtocolAdapter{constructor(options={}){this.http1Server=null;this.http2Server=null;this.options=options}listen(core,port,opts={}){if(opts.http2){this.http2Server=http2.createServer(opts,(req,res)=>{core.handleRequest("http2",req,res)});this.http2Server.listen(port)}else{this.http1Server=http.createServer((req,res)=>{core.handleRequest("http",req,res)});this.http1Server.listen(port)}}close(){if(this.http1Server)this.http1Server.close();if(this.http2Server)this.http2Server.close()}}module.exports=HTTPProtocolAdapter;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const net=require("net");class TCPProtocolAdapter{constructor(options={}){this.server=null;this.options=options}listen(core,port){this.server=net.createServer(socket=>{let buffer=Buffer.alloc(0);socket.on("data",data=>{buffer=Buffer.concat([buffer,data]);while(buffer.length>=4){const length=buffer.readUInt32BE(0);if(buffer.length<4+length)break;const message=buffer.slice(4,4+length);buffer=buffer.slice(4+length);const req={method:"TCP",url:"/",headers:{},body:message};const res={write:data=>socket.write(data),end:()=>socket.end(),writeHead:()=>{}};core.handleRequest("tcp",req,res,socket)}});socket.on("error",err=>{console.error("TCP socket error:",err)})});this.server.listen(port)}close(){if(this.server)this.server.close()}}module.exports=TCPProtocolAdapter;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const dgram=require("dgram");class UDPProtocolAdapter{constructor(options={}){this.server=dgram.createSocket("udp4")}async listen(core,port){this.server.on("message",async(msg,rinfo)=>{const ctx=core.pool.acquire();ctx.rinfo=rinfo;await core.handleRequest("udp",{method:"UDP",url:"/",headers:{},body:msg},{send:data=>this.server.send(data,rinfo.port,rinfo.address)})});this.server.on("error",err=>{console.error("UDP error:",err)});this.server.bind(port)}close(){this.server.close()}}module.exports=UDPProtocolAdapter;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const crypto=require("crypto");class WebSocketProtocolAdapter{constructor(options={}){this.options=options}listen(core,port){const http=require("http");this.server=http.createServer((req,res)=>{if(req.headers.upgrade&&req.headers.upgrade.toLowerCase()==="websocket"){this.handleUpgrade(req,res,core)}else{core.handleRequest("http",req,res)}});this.server.listen(port)}handleUpgrade(req,res,core){const key=req.headers["sec-websocket-key"];const accept=crypto.createHash("sha1").update(key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");res.writeHead(101,{Upgrade:"websocket",Connection:"Upgrade","Sec-WebSocket-Accept":accept});res.end();const socket=req.socket;let buffer=Buffer.alloc(0);socket.on("data",data=>{buffer=Buffer.concat([buffer,data]);buffer=this.parseFrames(buffer,frame=>{if(frame.opcode===1||frame.opcode===2){const req={method:"WS",url:"/",headers:{},body:frame.payload};const res={send:data=>process.nextTick(()=>this.sendFrame(socket,frame.opcode===2?2:1,data)),close:()=>socket.end()};core.handleRequest("ws",req,res,socket)}})})}parseFrames(buffer,onFrame){let offset=0;while(offset<buffer.length){if(buffer.length-offset<2)break;const byte1=buffer[offset++];const byte2=buffer[offset++];const fin=(byte1&128)!==0;const opcode=byte1&15;const masked=(byte2&128)!==0;let length=byte2&127;if(length===126){if(buffer.length-offset<2)break;length=buffer.readUInt16BE(offset);offset+=2}else if(length===127){if(buffer.length-offset<8)break;length=buffer.readUInt32BE(offset)*4294967296+buffer.readUInt32BE(offset+4);offset+=8}if(masked){if(buffer.length-offset<4)break;const mask=buffer.slice(offset,offset+4);offset+=4}if(buffer.length-offset<length)break;let payload=buffer.slice(offset,offset+length);offset+=length;if(masked){for(let i=0;i<payload.length;i++){payload[i]^=mask[i%4]}}onFrame({opcode:opcode,payload:payload,fin:fin})}return buffer.slice(offset)}sendFrame(socket,opcode,payload){const frame=Buffer.alloc(2+payload.length);frame[0]=128|opcode;frame[1]=payload.length;payload.copy(frame,2);socket.write(frame)}close(){if(this.server)this.server.close()}}module.exports=WebSocketProtocolAdapter;
|
package/Router/TrieRouter.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class RadixNode{constructor(){this.children={};this.handlers={};this.paramName=null;this.isWildcard=false}}class TrieRouter{constructor(){this.root=new RadixNode}insert(method,path,handler){let node=this.root;const segments=path.split("/").filter(s=>s.length>0);for(const segment of segments){let child=node.children[segment];if(!child){child=new RadixNode;if(segment.startsWith(":")){child.paramName=segment.slice(1)}else if(segment==="*"){child.isWildcard=true}node.children[segment]=child}node=child}node.handlers[method]=handler}lookup(method,path,params){let node=this.root;const segments=path.split("/").filter(s=>s.length>0);let paramIndex=0;for(const segment of segments){let child=node.children[segment];if(!child){for(const key in node.children){const c=node.children[key];if(c.paramName){params[paramIndex++]=segment;child=c;break}else if(c.isWildcard){child=c;break}}}if(!child)return null;node=child}return node.handlers[method]||null}}module.exports=TrieRouter;
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const UnifiedEngineCore=require("./Core/CoreEngine");const HTTPProtocolAdapter=require("./Protocols/HTTPProtocolAdapter");const TCPProtocolAdapter=require("./Protocols/TCPProtocolAdapter");const WebSocketProtocolAdapter=require("./Protocols/WebSocketProtocolAdapter");const HTTP2ProtocolAdapter=require("./Protocols/HTTP2ProtocolAdapter");const UDPProtocolAdapter=require("./Protocols/UDPProtocolAdapter");const FrameworkPlugin=require("./Plugins/FrameworkPlugin");const StructuredLoggingPlugin=require("./Plugins/StructuredLoggingPlugin");const SecurityPlugin=require("./Plugins/SecurityPlugin");const ResponseCompressionPlugin=require("./Plugins/ResponseCompressionPlugin");const FileStreamingPlugin=require("./Plugins/FileStreamingPlugin");const ObservabilityPlugin=require("./Plugins/ObservabilityPlugin");module.exports={CoreEngine:UnifiedEngineCore,UnifiedEngineCore:UnifiedEngineCore,HTTPProtocolAdapter:HTTPProtocolAdapter,HTTPAdapter:HTTPProtocolAdapter,TCPProtocolAdapter:TCPProtocolAdapter,TCPAdapter:TCPProtocolAdapter,WebSocketProtocolAdapter:WebSocketProtocolAdapter,WSAdapter:WebSocketProtocolAdapter,HTTP2ProtocolAdapter:HTTP2ProtocolAdapter,UDPProtocolAdapter:UDPProtocolAdapter,FrameworkPlugin:FrameworkPlugin,Plugin:FrameworkPlugin,StructuredLoggingPlugin:StructuredLoggingPlugin,LoggingPlugin:StructuredLoggingPlugin,SecurityPlugin:SecurityPlugin,ResponseCompressionPlugin:ResponseCompressionPlugin,CompressionPlugin:ResponseCompressionPlugin,FileStreamingPlugin:FileStreamingPlugin,StreamingPlugin:FileStreamingPlugin,ObservabilityPlugin:ObservabilityPlugin};
|