dolphin-server-modules 1.5.1 → 1.5.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.
Files changed (47) hide show
  1. package/DOLPHIN_MASTER_GUIDE_NEPALI.md +369 -478
  2. package/dist/adapters/mongoose/index.test.d.ts +1 -0
  3. package/dist/adapters/mongoose/index.test.js +103 -0
  4. package/dist/adapters/mongoose/index.test.js.map +1 -0
  5. package/dist/auth/auth.test.d.ts +1 -0
  6. package/dist/auth/auth.test.js +291 -0
  7. package/dist/auth/auth.test.js.map +1 -0
  8. package/dist/authController/authController.test.d.ts +1 -0
  9. package/dist/authController/authController.test.js +361 -0
  10. package/dist/authController/authController.test.js.map +1 -0
  11. package/dist/controller/controller.test.d.ts +1 -0
  12. package/dist/controller/controller.test.js +39 -0
  13. package/dist/controller/controller.test.js.map +1 -0
  14. package/dist/curd/crud.d.ts +2 -0
  15. package/dist/curd/crud.js +83 -24
  16. package/dist/curd/crud.js.map +1 -1
  17. package/dist/curd/crud.test.d.ts +1 -0
  18. package/dist/curd/crud.test.js +163 -0
  19. package/dist/curd/crud.test.js.map +1 -0
  20. package/dist/djson/djson.d.ts +42 -0
  21. package/dist/djson/djson.js +318 -0
  22. package/dist/djson/djson.js.map +1 -0
  23. package/dist/index.d.ts +1 -5
  24. package/dist/index.js +1 -12
  25. package/dist/index.js.map +1 -1
  26. package/dist/middleware/zod.test.d.ts +1 -0
  27. package/dist/middleware/zod.test.js +76 -0
  28. package/dist/middleware/zod.test.js.map +1 -0
  29. package/dist/realtime/core.d.ts +27 -28
  30. package/dist/realtime/core.js +297 -65
  31. package/dist/realtime/core.js.map +1 -1
  32. package/dist/realtime/index.d.ts +1 -1
  33. package/dist/realtime/index.js +1 -1
  34. package/dist/realtime/index.js.map +1 -1
  35. package/dist/realtime/plugins.d.ts +17 -4
  36. package/dist/realtime/plugins.js +300 -14
  37. package/dist/realtime/plugins.js.map +1 -1
  38. package/dist/realtime/realtime.test.d.ts +1 -0
  39. package/dist/realtime/realtime.test.js +271 -0
  40. package/dist/realtime/realtime.test.js.map +1 -0
  41. package/package.json +4 -2
  42. package/dist/router/router.d.ts +0 -26
  43. package/dist/router/router.js +0 -71
  44. package/dist/router/router.js.map +0 -1
  45. package/dist/server/server.d.ts +0 -23
  46. package/dist/server/server.js +0 -219
  47. package/dist/server/server.js.map +0 -1
@@ -4,26 +4,281 @@
4
4
  * Allows handling custom protocols (e.g. Modbus, HL7) seamlessly.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.JSONPlugin = exports.ModbusPlugin = exports.HL7Plugin = void 0;
7
+ exports.JSONPlugin = exports.HL7Plugin = exports.ModbusPlugin = void 0;
8
+ exports.buildModbusFrame = buildModbusFrame;
9
+ exports.buildReadRegistersFrame = buildReadRegistersFrame;
10
+ exports.buildWriteRegisterFrame = buildWriteRegisterFrame;
11
+ // ============================================
12
+ // Modbus RTU Complete Parser
13
+ // ============================================
14
+ // Modbus Function Codes
15
+ const ModbusFunction = {
16
+ READ_COILS: 0x01,
17
+ READ_DISCRETE_INPUTS: 0x02,
18
+ READ_HOLDING_REGISTERS: 0x03,
19
+ READ_INPUT_REGISTERS: 0x04,
20
+ WRITE_SINGLE_COIL: 0x05,
21
+ WRITE_SINGLE_REGISTER: 0x06,
22
+ WRITE_MULTIPLE_COILS: 0x0F,
23
+ WRITE_MULTIPLE_REGISTERS: 0x10
24
+ };
8
25
  /**
9
- * Sample HL7 Plugin
26
+ * CRC16 calculation for Modbus
10
27
  */
11
- exports.HL7Plugin = {
12
- name: 'hl7',
13
- match: (ctx) => ctx.raw?.includes?.(0x0b) ?? false,
14
- decode: (buf) => ({ msg: buf.toString().split('\r') })
15
- };
28
+ function calculateCRC(buffer) {
29
+ let crc = 0xFFFF;
30
+ for (let i = 0; i < buffer.length; i++) {
31
+ crc ^= buffer[i];
32
+ for (let bit = 0; bit < 8; bit++) {
33
+ if (crc & 0x0001) {
34
+ crc = (crc >> 1) ^ 0xA001;
35
+ }
36
+ else {
37
+ crc = crc >> 1;
38
+ }
39
+ }
40
+ }
41
+ return crc;
42
+ }
43
+ /**
44
+ * Complete Modbus RTU Frame Parser
45
+ */
46
+ function parseModbusFrame(buffer) {
47
+ if (buffer.length < 4) {
48
+ return { error: 'Frame too short', length: buffer.length };
49
+ }
50
+ const slaveId = buffer[0];
51
+ const functionCode = buffer[1];
52
+ // Validate slave ID (1-247)
53
+ if (slaveId < 1 || slaveId > 247) {
54
+ return { error: 'Invalid slave ID', slaveId };
55
+ }
56
+ // CRC check
57
+ const receivedCRC = buffer.readUInt16LE(buffer.length - 2);
58
+ const calculatedCRC = calculateCRC(buffer.slice(0, buffer.length - 2));
59
+ if (receivedCRC !== calculatedCRC) {
60
+ return {
61
+ error: 'CRC mismatch',
62
+ receivedCRC,
63
+ calculatedCRC,
64
+ raw: buffer.toString('hex')
65
+ };
66
+ }
67
+ const data = buffer.slice(2, buffer.length - 2);
68
+ // Parse based on function code
69
+ let parsedData = {};
70
+ switch (functionCode) {
71
+ case ModbusFunction.READ_HOLDING_REGISTERS:
72
+ case ModbusFunction.READ_INPUT_REGISTERS:
73
+ if (data.length > 0) {
74
+ const byteCount = data[0];
75
+ const registers = [];
76
+ for (let i = 1; i < 1 + byteCount; i += 2) {
77
+ if (i + 1 < data.length) {
78
+ registers.push(data.readUInt16BE(i));
79
+ }
80
+ }
81
+ parsedData = {
82
+ type: 'registers',
83
+ byteCount,
84
+ registers,
85
+ count: registers.length,
86
+ firstRegister: registers[0],
87
+ singleValue: registers.length === 1 ? registers[0] : null
88
+ };
89
+ }
90
+ break;
91
+ case ModbusFunction.READ_COILS:
92
+ case ModbusFunction.READ_DISCRETE_INPUTS:
93
+ if (data.length > 0) {
94
+ const byteCount = data[0];
95
+ const coils = [];
96
+ for (let i = 1; i < 1 + byteCount && i < data.length; i++) {
97
+ for (let bit = 0; bit < 8; bit++) {
98
+ const coilValue = (data[i] >> bit) & 0x01;
99
+ coils.push(coilValue === 1); // Convert to boolean properly
100
+ }
101
+ }
102
+ parsedData = {
103
+ type: 'coils',
104
+ byteCount,
105
+ coils: coils.slice(0, byteCount * 8),
106
+ firstCoil: coils[0] || false
107
+ };
108
+ }
109
+ break;
110
+ case ModbusFunction.WRITE_SINGLE_REGISTER:
111
+ if (data.length >= 4) {
112
+ parsedData = {
113
+ type: 'write-single-register',
114
+ address: data.readUInt16BE(0),
115
+ value: data.readUInt16BE(2)
116
+ };
117
+ }
118
+ break;
119
+ case ModbusFunction.WRITE_SINGLE_COIL:
120
+ if (data.length >= 4) {
121
+ const coilValue = data.readUInt16BE(2);
122
+ parsedData = {
123
+ type: 'write-single-coil',
124
+ address: data.readUInt16BE(0),
125
+ value: coilValue === 0xFF00 // Compare properly
126
+ };
127
+ }
128
+ break;
129
+ case ModbusFunction.WRITE_MULTIPLE_REGISTERS:
130
+ if (data.length >= 5) {
131
+ const byteCount = data[4];
132
+ const values = [];
133
+ for (let i = 5; i < 5 + byteCount && i + 1 < data.length; i += 2) {
134
+ values.push(data.readUInt16BE(i));
135
+ }
136
+ parsedData = {
137
+ type: 'write-multiple-registers',
138
+ address: data.readUInt16BE(0),
139
+ quantity: data.readUInt16BE(2),
140
+ byteCount,
141
+ values
142
+ };
143
+ }
144
+ break;
145
+ default:
146
+ // Check if it's an exception response
147
+ if ((functionCode & 0x80) !== 0) {
148
+ const exceptionCode = data[0];
149
+ const exceptionMessages = {
150
+ 0x01: 'Illegal Function',
151
+ 0x02: 'Illegal Data Address',
152
+ 0x03: 'Illegal Data Value',
153
+ 0x04: 'Slave Device Failure',
154
+ 0x05: 'Acknowledge',
155
+ 0x06: 'Slave Device Busy'
156
+ };
157
+ parsedData = {
158
+ type: 'exception',
159
+ exceptionCode,
160
+ message: exceptionMessages[exceptionCode] || 'Unknown Exception'
161
+ };
162
+ }
163
+ else {
164
+ parsedData = {
165
+ type: 'unknown',
166
+ raw: data.toString('hex'),
167
+ functionCode: `0x${functionCode.toString(16)}`
168
+ };
169
+ }
170
+ }
171
+ const functionNames = {
172
+ 0x01: 'READ_COILS',
173
+ 0x02: 'READ_DISCRETE_INPUTS',
174
+ 0x03: 'READ_HOLDING_REGISTERS',
175
+ 0x04: 'READ_INPUT_REGISTERS',
176
+ 0x05: 'WRITE_SINGLE_COIL',
177
+ 0x06: 'WRITE_SINGLE_REGISTER',
178
+ 0x0F: 'WRITE_MULTIPLE_COILS',
179
+ 0x10: 'WRITE_MULTIPLE_REGISTERS'
180
+ };
181
+ return {
182
+ protocol: 'modbus-rtu',
183
+ slaveId,
184
+ functionCode,
185
+ functionName: functionNames[functionCode] || `UNKNOWN_0x${functionCode.toString(16)}`,
186
+ data: parsedData,
187
+ crc: { received: receivedCRC, calculated: calculatedCRC, valid: receivedCRC === calculatedCRC },
188
+ raw: buffer.toString('hex'),
189
+ length: buffer.length,
190
+ timestamp: Date.now()
191
+ };
192
+ }
193
+ /**
194
+ * Convert Modbus registers to meaningful sensor values
195
+ */
196
+ function registersToSensor(registers, schema) {
197
+ if (!schema) {
198
+ // Default schema (temperature on register 0, humidity on register 1)
199
+ return {
200
+ temperature: registers[0] !== undefined ? registers[0] / 10 : null,
201
+ humidity: registers[1] !== undefined ? registers[1] / 10 : null,
202
+ rawRegisters: registers
203
+ };
204
+ }
205
+ const result = {};
206
+ for (const [key, config] of Object.entries(schema)) {
207
+ let value = registers[config.index] || 0;
208
+ if (config.scale)
209
+ value = value * config.scale;
210
+ if (config.offset)
211
+ value = value + config.offset;
212
+ result[key] = value;
213
+ }
214
+ result.rawRegisters = registers;
215
+ return result;
216
+ }
217
+ // ============================================
218
+ // Updated Plugins
219
+ // ============================================
16
220
  /**
17
- * Sample Modbus Plugin
221
+ * Complete Modbus Plugin
222
+ * अब 8 bytes मात्र होइन, सबै Modbus frames ह्यान्डल गर्छ
18
223
  */
19
224
  exports.ModbusPlugin = {
20
225
  name: 'modbus',
21
- match: (ctx) => ctx.raw?.length === 8,
22
- decode: (buf) => ({
23
- addr: buf[0],
24
- func: buf[1],
25
- value: buf.readUInt16BE(2)
26
- })
226
+ match: (ctx) => {
227
+ if (!ctx.raw || ctx.raw.length < 4)
228
+ return false;
229
+ const slaveId = ctx.raw[0];
230
+ // Valid Modbus slave IDs: 1-247
231
+ if (slaveId < 1 || slaveId > 247)
232
+ return false;
233
+ const funcCode = ctx.raw[1];
234
+ const validFuncCodes = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0F, 0x10];
235
+ // Valid function code or exception response (has 0x80 bit set)
236
+ const isValidFunc = validFuncCodes.includes(funcCode) || ((funcCode & 0x80) !== 0);
237
+ if (!isValidFunc)
238
+ return false;
239
+ // Modbus RTU max frame size is 256 bytes
240
+ return ctx.raw.length <= 256;
241
+ },
242
+ decode: (buf) => {
243
+ return parseModbusFrame(buf);
244
+ },
245
+ onMessage: (ctx) => {
246
+ const parsed = ctx.payload;
247
+ if (parsed.error) {
248
+ console.error(`[Modbus] Error: ${parsed.error}`, parsed);
249
+ return;
250
+ }
251
+ // Publish to general modbus topic
252
+ ctx.publish(`modbus/slave_${parsed.slaveId}`, {
253
+ function: parsed.functionName,
254
+ data: parsed.data,
255
+ timestamp: parsed.timestamp
256
+ });
257
+ // If it's register data (sensor values)
258
+ if (parsed.data?.type === 'registers' && parsed.data.registers) {
259
+ const sensorData = registersToSensor(parsed.data.registers);
260
+ // Publish as sensor data
261
+ ctx.publish(`modbus/sensors/${parsed.slaveId}`, {
262
+ slaveId: parsed.slaveId,
263
+ ...sensorData,
264
+ timestamp: parsed.timestamp
265
+ });
266
+ }
267
+ // Log nicely
268
+ console.log(`[Modbus] Slave ${parsed.slaveId} | ${parsed.functionName} | Data:`, parsed.data.type === 'registers' ? parsed.data.registers : parsed.data);
269
+ }
270
+ };
271
+ /**
272
+ * Sample HL7 Plugin
273
+ */
274
+ exports.HL7Plugin = {
275
+ name: 'hl7',
276
+ match: (ctx) => {
277
+ if (!ctx.raw)
278
+ return false;
279
+ return ctx.raw.includes(0x0b);
280
+ },
281
+ decode: (buf) => ({ msg: buf.toString().split('\r') })
27
282
  };
28
283
  /**
29
284
  * Standard JSON Plugin for Web
@@ -44,4 +299,35 @@ exports.JSONPlugin = {
44
299
  },
45
300
  decode: (buf) => JSON.parse(buf.toString())
46
301
  };
302
+ /**
303
+ * Modbus Frame Builder (Write operations को लागि)
304
+ */
305
+ function buildModbusFrame(slaveId, functionCode, data) {
306
+ const frame = Buffer.concat([
307
+ Buffer.from([slaveId, functionCode]),
308
+ data
309
+ ]);
310
+ const crc = calculateCRC(frame);
311
+ const crcBuffer = Buffer.alloc(2);
312
+ crcBuffer.writeUInt16LE(crc, 0);
313
+ return Buffer.concat([frame, crcBuffer]);
314
+ }
315
+ /**
316
+ * Read Holding Registers frame बनाउने
317
+ */
318
+ function buildReadRegistersFrame(slaveId, startAddress, quantity) {
319
+ const data = Buffer.alloc(4);
320
+ data.writeUInt16BE(startAddress, 0);
321
+ data.writeUInt16BE(quantity, 2);
322
+ return buildModbusFrame(slaveId, 0x03, data);
323
+ }
324
+ /**
325
+ * Write Single Register frame बनाउने
326
+ */
327
+ function buildWriteRegisterFrame(slaveId, address, value) {
328
+ const data = Buffer.alloc(4);
329
+ data.writeUInt16BE(address, 0);
330
+ data.writeUInt16BE(value, 2);
331
+ return buildModbusFrame(slaveId, 0x06, data);
332
+ }
47
333
  //# sourceMappingURL=plugins.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../realtime/plugins.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsBH;;GAEG;AACU,QAAA,SAAS,GAAmB;IACvC,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK;IAClD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;CACvD,CAAC;AAEF;;GAEG;AACU,QAAA,YAAY,GAAmB;IAC1C,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;IACrC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAChB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACZ,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACZ,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;KAC3B,CAAC;CACH,CAAC;AAEF;;GAEG;AACU,QAAA,UAAU,GAAmB;IACxC,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QACb,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;gBACZ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/B,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;CAC5C,CAAC"}
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../realtime/plugins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ /// <reference types="jest" />
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const trie_1 = require("./trie");
5
+ const core_1 = require("./core");
6
+ class MockWebSocket {
7
+ readyState = 1;
8
+ messages = [];
9
+ closed = false;
10
+ send(data) {
11
+ this.messages.push(data);
12
+ }
13
+ ping() { }
14
+ close() {
15
+ this.closed = true;
16
+ this.readyState = 3;
17
+ }
18
+ }
19
+ describe('Realtime Module - Tests', () => {
20
+ let trie;
21
+ let realtime;
22
+ let createdInstances = [];
23
+ beforeEach(() => {
24
+ trie = new trie_1.TopicTrie();
25
+ realtime = new core_1.RealtimeCore({
26
+ maxMessageSize: 1024 * 1024,
27
+ enableJSONCache: true,
28
+ useBinaryProtocol: false,
29
+ debug: false
30
+ });
31
+ createdInstances.push(realtime);
32
+ });
33
+ afterEach(async () => {
34
+ jest.clearAllMocks();
35
+ jest.restoreAllMocks();
36
+ // Clean up all created instances to prevent worker process leaks
37
+ for (const instance of createdInstances) {
38
+ if (instance && typeof instance.destroy === 'function') {
39
+ await instance.destroy();
40
+ }
41
+ }
42
+ createdInstances = [];
43
+ });
44
+ afterAll(async () => {
45
+ // Final cleanup and wait for any pending intervals
46
+ await new Promise(resolve => setTimeout(resolve, 200));
47
+ });
48
+ describe('TopicTrie', () => {
49
+ it('should match exact topics', () => {
50
+ const fn = jest.fn();
51
+ trie.add('sensors/temp', fn);
52
+ trie.match('sensors/temp', (f) => f());
53
+ expect(fn).toHaveBeenCalledTimes(1);
54
+ });
55
+ it('should match single level wildcard (+)', () => {
56
+ const fn = jest.fn();
57
+ trie.add('sensors/+', fn);
58
+ trie.match('sensors/temp', (f) => f());
59
+ trie.match('sensors/hum', (f) => f());
60
+ trie.match('actuators/led', (f) => f());
61
+ expect(fn).toHaveBeenCalledTimes(2);
62
+ });
63
+ it('should match multi-level wildcard (#)', () => {
64
+ const fn = jest.fn();
65
+ trie.add('sensors/#', fn);
66
+ trie.match('sensors/temp', (f) => f());
67
+ trie.match('sensors/temp/value', (f) => f());
68
+ trie.match('sensors/hum/status', (f) => f());
69
+ trie.match('actuators/led', (f) => f());
70
+ expect(fn).toHaveBeenCalledTimes(3);
71
+ });
72
+ it('should handle multiple subscribers on same topic', () => {
73
+ const fn1 = jest.fn();
74
+ const fn2 = jest.fn();
75
+ trie.add('device/status', fn1);
76
+ trie.add('device/status', fn2);
77
+ trie.match('device/status', (f) => f());
78
+ expect(fn1).toHaveBeenCalledTimes(1);
79
+ expect(fn2).toHaveBeenCalledTimes(1);
80
+ });
81
+ });
82
+ describe('Publish/Subscribe', () => {
83
+ it('should publish and receive messages', (done) => {
84
+ const testTopic = 'test/topic';
85
+ const testPayload = { message: 'hello world' };
86
+ realtime.subscribe(testTopic, (payload) => {
87
+ expect(payload).toEqual(testPayload);
88
+ done();
89
+ });
90
+ realtime.publish(testTopic, testPayload);
91
+ });
92
+ it('should handle retained messages', () => {
93
+ const fn = jest.fn();
94
+ const testTopic = 'retained/topic';
95
+ const testPayload = { data: 'retained message' };
96
+ realtime.publish(testTopic, testPayload, { retain: true, ttl: 10000 });
97
+ realtime.subscribe(testTopic, fn);
98
+ expect(fn).toHaveBeenCalledTimes(1);
99
+ expect(fn).toHaveBeenCalledWith(testPayload);
100
+ });
101
+ });
102
+ describe('Direct Publish via Handle', () => {
103
+ it('should handle pub format JSON payload', async () => {
104
+ const fn = jest.fn();
105
+ const topic = 'direct/test';
106
+ const testPayload = { sensor: 'temp', value: 25 };
107
+ realtime.subscribe(topic, fn);
108
+ const message = Buffer.from(JSON.stringify({
109
+ type: 'pub',
110
+ topic: topic,
111
+ payload: testPayload
112
+ }));
113
+ await realtime.handle(message, null, 'device-001');
114
+ // Wait for async operations
115
+ await new Promise(resolve => setTimeout(resolve, 50));
116
+ expect(fn).toHaveBeenCalledTimes(1);
117
+ expect(fn).toHaveBeenCalledWith(testPayload);
118
+ });
119
+ it('should handle base64 encoded pub message', async () => {
120
+ const fn = jest.fn();
121
+ const topic = 'base64/test';
122
+ const testPayload = { command: 'start', value: 100 };
123
+ realtime.subscribe(topic, fn);
124
+ const originalMessage = {
125
+ type: 'pub',
126
+ topic: topic,
127
+ payload: testPayload
128
+ };
129
+ const jsonStr = JSON.stringify(originalMessage);
130
+ const base64Message = Buffer.from(jsonStr).toString('base64');
131
+ await realtime.handle(Buffer.from(base64Message), null, 'device-002');
132
+ await new Promise(resolve => setTimeout(resolve, 50));
133
+ expect(fn).toHaveBeenCalledTimes(1);
134
+ expect(fn).toHaveBeenCalledWith(testPayload);
135
+ });
136
+ it('should handle hex encoded pub message', async () => {
137
+ const fn = jest.fn();
138
+ const topic = 'hex/test';
139
+ const testPayload = { command: 'toggle', state: true };
140
+ realtime.subscribe(topic, fn);
141
+ const originalMessage = {
142
+ type: 'pub',
143
+ topic: topic,
144
+ payload: testPayload
145
+ };
146
+ const jsonStr = JSON.stringify(originalMessage);
147
+ const hexMessage = Buffer.from(jsonStr).toString('hex');
148
+ await realtime.handle(Buffer.from(hexMessage), null, 'device-003');
149
+ await new Promise(resolve => setTimeout(resolve, 50));
150
+ expect(fn).toHaveBeenCalledTimes(1);
151
+ expect(fn).toHaveBeenCalledWith(testPayload);
152
+ });
153
+ });
154
+ describe('Device Management', () => {
155
+ it('should register and track devices', () => {
156
+ const deviceId = 'device-001';
157
+ const mockSocket = new MockWebSocket();
158
+ realtime.register(deviceId, mockSocket, { type: 'sensor' });
159
+ const socket = realtime.getSocket(deviceId);
160
+ expect(socket).toBe(mockSocket);
161
+ });
162
+ it('should handle device heartbeat', () => {
163
+ const deviceId = 'device-002';
164
+ realtime.register(deviceId);
165
+ realtime.touch(deviceId);
166
+ const stats = realtime.getStats();
167
+ expect(stats.devices).toBe(1);
168
+ });
169
+ it('should unregister devices', () => {
170
+ const deviceId = 'device-003';
171
+ const mockSocket = new MockWebSocket();
172
+ realtime.register(deviceId, mockSocket);
173
+ expect(realtime.getSocket(deviceId)).toBe(mockSocket);
174
+ realtime.unregister(deviceId);
175
+ expect(realtime.getSocket(deviceId)).toBeUndefined();
176
+ expect(mockSocket.closed).toBe(true);
177
+ });
178
+ });
179
+ describe('Broadcast', () => {
180
+ it('should broadcast to all devices', () => {
181
+ const device1 = new MockWebSocket();
182
+ const device2 = new MockWebSocket();
183
+ realtime.register('device-1', device1);
184
+ realtime.register('device-2', device2);
185
+ realtime.broadcast('test', { data: 'test' });
186
+ expect(device1.messages.length).toBeGreaterThan(0);
187
+ expect(device2.messages.length).toBeGreaterThan(0);
188
+ });
189
+ it('should exclude specific devices from broadcast', () => {
190
+ const device1 = new MockWebSocket();
191
+ const device2 = new MockWebSocket();
192
+ realtime.register('device-1', device1);
193
+ realtime.register('device-2', device2);
194
+ realtime.broadcast('test', { data: 'test' }, { exclude: ['device-1'] });
195
+ expect(device1.messages.length).toBe(0);
196
+ expect(device2.messages.length).toBeGreaterThan(0);
197
+ });
198
+ });
199
+ describe('Performance', () => {
200
+ it('should respect max message size', () => {
201
+ const largePayload = { data: 'x'.repeat(1024 * 1024 + 1) };
202
+ expect(() => {
203
+ realtime.publish('test/large', largePayload);
204
+ }).toThrow('Payload too large');
205
+ });
206
+ it('should cache JSON serialization results', () => {
207
+ const payload = { repeated: 'data', value: 123 };
208
+ const cachedRealtime = new core_1.RealtimeCore({ enableJSONCache: true, debug: false });
209
+ createdInstances.push(cachedRealtime);
210
+ cachedRealtime.publish('test', payload);
211
+ const start1 = Date.now();
212
+ cachedRealtime.publish('test', payload);
213
+ const time1 = Date.now() - start1;
214
+ const start2 = Date.now();
215
+ cachedRealtime.publish('test', payload);
216
+ const time2 = Date.now() - start2;
217
+ expect(time2).toBeLessThanOrEqual(time1 + 10);
218
+ const stats = cachedRealtime.getStats();
219
+ expect(stats.cacheEnabled).toBe(true);
220
+ });
221
+ });
222
+ describe('ACL', () => {
223
+ it('should enforce subscribe ACL', () => {
224
+ const aclRealtime = new core_1.RealtimeCore({
225
+ acl: {
226
+ canSubscribe: (deviceId, topic) => deviceId === 'allowed-device' && topic === 'allowed/topic',
227
+ canPublish: () => true
228
+ },
229
+ debug: false
230
+ });
231
+ createdInstances.push(aclRealtime);
232
+ const fn = jest.fn();
233
+ expect(() => {
234
+ aclRealtime.subscribe('allowed/topic', fn, 'allowed-device');
235
+ }).not.toThrow();
236
+ expect(() => {
237
+ aclRealtime.subscribe('forbidden/topic', fn, 'bad-device');
238
+ }).toThrow('ACL deny');
239
+ });
240
+ it('should enforce publish ACL', () => {
241
+ const aclRealtime = new core_1.RealtimeCore({
242
+ acl: {
243
+ canSubscribe: () => true,
244
+ canPublish: (deviceId, topic) => deviceId === 'allowed-device' && topic === 'allowed/topic'
245
+ },
246
+ debug: false
247
+ });
248
+ createdInstances.push(aclRealtime);
249
+ expect(() => {
250
+ aclRealtime.publish('allowed/topic', { data: 'test' }, {}, 'allowed-device');
251
+ }).not.toThrow();
252
+ expect(() => {
253
+ aclRealtime.publish('forbidden/topic', { data: 'test' }, {}, 'bad-device');
254
+ }).toThrow('ACL deny');
255
+ });
256
+ });
257
+ describe('Error Handling', () => {
258
+ it('should handle socket send errors', () => {
259
+ const faultySocket = new MockWebSocket();
260
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
261
+ faultySocket.send = jest.fn(() => { throw new Error('Send failed'); });
262
+ realtime.register('faulty-device', faultySocket);
263
+ expect(() => {
264
+ realtime.broadcast('test', { data: 'test' });
265
+ }).not.toThrow();
266
+ expect(faultySocket.send).toHaveBeenCalled();
267
+ consoleSpy.mockRestore();
268
+ });
269
+ });
270
+ });
271
+ //# sourceMappingURL=realtime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.test.js","sourceRoot":"","sources":["../../realtime/realtime.test.ts"],"names":[],"mappings":"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"}