ioserver 1.5.3 → 2.0.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.
- package/README.md +244 -287
- package/dist/BaseClasses.d.ts +301 -0
- package/dist/BaseClasses.d.ts.map +1 -0
- package/dist/BaseClasses.js +281 -0
- package/dist/BaseClasses.js.map +1 -0
- package/dist/IOServer.d.ts +260 -0
- package/dist/IOServer.d.ts.map +1 -0
- package/dist/IOServer.js +656 -0
- package/dist/IOServer.js.map +1 -0
- package/dist/IOServerError.d.ts +80 -0
- package/dist/IOServerError.d.ts.map +1 -0
- package/dist/IOServerError.js +85 -0
- package/dist/IOServerError.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -45
- package/build/ioserver.js +0 -580
- package/build/ioserver.js.map +0 -13
package/dist/IOServer.js
ADDED
@@ -0,0 +1,656 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* @fileoverview IOServer - A TypeScript framework for building real-time applications
|
4
|
+
* with Socket.IO and Fastify integration. Provides modular architecture with
|
5
|
+
* Services, Controllers, Managers, and Watchers.
|
6
|
+
*
|
7
|
+
* @author Ben Mz <0x42en@users.noreply.github.com>
|
8
|
+
* @version 2.0.0
|
9
|
+
* @since 1.0.0
|
10
|
+
*/
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
12
|
+
if (k2 === undefined) k2 = k;
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
16
|
+
}
|
17
|
+
Object.defineProperty(o, k2, desc);
|
18
|
+
}) : (function(o, m, k, k2) {
|
19
|
+
if (k2 === undefined) k2 = k;
|
20
|
+
o[k2] = m[k];
|
21
|
+
}));
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
24
|
+
}) : function(o, v) {
|
25
|
+
o["default"] = v;
|
26
|
+
});
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
28
|
+
var ownKeys = function(o) {
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
30
|
+
var ar = [];
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
32
|
+
return ar;
|
33
|
+
};
|
34
|
+
return ownKeys(o);
|
35
|
+
};
|
36
|
+
return function (mod) {
|
37
|
+
if (mod && mod.__esModule) return mod;
|
38
|
+
var result = {};
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
40
|
+
__setModuleDefault(result, mod);
|
41
|
+
return result;
|
42
|
+
};
|
43
|
+
})();
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
46
|
+
};
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
48
|
+
exports.IOServer = void 0;
|
49
|
+
const fs = __importStar(require("fs"));
|
50
|
+
const path = __importStar(require("path"));
|
51
|
+
const promises_1 = require("timers/promises");
|
52
|
+
const fastify_1 = __importDefault(require("fastify"));
|
53
|
+
const socket_io_1 = require("socket.io");
|
54
|
+
const cors_1 = __importDefault(require("@fastify/cors"));
|
55
|
+
const sensible_1 = __importDefault(require("@fastify/sensible"));
|
56
|
+
const IOServerError_1 = require("./IOServerError");
|
57
|
+
/**
|
58
|
+
* Main IOServer class - A framework for building real-time applications
|
59
|
+
*
|
60
|
+
* Combines Fastify HTTP server with Socket.IO for WebSocket support,
|
61
|
+
* providing a modular architecture with Services, Controllers, Managers, and Watchers.
|
62
|
+
*
|
63
|
+
* @example
|
64
|
+
* ```typescript
|
65
|
+
* const server = new IOServer({
|
66
|
+
* host: 'localhost',
|
67
|
+
* port: 3000,
|
68
|
+
* verbose: 'INFO'
|
69
|
+
* });
|
70
|
+
*
|
71
|
+
* server.addService({ service: ChatService });
|
72
|
+
* server.addController({ name: 'api', controller: ApiController });
|
73
|
+
* await server.start();
|
74
|
+
* ```
|
75
|
+
*/
|
76
|
+
class IOServer {
|
77
|
+
/**
|
78
|
+
* Creates a new IOServer instance
|
79
|
+
* @param {IOServerOptions} options - Configuration options for the server
|
80
|
+
*/
|
81
|
+
constructor(options = {}) {
|
82
|
+
this.serviceLists = new Map();
|
83
|
+
this.managerLists = new Map();
|
84
|
+
this.methodLists = new Map();
|
85
|
+
this.watcherLists = new Map();
|
86
|
+
this.controllerLists = new Map();
|
87
|
+
this.middlewareLists = new Map();
|
88
|
+
this.host = options.host || IOServer.DEFAULT_HOST;
|
89
|
+
this.port = this.validatePort(options.port || IOServer.DEFAULT_PORT);
|
90
|
+
this.verbose = this.validateLogLevel(options.verbose || 'ERROR');
|
91
|
+
const defaultRoutes = path.join(process.cwd(), 'routes');
|
92
|
+
this.routesPath =
|
93
|
+
options.routes && fs.existsSync(options.routes)
|
94
|
+
? options.routes
|
95
|
+
: defaultRoutes;
|
96
|
+
const transportModes = this.processTransportModes(options.mode);
|
97
|
+
const corsOptions = this.processCorsOptions(options.cors);
|
98
|
+
const cookieEnabled = Boolean(options.cookie);
|
99
|
+
this.webapp = this.initializeFastify();
|
100
|
+
this.setupPlugins(corsOptions);
|
101
|
+
this.setupSocketIO(transportModes, cookieEnabled, corsOptions);
|
102
|
+
this.appHandle = {
|
103
|
+
send: this.sendTo.bind(this),
|
104
|
+
log: this.log.bind(this),
|
105
|
+
verbose: this.verbose,
|
106
|
+
};
|
107
|
+
}
|
108
|
+
validatePort(port) {
|
109
|
+
const numPort = Number(port);
|
110
|
+
if (isNaN(numPort) || numPort <= 0 || numPort > 65535) {
|
111
|
+
throw new IOServerError_1.IOServerError('Invalid port number', 400);
|
112
|
+
}
|
113
|
+
return numPort;
|
114
|
+
}
|
115
|
+
validateLogLevel(level) {
|
116
|
+
const upperLevel = level.toUpperCase();
|
117
|
+
return IOServer.LOG_LEVELS.includes(upperLevel) ? upperLevel : 'ERROR';
|
118
|
+
}
|
119
|
+
processTransportModes(mode) {
|
120
|
+
if (!mode) {
|
121
|
+
return ['websocket', 'polling'];
|
122
|
+
}
|
123
|
+
const modes = [];
|
124
|
+
if (typeof mode === 'string') {
|
125
|
+
if (IOServer.TRANSPORTS.includes(mode)) {
|
126
|
+
modes.push(mode);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
else if (Array.isArray(mode)) {
|
130
|
+
mode.forEach(m => {
|
131
|
+
if (IOServer.TRANSPORTS.includes(m)) {
|
132
|
+
modes.push(m);
|
133
|
+
}
|
134
|
+
});
|
135
|
+
}
|
136
|
+
return modes.length > 0 ? modes : ['websocket', 'polling'];
|
137
|
+
}
|
138
|
+
processCorsOptions(cors) {
|
139
|
+
const corsConfig = cors || {};
|
140
|
+
if (!corsConfig.methods) {
|
141
|
+
corsConfig.methods = ['GET', 'POST'];
|
142
|
+
}
|
143
|
+
if (!corsConfig.origin) {
|
144
|
+
corsConfig.origin = [`https://${this.host}`, `http://${this.host}`];
|
145
|
+
}
|
146
|
+
return corsConfig;
|
147
|
+
}
|
148
|
+
initializeFastify() {
|
149
|
+
try {
|
150
|
+
return (0, fastify_1.default)({
|
151
|
+
logger: this.verbose === 'DEBUG',
|
152
|
+
ignoreTrailingSlash: true,
|
153
|
+
maxParamLength: 200,
|
154
|
+
caseSensitive: true,
|
155
|
+
});
|
156
|
+
}
|
157
|
+
catch (error) {
|
158
|
+
throw new IOServerError_1.IOServerError(`Unable to initialize server: ${error}`, 500);
|
159
|
+
}
|
160
|
+
}
|
161
|
+
setupPlugins(corsOptions) {
|
162
|
+
try {
|
163
|
+
// Register sensible plugin for HTTP shortcuts
|
164
|
+
this.webapp.register(sensible_1.default);
|
165
|
+
// Register CORS plugin with secure defaults
|
166
|
+
this.webapp.register(cors_1.default, {
|
167
|
+
...corsOptions,
|
168
|
+
credentials: corsOptions?.credentials ?? false, // Default to false for security
|
169
|
+
optionsSuccessStatus: 204, // For CORS preflight requests
|
170
|
+
});
|
171
|
+
// Add 404 handler
|
172
|
+
this.webapp.setNotFoundHandler((request, reply) => {
|
173
|
+
reply.code(404).send({
|
174
|
+
statusCode: 404,
|
175
|
+
error: 'Not Found',
|
176
|
+
message: `Route ${request.method}:${request.url} not found`,
|
177
|
+
});
|
178
|
+
});
|
179
|
+
// Setup error handler
|
180
|
+
this.webapp.setErrorHandler((error, request, reply) => {
|
181
|
+
if (error instanceof IOServerError_1.IOServerError) {
|
182
|
+
reply.status(error.statusCode).send({
|
183
|
+
statusCode: error.statusCode,
|
184
|
+
error: error.name,
|
185
|
+
message: error.message,
|
186
|
+
});
|
187
|
+
}
|
188
|
+
else if (error.status) {
|
189
|
+
reply.status(error.status).send({
|
190
|
+
statusCode: error.status,
|
191
|
+
error: error.name || 'Error',
|
192
|
+
message: error.message,
|
193
|
+
});
|
194
|
+
}
|
195
|
+
else {
|
196
|
+
reply.status(500).send({
|
197
|
+
statusCode: 500,
|
198
|
+
error: 'Internal Server Error',
|
199
|
+
message: error.message,
|
200
|
+
});
|
201
|
+
}
|
202
|
+
});
|
203
|
+
}
|
204
|
+
catch (error) {
|
205
|
+
throw new IOServerError_1.IOServerError(`Unable to setup plugins: ${error}`, 500);
|
206
|
+
}
|
207
|
+
}
|
208
|
+
setupSocketIO(transportModes, cookieEnabled, corsOptions) {
|
209
|
+
try {
|
210
|
+
// Create Socket.IO server immediately, but it will attach when Fastify starts
|
211
|
+
this.webapp.ready().then(() => {
|
212
|
+
this.socketio = new socket_io_1.Server(this.webapp.server, {
|
213
|
+
transports: transportModes,
|
214
|
+
cookie: cookieEnabled,
|
215
|
+
cors: corsOptions,
|
216
|
+
});
|
217
|
+
// Add io property to webapp for compatibility
|
218
|
+
this.webapp.io = this.socketio;
|
219
|
+
this.log(6, '[*] Socket.IO server attached to HTTP server');
|
220
|
+
});
|
221
|
+
}
|
222
|
+
catch (error) {
|
223
|
+
throw new IOServerError_1.IOServerError(`Unable to setup Socket.IO: ${error}`, 500);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
log(level, text) {
|
227
|
+
const currentLevel = IOServer.LOG_LEVELS.indexOf(this.verbose);
|
228
|
+
if (level <= currentLevel) {
|
229
|
+
if (level <= 4) {
|
230
|
+
console.error(text);
|
231
|
+
}
|
232
|
+
else {
|
233
|
+
console.log(text);
|
234
|
+
}
|
235
|
+
}
|
236
|
+
}
|
237
|
+
unique(array) {
|
238
|
+
return [...new Set(array)];
|
239
|
+
}
|
240
|
+
registerInternalClass(type, name, ClassConstructor) {
|
241
|
+
if (!name) {
|
242
|
+
throw new IOServerError_1.IOServerError('Name is mandatory', 400);
|
243
|
+
}
|
244
|
+
if (type !== 'service' && name.length < 2) {
|
245
|
+
throw new IOServerError_1.IOServerError('Name must be longer than 2 characters', 400);
|
246
|
+
}
|
247
|
+
if (IOServer.RESERVED_NAMES.includes(name)) {
|
248
|
+
throw new IOServerError_1.IOServerError('Sorry this is a reserved name', 400);
|
249
|
+
}
|
250
|
+
if (!ClassConstructor || !ClassConstructor.prototype) {
|
251
|
+
throw new IOServerError_1.IOServerError('Must be a constructor function', 400);
|
252
|
+
}
|
253
|
+
const listMap = this.getListMap(type);
|
254
|
+
if (listMap.has(name)) {
|
255
|
+
throw new IOServerError_1.IOServerError(`Sorry this ${type} already exists`, 409);
|
256
|
+
}
|
257
|
+
try {
|
258
|
+
this.log(7, `[*] Register ${type} ${name}`);
|
259
|
+
const instance = new ClassConstructor(this.appHandle);
|
260
|
+
listMap.set(name, instance);
|
261
|
+
}
|
262
|
+
catch (error) {
|
263
|
+
throw new IOServerError_1.IOServerError(`Error instantiating ${type}: ${error}`, 500);
|
264
|
+
}
|
265
|
+
}
|
266
|
+
getListMap(type) {
|
267
|
+
switch (type) {
|
268
|
+
case 'service':
|
269
|
+
return this.serviceLists;
|
270
|
+
case 'manager':
|
271
|
+
return this.managerLists;
|
272
|
+
case 'watcher':
|
273
|
+
return this.watcherLists;
|
274
|
+
case 'controller':
|
275
|
+
return this.controllerLists;
|
276
|
+
default:
|
277
|
+
throw new IOServerError_1.IOServerError(`Unknown type: ${type}`, 400);
|
278
|
+
}
|
279
|
+
}
|
280
|
+
dumpMethods(ClassConstructor) {
|
281
|
+
const result = [];
|
282
|
+
let prototype = ClassConstructor.prototype;
|
283
|
+
while (prototype && Object.getPrototypeOf(prototype)) {
|
284
|
+
const names = Object.getOwnPropertyNames(prototype);
|
285
|
+
result.push(...names);
|
286
|
+
prototype = Object.getPrototypeOf(prototype);
|
287
|
+
}
|
288
|
+
return this.unique(result).sort();
|
289
|
+
}
|
290
|
+
/**
|
291
|
+
* Registers a watcher component for background tasks
|
292
|
+
* @param {WatcherOptions} options - Watcher configuration options
|
293
|
+
* @throws {IOServerError} When watcher instantiation fails
|
294
|
+
*/
|
295
|
+
addWatcher(options) {
|
296
|
+
try {
|
297
|
+
this.registerInternalClass('watcher', options.name, options.watcher);
|
298
|
+
}
|
299
|
+
catch (error) {
|
300
|
+
throw new IOServerError_1.IOServerError(`Error while instantiating ${options.name} watcher: ${error}`, 500);
|
301
|
+
}
|
302
|
+
}
|
303
|
+
/**
|
304
|
+
* Registers a manager component for shared functionality
|
305
|
+
* @param {ManagerOptions} options - Manager configuration options
|
306
|
+
* @throws {IOServerError} When manager instantiation fails
|
307
|
+
*/
|
308
|
+
addManager(options) {
|
309
|
+
try {
|
310
|
+
this.registerInternalClass('manager', options.name, options.manager);
|
311
|
+
}
|
312
|
+
catch (error) {
|
313
|
+
throw new IOServerError_1.IOServerError(`Error while instantiating ${options.name} manager: ${error}`, 500);
|
314
|
+
}
|
315
|
+
}
|
316
|
+
/**
|
317
|
+
* Registers a service component for real-time WebSocket handling
|
318
|
+
* @param {ServiceOptions} options - Service configuration options
|
319
|
+
* @throws {IOServerError} When service instantiation fails
|
320
|
+
*/
|
321
|
+
addService(options) {
|
322
|
+
const name = options.name || '/';
|
323
|
+
try {
|
324
|
+
this.registerInternalClass('service', name, options.service);
|
325
|
+
}
|
326
|
+
catch (error) {
|
327
|
+
throw new IOServerError_1.IOServerError(`Error while instantiating ${name} service: ${error}`, 500);
|
328
|
+
}
|
329
|
+
this.methodLists.set(name, this.dumpMethods(options.service));
|
330
|
+
this.middlewareLists.set(name, options.middlewares || []);
|
331
|
+
}
|
332
|
+
/**
|
333
|
+
* Registers a controller component for HTTP route handling
|
334
|
+
* @param {ControllerOptions} options - Controller configuration options
|
335
|
+
* @throws {IOServerError} When controller instantiation or route loading fails
|
336
|
+
*/
|
337
|
+
addController(options) {
|
338
|
+
const middlewares = options.middlewares || [];
|
339
|
+
let prefix = options.prefix;
|
340
|
+
// Sanitize prefix
|
341
|
+
if (prefix) {
|
342
|
+
if (!prefix.startsWith('/')) {
|
343
|
+
prefix = `/${prefix}`;
|
344
|
+
}
|
345
|
+
if (prefix.endsWith('/')) {
|
346
|
+
prefix = prefix.slice(0, -1);
|
347
|
+
}
|
348
|
+
}
|
349
|
+
try {
|
350
|
+
this.registerInternalClass('controller', options.name, options.controller);
|
351
|
+
}
|
352
|
+
catch (error) {
|
353
|
+
throw new IOServerError_1.IOServerError(`Error while instantiating ${options.name} controller: ${error}`, 500);
|
354
|
+
}
|
355
|
+
const routeFile = path.join(this.routesPath, `${options.name}.json`);
|
356
|
+
if (!fs.existsSync(routeFile)) {
|
357
|
+
throw new IOServerError_1.IOServerError(`Routes file does not exist: ${routeFile}`, 404);
|
358
|
+
}
|
359
|
+
try {
|
360
|
+
const routes = JSON.parse(fs.readFileSync(routeFile, 'utf8'));
|
361
|
+
this.registerControllerRoutes(routes, options.name, prefix, middlewares);
|
362
|
+
}
|
363
|
+
catch (error) {
|
364
|
+
throw new IOServerError_1.IOServerError(`Error loading routes for ${options.name}: ${error}`, 500);
|
365
|
+
}
|
366
|
+
}
|
367
|
+
registerControllerRoutes(routes, controllerName, prefix, middlewares = []) {
|
368
|
+
const controller = this.controllerLists.get(controllerName);
|
369
|
+
routes.forEach(route => {
|
370
|
+
// Map controller methods to route handlers
|
371
|
+
const handlerOptions = [
|
372
|
+
'onRequest',
|
373
|
+
'preParsing',
|
374
|
+
'preValidation',
|
375
|
+
'preHandler',
|
376
|
+
'preSerialization',
|
377
|
+
'onSend',
|
378
|
+
'onResponse',
|
379
|
+
'handler',
|
380
|
+
'errorHandler',
|
381
|
+
];
|
382
|
+
handlerOptions.forEach(option => {
|
383
|
+
if (route[option] && controller[route[option]]) {
|
384
|
+
route[option] = controller[route[option]].bind(controller);
|
385
|
+
}
|
386
|
+
});
|
387
|
+
// Set URL with prefix logic:
|
388
|
+
// 1. If custom prefix is provided, use it
|
389
|
+
// 2. Otherwise, use controller name as prefix (unless it's root route)
|
390
|
+
if (prefix !== undefined) {
|
391
|
+
// Custom prefix provided (can be empty string for no prefix)
|
392
|
+
route.url = prefix + route.url;
|
393
|
+
}
|
394
|
+
else {
|
395
|
+
// Default behavior: use controller name as prefix unless route is "/"
|
396
|
+
if (route.url === '/' && controllerName !== 'root') {
|
397
|
+
// Keep root route as-is for main controllers
|
398
|
+
route.url = '/';
|
399
|
+
}
|
400
|
+
else {
|
401
|
+
route.url = `/${controllerName}${route.url}`;
|
402
|
+
}
|
403
|
+
}
|
404
|
+
// Setup middleware
|
405
|
+
if (!route.preValidation) {
|
406
|
+
route.preValidation = [];
|
407
|
+
}
|
408
|
+
middlewares.forEach(MiddlewareClass => {
|
409
|
+
const middleware = new MiddlewareClass();
|
410
|
+
if (middleware.handle) {
|
411
|
+
route.preValidation.push(middleware.handle(this.appHandle));
|
412
|
+
}
|
413
|
+
});
|
414
|
+
try {
|
415
|
+
this.log(7, `[*] Register controller route ${route.method} ${route.url}`);
|
416
|
+
this.webapp.route(route);
|
417
|
+
}
|
418
|
+
catch (error) {
|
419
|
+
this.log(3, `[!] Unable to register route: ${error}`);
|
420
|
+
}
|
421
|
+
});
|
422
|
+
}
|
423
|
+
/**
|
424
|
+
* Retrieves a registered service by name
|
425
|
+
* @param {string} name - The service name
|
426
|
+
* @returns {any} The service instance or undefined if not found
|
427
|
+
*/
|
428
|
+
getService(name) {
|
429
|
+
return this.serviceLists.get(name);
|
430
|
+
}
|
431
|
+
/**
|
432
|
+
* Starts the IOServer instance
|
433
|
+
* Initializes Socket.IO, starts watchers, and begins listening for connections
|
434
|
+
* @returns {Promise<void>} Promise that resolves when server is started
|
435
|
+
* @throws {IOServerError} When server startup fails
|
436
|
+
*/
|
437
|
+
async start() {
|
438
|
+
const now = new Date();
|
439
|
+
const timestamp = now.toISOString();
|
440
|
+
this.log(4, `################### IOServer v${IOServer.VERSION} ###################`);
|
441
|
+
this.log(5, `################### ${timestamp} ###################`);
|
442
|
+
// Register managers in appHandle
|
443
|
+
this.managerLists.forEach((manager, name) => {
|
444
|
+
this.log(6, `[*] Register ${name} manager`);
|
445
|
+
this.appHandle[name] = manager;
|
446
|
+
});
|
447
|
+
// Ensure Fastify is ready and Socket.IO is initialized
|
448
|
+
await this.webapp.ready();
|
449
|
+
// Wait for Socket.IO to be properly initialized
|
450
|
+
let retries = 0;
|
451
|
+
const maxRetries = 10;
|
452
|
+
while (!this.socketio && retries < maxRetries) {
|
453
|
+
await (0, promises_1.setTimeout)(100);
|
454
|
+
retries++;
|
455
|
+
}
|
456
|
+
if (!this.socketio) {
|
457
|
+
throw new IOServerError_1.IOServerError('Socket.IO server failed to initialize', 500);
|
458
|
+
}
|
459
|
+
this.log(6, '[*] Socket.IO server ready');
|
460
|
+
// Setup Socket.IO namespaces and services
|
461
|
+
this.serviceLists.forEach((service, serviceName) => {
|
462
|
+
const namespace = serviceName === '/'
|
463
|
+
? this.socketio.of('/')
|
464
|
+
: this.socketio.of(`/${serviceName}`);
|
465
|
+
// Register middleware for namespace
|
466
|
+
const middlewares = this.middlewareLists.get(serviceName) || [];
|
467
|
+
middlewares.forEach(MiddlewareClass => {
|
468
|
+
const middleware = new MiddlewareClass();
|
469
|
+
if (middleware.handle) {
|
470
|
+
namespace.use(middleware.handle(this.appHandle));
|
471
|
+
}
|
472
|
+
});
|
473
|
+
// Setup connection handler
|
474
|
+
namespace.on('connection', this.handleConnection(serviceName));
|
475
|
+
this.log(6, `[*] Service ${serviceName} registered...`);
|
476
|
+
});
|
477
|
+
// Start watchers
|
478
|
+
try {
|
479
|
+
const watcherPromises = Array.from(this.watcherLists.values()).map(async (watcher) => {
|
480
|
+
try {
|
481
|
+
this.log(6, `[*] Start watcher ${watcher.constructor.name}`);
|
482
|
+
if (watcher.watch) {
|
483
|
+
await watcher.watch();
|
484
|
+
}
|
485
|
+
}
|
486
|
+
catch (error) {
|
487
|
+
throw new IOServerError_1.IOServerError(`Unable to start ${watcher.constructor.name} watcher: ${error}`, 500);
|
488
|
+
}
|
489
|
+
});
|
490
|
+
// Don't wait for watchers to complete
|
491
|
+
Promise.all(watcherPromises).catch(error => {
|
492
|
+
this.log(3, `[!] Error starting watchers: ${error}`);
|
493
|
+
});
|
494
|
+
}
|
495
|
+
catch (error) {
|
496
|
+
throw new IOServerError_1.IOServerError(`Error starting watchers: ${error}`, 500);
|
497
|
+
}
|
498
|
+
// Start web server
|
499
|
+
try {
|
500
|
+
this.log(5, `[*] Starting server on http://${this.host}:${this.port} ...`);
|
501
|
+
await this.webapp.listen({ port: this.port, host: this.host });
|
502
|
+
this.log(5, `[*] Server listening on http://${this.host}:${this.port}`);
|
503
|
+
}
|
504
|
+
catch (error) {
|
505
|
+
this.log(3, `[!] Unable to start server: ${error}`);
|
506
|
+
throw new IOServerError_1.IOServerError(`Unable to start server: ${error}`, 500);
|
507
|
+
}
|
508
|
+
}
|
509
|
+
/**
|
510
|
+
* Gets the server hostname
|
511
|
+
* @returns {string} The server hostname
|
512
|
+
*/
|
513
|
+
getHost() {
|
514
|
+
return this.host;
|
515
|
+
}
|
516
|
+
/**
|
517
|
+
* Gets the server port number
|
518
|
+
* @returns {number} The server port
|
519
|
+
*/
|
520
|
+
getPort() {
|
521
|
+
return this.port;
|
522
|
+
}
|
523
|
+
/**
|
524
|
+
* Gets the Fastify instance
|
525
|
+
* @returns {FastifyInstance} The Fastify application instance
|
526
|
+
*/
|
527
|
+
getApp() {
|
528
|
+
return this.webapp;
|
529
|
+
}
|
530
|
+
/**
|
531
|
+
* Stops the IOServer instance
|
532
|
+
* @returns {Promise<void>} Promise that resolves when server is stopped
|
533
|
+
* @throws {IOServerError} When server shutdown fails
|
534
|
+
*/
|
535
|
+
async stop() {
|
536
|
+
try {
|
537
|
+
await this.webapp.close();
|
538
|
+
this.log(6, '[*] Server stopped');
|
539
|
+
}
|
540
|
+
catch (error) {
|
541
|
+
throw new IOServerError_1.IOServerError(`Unable to stop server: ${error}`, 500);
|
542
|
+
}
|
543
|
+
}
|
544
|
+
/**
|
545
|
+
* Sends real-time messages to connected clients
|
546
|
+
* @param {SendToOptions} options - Options for message delivery
|
547
|
+
* @returns {boolean} True if message was sent successfully, false otherwise
|
548
|
+
*/
|
549
|
+
sendTo(options) {
|
550
|
+
if (!this.socketio) {
|
551
|
+
this.log(3, '[!] Socket.IO not initialized, cannot send message');
|
552
|
+
return false;
|
553
|
+
}
|
554
|
+
let namespace = options.namespace;
|
555
|
+
if (namespace) {
|
556
|
+
if (!namespace.startsWith('/')) {
|
557
|
+
namespace = `/${namespace}`;
|
558
|
+
}
|
559
|
+
}
|
560
|
+
else {
|
561
|
+
namespace = '/';
|
562
|
+
}
|
563
|
+
const ns = this.socketio.of(namespace);
|
564
|
+
if (options.sid) {
|
565
|
+
const socket = ns.sockets.get(options.sid);
|
566
|
+
if (socket) {
|
567
|
+
socket.emit(options.event, options.data);
|
568
|
+
}
|
569
|
+
}
|
570
|
+
else {
|
571
|
+
const target = options.room ? ns.in(options.room) : ns;
|
572
|
+
target.emit(options.event, options.data);
|
573
|
+
}
|
574
|
+
return true;
|
575
|
+
}
|
576
|
+
/**
|
577
|
+
* Handles new WebSocket connections for a specific service
|
578
|
+
* @private
|
579
|
+
* @param {string} serviceName - The name of the service
|
580
|
+
* @returns {Function} Connection handler function
|
581
|
+
*/
|
582
|
+
handleConnection(serviceName) {
|
583
|
+
return (socket) => {
|
584
|
+
this.log(5, `[*] Received connection for service ${serviceName}`);
|
585
|
+
const methods = this.methodLists.get(serviceName) || [];
|
586
|
+
this.serviceLists.get(serviceName);
|
587
|
+
methods.forEach(method => {
|
588
|
+
// Skip private methods and constructor
|
589
|
+
if (method.startsWith('_') || method === 'constructor') {
|
590
|
+
return;
|
591
|
+
}
|
592
|
+
this.log(6, `[*] Method ${method} of ${serviceName} listening...`);
|
593
|
+
socket.on(method, this.handleCallback(serviceName, method, socket));
|
594
|
+
});
|
595
|
+
};
|
596
|
+
}
|
597
|
+
/**
|
598
|
+
* Creates a callback handler for WebSocket method calls
|
599
|
+
* @private
|
600
|
+
* @param {string} serviceName - The name of the service
|
601
|
+
* @param {string} methodName - The name of the method
|
602
|
+
* @param {any} socket - The Socket.IO socket instance
|
603
|
+
* @returns {Function} Callback handler function
|
604
|
+
*/
|
605
|
+
handleCallback(serviceName, methodName, socket) {
|
606
|
+
return async (data, callback) => {
|
607
|
+
this.log(6, `[*] Call method ${methodName} of service ${serviceName}`);
|
608
|
+
try {
|
609
|
+
const service = this.serviceLists.get(serviceName);
|
610
|
+
if (service && service[methodName]) {
|
611
|
+
await service[methodName](socket, data, callback);
|
612
|
+
}
|
613
|
+
}
|
614
|
+
catch (error) {
|
615
|
+
let ioError = error;
|
616
|
+
if (typeof error === 'string') {
|
617
|
+
ioError = new IOServerError_1.IOServerError(error, 500);
|
618
|
+
}
|
619
|
+
const payload = {
|
620
|
+
status: 'error',
|
621
|
+
type: ioError?.constructor?.name || 'Error',
|
622
|
+
message: ioError?.message || null,
|
623
|
+
statusCode: ioError?.statusCode || 500,
|
624
|
+
};
|
625
|
+
this.log(5, `Error on ${serviceName}:${methodName} execution: ${error}`);
|
626
|
+
if (callback) {
|
627
|
+
callback(payload);
|
628
|
+
}
|
629
|
+
else {
|
630
|
+
socket.emit('error', payload);
|
631
|
+
}
|
632
|
+
}
|
633
|
+
};
|
634
|
+
}
|
635
|
+
}
|
636
|
+
exports.IOServer = IOServer;
|
637
|
+
IOServer.VERSION = '2.0.0';
|
638
|
+
IOServer.DEFAULT_PORT = 8080;
|
639
|
+
IOServer.DEFAULT_HOST = 'localhost';
|
640
|
+
IOServer.LOG_LEVELS = [
|
641
|
+
'EMERGENCY',
|
642
|
+
'ALERT',
|
643
|
+
'CRITICAL',
|
644
|
+
'ERROR',
|
645
|
+
'WARNING',
|
646
|
+
'NOTIFICATION',
|
647
|
+
'INFORMATION',
|
648
|
+
'DEBUG',
|
649
|
+
];
|
650
|
+
IOServer.TRANSPORTS = [
|
651
|
+
'websocket',
|
652
|
+
'polling',
|
653
|
+
];
|
654
|
+
IOServer.RESERVED_NAMES = ['send', 'log', 'verbose'];
|
655
|
+
exports.default = IOServer;
|
656
|
+
//# sourceMappingURL=IOServer.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"IOServer.js","sourceRoot":"","sources":["../src/IOServer.ts"],"names":[],"mappings":"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"}
|