{"_id":"@aegis-fluxion/core","_rev":"9-5232456ebbef7751ba89a6f4eca755e7","name":"@aegis-fluxion/core","dist-tags":{"latest":"0.10.0"},"versions":{"0.3.0":{"name":"@aegis-fluxion/core","version":"0.3.0","_id":"@aegis-fluxion/core@0.3.0","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"ceb6733d59f4c3314f226a02f27e7659bbeaf93f","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.3.0.tgz","fileCount":7,"integrity":"sha512-hzQ5yNIJX127RT0d2lgGqOoHsjUd2KZE+CQ0EgxEZ9hnGECHBQT3JNp0f2mIcHEv3qXKLmYi9wFcLtbKwmfCmA==","signatures":[{"sig":"MEUCIQDjZJS+lKGGCUusjMVGKmY+NuZWzez2n/M58hd9ArbZRwIgYe5qG3gjB0aJes+dMlArkMOlpmnG6O7RWqAsUWfylyE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":275760},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"278268d89f8a696d40d45d63ba0e8024d8bc5d77","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.3.0_1776270705634_0.2166813960266314","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aegis-fluxion/core","version":"0.4.0","_id":"@aegis-fluxion/core@0.4.0","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"acb9ad521a4caecdffd9dd2b8108ddbb2875f8d7","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.4.0.tgz","fileCount":8,"integrity":"sha512-wM1lKSPbUU2aejOQu1KRNKm7FUkzl0XlCT87veMfnSQ2jFtiSb0iksXHpgyvrJQVktqk/LQwARMj47shbMGQjA==","signatures":[{"sig":"MEYCIQD9Q84suP6/KxfXCof3rWuN/L0cbqOgJLf7Uw6PuSF88AIhAMkGVJGDH5rFeWx72EwFJdMNCNYApBpR1xh80LvtBtnf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":376078},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"2eecb930bcd7839ff3271c9b50e6aa352ad7f1da","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.4.0_1776272153148_0.8797660701740695","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@aegis-fluxion/core","version":"0.5.0","_id":"@aegis-fluxion/core@0.5.0","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"b5c7ae82babc61f8054dc0c9a527983240d7add2","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.5.0.tgz","fileCount":8,"integrity":"sha512-T0jJC5Y+ZGVSROF0jsJyn6QUrq0ZosKehkDeUKz/4yeAzJ695MvrxZ06wNXBzZwq86XVbG8kJvuNiHX5w2sg8Q==","signatures":[{"sig":"MEUCIDXYcmF1gvTFZs1cuK1Wo56JAhScGZvE7S6wN5tC0wFyAiEAyLZRV2kqscUcYk4pNE29pUM7mnA9//JBh9UysLGXJkA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":405131},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"35e9655170a5269d563b5082be6041239cf0d38c","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.5.0_1776274281022_0.2931498124535572","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@aegis-fluxion/core","version":"0.7.0","_id":"@aegis-fluxion/core@0.7.0","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"39a1d468a4ab9b107271a9ffc90bbd93f7912160","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.7.0.tgz","fileCount":8,"integrity":"sha512-fTCpPmBxF6rY8O/n8KP2p6C4HlxQcMmGjyDlbW5ffcVoNNBst+YuEE1y/2lpTZW/fWK+iJkqTmHl6yH4RmHM9A==","signatures":[{"sig":"MEQCIHWccDDGaB8/UYL52PqCzduyNtezJ5c+74Fffb9q5P8ZAiBbgS4Io+7P6MftQbcaabZV+uKDpGKp5fd8X8B/iX64aQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":436272},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"ba06a4a4d27ce414f74bec2f68c5a88265b78578","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.7.0_1776277754913_0.5206546879571481","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@aegis-fluxion/core","version":"0.7.1","_id":"@aegis-fluxion/core@0.7.1","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"ec2bb703b9d2878e53dfd983b3e9d588ad75f548","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.7.1.tgz","fileCount":8,"integrity":"sha512-Hy3WIg33YTT0YSaQCWD0MAToH3isUmTBq46XCCpq2pT/iVJoqrNZGq2fpF5l4Ra9UEnLM03+w4wYsQ/1qxni7A==","signatures":[{"sig":"MEUCIQDLOrSH+1S6KSfggpxIb2fTcaUP6F7zZXcaJzgIigFo6wIgX5zq3nc6e9lslaM8m8e84hjL9Q9oZ9CUQ8WK2TdP+P8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":502789},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"2f071c326e70d2619b46e2e1dac42be23c4e9194","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.7.1_1776279437124_0.2978040780470472","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@aegis-fluxion/core","version":"0.7.2","_id":"@aegis-fluxion/core@0.7.2","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"16a618c74e7acf31398f02fa9e51d35072a22e91","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.7.2.tgz","fileCount":8,"integrity":"sha512-CJX038Lz3ppUVZrWi7Qr4SakOMj2UtCzJphyDQM/KsnJZatGgqiNidf+vEhTnWBIn6ysjD4ZX6PWYC6lUVMhcQ==","signatures":[{"sig":"MEQCIGjoAafDhO345jC6E38OdMssOjRRQrtqMrEiDa+fkyLaAiBbLgkUmLUISTU8IDdeJmBZJukGhCXmKC9X/swtu9g0GQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":532707},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"c13f44be6ff0449a22ab996bc9c15df306b7552a","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.7.2_1776282930151_0.9385461452709654","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@aegis-fluxion/core","version":"0.8.0","_id":"@aegis-fluxion/core@0.8.0","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"da1d778b5c64ec6ffd92971ab24236ff110865e2","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.8.0.tgz","fileCount":8,"integrity":"sha512-K9rkdRKMtSiQ/UKOrEv6z/KGHh/JZ2n34vTOO6LeNUCmSmVpVY4guVK69vYUFV6h8q33xZJuPDmEEn/2z9fj9Q==","signatures":[{"sig":"MEQCIFcOVub+c5IETh4UBzx6rEy5R/wfv8Af/rObrUQFqNvvAiB0pocIWgE+NKGE8SOsZ1jlLEdbOpZFiMhPR/OoCz3XmA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":665186},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"075e1641a993fb52559b3cd0355846afb53fecf2","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.8.0_1776285228800_0.9959538328765531","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@aegis-fluxion/core","version":"0.9.0","_id":"@aegis-fluxion/core@0.9.0","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"dist":{"shasum":"49bc2571c16eee654148e34f01bcf1bfd210108a","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.9.0.tgz","fileCount":8,"integrity":"sha512-9ZtlZA65ohO7gr5fRzyrBUW9jxJ1al2NIdUAlCZF5SZaoTVQhte+3+BqQj6ypKUSbhFgYfNEzcAiayfvtbMujg==","signatures":[{"sig":"MEQCIDN6rgVScG0/NFRSSMdEE137AGOxJHNmJaobW0+fAOmHAiASuwQaRpSH28ClgrULQ+IAdvvP33hDtXuT/W0DTVr26w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":837806},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.18.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"7d52d0f32cb72933480060524dd60c466a3718b3","scripts":{"dev":"tsup --watch","test":"vitest run --passWithNoTests","build":"tsup","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","typecheck":"tsc --noEmit","test:watch":"vitest --passWithNoTests","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"_npmVersion":"11.6.2","description":"Core WebSocket primitives for aegis-fluxion.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ws":"^8.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^3.2.4","@types/ws":"^8.5.13","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/core_0.9.0_1776327074842_0.6327943011603128","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@aegis-fluxion/core","version":"0.10.0","description":"Core WebSocket primitives for aegis-fluxion.","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs","default":"./dist/index.js"}},"publishConfig":{"access":"public"},"sideEffects":false,"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"vitest run --passWithNoTests","test:watch":"vitest --passWithNoTests","clean":"node -e \"import('node:fs').then(({ rmSync }) => rmSync('dist', { recursive: true, force: true }))\"","prepublishOnly":"npm run clean && npm run build && npm run typecheck && npm run test"},"dependencies":{"ws":"^8.18.1"},"devDependencies":{"@types/ws":"^8.5.13","tsup":"^8.3.5","typescript":"^5.8.3","vitest":"^3.2.4"},"engines":{"node":">=18.18.0"},"gitHead":"d6b0aee63d18cde035255a52e4b383469568d2a8","_id":"@aegis-fluxion/core@0.10.0","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-3BXqATHz79BSEblbEqJROOV8Z+yNnHfnliM5E6E2Pz76Z+ah0+/nk8Ekqn3dQK9Jxce2AT6DxEOPx0IAm4GC1g==","shasum":"8b98adb017b10bd0b62291971eded39b4f9a196e","tarball":"https://registry.npmjs.org/@aegis-fluxion/core/-/core-0.10.0.tgz","fileCount":8,"unpackedSize":886416,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD92Y26xDQCs3ywzrNdGpEwlpeMQR3ci2uHqZyjp5qLtQIhAMn9g+M8MIr991unjHv10628SoEZ0s15JdCPlZgUBKWm"}]},"_npmUser":{"name":"donboz","email":"muratbatak052005@gmail.com"},"directories":{},"maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_0.10.0_1776332913502_0.5991807289717495"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-15T16:31:45.494Z","modified":"2026-04-16T09:48:33.786Z","0.3.0":"2026-04-15T16:31:45.774Z","0.4.0":"2026-04-15T16:55:53.297Z","0.5.0":"2026-04-15T17:31:21.165Z","0.7.0":"2026-04-15T18:29:15.066Z","0.7.1":"2026-04-15T18:57:17.314Z","0.7.2":"2026-04-15T19:55:30.302Z","0.8.0":"2026-04-15T20:33:49.020Z","0.9.0":"2026-04-16T08:11:15.049Z","0.10.0":"2026-04-16T09:48:33.645Z"},"description":"Core WebSocket primitives for aegis-fluxion.","maintainers":[{"name":"donboz","email":"muratbatak052005@gmail.com"}],"readme":"# @aegis-fluxion/core\r\n\r\nLow-level encrypted WebSocket primitives for the `aegis-fluxion` ecosystem.\r\n\r\nVersion: **0.10.0**\r\n\r\n---\r\n\r\n## Highlights\r\n\r\n- Ephemeral ECDH handshake (`prime256v1`)\r\n- AES-256-GCM encrypted envelopes\r\n- Built-in telemetry via `getMetrics()` and `getMetricsPrometheus()`\r\n- ACK request/response (Promise + callback styles)\r\n- Encrypted chunked streaming for large `Buffer`/`Readable` payloads\r\n- Secure room routing (`join`, `leave`, `leaveAll`, `to(room).emit(...)`)\r\n- Middleware phases: `connection`, `incoming`, `outgoing`\r\n- Rate limiting and DDoS controls per connection and IP\r\n- TLS 1.3-style session resumption with encrypted one-time tickets\r\n- **Horizontal scaling hooks** via pluggable `SecureServerAdapter`\r\n\r\n---\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install @aegis-fluxion/core ws\r\n```\r\n\r\n---\r\n\r\n## Observability & telemetry (new in 0.10.0)\r\n\r\n`SecureServer` exposes real-time metrics for operational visibility:\r\n\r\n- active secure connections\r\n- successful/failed handshakes (including resume attempts)\r\n- encrypted message and byte throughput (ingress/egress)\r\n- DDoS/rate-limit counters (blocked, throttled, disconnected)\r\n\r\n### JSON metrics snapshot\r\n\r\n```ts\r\nimport { SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst server = new SecureServer({ host: \"127.0.0.1\", port: 8080 });\r\n\r\nconst snapshot = server.getMetrics();\r\nconsole.log(snapshot.activeConnections);\r\nconsole.log(snapshot.encryptedMessagesReceivedTotal);\r\n```\r\n\r\n### Prometheus endpoint integration\r\n\r\n```ts\r\nimport { createServer } from \"node:http\";\r\nimport { SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst secureServer = new SecureServer({ host: \"127.0.0.1\", port: 8080 });\r\n\r\ncreateServer((request, response) => {\r\n  if (request.url === \"/metrics\") {\r\n    response.setHeader(\"Content-Type\", \"text/plain; version=0.0.4; charset=utf-8\");\r\n    response.end(secureServer.getMetricsPrometheus());\r\n    return;\r\n  }\r\n\r\n  response.statusCode = 404;\r\n  response.end(\"Not Found\");\r\n}).listen(9100, \"127.0.0.1\");\r\n```\r\n\r\n---\r\n\r\n## Frontend integration (React)\r\n\r\n`@aegis-fluxion/core` is server/runtime focused. For browser clients, pair it with\r\n`@aegis-fluxion/browser-client`.\r\n\r\n### Node backend (`SecureServer`)\r\n\r\n```ts\r\nimport { SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst server = new SecureServer({ host: \"127.0.0.1\", port: 8080 });\r\n\r\nserver.on(\"feed:publish\", async (payload) => {\r\n  server.emit(\"feed:message\", payload);\r\n  return { ok: true };\r\n});\r\n```\r\n\r\n### React frontend (`BrowserSecureClient`)\r\n\r\n```tsx\r\nimport { useEffect, useMemo, useState } from \"react\";\r\nimport { BrowserSecureClient } from \"@aegis-fluxion/browser-client\";\r\n\r\nexport function SecureFeedPanel() {\r\n  const [status, setStatus] = useState(\"connecting\");\r\n  const [messages, setMessages] = useState<string[]>([]);\r\n\r\n  const client = useMemo(() => {\r\n    return new BrowserSecureClient(\"ws://127.0.0.1:8080\", {\r\n      autoConnect: false,\r\n      reconnect: true\r\n    });\r\n  }, []);\r\n\r\n  useEffect(() => {\r\n    const onReady = () => setStatus(\"ready\");\r\n    const onDisconnect = () => setStatus(\"disconnected\");\r\n    const onFeedMessage = (payload: unknown) => {\r\n      const data = payload as { text?: string };\r\n      if (typeof data.text === \"string\") {\r\n        setMessages((prev) => [data.text, ...prev]);\r\n      }\r\n    };\r\n\r\n    client.on(\"ready\", onReady);\r\n    client.on(\"disconnect\", onDisconnect);\r\n    client.on(\"feed:message\", onFeedMessage);\r\n    client.connect();\r\n\r\n    return () => {\r\n      client.off(\"ready\", onReady);\r\n      client.off(\"disconnect\", onDisconnect);\r\n      client.off(\"feed:message\", onFeedMessage);\r\n      client.disconnect();\r\n    };\r\n  }, [client]);\r\n\r\n  return (\r\n    <section>\r\n      <p>Status: {status}</p>\r\n      <ul>\r\n        {messages.map((message) => (\r\n          <li key={message}>{message}</li>\r\n        ))}\r\n      </ul>\r\n    </section>\r\n  );\r\n}\r\n```\r\n\r\n---\r\n\r\n## Chunked streaming (new in 0.9.0)\r\n\r\n`@aegis-fluxion/core@0.9.0` adds secure chunked stream transport for large payloads.\r\n\r\n### Supported stream sources\r\n\r\n- `Buffer`\r\n- `Uint8Array`\r\n- `Readable`\r\n- `AsyncIterable<Buffer | Uint8Array | ArrayBuffer>`\r\n\r\n### Stream APIs\r\n\r\n- Client outbound: `client.emitStream(event, source, options?)`\r\n- Client inbound: `client.onStream(event, handler)`\r\n- Server outbound: `server.emitStreamTo(clientId, event, source, options?)`\r\n- Server inbound: `server.onStream(event, handler)`\r\n- Per-client server outbound helper: `serverClient.emitStream(event, source, options?)`\r\n\r\n### Options\r\n\r\n- `chunkSizeBytes` (default `64 * 1024`, max `1024 * 1024`)\r\n- `metadata` (optional object attached to the stream start frame)\r\n- `totalBytes` (optional size hint; required when source size is unknown and you want announced size)\r\n- `signal` (`AbortSignal` to cancel transfer)\r\n\r\n### Example\r\n\r\n```ts\r\nimport { Readable } from \"node:stream\";\r\nimport { SecureClient, SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst server = new SecureServer({ host: \"127.0.0.1\", port: 8080 });\r\nconst client = new SecureClient(\"ws://127.0.0.1:8080\");\r\n\r\nserver.onStream(\"media:upload\", async (stream, info, peer) => {\r\n  const chunks: Buffer[] = [];\r\n\r\n  for await (const chunk of stream) {\r\n    chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\r\n  }\r\n\r\n  const uploaded = Buffer.concat(chunks);\r\n\r\n  await peer.emitStream(\"media:download\", Readable.from(uploaded), {\r\n    chunkSizeBytes: 64 * 1024,\r\n    totalBytes: uploaded.length,\r\n    metadata: { direction: \"server-to-client\" }\r\n  });\r\n\r\n  console.log(\"Server received stream\", {\r\n    streamId: info.streamId,\r\n    announcedTotalBytes: info.totalBytes,\r\n    receivedBytes: uploaded.length\r\n  });\r\n});\r\n\r\nclient.on(\"ready\", async () => {\r\n  const payload = Buffer.from(\"chunked secure payload\");\r\n\r\n  const result = await client.emitStream(\"media:upload\", payload, {\r\n    chunkSizeBytes: 64 * 1024,\r\n    totalBytes: payload.length,\r\n    metadata: { direction: \"client-to-server\" }\r\n  });\r\n\r\n  console.log(result); // { streamId, chunkCount, totalBytes }\r\n});\r\n```\r\n\r\nEach chunk is delivered inside reserved internal `start/chunk/end/abort` frames and encrypted\r\nthrough the same AES-256-GCM channel used by standard events.\r\n\r\n---\r\n\r\n## Session resumption (TLS 1.3-style)\r\n\r\n`@aegis-fluxion/core@0.8.0` introduced secure resume-first reconnect behavior:\r\n\r\n- Full handshake path uses ephemeral ECDH (`hello` frame).\r\n- Resume path uses ticket-bound proofs (`resume` / `resume-ack` frames).\r\n- Successful resumes derive fresh channel keys from ticket secret + client nonce.\r\n- Servers enforce ticket TTL, bounded cache size, and one-time ticket consumption.\r\n- Clients automatically fall back to full handshake when resume is rejected.\r\n\r\n### Server configuration\r\n\r\n```ts\r\nimport { SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst server = new SecureServer({\r\n  host: \"127.0.0.1\",\r\n  port: 8080,\r\n  sessionResumption: {\r\n    enabled: true,\r\n    ticketTtlMs: 60_000,\r\n    maxCachedTickets: 10_000\r\n  }\r\n});\r\n```\r\n\r\n### Client configuration\r\n\r\n```ts\r\nimport { SecureClient } from \"@aegis-fluxion/core\";\r\n\r\nconst client = new SecureClient(\"ws://127.0.0.1:8080\", {\r\n  reconnect: true,\r\n  sessionResumption: {\r\n    enabled: true,\r\n    maxAcceptedTicketTtlMs: 60_000\r\n  }\r\n});\r\n```\r\n\r\n### Security model\r\n\r\n- Resume proofs are validated with HMAC and constant-time comparison.\r\n- Resume tickets are encrypted in transit (same channel protections as all payloads).\r\n- Resume tickets are discarded if expired, policy-invalid, or already consumed.\r\n- Reserved internal events (e.g., session-ticket transport) cannot be emitted by user code.\r\n\r\n---\r\n\r\n## SecureServer adapter API (horizontal scaling)\r\n\r\n### Core types\r\n\r\n```ts\r\nexport interface SecureServerAdapterMessage {\r\n  version: 1;\r\n  originServerId: string;\r\n  scope: \"broadcast\" | \"room\";\r\n  event: string;\r\n  data: unknown;\r\n  emittedAt: number;\r\n  room?: string;\r\n}\r\n\r\nexport interface SecureServerAdapter {\r\n  attach(server: SecureServer): void | Promise<void>;\r\n  publish(message: SecureServerAdapterMessage): void | Promise<void>;\r\n  detach?(server: SecureServer): void | Promise<void>;\r\n}\r\n```\r\n\r\n### SecureServer hooks\r\n\r\n- constructor option: `new SecureServer({ ..., adapter })`\r\n- runtime binding: `await server.setAdapter(adapter)`\r\n- inbound relay: `await server.handleAdapterMessage(message)`\r\n- instance identity: `server.serverId`\r\n\r\n### Message normalization helper\r\n\r\n```ts\r\nimport { normalizeSecureServerAdapterMessage } from \"@aegis-fluxion/core\";\r\n```\r\n\r\nUse it in adapters before delivering inbound Pub/Sub payloads to `SecureServer`.\r\n\r\n---\r\n\r\n## Adapter integration example\r\n\r\n```ts\r\nimport {\r\n  SecureServer,\r\n  type SecureServerAdapter,\r\n  type SecureServerAdapterMessage\r\n} from \"@aegis-fluxion/core\";\r\n\r\nclass InMemoryAdapter implements SecureServerAdapter {\r\n  private static readonly peers = new Set<InMemoryAdapter>();\r\n  private server: SecureServer | null = null;\r\n\r\n  async attach(server: SecureServer): Promise<void> {\r\n    this.server = server;\r\n    InMemoryAdapter.peers.add(this);\r\n  }\r\n\r\n  async publish(message: SecureServerAdapterMessage): Promise<void> {\r\n    for (const peer of InMemoryAdapter.peers) {\r\n      if (peer === this || !peer.server) {\r\n        continue;\r\n      }\r\n\r\n      await peer.server.handleAdapterMessage(message);\r\n    }\r\n  }\r\n\r\n  async detach(server: SecureServer): Promise<void> {\r\n    if (this.server !== server) {\r\n      return;\r\n    }\r\n\r\n    this.server = null;\r\n    InMemoryAdapter.peers.delete(this);\r\n  }\r\n}\r\n\r\nconst server = new SecureServer({\r\n  host: \"127.0.0.1\",\r\n  port: 8080,\r\n  adapter: new InMemoryAdapter()\r\n});\r\n```\r\n\r\n---\r\n\r\n## Middleware and ACK example\r\n\r\n```ts\r\nimport { SecureClient, SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst server = new SecureServer({ host: \"127.0.0.1\", port: 8080 });\r\n\r\nserver.use(async (context, next) => {\r\n  if (context.phase === \"connection\") {\r\n    context.metadata.set(\"auth.role\", \"operator\");\r\n  }\r\n\r\n  await next();\r\n});\r\n\r\nserver.on(\"jobs:create\", async (payload, client) => {\r\n  return {\r\n    ok: true,\r\n    role: client.metadata.get(\"auth.role\"),\r\n    payload\r\n  };\r\n});\r\n\r\nconst client = new SecureClient(\"ws://127.0.0.1:8080\");\r\n\r\nclient.on(\"ready\", async () => {\r\n  const response = await client.emit(\"jobs:create\", { id: \"job-42\" }, { timeoutMs: 1200 });\r\n  console.log(response);\r\n});\r\n```\r\n\r\n---\r\n\r\n## Rate limiting and DDoS shield\r\n\r\n```ts\r\nimport { SecureServer } from \"@aegis-fluxion/core\";\r\n\r\nconst server = new SecureServer({\r\n  host: \"127.0.0.1\",\r\n  port: 8080,\r\n  rateLimit: {\r\n    enabled: true,\r\n    windowMs: 1_000,\r\n    maxEventsPerConnection: 120,\r\n    maxEventsPerIp: 300,\r\n    action: \"throttle\", // or \"disconnect\"\r\n    throttleMs: 150,\r\n    maxThrottleMs: 2_000,\r\n    disconnectAfterViolations: 4,\r\n    disconnectCode: 1013,\r\n    disconnectReason: \"Rate limit exceeded. Please retry later.\"\r\n  }\r\n});\r\n```\r\n\r\n---\r\n\r\n## Binary payload support\r\n\r\nSupported encrypted payload types:\r\n\r\n- `Buffer`\r\n- `Uint8Array`\r\n- `Blob`\r\n\r\nBinary fields can be nested in standard JSON objects and arrays.\r\n\r\n---\r\n\r\n## Development\r\n\r\nFrom repository root:\r\n\r\n```bash\r\nnpm run typecheck -w @aegis-fluxion/core\r\nnpm run test -w @aegis-fluxion/core\r\nnpm run build -w @aegis-fluxion/core\r\n```\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}