@venizia/ignis-docs 0.0.5 → 0.0.6-1

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.
Files changed (123) hide show
  1. package/package.json +1 -1
  2. package/wiki/best-practices/architectural-patterns.md +0 -2
  3. package/wiki/best-practices/architecture-decisions.md +0 -8
  4. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  5. package/wiki/best-practices/code-style-standards/index.md +0 -1
  6. package/wiki/best-practices/code-style-standards/tooling.md +0 -3
  7. package/wiki/best-practices/contribution-workflow.md +12 -12
  8. package/wiki/best-practices/index.md +4 -14
  9. package/wiki/best-practices/performance-optimization.md +3 -3
  10. package/wiki/best-practices/security-guidelines.md +2 -2
  11. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  12. package/wiki/guides/core-concepts/application/bootstrapping.md +6 -7
  13. package/wiki/guides/core-concepts/components-guide.md +1 -1
  14. package/wiki/guides/core-concepts/components.md +2 -2
  15. package/wiki/guides/core-concepts/dependency-injection.md +4 -5
  16. package/wiki/guides/core-concepts/persistent/datasources.md +4 -5
  17. package/wiki/guides/core-concepts/services.md +1 -1
  18. package/wiki/guides/get-started/5-minute-quickstart.md +4 -5
  19. package/wiki/guides/get-started/philosophy.md +12 -24
  20. package/wiki/guides/index.md +2 -9
  21. package/wiki/guides/reference/mcp-docs-server.md +13 -13
  22. package/wiki/guides/tutorials/building-a-crud-api.md +10 -10
  23. package/wiki/guides/tutorials/complete-installation.md +11 -12
  24. package/wiki/guides/tutorials/ecommerce-api.md +3 -3
  25. package/wiki/guides/tutorials/realtime-chat.md +6 -6
  26. package/wiki/guides/tutorials/testing.md +4 -5
  27. package/wiki/index.md +8 -14
  28. package/wiki/references/base/bootstrapping.md +0 -3
  29. package/wiki/references/base/components.md +2 -2
  30. package/wiki/references/base/controllers.md +0 -1
  31. package/wiki/references/base/datasources.md +1 -1
  32. package/wiki/references/base/dependency-injection.md +2 -2
  33. package/wiki/references/base/filter-system/default-filter.md +2 -3
  34. package/wiki/references/base/filter-system/index.md +1 -1
  35. package/wiki/references/base/filter-system/quick-reference.md +0 -14
  36. package/wiki/references/base/middlewares.md +0 -8
  37. package/wiki/references/base/providers.md +0 -9
  38. package/wiki/references/base/repositories/advanced.md +1 -1
  39. package/wiki/references/base/repositories/mixins.md +2 -3
  40. package/wiki/references/base/services.md +0 -1
  41. package/wiki/references/components/authentication/api.md +444 -0
  42. package/wiki/references/components/authentication/errors.md +177 -0
  43. package/wiki/references/components/authentication/index.md +571 -0
  44. package/wiki/references/components/authentication/usage.md +781 -0
  45. package/wiki/references/components/health-check.md +292 -103
  46. package/wiki/references/components/index.md +14 -12
  47. package/wiki/references/components/mail/api.md +505 -0
  48. package/wiki/references/components/mail/errors.md +176 -0
  49. package/wiki/references/components/mail/index.md +535 -0
  50. package/wiki/references/components/mail/usage.md +404 -0
  51. package/wiki/references/components/request-tracker.md +229 -25
  52. package/wiki/references/components/socket-io/api.md +1051 -0
  53. package/wiki/references/components/socket-io/errors.md +119 -0
  54. package/wiki/references/components/socket-io/index.md +410 -0
  55. package/wiki/references/components/socket-io/usage.md +322 -0
  56. package/wiki/references/components/static-asset/api.md +261 -0
  57. package/wiki/references/components/static-asset/errors.md +89 -0
  58. package/wiki/references/components/static-asset/index.md +617 -0
  59. package/wiki/references/components/static-asset/usage.md +364 -0
  60. package/wiki/references/components/swagger.md +390 -110
  61. package/wiki/references/components/template/api-page.md +125 -0
  62. package/wiki/references/components/template/errors-page.md +100 -0
  63. package/wiki/references/components/template/index.md +104 -0
  64. package/wiki/references/components/template/setup-page.md +134 -0
  65. package/wiki/references/components/template/single-page.md +132 -0
  66. package/wiki/references/components/template/usage-page.md +127 -0
  67. package/wiki/references/components/websocket/api.md +508 -0
  68. package/wiki/references/components/websocket/errors.md +123 -0
  69. package/wiki/references/components/websocket/index.md +453 -0
  70. package/wiki/references/components/websocket/usage.md +475 -0
  71. package/wiki/references/helpers/cron/index.md +224 -0
  72. package/wiki/references/helpers/crypto/index.md +537 -0
  73. package/wiki/references/helpers/env/index.md +214 -0
  74. package/wiki/references/helpers/error/index.md +232 -0
  75. package/wiki/references/helpers/index.md +16 -15
  76. package/wiki/references/helpers/inversion/index.md +608 -0
  77. package/wiki/references/helpers/logger/index.md +600 -0
  78. package/wiki/references/helpers/network/api.md +986 -0
  79. package/wiki/references/helpers/network/index.md +620 -0
  80. package/wiki/references/helpers/queue/index.md +589 -0
  81. package/wiki/references/helpers/redis/index.md +495 -0
  82. package/wiki/references/helpers/socket-io/api.md +497 -0
  83. package/wiki/references/helpers/socket-io/index.md +513 -0
  84. package/wiki/references/helpers/storage/api.md +705 -0
  85. package/wiki/references/helpers/storage/index.md +583 -0
  86. package/wiki/references/helpers/template/index.md +66 -0
  87. package/wiki/references/helpers/template/single-page.md +126 -0
  88. package/wiki/references/helpers/testing/index.md +510 -0
  89. package/wiki/references/helpers/types/index.md +512 -0
  90. package/wiki/references/helpers/uid/index.md +272 -0
  91. package/wiki/references/helpers/websocket/api.md +736 -0
  92. package/wiki/references/helpers/websocket/index.md +574 -0
  93. package/wiki/references/helpers/worker-thread/index.md +470 -0
  94. package/wiki/references/index.md +2 -9
  95. package/wiki/references/quick-reference.md +3 -18
  96. package/wiki/references/utilities/jsx.md +1 -8
  97. package/wiki/references/utilities/statuses.md +0 -7
  98. package/wiki/references/components/authentication.md +0 -476
  99. package/wiki/references/components/mail.md +0 -687
  100. package/wiki/references/components/socket-io.md +0 -562
  101. package/wiki/references/components/static-asset.md +0 -1277
  102. package/wiki/references/helpers/cron.md +0 -108
  103. package/wiki/references/helpers/crypto.md +0 -132
  104. package/wiki/references/helpers/env.md +0 -83
  105. package/wiki/references/helpers/error.md +0 -97
  106. package/wiki/references/helpers/inversion.md +0 -176
  107. package/wiki/references/helpers/logger.md +0 -296
  108. package/wiki/references/helpers/network.md +0 -396
  109. package/wiki/references/helpers/queue.md +0 -150
  110. package/wiki/references/helpers/redis.md +0 -142
  111. package/wiki/references/helpers/socket-io.md +0 -932
  112. package/wiki/references/helpers/storage.md +0 -665
  113. package/wiki/references/helpers/testing.md +0 -133
  114. package/wiki/references/helpers/types.md +0 -167
  115. package/wiki/references/helpers/uid.md +0 -167
  116. package/wiki/references/helpers/worker-thread.md +0 -178
  117. package/wiki/references/src-details/boot.md +0 -379
  118. package/wiki/references/src-details/core.md +0 -263
  119. package/wiki/references/src-details/dev-configs.md +0 -298
  120. package/wiki/references/src-details/docs.md +0 -71
  121. package/wiki/references/src-details/helpers.md +0 -211
  122. package/wiki/references/src-details/index.md +0 -86
  123. package/wiki/references/src-details/inversion.md +0 -340
@@ -0,0 +1,119 @@
1
+ # Socket.IO -- Error Reference
2
+
3
+ > Error conditions, failure messages, and troubleshooting for the Socket.IO component, server helper, and client helper.
4
+
5
+ ## Error Conditions
6
+
7
+ ### Component Errors
8
+
9
+ | Method | Condition | Error Message |
10
+ |--------|-----------|---------------|
11
+ | `binding()` | `application` is falsy | `"[binding] Invalid application to bind SocketIOComponent"` |
12
+ | `binding()` | Unsupported runtime | `"[SocketIOComponent] Unsupported runtime: <runtime>"` |
13
+ | `resolveBindings()` | `REDIS_CONNECTION` not instanceof `DefaultRedisHelper` | `"Invalid instance of redisConnection | Please init connection with RedisHelper for single redis connection or RedisClusterHelper for redis cluster mode!"` |
14
+ | `resolveBindings()` | `AUTHENTICATE_HANDLER` is falsy | `"[DANGER][SocketIOComponent] Invalid authenticateFn to setup io socket server!"` |
15
+ | `registerNodeHook()` | HTTP server not available | `"[SocketIOComponent] HTTP server not available for Node.js runtime!"` |
16
+
17
+ ### Server Helper Errors
18
+
19
+ | Method | Condition | Error Message |
20
+ |--------|-----------|---------------|
21
+ | `setRuntime()` | Node.js runtime, `server` missing | `"[SocketIOServerHelper] Invalid HTTP server for Node.js runtime!"` |
22
+ | `setRuntime()` | Bun runtime, `engine` missing | `"[SocketIOServerHelper] Invalid @socket.io/bun-engine instance for Bun runtime!"` |
23
+ | `setRuntime()` | Unknown runtime | `"[SocketIOServerHelper] Unsupported runtime!"` |
24
+ | `initRedisClients()` | `redisConnection` is falsy | `"Invalid redis connection to config socket.io adapter!"` |
25
+ | `initIOServer()` | Node.js runtime, `server` missing at configure time | `"[DANGER] Invalid HTTP server instance to init Socket.io server!"` |
26
+ | `initIOServer()` | Bun runtime, `engine` missing at configure time | `"[DANGER] Invalid @socket.io/bun-engine instance to init Socket.io server!"` |
27
+ | `initIOServer()` | Unknown runtime at configure time | `"[configure] Unsupported runtime: <runtime>"` |
28
+ | `getEngine()` | Runtime is not Bun | `"[getEngine] Engine is only available for Bun runtime!"` |
29
+ | `on()` | `topic` is empty | `"[on] Invalid topic to start binding handler"` |
30
+ | `on()` | `handler` is falsy | `"[on] Invalid event handler | topic: <topic>"` |
31
+ | `on()` | IO server not initialized | `"[on] IOServer is not initialized yet!"` |
32
+
33
+ ### Client Helper Errors
34
+
35
+ | Method | Condition | Error Message |
36
+ |--------|-----------|---------------|
37
+ | `emit()` | Socket not connected | `"Invalid socket client state to emit"` (statusCode: 400) |
38
+ | `emit()` | `topic` is falsy | `"Topic is required to emit"` (statusCode: 400) |
39
+
40
+ ### Server Authentication Errors (sent to client)
41
+
42
+ | Condition | Event | Message |
43
+ |-----------|-------|---------|
44
+ | `authenticateFn` returned `false` | `unauthenticated` | `"Invalid token to authenticate! Please login again!"` |
45
+ | `authenticateFn` threw an error | `unauthenticated` | `"Failed to authenticate connection! Please login again!"` |
46
+
47
+ ## Troubleshooting
48
+
49
+ ### "SocketIO not initialized"
50
+
51
+ **Cause**: You're trying to use `SocketIOServerHelper` before the server has started (e.g., during DI construction).
52
+
53
+ **Fix**: Use the lazy getter pattern shown in the [Usage & Examples](./usage) page. Never `@inject` `SOCKET_IO_INSTANCE` directly in a constructor -- it doesn't exist yet at construction time.
54
+
55
+ ### "Invalid instance of redisConnection"
56
+
57
+ **Cause**: The value bound to `REDIS_CONNECTION` is not an instance of `DefaultRedisHelper` (or its subclasses `RedisHelper` / `RedisClusterHelper`).
58
+
59
+ **Fix**: Use `RedisHelper` (single instance) or `RedisClusterHelper` (cluster mode):
60
+
61
+ ```typescript
62
+ // Correct -- single instance
63
+ this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION })
64
+ .toValue(new RedisHelper({ name: 'socket-io', host, port, password }));
65
+
66
+ // Correct -- cluster mode
67
+ this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION })
68
+ .toValue(new RedisClusterHelper({ name: 'socket-io', nodes, password }));
69
+
70
+ // Wrong -- raw ioredis client
71
+ this.bind({ key: SocketIOBindingKeys.REDIS_CONNECTION })
72
+ .toValue(new Redis(6379)); // This is NOT a DefaultRedisHelper!
73
+ ```
74
+
75
+ ### "Cannot find module '@socket.io/bun-engine'"
76
+
77
+ **Cause**: Running on Bun runtime without the optional peer dependency installed.
78
+
79
+ **Fix**: `bun add @socket.io/bun-engine`
80
+
81
+ ### Socket.IO connects but events aren't received
82
+
83
+ **Cause**: Clients must emit `authenticate` after connecting. Unauthenticated clients are disconnected after the timeout (default: 10 seconds).
84
+
85
+ **Fix**: Ensure your client emits the authenticate event:
86
+
87
+ ```typescript
88
+ socket.on('connect', () => {
89
+ socket.emit('authenticate');
90
+ });
91
+
92
+ socket.on('authenticated', (data) => {
93
+ // Now ready to send/receive events
94
+ });
95
+ ```
96
+
97
+ ### "Invalid socket client state to emit"
98
+
99
+ **Cause**: Calling `emit()` on `SocketIOClientHelper` when the socket is not connected.
100
+
101
+ **Fix**: Ensure the socket is connected before emitting. Check `client.getSocketClient().connected` or wait for the `onConnected` callback.
102
+
103
+ ### Client disconnects immediately after connecting
104
+
105
+ **Cause**: The authentication timeout expired (default: 10 seconds). The client connected but did not emit `authenticate` in time.
106
+
107
+ **Fix**: Emit `authenticate` immediately on connect, or increase the `authenticateTimeout` in the server helper options.
108
+
109
+ ### Room join requests are silently rejected
110
+
111
+ **Cause**: No `validateRoomFn` is bound. Without a validation function, all room join requests are rejected by design (security-by-default).
112
+
113
+ **Fix**: Bind a `VALIDATE_ROOM_HANDLER` that returns the list of allowed rooms.
114
+
115
+ ## See Also
116
+
117
+ - [Setup & Configuration](./) -- Quick reference, installation, bindings, constants
118
+ - [Usage & Examples](./usage) -- Server-side usage, client helper, advanced patterns
119
+ - [API Reference](./api) -- Architecture, method signatures, internals, types
@@ -0,0 +1,410 @@
1
+ # Socket.IO -- Setup & Configuration
2
+
3
+ > Real-time, bidirectional, event-based communication using Socket.IO -- with automatic runtime detection for both Node.js and Bun.
4
+
5
+ ## Quick Reference
6
+
7
+ | Item | Value |
8
+ |------|-------|
9
+ | **Package** | `@venizia/ignis` (core) |
10
+ | **Class** | `SocketIOComponent` |
11
+ | **Server Helper** | [`SocketIOServerHelper`](/references/helpers/socket-io/) |
12
+ | **Client Helper** | [`SocketIOClientHelper`](/references/helpers/socket-io/) |
13
+ | **Runtimes** | Node.js (`@hono/node-server`) and Bun (native) |
14
+ | **Scaling** | `@socket.io/redis-adapter` + `@socket.io/redis-emitter` |
15
+
16
+ #### Import Paths
17
+ ```typescript
18
+ import {
19
+ SocketIOComponent,
20
+ SocketIOBindingKeys,
21
+ SocketIOServerHelper,
22
+ RedisHelper,
23
+ } from '@venizia/ignis';
24
+
25
+ import {
26
+ SocketIOClientHelper,
27
+ SocketIOConstants,
28
+ SocketIOClientStates,
29
+ } from '@venizia/ignis-helpers/socket-io';
30
+
31
+ import type {
32
+ IServerOptions,
33
+ TSocketIOAuthenticateFn,
34
+ TSocketIOValidateRoomFn,
35
+ TSocketIOClientConnectedFn,
36
+ ISocketIOClientOptions,
37
+ IOptions,
38
+ TSocketIOEventHandler,
39
+ TSocketIOClientState,
40
+ } from '@venizia/ignis';
41
+ ```
42
+
43
+ ### Use Cases
44
+
45
+ - Live notifications and alerts
46
+ - Real-time chat and messaging
47
+ - Collaborative editing (docs, whiteboards)
48
+ - Live data streams (dashboards, monitoring)
49
+ - Multiplayer game state synchronization
50
+ - Service-to-service real-time communication (via `SocketIOClientHelper`)
51
+
52
+ ## Server Helper Setup
53
+
54
+ ### Step 1: Install Dependencies
55
+
56
+ ```bash
57
+ # Core dependency (already included via @venizia/ignis)
58
+ # ioredis is required for the Redis adapter
59
+
60
+ # For Bun runtime only -- optional peer dependency
61
+ bun add @socket.io/bun-engine
62
+ ```
63
+
64
+ ### Step 2: Bind Required Services
65
+
66
+ In your application's `preConfigure()` method, bind the required services and register the component:
67
+
68
+ ```typescript
69
+ import {
70
+ BaseApplication,
71
+ SocketIOComponent,
72
+ SocketIOBindingKeys,
73
+ RedisHelper,
74
+ TSocketIOAuthenticateFn,
75
+ TSocketIOValidateRoomFn,
76
+ TSocketIOClientConnectedFn,
77
+ ValueOrPromise,
78
+ } from '@venizia/ignis';
79
+
80
+ export class Application extends BaseApplication {
81
+ private redisHelper: RedisHelper;
82
+
83
+ preConfigure(): ValueOrPromise<void> {
84
+ this.setupSocketIO();
85
+ // ... other setup
86
+ }
87
+
88
+ setupSocketIO() {
89
+ // 1. Redis connection (required for adapter + emitter)
90
+ this.redisHelper = new RedisHelper({
91
+ name: 'socket-io-redis',
92
+ host: process.env.REDIS_HOST ?? 'localhost',
93
+ port: +(process.env.REDIS_PORT ?? 6379),
94
+ password: process.env.REDIS_PASSWORD,
95
+ autoConnect: false,
96
+ });
97
+
98
+ this.bind<RedisHelper>({
99
+ key: SocketIOBindingKeys.REDIS_CONNECTION,
100
+ }).toValue(this.redisHelper);
101
+
102
+ // 2. Authentication handler (required)
103
+ const authenticateFn: TSocketIOAuthenticateFn = handshake => {
104
+ const token = handshake.headers.authorization;
105
+ // Implement your auth logic -- JWT verification, session check, etc.
106
+ return !!token;
107
+ };
108
+
109
+ this.bind<TSocketIOAuthenticateFn>({
110
+ key: SocketIOBindingKeys.AUTHENTICATE_HANDLER,
111
+ }).toValue(authenticateFn);
112
+
113
+ // 3. Room validation handler (optional -- joins rejected without this)
114
+ const validateRoomFn: TSocketIOValidateRoomFn = ({ socket, rooms }) => {
115
+ // Return the rooms that the client is allowed to join
116
+ const allowedRooms = rooms.filter(room => room.startsWith('public-'));
117
+ return allowedRooms;
118
+ };
119
+
120
+ this.bind<TSocketIOValidateRoomFn>({
121
+ key: SocketIOBindingKeys.VALIDATE_ROOM_HANDLER,
122
+ }).toValue(validateRoomFn);
123
+
124
+ // 4. Client connected handler (optional)
125
+ const clientConnectedFn: TSocketIOClientConnectedFn = ({ socket }) => {
126
+ console.log('Client connected:', socket.id);
127
+ // Register custom event handlers on the socket
128
+ };
129
+
130
+ this.bind<TSocketIOClientConnectedFn>({
131
+ key: SocketIOBindingKeys.CLIENT_CONNECTED_HANDLER,
132
+ }).toValue(clientConnectedFn);
133
+
134
+ // 5. Register the component -- that's it!
135
+ this.component(SocketIOComponent);
136
+ }
137
+ }
138
+ ```
139
+
140
+ #### `autoConnect: false` Rationale
141
+
142
+ The `RedisHelper` is created with `autoConnect: false` because the server helper internally calls `client.duplicate()` to create 3 independent Redis connections (pub, sub, emitter). The duplicated clients inherit the `lazyConnect` setting from the parent. During `configure()`, the helper detects clients in `wait` status and explicitly calls `client.connect()` on each, then awaits all 3 to reach `ready` status before proceeding. This avoids race conditions where the parent connects before the duplicates are created.
143
+
144
+ #### Redis Connection Alternatives
145
+
146
+ You can use either `RedisHelper` (single Redis instance) or `RedisClusterHelper` (Redis Cluster mode). Both extend `DefaultRedisHelper`, which is the type the component validates against:
147
+
148
+ ```typescript
149
+ import { RedisClusterHelper } from '@venizia/ignis';
150
+
151
+ // For Redis Cluster deployments
152
+ const redisHelper = new RedisClusterHelper({
153
+ name: 'socket-io-redis-cluster',
154
+ nodes: [
155
+ { host: 'redis-node-1', port: 6379 },
156
+ { host: 'redis-node-2', port: 6380 },
157
+ { host: 'redis-node-3', port: 6381 },
158
+ ],
159
+ password: process.env.REDIS_PASSWORD,
160
+ autoConnect: false,
161
+ });
162
+
163
+ this.bind<RedisClusterHelper>({
164
+ key: SocketIOBindingKeys.REDIS_CONNECTION,
165
+ }).toValue(redisHelper);
166
+ ```
167
+
168
+ The internal `TRedisClient` type is `Redis | Cluster`, so both ioredis connection types are supported transparently.
169
+
170
+ ## Configuration
171
+
172
+ ### Default Server Options
173
+
174
+ The component applies these defaults if `SocketIOBindingKeys.SERVER_OPTIONS` is not bound or partially overridden:
175
+
176
+ | Option | Default | Description |
177
+ |--------|---------|-------------|
178
+ | `identifier` | `'SOCKET_IO_SERVER'` | Unique identifier for the helper instance |
179
+ | `path` | `'/io'` | URL path for Socket.IO handshake/polling |
180
+ | `cors.origin` | `'*'` | Allowed origins (restrict in production!) |
181
+ | `cors.methods` | `['GET', 'POST']` | Allowed HTTP methods for CORS preflight |
182
+ | `cors.preflightContinue` | `false` | Pass preflight to next handler |
183
+ | `cors.optionsSuccessStatus` | `204` | Status code for successful OPTIONS requests |
184
+ | `cors.credentials` | `true` | Allow cookies/auth headers |
185
+ | `perMessageDeflate.threshold` | `4096` | Minimum message size to compress (bytes) |
186
+ | `perMessageDeflate.concurrencyLimit` | `20` | Max concurrent compression operations |
187
+ | `perMessageDeflate.clientNoContextTakeover` | `true` | Client releases compression context after each message |
188
+ | `perMessageDeflate.serverNoContextTakeover` | `true` | Server releases compression context after each message |
189
+ | `perMessageDeflate.serverMaxWindowBits` | `10` | Server-side maximum window size (2^10 = 1KB) |
190
+
191
+ > [!WARNING]
192
+ > The default `cors.origin: '*'` is suitable for development only. In production, restrict this to your specific domains.
193
+
194
+ #### Full `DEFAULT_SERVER_OPTIONS`
195
+ ```typescript
196
+ const DEFAULT_SERVER_OPTIONS: Partial<IServerOptions> = {
197
+ identifier: 'SOCKET_IO_SERVER',
198
+ path: '/io',
199
+ cors: {
200
+ origin: '*',
201
+ methods: ['GET', 'POST'],
202
+ preflightContinue: false,
203
+ optionsSuccessStatus: 204,
204
+ credentials: true,
205
+ },
206
+ perMessageDeflate: {
207
+ threshold: 4096,
208
+ zlibDeflateOptions: { chunkSize: 10 * 1024 },
209
+ zlibInflateOptions: { windowBits: 12, memLevel: 8 },
210
+ clientNoContextTakeover: true,
211
+ serverNoContextTakeover: true,
212
+ serverMaxWindowBits: 10,
213
+ concurrencyLimit: 20,
214
+ },
215
+ };
216
+ ```
217
+
218
+ ### Custom Configuration
219
+
220
+ Bind custom server options before registering the component:
221
+
222
+ ```typescript
223
+ import { SocketIOBindingKeys, IServerOptions } from '@venizia/ignis';
224
+
225
+ const customOptions: Partial<IServerOptions> = {
226
+ identifier: 'my-app-socket',
227
+ path: '/socket.io',
228
+ cors: {
229
+ origin: ['https://myapp.com', 'https://admin.myapp.com'],
230
+ methods: ['GET', 'POST'],
231
+ credentials: true,
232
+ },
233
+ pingTimeout: 60000,
234
+ pingInterval: 25000,
235
+ maxHttpBufferSize: 1e6, // 1MB
236
+ };
237
+
238
+ this.bind<Partial<IServerOptions>>({
239
+ key: SocketIOBindingKeys.SERVER_OPTIONS,
240
+ }).toValue(customOptions);
241
+
242
+ this.component(SocketIOComponent);
243
+ ```
244
+
245
+ ## Binding Keys
246
+
247
+ All binding keys are available in `SocketIOBindingKeys`:
248
+
249
+ | Binding Key | Constant | Type | Required | Default |
250
+ |------------|----------|------|----------|---------|
251
+ | `@app/socket-io/server-options` | `SERVER_OPTIONS` | `Partial<IServerOptions>` | No | See defaults above |
252
+ | `@app/socket-io/redis-connection` | `REDIS_CONNECTION` | `RedisHelper` / `RedisClusterHelper` / `DefaultRedisHelper` | **Yes** | `null` |
253
+ | `@app/socket-io/authenticate-handler` | `AUTHENTICATE_HANDLER` | `TSocketIOAuthenticateFn` | **Yes** | `null` |
254
+ | `@app/socket-io/validate-room-handler` | `VALIDATE_ROOM_HANDLER` | `TSocketIOValidateRoomFn` | No | `null` |
255
+ | `@app/socket-io/client-connected-handler` | `CLIENT_CONNECTED_HANDLER` | `TSocketIOClientConnectedFn` | No | `null` |
256
+ | `@app/socket-io/instance` | `SOCKET_IO_INSTANCE` | `SocketIOServerHelper` | -- | *Set by component* |
257
+
258
+ > [!NOTE]
259
+ > `SOCKET_IO_INSTANCE` is **not** set by you -- the component creates and binds it automatically after the server starts. Inject it in services/controllers to interact with Socket.IO.
260
+
261
+ ## Constants
262
+
263
+ Constants are exported from `@venizia/ignis-helpers/socket-io` and used internally by both the component and the helper.
264
+
265
+ ### System Events
266
+
267
+ | Constant | Value | Description |
268
+ |----------|-------|-------------|
269
+ | `SocketIOConstants.EVENT_PING` | `'ping'` | Keep-alive ping emitted at `pingInterval` (default: 30s) |
270
+ | `SocketIOConstants.EVENT_CONNECT` | `'connection'` | New client connected (server-side event) |
271
+ | `SocketIOConstants.EVENT_DISCONNECT` | `'disconnect'` | Client disconnected |
272
+ | `SocketIOConstants.EVENT_JOIN` | `'join'` | Client requests to join room(s) |
273
+ | `SocketIOConstants.EVENT_LEAVE` | `'leave'` | Client requests to leave room(s) |
274
+ | `SocketIOConstants.EVENT_AUTHENTICATE` | `'authenticate'` | Client sends auth credentials |
275
+ | `SocketIOConstants.EVENT_AUTHENTICATED` | `'authenticated'` | Auth success response sent to client |
276
+ | `SocketIOConstants.EVENT_UNAUTHENTICATE` | `'unauthenticated'` | Auth failure response sent to client |
277
+
278
+ ### Default Rooms
279
+
280
+ All authenticated clients are automatically joined to these rooms:
281
+
282
+ | Constant | Value | Description |
283
+ |----------|-------|-------------|
284
+ | `SocketIOConstants.ROOM_DEFAULT` | `'io-default'` | Default room all authenticated clients join |
285
+ | `SocketIOConstants.ROOM_NOTIFICATION` | `'io-notification'` | Notification broadcast room |
286
+
287
+ > [!TIP]
288
+ > You can override default rooms via the `defaultRooms` option on `SocketIOServerHelper`. The component uses the defaults above when not overridden.
289
+
290
+ ### Internal Constants (Server Helper)
291
+
292
+ These constants are defined at module scope in the server helper and are not exported, but they govern default behavior:
293
+
294
+ | Constant | Value | Description |
295
+ |----------|-------|-------------|
296
+ | `CLIENT_AUTHENTICATE_TIMEOUT` | `10_000` (10s) | Time allowed for a client to authenticate before forced disconnect |
297
+ | `CLIENT_PING_INTERVAL` | `30_000` (30s) | Interval between server-to-client ping emissions |
298
+
299
+ Both can be overridden via the `authenticateTimeout` and `pingInterval` constructor options on `SocketIOServerHelper`.
300
+
301
+ ### Client States
302
+
303
+ Each connected client tracks an authentication state that governs what actions are permitted:
304
+
305
+ | State | Constant | Description |
306
+ |-------|----------|-------------|
307
+ | `unauthorized` | `SocketIOClientStates.UNAUTHORIZED` | Initial state -- client must emit `authenticate` within the timeout (default: 10s) |
308
+ | `authenticating` | `SocketIOClientStates.AUTHENTICATING` | Auth in progress -- `authenticateFn` is executing |
309
+ | `authenticated` | `SocketIOClientStates.AUTHENTICATED` | Auth successful -- client can send/receive events and join rooms |
310
+
311
+ #### State Machine Diagram
312
+ ```
313
+ +------------------+
314
+ connect ---------->| unauthorized |
315
+ +--------+---------+
316
+ | emit('authenticate')
317
+ +--------v---------+
318
+ | authenticating |
319
+ +---+----------+---+
320
+ success | | failure
321
+ +---------v--+ +-------v-----------+
322
+ |authenticated| | unauthorized |--> disconnect
323
+ +-------------+ +------------------+
324
+ ^
325
+ timeout (10s)
326
+ ```
327
+
328
+ #### `SocketIOClientStates` Source
329
+ ```typescript
330
+ export class SocketIOClientStates {
331
+ static readonly UNAUTHORIZED = 'unauthorized';
332
+ static readonly AUTHENTICATING = 'authenticating';
333
+ static readonly AUTHENTICATED = 'authenticated';
334
+
335
+ static readonly SCHEME_SET = new Set([
336
+ this.UNAUTHORIZED,
337
+ this.AUTHENTICATING,
338
+ this.AUTHENTICATED,
339
+ ]);
340
+
341
+ static isValid(input: string): input is TConstValue<typeof SocketIOClientStates> {
342
+ return this.SCHEME_SET.has(input);
343
+ }
344
+ }
345
+ ```
346
+
347
+ ### Resolved Bindings
348
+
349
+ The component resolves all binding keys into a single `IResolvedBindings` object during the `binding()` phase:
350
+
351
+ #### `IResolvedBindings` Interface
352
+ ```typescript
353
+ interface IResolvedBindings {
354
+ redisConnection: DefaultRedisHelper;
355
+ authenticateFn: TSocketIOAuthenticateFn;
356
+ validateRoomFn?: TSocketIOValidateRoomFn;
357
+ clientConnectedFn?: TSocketIOClientConnectedFn;
358
+ }
359
+ ```
360
+
361
+ #### Callback Type Signatures
362
+ ```typescript
363
+ // Called with the socket handshake -- return true to authenticate, false to reject
364
+ type TSocketIOAuthenticateFn = (args: IHandshake) => ValueOrPromise<boolean>;
365
+
366
+ // Called when client emits 'join' -- return the subset of rooms the client is allowed to join
367
+ type TSocketIOValidateRoomFn = (opts: {
368
+ socket: IOSocket;
369
+ rooms: string[];
370
+ }) => ValueOrPromise<string[]>;
371
+
372
+ // Called after successful authentication -- register custom event handlers here
373
+ type TSocketIOClientConnectedFn = (opts: { socket: IOSocket }) => ValueOrPromise<void>;
374
+ ```
375
+
376
+ #### `IHandshake` Interface
377
+ ```typescript
378
+ interface IHandshake {
379
+ headers: IncomingHttpHeaders;
380
+ time: string;
381
+ address: string;
382
+ xdomain: boolean;
383
+ secure: boolean;
384
+ issued: number;
385
+ url: string;
386
+ query: ParsedUrlQuery;
387
+ auth: { [key: string]: any };
388
+ }
389
+ ```
390
+
391
+ ## See Also
392
+
393
+ - [Usage & Examples](./usage) -- Server-side usage, client helper, advanced patterns
394
+ - [API Reference](./api) -- Architecture, method signatures, internals, types
395
+ - [Error Reference](./errors) -- Error conditions and troubleshooting
396
+ - **Guides:**
397
+ - [Components Overview](/guides/core-concepts/components) -- Component system basics
398
+ - [Application](/guides/core-concepts/application/) -- Registering components
399
+ - **Components:**
400
+ - [Components Index](../index) -- All built-in components
401
+ - **Helpers:**
402
+ - [Socket.IO Helper](/references/helpers/socket-io/) -- Full `SocketIOServerHelper` + `SocketIOClientHelper` API reference
403
+ - **External Resources:**
404
+ - [Socket.IO Documentation](https://socket.io/docs/) -- Official docs
405
+ - [Socket.IO Redis Adapter](https://socket.io/docs/v4/redis-adapter/) -- Horizontal scaling guide
406
+ - [@socket.io/bun-engine](https://github.com/socketio/bun-engine) -- Bun runtime support
407
+ - **Tutorials:**
408
+ - [Real-Time Chat](/guides/tutorials/realtime-chat) -- Building a chat app with Socket.IO
409
+ - **Changelog:**
410
+ - [2026-02-06: Socket.IO Integration Fix](/changelogs/2026-02-06-socket-io-integration-fix) -- Lifecycle timing fix + Bun runtime support