streamer-node 1.0.0

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/README.md +11 -0
  2. package/dist/public/client.png +0 -0
  3. package/dist/public/ds.png +0 -0
  4. package/dist/src/application/interfaces/Logger.d.ts +7 -0
  5. package/dist/src/application/interfaces/Logger.d.ts.map +1 -0
  6. package/dist/src/application/interfaces/Logger.js +3 -0
  7. package/dist/src/application/interfaces/Logger.js.map +1 -0
  8. package/dist/src/application/interfaces/StartStreamUseCase.types.d.ts +36 -0
  9. package/dist/src/application/interfaces/StartStreamUseCase.types.d.ts.map +1 -0
  10. package/dist/src/application/interfaces/StartStreamUseCase.types.js +12 -0
  11. package/dist/src/application/interfaces/StartStreamUseCase.types.js.map +1 -0
  12. package/dist/src/application/services/HttpClient.d.ts +5 -0
  13. package/dist/src/application/services/HttpClient.d.ts.map +1 -0
  14. package/dist/src/application/services/HttpClient.js +30 -0
  15. package/dist/src/application/services/HttpClient.js.map +1 -0
  16. package/dist/src/application/services/StreamManagerService.d.ts +38 -0
  17. package/dist/src/application/services/StreamManagerService.d.ts.map +1 -0
  18. package/dist/src/application/services/StreamManagerService.js +298 -0
  19. package/dist/src/application/services/StreamManagerService.js.map +1 -0
  20. package/dist/src/application/use-cases/StartStreamUseCase.d.ts +27 -0
  21. package/dist/src/application/use-cases/StartStreamUseCase.d.ts.map +1 -0
  22. package/dist/src/application/use-cases/StartStreamUseCase.js +195 -0
  23. package/dist/src/application/use-cases/StartStreamUseCase.js.map +1 -0
  24. package/dist/src/application/use-cases/StopStreamUseCase.d.ts +18 -0
  25. package/dist/src/application/use-cases/StopStreamUseCase.d.ts.map +1 -0
  26. package/dist/src/application/use-cases/StopStreamUseCase.js +96 -0
  27. package/dist/src/application/use-cases/StopStreamUseCase.js.map +1 -0
  28. package/dist/src/domain/entities/Stream.d.ts +40 -0
  29. package/dist/src/domain/entities/Stream.d.ts.map +1 -0
  30. package/dist/src/domain/entities/Stream.js +115 -0
  31. package/dist/src/domain/entities/Stream.js.map +1 -0
  32. package/dist/src/domain/events/StreamEvent.d.ts +48 -0
  33. package/dist/src/domain/events/StreamEvent.d.ts.map +1 -0
  34. package/dist/src/domain/events/StreamEvent.js +3 -0
  35. package/dist/src/domain/events/StreamEvent.js.map +1 -0
  36. package/dist/src/domain/repositories/StreamRepository.d.ts +41 -0
  37. package/dist/src/domain/repositories/StreamRepository.d.ts.map +1 -0
  38. package/dist/src/domain/repositories/StreamRepository.js +3 -0
  39. package/dist/src/domain/repositories/StreamRepository.js.map +1 -0
  40. package/dist/src/domain/services/FFmpegService.d.ts +42 -0
  41. package/dist/src/domain/services/FFmpegService.d.ts.map +1 -0
  42. package/dist/src/domain/services/FFmpegService.js +3 -0
  43. package/dist/src/domain/services/FFmpegService.js.map +1 -0
  44. package/dist/src/domain/services/SSEService.d.ts +42 -0
  45. package/dist/src/domain/services/SSEService.d.ts.map +1 -0
  46. package/dist/src/domain/services/SSEService.js +3 -0
  47. package/dist/src/domain/services/SSEService.js.map +1 -0
  48. package/dist/src/domain/value-objects/StreamId.d.ts +10 -0
  49. package/dist/src/domain/value-objects/StreamId.d.ts.map +1 -0
  50. package/dist/src/domain/value-objects/StreamId.js +31 -0
  51. package/dist/src/domain/value-objects/StreamId.js.map +1 -0
  52. package/dist/src/domain/value-objects/StreamState.d.ts +12 -0
  53. package/dist/src/domain/value-objects/StreamState.d.ts.map +1 -0
  54. package/dist/src/domain/value-objects/StreamState.js +35 -0
  55. package/dist/src/domain/value-objects/StreamState.js.map +1 -0
  56. package/dist/src/domain/value-objects/StreamUrl.d.ts +12 -0
  57. package/dist/src/domain/value-objects/StreamUrl.d.ts.map +1 -0
  58. package/dist/src/domain/value-objects/StreamUrl.js +48 -0
  59. package/dist/src/domain/value-objects/StreamUrl.js.map +1 -0
  60. package/dist/src/infrastructure/config/Config.d.ts +42 -0
  61. package/dist/src/infrastructure/config/Config.d.ts.map +1 -0
  62. package/dist/src/infrastructure/config/Config.js +113 -0
  63. package/dist/src/infrastructure/config/Config.js.map +1 -0
  64. package/dist/src/infrastructure/logging/ConsoleLogger.d.ts +12 -0
  65. package/dist/src/infrastructure/logging/ConsoleLogger.d.ts.map +1 -0
  66. package/dist/src/infrastructure/logging/ConsoleLogger.js +41 -0
  67. package/dist/src/infrastructure/logging/ConsoleLogger.js.map +1 -0
  68. package/dist/src/infrastructure/logging/LogBuffer.d.ts +20 -0
  69. package/dist/src/infrastructure/logging/LogBuffer.d.ts.map +1 -0
  70. package/dist/src/infrastructure/logging/LogBuffer.js +95 -0
  71. package/dist/src/infrastructure/logging/LogBuffer.js.map +1 -0
  72. package/dist/src/infrastructure/logging/LogShippingService.d.ts +23 -0
  73. package/dist/src/infrastructure/logging/LogShippingService.d.ts.map +1 -0
  74. package/dist/src/infrastructure/logging/LogShippingService.js +128 -0
  75. package/dist/src/infrastructure/logging/LogShippingService.js.map +1 -0
  76. package/dist/src/infrastructure/logging/RemoteLogger.d.ts +37 -0
  77. package/dist/src/infrastructure/logging/RemoteLogger.d.ts.map +1 -0
  78. package/dist/src/infrastructure/logging/RemoteLogger.js +120 -0
  79. package/dist/src/infrastructure/logging/RemoteLogger.js.map +1 -0
  80. package/dist/src/infrastructure/logging/types/LogTypes.d.ts +27 -0
  81. package/dist/src/infrastructure/logging/types/LogTypes.d.ts.map +1 -0
  82. package/dist/src/infrastructure/logging/types/LogTypes.js +3 -0
  83. package/dist/src/infrastructure/logging/types/LogTypes.js.map +1 -0
  84. package/dist/src/infrastructure/repositories/FileSystemStreamRepository.d.ts +22 -0
  85. package/dist/src/infrastructure/repositories/FileSystemStreamRepository.d.ts.map +1 -0
  86. package/dist/src/infrastructure/repositories/FileSystemStreamRepository.js +212 -0
  87. package/dist/src/infrastructure/repositories/FileSystemStreamRepository.js.map +1 -0
  88. package/dist/src/infrastructure/services/NodeFFmpegService.d.ts +17 -0
  89. package/dist/src/infrastructure/services/NodeFFmpegService.d.ts.map +1 -0
  90. package/dist/src/infrastructure/services/NodeFFmpegService.js +306 -0
  91. package/dist/src/infrastructure/services/NodeFFmpegService.js.map +1 -0
  92. package/dist/src/infrastructure/services/NodeSSEService.d.ts +30 -0
  93. package/dist/src/infrastructure/services/NodeSSEService.d.ts.map +1 -0
  94. package/dist/src/infrastructure/services/NodeSSEService.js +268 -0
  95. package/dist/src/infrastructure/services/NodeSSEService.js.map +1 -0
  96. package/dist/src/main.d.ts +3 -0
  97. package/dist/src/main.d.ts.map +1 -0
  98. package/dist/src/main.js +87 -0
  99. package/dist/src/main.js.map +1 -0
  100. package/package.json +52 -0
@@ -0,0 +1,17 @@
1
+ import { FFmpegService, FFmpegCommand, FFmpegProcess } from "../../domain/services/FFmpegService";
2
+ import { StreamUrl } from "../../domain/value-objects/StreamUrl";
3
+ import { Logger } from "../../application/interfaces/Logger";
4
+ export declare class NodeFFmpegService implements FFmpegService {
5
+ private readonly logger;
6
+ private readonly runningProcesses;
7
+ constructor(logger: Logger);
8
+ startStream(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean): Promise<FFmpegProcess>;
9
+ stopStream(pid: number): Promise<void>;
10
+ isProcessRunning(pid: number): Promise<boolean>;
11
+ detectAudio(cameraUrl: StreamUrl): Promise<boolean>;
12
+ buildStreamCommand(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean): FFmpegCommand;
13
+ getRunningProcesses(): Promise<FFmpegProcess[]>;
14
+ killAllProcesses(): Promise<void>;
15
+ private validateImageFiles;
16
+ }
17
+ //# sourceMappingURL=NodeFFmpegService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeFFmpegService.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/services/NodeFFmpegService.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACd,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,qBAAa,iBAAkB,YAAW,aAAa;IAGzC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAyC;gBAE7C,MAAM,EAAE,MAAM;IAE9B,WAAW,CACtB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,aAAa,CAAC;IAkGZ,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DtC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU/C,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDzD,kBAAkB,CACvB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,GAChB,aAAa;IA2EH,mBAAmB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAI/C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9C,OAAO,CAAC,kBAAkB;CAiB3B"}
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.NodeFFmpegService = void 0;
37
+ const child_process_1 = require("child_process");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ class NodeFFmpegService {
41
+ constructor(logger) {
42
+ this.logger = logger;
43
+ this.runningProcesses = new Map();
44
+ }
45
+ async startStream(cameraUrl, streamKey, hasAudio) {
46
+ const command = this.buildStreamCommand(cameraUrl, streamKey, hasAudio);
47
+ this.logger.info("Command full form", command);
48
+ this.logger.info("Starting FFmpeg process", {
49
+ command: command.fullCommand,
50
+ cameraUrl: cameraUrl.value,
51
+ streamKey,
52
+ hasAudio,
53
+ });
54
+ return new Promise((resolve, reject) => {
55
+ const process = (0, child_process_1.spawn)(command.command, command.args, {
56
+ stdio: ["ignore", "pipe", "pipe"],
57
+ detached: false,
58
+ });
59
+ const ffmpegProcess = {
60
+ pid: process.pid,
61
+ command,
62
+ startTime: new Date(),
63
+ };
64
+ // Handle process startup
65
+ let resolved = false;
66
+ const startupTimeout = setTimeout(() => {
67
+ if (!resolved) {
68
+ resolved = true;
69
+ process.kill("SIGTERM");
70
+ reject(new Error("FFmpeg process startup timeout"));
71
+ }
72
+ }, 10000); // 10 second timeout
73
+ // Monitor stderr for startup confirmation
74
+ process.stderr?.on("data", (data) => {
75
+ const output = data.toString();
76
+ this.logger.debug("FFmpeg stderr", { pid: process.pid, output });
77
+ // Look for successful stream start indicators
78
+ if (output.includes("Stream mapping:") ||
79
+ output.includes("Press [q] to stop")) {
80
+ if (!resolved) {
81
+ resolved = true;
82
+ clearTimeout(startupTimeout);
83
+ this.runningProcesses.set(process.pid, ffmpegProcess);
84
+ resolve(ffmpegProcess);
85
+ }
86
+ }
87
+ // Check for errors
88
+ if (output.includes("Connection refused") ||
89
+ output.includes("No route to host") ||
90
+ output.includes("Invalid data found")) {
91
+ if (!resolved) {
92
+ resolved = true;
93
+ clearTimeout(startupTimeout);
94
+ process.kill("SIGTERM");
95
+ reject(new Error(`FFmpeg error: ${output}`));
96
+ }
97
+ }
98
+ });
99
+ // Handle process exit
100
+ process.on("exit", (code, signal) => {
101
+ this.logger.info("FFmpeg process exited", {
102
+ pid: process.pid,
103
+ code,
104
+ signal,
105
+ cameraUrl: cameraUrl.value,
106
+ });
107
+ if (process.pid) {
108
+ this.runningProcesses.delete(process.pid);
109
+ }
110
+ if (!resolved && code !== 0) {
111
+ resolved = true;
112
+ clearTimeout(startupTimeout);
113
+ reject(new Error(`FFmpeg process exited with code ${code}`));
114
+ }
115
+ });
116
+ // Handle spawn errors
117
+ process.on("error", (error) => {
118
+ this.logger.error("FFmpeg process error", { error: error.message });
119
+ if (!resolved) {
120
+ resolved = true;
121
+ clearTimeout(startupTimeout);
122
+ reject(error);
123
+ }
124
+ });
125
+ });
126
+ }
127
+ async stopStream(pid) {
128
+ this.logger.info("Stopping FFmpeg process", { pid });
129
+ const ffmpegProcess = this.runningProcesses.get(pid);
130
+ if (!ffmpegProcess) {
131
+ this.logger.warn("Process not found in running processes", { pid });
132
+ // Try to kill the process anyway using Node.js process.kill
133
+ try {
134
+ process.kill(pid, "SIGTERM");
135
+ // Wait a bit, then force kill if needed
136
+ setTimeout(() => {
137
+ try {
138
+ process.kill(pid, "SIGKILL");
139
+ }
140
+ catch (error) {
141
+ // Process might already be dead
142
+ }
143
+ }, 5000);
144
+ }
145
+ catch (error) {
146
+ // Process might not exist
147
+ }
148
+ return;
149
+ }
150
+ return new Promise((resolve) => {
151
+ try {
152
+ process.kill(pid, "SIGTERM");
153
+ // Force kill after 5 seconds if not terminated
154
+ const forceKillTimeout = setTimeout(() => {
155
+ try {
156
+ process.kill(pid, "SIGKILL");
157
+ }
158
+ catch (error) {
159
+ // Process might already be dead
160
+ }
161
+ }, 5000);
162
+ // Clean up when process actually exits
163
+ const checkInterval = setInterval(() => {
164
+ if (!this.runningProcesses.has(pid)) {
165
+ clearTimeout(forceKillTimeout);
166
+ clearInterval(checkInterval);
167
+ resolve();
168
+ }
169
+ }, 100);
170
+ // Fallback timeout
171
+ setTimeout(() => {
172
+ clearTimeout(forceKillTimeout);
173
+ clearInterval(checkInterval);
174
+ this.runningProcesses.delete(pid);
175
+ resolve();
176
+ }, 10000);
177
+ }
178
+ catch (error) {
179
+ this.logger.error("Error stopping FFmpeg process", { pid, error });
180
+ this.runningProcesses.delete(pid);
181
+ resolve();
182
+ }
183
+ });
184
+ }
185
+ async isProcessRunning(pid) {
186
+ try {
187
+ // Check if process exists and is running
188
+ process.kill(pid, 0);
189
+ return true;
190
+ }
191
+ catch (error) {
192
+ return false;
193
+ }
194
+ }
195
+ async detectAudio(cameraUrl) {
196
+ this.logger.info("Detecting audio for stream", {
197
+ cameraUrl: cameraUrl.value,
198
+ });
199
+ const args = [
200
+ "-rtsp_transport",
201
+ "tcp",
202
+ "-i",
203
+ cameraUrl.value,
204
+ "-t",
205
+ "5", // Test for 5 seconds
206
+ "-f",
207
+ "null",
208
+ "-",
209
+ ];
210
+ return new Promise((resolve) => {
211
+ const process = (0, child_process_1.spawn)("ffmpeg", args, {
212
+ stdio: ["ignore", "pipe", "pipe"],
213
+ });
214
+ let hasAudio = false;
215
+ const timeout = setTimeout(() => {
216
+ process.kill("SIGTERM");
217
+ resolve(hasAudio);
218
+ }, 10000); // 10 second timeout
219
+ process.stderr?.on("data", (data) => {
220
+ const output = data.toString();
221
+ // Look for audio stream indicators
222
+ if (output.includes("Stream #") && output.includes("Audio:")) {
223
+ hasAudio = true;
224
+ }
225
+ });
226
+ process.on("exit", () => {
227
+ clearTimeout(timeout);
228
+ resolve(hasAudio);
229
+ });
230
+ process.on("error", (error) => {
231
+ this.logger.error("Audio detection error", { error: error.message });
232
+ clearTimeout(timeout);
233
+ resolve(false);
234
+ });
235
+ });
236
+ }
237
+ buildStreamCommand(cameraUrl, streamKey, hasAudio) {
238
+ const rtmpUrl = `rtmp://a.rtmp.youtube.com/live2/${streamKey}`;
239
+ let fakeAudioInputCounter = 0;
240
+ let args = [];
241
+ // Add input parameters
242
+ args.push("-rtsp_transport", "tcp");
243
+ args.push("-i", cameraUrl.value);
244
+ if (!hasAudio) {
245
+ // Without audio - add null audio source like in bash script
246
+ args.push("-f", "lavfi");
247
+ args.push("-i", "anullsrc=channel_layout=stereo:sample_rate=44100");
248
+ fakeAudioInputCounter++;
249
+ }
250
+ // Validate logo files exist before adding them
251
+ this.validateImageFiles();
252
+ // logo overlays & their formatting
253
+ // Add logo image inputs
254
+ args.push("-i", "./public/ds.png"); // Input 1: DropShot logo
255
+ const dsInputIndex = 1 + fakeAudioInputCounter;
256
+ args.push("-i", "./public/client.png"); // Input 2: Client logo
257
+ const clientInputIndex = 2 + fakeAudioInputCounter;
258
+ // position them correctly using filter complex
259
+ const filterComplex = [
260
+ `[${dsInputIndex}:v] scale=500:-1:force_original_aspect_ratio=decrease [ds];`,
261
+ `[${clientInputIndex}:v] scale=350:-1:force_original_aspect_ratio=decrease [client];`,
262
+ "[0:v] scale=1920:1080 [base];",
263
+ "[base][ds] overlay=main_w-overlay_w-10:main_h-overlay_h-10 [tmp1];",
264
+ "[tmp1][client] overlay=main_w-overlay_w-10:10",
265
+ ].join(" ");
266
+ args.push("-filter_complex", filterComplex);
267
+ // audio & video output configurations
268
+ args.push("-c:v", "libx264", "-preset", "veryfast", "-b:v", "4500k", "-maxrate", "5000k", "-bufsize", "10000k");
269
+ args.push("-c:a", "aac", "-b:a", "128k", "-ar", "44100", "-ac", "2", "-shortest");
270
+ // Specify output format for RTMP streaming
271
+ args.push("-f", "flv", rtmpUrl);
272
+ const fullCommand = `ffmpeg ${args.join(" ")}`;
273
+ return {
274
+ command: "ffmpeg",
275
+ args,
276
+ fullCommand,
277
+ };
278
+ }
279
+ async getRunningProcesses() {
280
+ return Array.from(this.runningProcesses.values());
281
+ }
282
+ async killAllProcesses() {
283
+ this.logger.info("Killing all FFmpeg processes", {
284
+ count: this.runningProcesses.size,
285
+ });
286
+ const killPromises = Array.from(this.runningProcesses.keys()).map((pid) => this.stopStream(pid));
287
+ await Promise.all(killPromises);
288
+ this.runningProcesses.clear();
289
+ }
290
+ validateImageFiles() {
291
+ const dsLogoPath = path.resolve("./public/ds.png");
292
+ const clientLogoPath = path.resolve("./public/client.png");
293
+ if (!fs.existsSync(dsLogoPath)) {
294
+ throw new Error(`DropShot logo not found at: ${dsLogoPath}`);
295
+ }
296
+ if (!fs.existsSync(clientLogoPath)) {
297
+ throw new Error(`Client logo not found at: ${clientLogoPath}`);
298
+ }
299
+ this.logger.info("Logo files validated successfully", {
300
+ dsLogo: dsLogoPath,
301
+ clientLogo: clientLogoPath,
302
+ });
303
+ }
304
+ }
305
+ exports.NodeFFmpegService = NodeFFmpegService;
306
+ //# sourceMappingURL=NodeFFmpegService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeFFmpegService.js","sourceRoot":"","sources":["../../../../src/infrastructure/services/NodeFFmpegService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { EventEmitter } from "events";
2
+ import { SSEService, SSEConnectionConfig } from "../../domain/services/SSEService";
3
+ import { SSEStreamEvent } from "../../domain/events/StreamEvent";
4
+ import { Logger } from "../../application/interfaces/Logger";
5
+ export declare class NodeSSEService extends EventEmitter implements SSEService {
6
+ private readonly logger;
7
+ private isActive;
8
+ private isConnecting;
9
+ private connectionStatus;
10
+ private retryCount;
11
+ private retryTimeout?;
12
+ private config?;
13
+ private abortController?;
14
+ constructor(logger: Logger);
15
+ start(config: SSEConnectionConfig): Promise<void>;
16
+ stop(): Promise<void>;
17
+ isConnected(): boolean;
18
+ onStreamEvent(callback: (event: SSEStreamEvent) => void): void;
19
+ onConnectionChange(callback: (status: "connected" | "disconnected" | "reconnecting") => void): void;
20
+ getConnectionStatus(): "connected" | "disconnected" | "reconnecting";
21
+ getRetryCount(): number;
22
+ reconnect(): Promise<void>;
23
+ private connect;
24
+ private processEventStream;
25
+ private parseSSEEvents;
26
+ private handleSSEEvent;
27
+ private scheduleRetry;
28
+ private emitConnectionEvent;
29
+ }
30
+ //# sourceMappingURL=NodeSSEService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeSSEService.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/services/NodeSSEService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,UAAU,EACV,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,qBAAa,cAAe,SAAQ,YAAa,YAAW,UAAU;IAUxD,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CACP;IACjB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,MAAM,CAAC,CAAsB;IACrC,OAAO,CAAC,eAAe,CAAC,CAAkB;gBAEb,MAAM,EAAE,MAAM;IAI9B,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,WAAW,IAAI,OAAO;IAItB,aAAa,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAI9D,kBAAkB,CACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,cAAc,KAAK,IAAI,GACxE,IAAI;IAIA,mBAAmB,IAAI,WAAW,GAAG,cAAc,GAAG,cAAc;IAIpE,aAAa,IAAI,MAAM;IAIjB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;YAczB,OAAO;YAwFP,kBAAkB;IAoChC,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,cAAc;IA8DtB,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,mBAAmB;CAS5B"}
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NodeSSEService = void 0;
4
+ const events_1 = require("events");
5
+ class NodeSSEService extends events_1.EventEmitter {
6
+ constructor(logger) {
7
+ super();
8
+ this.logger = logger;
9
+ this.isActive = false;
10
+ this.isConnecting = false;
11
+ this.connectionStatus = "disconnected";
12
+ this.retryCount = 0;
13
+ }
14
+ async start(config) {
15
+ this.config = config;
16
+ this.isActive = true;
17
+ this.retryCount = 0;
18
+ this.logger.info("Starting SSE client", { groundId: config.groundId });
19
+ await this.connect();
20
+ }
21
+ async stop() {
22
+ this.logger.info("Stopping SSE client");
23
+ this.isActive = false;
24
+ if (this.retryTimeout) {
25
+ clearTimeout(this.retryTimeout);
26
+ this.retryTimeout = undefined;
27
+ }
28
+ if (this.abortController) {
29
+ this.abortController.abort();
30
+ this.abortController = undefined;
31
+ }
32
+ this.connectionStatus = "disconnected";
33
+ this.emitConnectionEvent("disconnected");
34
+ }
35
+ isConnected() {
36
+ return this.connectionStatus === "connected";
37
+ }
38
+ onStreamEvent(callback) {
39
+ this.on("streamEvent", callback);
40
+ }
41
+ onConnectionChange(callback) {
42
+ this.on("connectionChange", callback);
43
+ }
44
+ getConnectionStatus() {
45
+ return this.connectionStatus;
46
+ }
47
+ getRetryCount() {
48
+ return this.retryCount;
49
+ }
50
+ async reconnect() {
51
+ if (!this.config) {
52
+ throw new Error("SSE service not configured");
53
+ }
54
+ this.logger.info("Manual reconnection requested");
55
+ if (this.abortController) {
56
+ this.abortController.abort();
57
+ }
58
+ await this.connect();
59
+ }
60
+ async connect() {
61
+ if (!this.config || !this.isActive) {
62
+ return;
63
+ }
64
+ // Prevent concurrent connection attempts
65
+ if (this.isConnecting) {
66
+ this.logger.debug("Connection attempt already in progress, skipping");
67
+ return;
68
+ }
69
+ this.isConnecting = true;
70
+ // Abort any existing connection attempt
71
+ if (this.abortController) {
72
+ this.abortController.abort();
73
+ }
74
+ this.abortController = new AbortController();
75
+ this.connectionStatus = "reconnecting";
76
+ this.emitConnectionEvent("reconnecting");
77
+ try {
78
+ this.logger.info("Connecting to SSE endpoint", {
79
+ groundId: this.config.groundId,
80
+ retryCount: this.retryCount,
81
+ });
82
+ // Create timeout promise
83
+ const timeoutPromise = new Promise((_, reject) => {
84
+ setTimeout(() => reject(new Error("Connection timeout")), 30000);
85
+ });
86
+ // Race between fetch and timeout
87
+ const response = await Promise.race([
88
+ fetch(`${this.config.baseUrl}/api/v1/padel-grounds/${this.config.groundId}/events`, {
89
+ headers: {
90
+ Accept: "text/event-stream",
91
+ "Cache-Control": "no-cache",
92
+ },
93
+ signal: this.abortController.signal,
94
+ }),
95
+ timeoutPromise,
96
+ ]);
97
+ if (!response.ok) {
98
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
99
+ }
100
+ if (!response.body) {
101
+ throw new Error("No response body received");
102
+ }
103
+ this.connectionStatus = "connected";
104
+ this.retryCount = 0;
105
+ this.isConnecting = false;
106
+ this.emitConnectionEvent("connected");
107
+ this.logger.info("SSE connection established");
108
+ // Process the stream
109
+ await this.processEventStream(response.body);
110
+ }
111
+ catch (error) {
112
+ this.isConnecting = false;
113
+ if (error instanceof Error && error.name === "AbortError") {
114
+ this.logger.info("SSE connection aborted");
115
+ return;
116
+ }
117
+ this.logger.error("SSE connection failed", {
118
+ error: error instanceof Error ? error.message : String(error),
119
+ retryCount: this.retryCount,
120
+ });
121
+ this.connectionStatus = "disconnected";
122
+ this.emitConnectionEvent("disconnected");
123
+ // Schedule retry if still active (infinite retries)
124
+ if (this.isActive) {
125
+ this.scheduleRetry();
126
+ }
127
+ }
128
+ }
129
+ async processEventStream(body) {
130
+ const reader = body.getReader();
131
+ const decoder = new TextDecoder();
132
+ let buffer = "";
133
+ try {
134
+ while (this.isActive) {
135
+ const { done, value } = await reader.read();
136
+ if (done) {
137
+ this.logger.info("SSE stream ended");
138
+ break;
139
+ }
140
+ buffer += decoder.decode(value, { stream: true });
141
+ // Process complete events
142
+ const events = this.parseSSEEvents(buffer);
143
+ for (const event of events.complete) {
144
+ this.handleSSEEvent(event);
145
+ }
146
+ buffer = events.remaining;
147
+ }
148
+ }
149
+ catch (error) {
150
+ this.logger.error("Error processing SSE stream", {
151
+ error: error instanceof Error ? error.message : String(error),
152
+ });
153
+ throw error;
154
+ }
155
+ finally {
156
+ reader.releaseLock();
157
+ }
158
+ }
159
+ parseSSEEvents(buffer) {
160
+ const events = [];
161
+ const lines = buffer.split("\n");
162
+ let currentEvent = "";
163
+ let i = 0;
164
+ while (i < lines.length) {
165
+ const line = lines[i];
166
+ if (line === "") {
167
+ // Empty line indicates end of event
168
+ if (currentEvent.trim()) {
169
+ events.push(currentEvent.trim());
170
+ currentEvent = "";
171
+ }
172
+ }
173
+ else {
174
+ currentEvent += line + "\n";
175
+ }
176
+ i++;
177
+ }
178
+ // Return complete events and remaining buffer
179
+ return {
180
+ complete: events,
181
+ remaining: currentEvent,
182
+ };
183
+ }
184
+ handleSSEEvent(eventData) {
185
+ try {
186
+ const lines = eventData.split("\n");
187
+ let data = "";
188
+ let eventType = "";
189
+ for (const line of lines) {
190
+ if (line.startsWith("data: ")) {
191
+ data = line.substring(6);
192
+ }
193
+ else if (line.startsWith("event: ")) {
194
+ eventType = line.substring(7);
195
+ }
196
+ }
197
+ if (!data) {
198
+ return;
199
+ }
200
+ this.logger.debug("Received SSE event", { eventType, data });
201
+ // Parse the JSON data
202
+ const parsedData = JSON.parse(data);
203
+ // Validate required fields
204
+ if (!parsedData.cameraUrl ||
205
+ !parsedData.streamKey ||
206
+ !parsedData.eventType ||
207
+ !parsedData.courtId) {
208
+ this.logger.warn("Invalid SSE event data", { data: parsedData });
209
+ return;
210
+ }
211
+ // Create stream event
212
+ const streamEvent = {
213
+ eventId: `sse_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
214
+ occurredOn: new Date(),
215
+ eventType: "SSEStreamEvent",
216
+ action: parsedData.eventType,
217
+ cameraUrl: parsedData.cameraUrl,
218
+ streamKey: parsedData.streamKey,
219
+ courtId: parsedData.courtId,
220
+ reconciliationMode: parsedData.reconciliation_mode || false,
221
+ };
222
+ this.logger.info("Processing SSE stream event", {
223
+ action: streamEvent.action,
224
+ cameraUrl: streamEvent.cameraUrl,
225
+ streamKey: streamEvent.streamKey,
226
+ reconciliationMode: streamEvent.reconciliationMode,
227
+ });
228
+ this.emit("streamEvent", streamEvent);
229
+ }
230
+ catch (error) {
231
+ this.logger.error("Failed to parse SSE event", {
232
+ error: error instanceof Error ? error.message : String(error),
233
+ eventData,
234
+ });
235
+ }
236
+ }
237
+ scheduleRetry() {
238
+ if (!this.config) {
239
+ return;
240
+ }
241
+ // Don't schedule retry if already connecting
242
+ if (this.isConnecting) {
243
+ this.logger.debug("Connection attempt in progress, skipping retry schedule");
244
+ return;
245
+ }
246
+ this.retryCount++;
247
+ // Cap retry count at 10 for exponential backoff calculation to prevent overflow
248
+ const effectiveRetryCount = Math.min(this.retryCount, 10);
249
+ const delay = Math.min(this.config.retryInterval * Math.pow(2, effectiveRetryCount - 1), 30000 // Max 30 seconds
250
+ );
251
+ this.logger.info("Scheduling SSE reconnection", {
252
+ retryCount: this.retryCount,
253
+ delayMs: delay,
254
+ });
255
+ this.retryTimeout = setTimeout(() => {
256
+ this.connect();
257
+ }, delay);
258
+ }
259
+ emitConnectionEvent(status) {
260
+ this.emit("connectionChange", status);
261
+ this.logger.debug("SSE connection status changed", {
262
+ status,
263
+ retryCount: this.retryCount,
264
+ });
265
+ }
266
+ }
267
+ exports.NodeSSEService = NodeSSEService;
268
+ //# sourceMappingURL=NodeSSEService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeSSEService.js","sourceRoot":"","sources":["../../../../src/infrastructure/services/NodeSSEService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map