@phystack/device-simulator 6.3.5 → 6.3.7

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 (100) hide show
  1. package/dist/command.d.ts +6 -0
  2. package/dist/command.d.ts.map +1 -0
  3. package/dist/command.js +44 -0
  4. package/dist/command.js.map +1 -0
  5. package/dist/commands/list.d.ts +2 -0
  6. package/dist/commands/list.d.ts.map +1 -0
  7. package/dist/commands/list.js +20 -0
  8. package/dist/commands/list.js.map +1 -0
  9. package/dist/commands/remove.d.ts +2 -0
  10. package/dist/commands/remove.d.ts.map +1 -0
  11. package/dist/commands/remove.js +19 -0
  12. package/dist/commands/remove.js.map +1 -0
  13. package/dist/commands/run.d.ts +13 -0
  14. package/dist/commands/run.d.ts.map +1 -0
  15. package/dist/commands/run.js +356 -0
  16. package/dist/commands/run.js.map +1 -0
  17. package/dist/commands/start.d.ts +6 -0
  18. package/dist/commands/start.d.ts.map +1 -0
  19. package/dist/commands/start.js +216 -0
  20. package/dist/commands/start.js.map +1 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/services/dev-token.d.ts +2 -0
  25. package/dist/services/dev-token.d.ts.map +1 -0
  26. package/dist/services/dev-token.js +36 -0
  27. package/dist/services/dev-token.js.map +1 -0
  28. package/dist/services/env.d.ts +2 -0
  29. package/dist/services/env.d.ts.map +1 -0
  30. package/dist/services/env.js +14 -0
  31. package/dist/services/env.js.map +1 -0
  32. package/dist/simulator/index.d.ts +19 -0
  33. package/dist/simulator/index.d.ts.map +1 -0
  34. package/dist/simulator/index.js +158 -0
  35. package/dist/simulator/index.js.map +1 -0
  36. package/dist/simulator/local-server.d.ts +24 -0
  37. package/dist/simulator/local-server.d.ts.map +1 -0
  38. package/dist/simulator/local-server.js +125 -0
  39. package/dist/simulator/local-server.js.map +1 -0
  40. package/dist/simulator/logger.d.ts +11 -0
  41. package/dist/simulator/logger.d.ts.map +1 -0
  42. package/dist/simulator/logger.js +42 -0
  43. package/dist/simulator/logger.js.map +1 -0
  44. package/dist/simulator/message-router.d.ts +34 -0
  45. package/dist/simulator/message-router.d.ts.map +1 -0
  46. package/dist/simulator/message-router.js +409 -0
  47. package/dist/simulator/message-router.js.map +1 -0
  48. package/dist/simulator/twin-cache.d.ts +16 -0
  49. package/dist/simulator/twin-cache.d.ts.map +1 -0
  50. package/dist/simulator/twin-cache.js +54 -0
  51. package/dist/simulator/twin-cache.js.map +1 -0
  52. package/dist/simulator/types.d.ts +48 -0
  53. package/dist/simulator/types.d.ts.map +1 -0
  54. package/dist/simulator/types.js +16 -0
  55. package/dist/simulator/types.js.map +1 -0
  56. package/dist/utils/config-paths.d.ts +12 -0
  57. package/dist/utils/config-paths.d.ts.map +1 -0
  58. package/dist/utils/config-paths.js +33 -0
  59. package/dist/utils/config-paths.js.map +1 -0
  60. package/dist/utils/index.d.ts +4 -0
  61. package/dist/utils/index.d.ts.map +1 -0
  62. package/dist/utils/index.js +42 -0
  63. package/dist/utils/index.js.map +1 -0
  64. package/dist/utils/simulator-config.d.ts +25 -0
  65. package/dist/utils/simulator-config.d.ts.map +1 -0
  66. package/dist/utils/simulator-config.js +140 -0
  67. package/dist/utils/simulator-config.js.map +1 -0
  68. package/dist/utils/tenant-storage.d.ts +14 -0
  69. package/dist/utils/tenant-storage.d.ts.map +1 -0
  70. package/dist/utils/tenant-storage.js +65 -0
  71. package/dist/utils/tenant-storage.js.map +1 -0
  72. package/package.json +5 -2
  73. package/CHANGELOG.md +0 -51
  74. package/build-binary.sh +0 -37
  75. package/src/__tests__/e2e/binary.e2e.test.ts +0 -394
  76. package/src/__tests__/preload.ts +0 -44
  77. package/src/command.ts +0 -66
  78. package/src/commands/__tests__/run-helpers.test.ts +0 -181
  79. package/src/commands/list.ts +0 -25
  80. package/src/commands/remove.ts +0 -16
  81. package/src/commands/run.ts +0 -518
  82. package/src/commands/start.ts +0 -309
  83. package/src/index.ts +0 -46
  84. package/src/services/__tests__/dev-token.test.ts +0 -156
  85. package/src/services/dev-token.ts +0 -52
  86. package/src/services/env.ts +0 -10
  87. package/src/simulator/__tests__/message-router.test.ts +0 -782
  88. package/src/simulator/__tests__/twin-cache.test.ts +0 -129
  89. package/src/simulator/index.ts +0 -200
  90. package/src/simulator/local-server.ts +0 -184
  91. package/src/simulator/logger.ts +0 -44
  92. package/src/simulator/message-router.ts +0 -525
  93. package/src/simulator/twin-cache.ts +0 -61
  94. package/src/simulator/types.ts +0 -53
  95. package/src/utils/__tests__/simulator-config.test.ts +0 -230
  96. package/src/utils/config-paths.ts +0 -38
  97. package/src/utils/index.ts +0 -41
  98. package/src/utils/simulator-config.ts +0 -185
  99. package/src/utils/tenant-storage.ts +0 -106
  100. package/tsconfig.json +0 -12
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalServer = void 0;
4
+ const http_1 = require("http");
5
+ const events_1 = require("events");
6
+ const socket_io_1 = require("socket.io");
7
+ class LocalServer extends events_1.EventEmitter {
8
+ httpServer = null;
9
+ io = null;
10
+ port;
11
+ router = null;
12
+ connectedClients = new Map();
13
+ eventDebounceTimers = new Map();
14
+ constructor(port = 55000) {
15
+ super();
16
+ this.port = port;
17
+ }
18
+ getIO() {
19
+ return this.io;
20
+ }
21
+ setRouter(router) {
22
+ this.router = router;
23
+ }
24
+ start() {
25
+ this.httpServer = (0, http_1.createServer)((_req, res) => {
26
+ res.writeHead(200, { "Content-Type": "application/json" });
27
+ res.end(JSON.stringify({ status: "ok", simulator: true }));
28
+ });
29
+ this.io = new socket_io_1.Server(this.httpServer, {
30
+ cors: { origin: "*" },
31
+ });
32
+ this.io.on("connection", (socket) => {
33
+ this.setupSocketHandlers(socket);
34
+ });
35
+ return new Promise((resolve, reject) => {
36
+ this.httpServer.listen(this.port, "127.0.0.1", () => {
37
+ resolve();
38
+ });
39
+ this.httpServer.on("error", reject);
40
+ });
41
+ }
42
+ setupSocketHandlers(socket) {
43
+ const auth = (socket.handshake.auth || {});
44
+ const twinId = auth.instanceId || auth.moduleName;
45
+ socket.on("simulator", async (payload, callback) => {
46
+ if (this.router) {
47
+ await this.router.handleMessage(socket, "", payload, callback);
48
+ }
49
+ });
50
+ socket.on("ping", (data) => {
51
+ setTimeout(() => {
52
+ socket.emit("pong", { count: (data?.count || 0) + 1 });
53
+ }, 100);
54
+ });
55
+ if (!twinId)
56
+ return;
57
+ if (!this.connectedClients.has(twinId)) {
58
+ this.connectedClients.set(twinId, []);
59
+ }
60
+ this.connectedClients.get(twinId).push(socket);
61
+ this.emitDebounced(twinId);
62
+ socket.join(twinId);
63
+ socket.on("disconnect", () => {
64
+ const sockets = this.connectedClients.get(twinId);
65
+ if (sockets) {
66
+ const idx = sockets.indexOf(socket);
67
+ if (idx !== -1)
68
+ sockets.splice(idx, 1);
69
+ if (sockets.length === 0)
70
+ this.connectedClients.delete(twinId);
71
+ }
72
+ this.emitDebounced(twinId);
73
+ });
74
+ socket.on(twinId, async (payload, callback) => {
75
+ if (this.router) {
76
+ await this.router.handleMessage(socket, twinId, payload, callback);
77
+ }
78
+ });
79
+ socket.on("reconnect", () => {
80
+ socket.join(twinId);
81
+ });
82
+ socket.on("getDeviceTwin", (callback) => {
83
+ if (this.router) {
84
+ const result = this.router.handleLocalMethod("getDeviceInstance", {});
85
+ if (result && typeof result.then === "function") {
86
+ result.then((r) => callback(r?.twin || {}));
87
+ }
88
+ else {
89
+ callback(result?.twin || {});
90
+ }
91
+ }
92
+ });
93
+ }
94
+ stop() {
95
+ return new Promise((resolve) => {
96
+ if (this.io) {
97
+ this.io.disconnectSockets(true);
98
+ this.io.close();
99
+ }
100
+ if (this.httpServer) {
101
+ this.httpServer.close(() => resolve());
102
+ }
103
+ else {
104
+ resolve();
105
+ }
106
+ });
107
+ }
108
+ getConnectedClients() {
109
+ return Array.from(this.connectedClients.keys());
110
+ }
111
+ emitDebounced(twinId) {
112
+ const existing = this.eventDebounceTimers.get(twinId);
113
+ if (existing)
114
+ clearTimeout(existing);
115
+ const timer = setTimeout(() => {
116
+ this.eventDebounceTimers.delete(twinId);
117
+ const isConnected = this.connectedClients.has(twinId);
118
+ const event = isConnected ? "instanceConnected" : "instanceDisconnected";
119
+ this.emit(event, { twinId, activeCount: this.connectedClients.size });
120
+ }, 500);
121
+ this.eventDebounceTimers.set(twinId, timer);
122
+ }
123
+ }
124
+ exports.LocalServer = LocalServer;
125
+ //# sourceMappingURL=local-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-server.js","sourceRoot":"","sources":["../../src/simulator/local-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare class SimulatorLogger {
2
+ log(message: string): void;
3
+ info(message: string): void;
4
+ success(message: string): void;
5
+ warn(message: string): void;
6
+ error(message: string): void;
7
+ dim(message: string): void;
8
+ printBanner(lines: string[]): void;
9
+ }
10
+ export declare const simulatorLog: SimulatorLogger;
11
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/simulator/logger.ts"],"names":[],"mappings":"AAWA,qBAAa,eAAe;IAC1B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;CAKnC;AAED,eAAO,MAAM,YAAY,iBAAwB,CAAC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.simulatorLog = exports.SimulatorLogger = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ function timestamp() {
9
+ const now = new Date();
10
+ const h = String(now.getHours()).padStart(2, "0");
11
+ const m = String(now.getMinutes()).padStart(2, "0");
12
+ const s = String(now.getSeconds()).padStart(2, "0");
13
+ return chalk_1.default.dim(`[${h}:${m}:${s}]`);
14
+ }
15
+ class SimulatorLogger {
16
+ log(message) {
17
+ console.log(`${timestamp()} ${message}`);
18
+ }
19
+ info(message) {
20
+ this.log(message);
21
+ }
22
+ success(message) {
23
+ this.log(chalk_1.default.green(message));
24
+ }
25
+ warn(message) {
26
+ this.log(chalk_1.default.yellow(message));
27
+ }
28
+ error(message) {
29
+ this.log(chalk_1.default.red(message));
30
+ }
31
+ dim(message) {
32
+ this.log(chalk_1.default.dim(message));
33
+ }
34
+ printBanner(lines) {
35
+ for (const line of lines) {
36
+ console.log(line);
37
+ }
38
+ }
39
+ }
40
+ exports.SimulatorLogger = SimulatorLogger;
41
+ exports.simulatorLog = new SimulatorLogger();
42
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/simulator/logger.ts"],"names":[],"mappings":";;;;;;AACA,kDAA0B;AAE1B,SAAS,SAAS;IAChB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,MAAa,eAAe;IAC1B,GAAG,CAAC,OAAe;QACjB,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,OAAe;QACrB,IAAI,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAe;QACnB,IAAI,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,OAAe;QACjB,IAAI,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,WAAW,CAAC,KAAe;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;CACF;AA9BD,0CA8BC;AAEY,QAAA,YAAY,GAAG,IAAI,eAAe,EAAE,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { Socket } from "socket.io";
2
+ import { TwinCache } from "./twin-cache";
3
+ import { EventPayload, TwinResponse } from "./types";
4
+ export declare class MessageRouter {
5
+ private twinCache;
6
+ private twinSubscriptions;
7
+ private messageDeliveryTracker;
8
+ private readonly MAX_TRACKED_MESSAGES;
9
+ private io;
10
+ constructor(twinCache: TwinCache, io: any);
11
+ handleMessage(socket: Socket, callerTwinId: string, payload: EventPayload, callback?: Function): Promise<any>;
12
+ handleIncomingTwinMessage(payload: EventPayload): void;
13
+ handleIncomingTwinUpdated(twin: TwinResponse): void;
14
+ private respond;
15
+ private handleGetDeviceStatus;
16
+ private handleGetDeviceInstance;
17
+ private handleGetTwinById;
18
+ private handleCreateInstanceTwin;
19
+ private handleCreatePeripheralTwin;
20
+ private handleDeletePeripheralTwin;
21
+ private handleGetPeripheralTwins;
22
+ private handleReportProperties;
23
+ private handleReportDeviceProperties;
24
+ private handleTwinSubscribe;
25
+ private handleTwinUnsubscribe;
26
+ private getSocketsFromARoom;
27
+ private generateMessageId;
28
+ private trackMessageDelivery;
29
+ private hasMessageBeenDelivered;
30
+ private handleTwinMessageFromSubscription;
31
+ private deliverTwinMessageLocally;
32
+ private createLocalTwin;
33
+ }
34
+ //# sourceMappingURL=message-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-router.d.ts","sourceRoot":"","sources":["../../src/simulator/message-router.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAgB,MAAM,SAAS,CAAC;AAmBnE,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAY;IAE7B,OAAO,CAAC,iBAAiB,CAAuC;IAEhE,OAAO,CAAC,sBAAsB,CAAuC;IAErE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAQ;IAE7C,OAAO,CAAC,EAAE,CAAM;gBAEJ,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG;IAKnC,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,YAAY,EACrB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,GAAG,CAAC;IA6Gf,yBAAyB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAKtD,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IASnD,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,qBAAqB;IAyB7B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,0BAA0B;IA6DlC,OAAO,CAAC,0BAA0B;IAiBlC,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,4BAA4B;IAgBpC,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,iCAAiC;IAmBzC,OAAO,CAAC,yBAAyB;IAiGjC,OAAO,CAAC,eAAe;CAiBxB"}
@@ -0,0 +1,409 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MessageRouter = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const uuid_1 = require("uuid");
6
+ const types_1 = require("./types");
7
+ const logger_1 = require("./logger");
8
+ const utils_1 = require("../utils");
9
+ const UNSUPPORTED_METHODS = new Set([
10
+ "setWirelessNetwork",
11
+ "setLanNetwork",
12
+ "reboot",
13
+ "setEnv",
14
+ ]);
15
+ const SIGNAL_METHODS = new Set([
16
+ "sendEventSignal",
17
+ "sendSessionSignal",
18
+ "sendClientSignal",
19
+ ]);
20
+ class MessageRouter {
21
+ twinCache;
22
+ twinSubscriptions = new Map();
23
+ messageDeliveryTracker = new Map();
24
+ MAX_TRACKED_MESSAGES = 1000;
25
+ io;
26
+ constructor(twinCache, io) {
27
+ this.twinCache = twinCache;
28
+ this.io = io;
29
+ }
30
+ async handleMessage(socket, callerTwinId, payload, callback) {
31
+ const { method } = payload;
32
+ logger_1.simulatorLog.dim(`← ${callerTwinId} ${method || "(no method)"} ${payload.twinId ? `→ ${payload.twinId}` : ""}`);
33
+ if (!method) {
34
+ logger_1.simulatorLog.warn(`Received event without method from ${callerTwinId}, ignoring`);
35
+ if (callback)
36
+ callback({ status: "error", message: "No method specified" });
37
+ return undefined;
38
+ }
39
+ if (UNSUPPORTED_METHODS.has(method)) {
40
+ const result = {
41
+ status: "error",
42
+ message: `${method} is not supported in simulator mode`,
43
+ };
44
+ if (callback)
45
+ callback(result);
46
+ return result;
47
+ }
48
+ if (SIGNAL_METHODS.has(method)) {
49
+ const signalData = payload.data || {};
50
+ logger_1.simulatorLog.info(`Signal [${method}] from ${callerTwinId}: ${JSON.stringify(signalData)}`);
51
+ const result = { status: "success" };
52
+ if (callback)
53
+ callback(result);
54
+ return result;
55
+ }
56
+ switch (method) {
57
+ case "getDeviceStatus":
58
+ return this.respond(callback, this.handleGetDeviceStatus());
59
+ case "getInstance":
60
+ case "getDeviceInstance":
61
+ return this.respond(callback, this.handleGetDeviceInstance());
62
+ case "getTwinById":
63
+ return this.respond(callback, this.handleGetTwinById(payload));
64
+ case "ping":
65
+ return this.respond(callback, { status: "success", message: "pong" });
66
+ case "twinMessage":
67
+ this.deliverTwinMessageLocally(callerTwinId, payload, callback);
68
+ return undefined;
69
+ case "twinSubscribe":
70
+ if (payload.twinId) {
71
+ this.handleTwinSubscribe(socket, callerTwinId, payload.twinId);
72
+ logger_1.simulatorLog.info(`twinSubscribe: ${callerTwinId} now listening to ${payload.twinId}`);
73
+ }
74
+ if (callback)
75
+ callback({ status: "success" });
76
+ return undefined;
77
+ case "twinUnsubscribe":
78
+ if (payload.twinId) {
79
+ this.handleTwinUnsubscribe(callerTwinId, payload.twinId);
80
+ }
81
+ if (callback)
82
+ callback({ status: "success" });
83
+ return undefined;
84
+ case "createInstanceTwin":
85
+ return this.respond(callback, this.handleCreateInstanceTwin(payload));
86
+ case "createPeripheralTwin":
87
+ return this.respond(callback, this.handleCreatePeripheralTwin(payload));
88
+ case "deletePeripheralTwin":
89
+ return this.respond(callback, this.handleDeletePeripheralTwin(payload));
90
+ case "getPeripheralTwins":
91
+ return this.respond(callback, this.handleGetPeripheralTwins(payload));
92
+ case "reportScreenTwinProperties":
93
+ case "reportEdgeTwinProperties":
94
+ case "reportPeripheralTwinProperties":
95
+ return this.respond(callback, this.handleReportProperties(method, payload));
96
+ case "reportDeviceTwinProperties":
97
+ return this.respond(callback, this.handleReportDeviceProperties(payload));
98
+ case "reportDeviceJob":
99
+ logger_1.simulatorLog.dim("Device job reported (local mode, no-op)");
100
+ return this.respond(callback, { status: "success" });
101
+ default:
102
+ logger_1.simulatorLog.warn(`Unknown method: ${method}`);
103
+ return this.respond(callback, {
104
+ status: "error",
105
+ message: `Unknown method: ${method}`,
106
+ });
107
+ }
108
+ }
109
+ handleIncomingTwinMessage(payload) {
110
+ this.deliverTwinMessageLocally("", payload);
111
+ }
112
+ handleIncomingTwinUpdated(twin) {
113
+ this.twinCache.updateTwin(twin);
114
+ this.io.to(twin.id).emit("twinMessage", {
115
+ method: "twinUpdated",
116
+ twinId: twin.id,
117
+ data: twin,
118
+ });
119
+ }
120
+ respond(callback, result) {
121
+ if (callback)
122
+ callback(result);
123
+ return result;
124
+ }
125
+ handleGetDeviceStatus() {
126
+ const deviceTwin = this.twinCache.getDeviceTwin();
127
+ const desired = deviceTwin?.properties?.desired || {};
128
+ const reported = deviceTwin?.properties?.reported || {};
129
+ return {
130
+ status: "success",
131
+ socketConnected: true,
132
+ socketAuthenticated: true,
133
+ twins: this.twinCache.getGroupedByType(),
134
+ deviceId: deviceTwin?.deviceId,
135
+ tenantId: deviceTwin?.tenantId,
136
+ displayName: desired.displayName || "Simulator",
137
+ spaceId: desired.spaceId || "",
138
+ gridEnv: desired.env || "development",
139
+ dataResidency: "DEV",
140
+ accessKey: desired.accessKey || "simulator-local-key",
141
+ deviceSerial: desired.deviceSerial || "SIM-LOCAL",
142
+ osVersion: reported.os?.osVersion || "Simulator",
143
+ deviceEnv: desired.env || "development",
144
+ ip: reported.ip || [{ interface: "lo", ipv4: "127.0.0.1", ipv6: "::1" }],
145
+ isConnected: "true",
146
+ provisioningCode: "",
147
+ };
148
+ }
149
+ handleGetDeviceInstance() {
150
+ const deviceTwin = this.twinCache.getDeviceTwin();
151
+ if (deviceTwin) {
152
+ return { status: "success", twin: deviceTwin };
153
+ }
154
+ return { status: "error", message: "Device twin not found" };
155
+ }
156
+ handleGetTwinById(payload) {
157
+ const twinId = payload.data?.twinId;
158
+ if (!twinId) {
159
+ return { status: "error", message: "Twin ID is required" };
160
+ }
161
+ const twin = this.twinCache.getTwin(twinId);
162
+ if (twin) {
163
+ return { status: "success", twin };
164
+ }
165
+ return { status: "error", message: "Twin not found" };
166
+ }
167
+ handleCreateInstanceTwin(payload) {
168
+ const { type, desiredProperties, id } = payload.data || {};
169
+ const deviceTwin = this.twinCache.getDeviceTwin();
170
+ const twin = this.createLocalTwin(type || types_1.TwinTypeEnum.Screen, desiredProperties || {}, deviceTwin, id);
171
+ this.twinCache.addTwin(twin);
172
+ this.io.emit("twinCreated", { data: twin });
173
+ logger_1.simulatorLog.info(`Twin created: ${JSON.stringify(twin)}`);
174
+ return { status: "success", twin };
175
+ }
176
+ handleCreatePeripheralTwin(payload) {
177
+ const { deviceId, tenantId, instanceId, peripheralName, hardwareId, desiredProperties, descriptors, } = payload.data || {};
178
+ if (!instanceId || !hardwareId) {
179
+ return {
180
+ status: "error",
181
+ message: "instanceId and hardwareId are required",
182
+ };
183
+ }
184
+ const deviceTwin = this.twinCache.getDeviceTwin();
185
+ const twinId = (0, utils_1.mockObjectId)(`${instanceId}:${hardwareId}`);
186
+ const existingTwin = this.twinCache.getTwin(twinId);
187
+ const twin = {
188
+ id: twinId,
189
+ deviceId: deviceId || deviceTwin?.deviceId || (0, uuid_1.v4)(),
190
+ tenantId: tenantId || deviceTwin?.tenantId || (0, uuid_1.v4)(),
191
+ type: types_1.TwinTypeEnum.Peripheral,
192
+ properties: {
193
+ desired: {
194
+ ...desiredProperties,
195
+ peripheralName,
196
+ hardwareId,
197
+ instanceId,
198
+ },
199
+ reported: existingTwin?.properties.reported ?? {},
200
+ },
201
+ descriptors: descriptors ?? {},
202
+ };
203
+ this.twinCache.addTwin(twin);
204
+ this.io.emit("twinCreated", { data: twin, twinId: twin.id });
205
+ if (existingTwin) {
206
+ logger_1.simulatorLog.info(`Peripheral twin refreshed: ${twin.id} (${peripheralName}, owner ${instanceId})`);
207
+ }
208
+ else {
209
+ logger_1.simulatorLog.info(`Peripheral twin created: ${JSON.stringify(twin)}`);
210
+ }
211
+ return { status: "success", twin };
212
+ }
213
+ handleDeletePeripheralTwin(payload) {
214
+ const twinId = payload.data?.twinId || payload.twinId;
215
+ if (!twinId) {
216
+ return { status: "error", message: "Twin ID is required" };
217
+ }
218
+ const twin = this.twinCache.getTwin(twinId);
219
+ if (!twin) {
220
+ return { status: "error", message: "Twin not found" };
221
+ }
222
+ this.twinCache.removeTwin(twinId);
223
+ this.io.emit("twinDeleted", { data: twin, twinId: twin.id });
224
+ logger_1.simulatorLog.info(`Peripheral twin deleted: ${twin.id} (${twin.properties?.desired?.peripheralName})`);
225
+ return { status: "success" };
226
+ }
227
+ handleGetPeripheralTwins(payload) {
228
+ const instanceId = payload.data?.instanceId;
229
+ let peripherals = this.twinCache.getTwinsByType(types_1.TwinTypeEnum.Peripheral);
230
+ if (instanceId) {
231
+ peripherals = peripherals.filter((twin) => twin.properties?.desired?.instanceId === instanceId);
232
+ }
233
+ return { status: "success", twins: peripherals };
234
+ }
235
+ handleReportProperties(method, payload) {
236
+ const twinId = payload.twinId;
237
+ const properties = payload.data;
238
+ if (!twinId) {
239
+ return { status: "error", message: "Twin ID is required" };
240
+ }
241
+ const twin = this.twinCache.getTwin(twinId);
242
+ if (!twin) {
243
+ return { status: "error", message: "Twin not found" };
244
+ }
245
+ if (properties) {
246
+ twin.properties.reported = { ...twin.properties.reported, ...properties };
247
+ this.twinCache.updateTwin(twin);
248
+ this.handleIncomingTwinUpdated(twin);
249
+ }
250
+ return { status: "success", twin };
251
+ }
252
+ handleReportDeviceProperties(payload) {
253
+ const properties = payload.data?.properties || payload.data?.reported;
254
+ const deviceTwin = this.twinCache.getDeviceTwin();
255
+ if (deviceTwin && properties) {
256
+ deviceTwin.properties.reported = {
257
+ ...deviceTwin.properties.reported,
258
+ ...properties,
259
+ };
260
+ this.twinCache.updateTwin(deviceTwin);
261
+ logger_1.simulatorLog.dim("Device twin properties reported");
262
+ this.handleIncomingTwinUpdated(deviceTwin);
263
+ }
264
+ return { status: "success" };
265
+ }
266
+ handleTwinSubscribe(socket, subscriberTwinId, targetTwinId) {
267
+ if (!this.twinSubscriptions.has(subscriberTwinId)) {
268
+ this.twinSubscriptions.set(subscriberTwinId, new Set());
269
+ }
270
+ this.twinSubscriptions.get(subscriberTwinId).add(targetTwinId);
271
+ socket.join(targetTwinId);
272
+ logger_1.simulatorLog.dim(`Twin ${subscriberTwinId} subscribed to ${targetTwinId}`);
273
+ }
274
+ handleTwinUnsubscribe(subscriberTwinId, targetTwinId) {
275
+ const subscriptions = this.twinSubscriptions.get(subscriberTwinId);
276
+ if (subscriptions) {
277
+ subscriptions.delete(targetTwinId);
278
+ if (subscriptions.size === 0) {
279
+ this.twinSubscriptions.delete(subscriberTwinId);
280
+ }
281
+ }
282
+ logger_1.simulatorLog.dim(`Twin ${subscriberTwinId} unsubscribed from ${targetTwinId}`);
283
+ }
284
+ getSocketsFromARoom(roomName) {
285
+ const sockets = [];
286
+ const socketIds = this.io.sockets?.adapter?.rooms?.get(roomName);
287
+ socketIds?.forEach((socketId) => {
288
+ const socket = this.io.sockets?.sockets?.get(socketId);
289
+ if (socket)
290
+ sockets.push(socket);
291
+ });
292
+ return sockets;
293
+ }
294
+ generateMessageId(payload) {
295
+ const { twinId, sourceTwinId, method, data } = payload;
296
+ const timestamp = Math.floor(Date.now() / 3000) * 3;
297
+ const dataString = data
298
+ ? JSON.stringify(data, (_, value) => Buffer.isBuffer(value) ? value.toString("base64") : value)
299
+ : "";
300
+ const hash = (0, crypto_1.createHash)("sha256")
301
+ .update(`${twinId}-${sourceTwinId}-${method}-${dataString}-${timestamp}`)
302
+ .digest("hex");
303
+ return hash;
304
+ }
305
+ trackMessageDelivery(messageId, recipientId) {
306
+ if (!this.messageDeliveryTracker.has(messageId)) {
307
+ this.messageDeliveryTracker.set(messageId, new Set());
308
+ if (this.messageDeliveryTracker.size > this.MAX_TRACKED_MESSAGES) {
309
+ const oldestKey = this.messageDeliveryTracker.keys().next().value;
310
+ if (oldestKey) {
311
+ this.messageDeliveryTracker.delete(oldestKey);
312
+ }
313
+ }
314
+ }
315
+ this.messageDeliveryTracker.get(messageId).add(recipientId);
316
+ }
317
+ hasMessageBeenDelivered(messageId, recipientId) {
318
+ return (this.messageDeliveryTracker.get(messageId)?.has(recipientId) || false);
319
+ }
320
+ handleTwinMessageFromSubscription(subscriberTwinId, payload, callback) {
321
+ const { twinId } = payload;
322
+ const roomSockets = this.getSocketsFromARoom(subscriberTwinId);
323
+ roomSockets.forEach((roomSocket) => {
324
+ roomSocket.emit("twinMessage", payload, (response) => {
325
+ if (twinId && payload.data?.type) {
326
+ roomSocket.to(twinId).emit(payload.data.type, response);
327
+ }
328
+ if (callback)
329
+ callback(response);
330
+ });
331
+ });
332
+ }
333
+ deliverTwinMessageLocally(callerTwinId, payload, callback) {
334
+ const { twinId, sourceTwinId } = payload;
335
+ if (!twinId) {
336
+ logger_1.simulatorLog.warn("twinMessage: no target twinId, dropping");
337
+ return;
338
+ }
339
+ const dataType = payload.data?.type || "(no type)";
340
+ const webrtcMatch = dataType.match(/^(.+):(offer|answer|ice)$/);
341
+ if (webrtcMatch) {
342
+ const [, channelPrefix, signalType] = webrtcMatch;
343
+ const isData = channelPrefix.startsWith("dc-");
344
+ const kind = isData ? "DataChannel" : "MediaStream";
345
+ logger_1.simulatorLog.info(`⚡ WebRTC ${signalType} (${kind}): ${sourceTwinId || "?"} → ${twinId}`);
346
+ }
347
+ else {
348
+ logger_1.simulatorLog.info(`twinMessage: ${sourceTwinId || "?"} → ${twinId} [${dataType}]`);
349
+ }
350
+ const messageId = this.generateMessageId(payload);
351
+ this.twinSubscriptions.forEach((subscribedTwins, subscriberTwinId) => {
352
+ if (subscribedTwins.has(twinId) &&
353
+ !this.hasMessageBeenDelivered(messageId, subscriberTwinId)) {
354
+ this.handleTwinMessageFromSubscription(subscriberTwinId, payload, callback);
355
+ this.trackMessageDelivery(messageId, subscriberTwinId);
356
+ }
357
+ });
358
+ const deviceTwins = this.twinCache.getGroupedByType();
359
+ if (deviceTwins[types_1.TwinTypeEnum.Edge]) {
360
+ for (const edgeTwinId of deviceTwins[types_1.TwinTypeEnum.Edge]) {
361
+ const edgeTwin = this.twinCache.getTwin(edgeTwinId);
362
+ if (edgeTwin &&
363
+ edgeTwin.id === twinId &&
364
+ !this.hasMessageBeenDelivered(messageId, edgeTwin.id)) {
365
+ this.io.to(edgeTwin.id).emit("twinMessage", payload, callback);
366
+ this.trackMessageDelivery(messageId, edgeTwin.id);
367
+ }
368
+ }
369
+ }
370
+ if (deviceTwins[types_1.TwinTypeEnum.Screen]) {
371
+ for (const screenTwinId of deviceTwins[types_1.TwinTypeEnum.Screen]) {
372
+ const screenTwin = this.twinCache.getTwin(screenTwinId);
373
+ if (screenTwin &&
374
+ screenTwin.id === twinId &&
375
+ !this.hasMessageBeenDelivered(messageId, screenTwin.id)) {
376
+ this.io.to(screenTwin.id).emit("twinMessage", payload, callback);
377
+ this.trackMessageDelivery(messageId, screenTwin.id);
378
+ }
379
+ }
380
+ }
381
+ if (deviceTwins[types_1.TwinTypeEnum.Peripheral] &&
382
+ deviceTwins[types_1.TwinTypeEnum.Edge]) {
383
+ for (const peripheralTwinId of deviceTwins[types_1.TwinTypeEnum.Peripheral]) {
384
+ const peripheralTwin = this.twinCache.getTwin(peripheralTwinId);
385
+ const instanceId = peripheralTwin?.properties?.desired?.instanceId;
386
+ if (instanceId &&
387
+ deviceTwins[types_1.TwinTypeEnum.Edge].includes(instanceId) &&
388
+ !this.hasMessageBeenDelivered(messageId, instanceId)) {
389
+ this.io.to(instanceId).emit("twinMessage", payload);
390
+ this.trackMessageDelivery(messageId, instanceId);
391
+ }
392
+ }
393
+ }
394
+ }
395
+ createLocalTwin(type, desiredProperties, deviceTwin, reuseId) {
396
+ return {
397
+ id: reuseId || (0, uuid_1.v4)(),
398
+ deviceId: deviceTwin?.deviceId || (0, uuid_1.v4)(),
399
+ tenantId: deviceTwin?.tenantId || (0, uuid_1.v4)(),
400
+ type,
401
+ properties: {
402
+ desired: desiredProperties,
403
+ reported: {},
404
+ },
405
+ };
406
+ }
407
+ }
408
+ exports.MessageRouter = MessageRouter;
409
+ //# sourceMappingURL=message-router.js.map