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,42 @@
1
+ import { StreamUrl } from '../value-objects/StreamUrl';
2
+ export interface FFmpegCommand {
3
+ readonly command: string;
4
+ readonly args: string[];
5
+ readonly fullCommand: string;
6
+ }
7
+ export interface FFmpegProcess {
8
+ readonly pid: number;
9
+ readonly command: FFmpegCommand;
10
+ readonly startTime: Date;
11
+ }
12
+ export interface FFmpegService {
13
+ /**
14
+ * Start an FFmpeg stream process
15
+ */
16
+ startStream(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean, maxRetries?: number, retryDelayMs?: number, onPidUpdate?: (newPid: number) => Promise<void>): Promise<FFmpegProcess>;
17
+ /**
18
+ * Stop an FFmpeg process by PID
19
+ */
20
+ stopStream(pid: number): Promise<void>;
21
+ /**
22
+ * Check if a process is running
23
+ */
24
+ isProcessRunning(pid: number): Promise<boolean>;
25
+ /**
26
+ * Detect if a stream has audio
27
+ */
28
+ detectAudio(cameraUrl: StreamUrl): Promise<boolean>;
29
+ /**
30
+ * Build FFmpeg command for streaming
31
+ */
32
+ buildStreamCommand(cameraUrl: StreamUrl, streamKey: string, hasAudio: boolean): FFmpegCommand;
33
+ /**
34
+ * Get all running FFmpeg processes managed by this service
35
+ */
36
+ getRunningProcesses(): Promise<FFmpegProcess[]>;
37
+ /**
38
+ * Kill all FFmpeg processes (cleanup)
39
+ */
40
+ killAllProcesses(): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=FFmpegService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FFmpegService.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/FFmpegService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,CACT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAC9C,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1B;;OAEG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpD;;OAEG;IACH,kBAAkB,CAChB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,GAChB,aAAa,CAAC;IAEjB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=FFmpegService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FFmpegService.js","sourceRoot":"","sources":["../../../../src/domain/services/FFmpegService.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { SSEStreamEvent } from "../events/StreamEvent";
2
+ export interface SSEConnectionConfig {
3
+ readonly groundId: string;
4
+ readonly baseUrl: string;
5
+ readonly retryInterval: number;
6
+ readonly maxRetries: number;
7
+ }
8
+ export interface SSEService {
9
+ /**
10
+ * Start listening to SSE events
11
+ */
12
+ start(config: SSEConnectionConfig): Promise<void>;
13
+ /**
14
+ * Stop listening to SSE events
15
+ */
16
+ stop(): Promise<void>;
17
+ /**
18
+ * Check if the SSE connection is active
19
+ */
20
+ isConnected(): boolean;
21
+ /**
22
+ * Subscribe to SSE stream events
23
+ */
24
+ onStreamEvent(callback: (event: SSEStreamEvent) => void): void;
25
+ /**
26
+ * Subscribe to connection status changes
27
+ */
28
+ onConnectionChange(callback: (status: "connected" | "disconnected" | "reconnecting") => void): void;
29
+ /**
30
+ * Get current connection status
31
+ */
32
+ getConnectionStatus(): "connected" | "disconnected" | "reconnecting";
33
+ /**
34
+ * Get retry count for current connection attempt
35
+ */
36
+ getRetryCount(): number;
37
+ /**
38
+ * Force reconnection
39
+ */
40
+ reconnect(): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=SSEService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSEService.d.ts","sourceRoot":"","sources":["../../../../src/domain/services/SSEService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAAC;IAE/D;;OAEG;IACH,kBAAkB,CAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,cAAc,KAAK,IAAI,GACxE,IAAI,CAAC;IAER;;OAEG;IACH,mBAAmB,IAAI,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;IAErE;;OAEG;IACH,aAAa,IAAI,MAAM,CAAC;IAExB;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=SSEService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSEService.js","sourceRoot":"","sources":["../../../../src/domain/services/SSEService.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ export declare class StreamId {
2
+ private readonly _value;
3
+ private constructor();
4
+ static create(): StreamId;
5
+ static fromString(value: string): StreamId;
6
+ get value(): string;
7
+ equals(other: StreamId): boolean;
8
+ toString(): string;
9
+ }
10
+ //# sourceMappingURL=StreamId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamId.d.ts","sourceRoot":"","sources":["../../../../src/domain/value-objects/StreamId.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAQ;IACC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAA3C,OAAO;WAMO,MAAM,IAAI,QAAQ;WAMlB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;IAIjD,IAAW,KAAK,IAAI,MAAM,CAEzB;IAEM,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;IAIhC,QAAQ,IAAI,MAAM;CAG1B"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamId = void 0;
4
+ const crypto_1 = require("crypto");
5
+ class StreamId {
6
+ constructor(_value) {
7
+ this._value = _value;
8
+ if (!_value || _value.trim().length === 0) {
9
+ throw new Error('StreamId cannot be empty');
10
+ }
11
+ }
12
+ static create() {
13
+ const timestamp = Date.now().toString(36);
14
+ const random = (0, crypto_1.randomBytes)(8).toString('hex');
15
+ return new StreamId(`stream_${timestamp}_${random}`);
16
+ }
17
+ static fromString(value) {
18
+ return new StreamId(value);
19
+ }
20
+ get value() {
21
+ return this._value;
22
+ }
23
+ equals(other) {
24
+ return this._value === other._value;
25
+ }
26
+ toString() {
27
+ return this._value;
28
+ }
29
+ }
30
+ exports.StreamId = StreamId;
31
+ //# sourceMappingURL=StreamId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamId.js","sourceRoot":"","sources":["../../../../src/domain/value-objects/StreamId.ts"],"names":[],"mappings":";;;AAAA,mCAAqC;AAErC,MAAa,QAAQ;IACnB,YAAqC,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QACjD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,MAAM;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAA,oBAAW,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,IAAI,QAAQ,CAAC,UAAU,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,KAAa;QACpC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,MAAM,CAAC,KAAe;QAC3B,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;IACtC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AA5BD,4BA4BC"}
@@ -0,0 +1,12 @@
1
+ export declare enum StreamState {
2
+ PENDING = "pending",
3
+ RUNNING = "running",
4
+ STOPPED = "stopped",
5
+ FAILED = "failed",
6
+ RECONCILING = "reconciling"
7
+ }
8
+ export declare class StreamStateValidator {
9
+ static isValidTransition(from: StreamState, to: StreamState): boolean;
10
+ static getAllowedTransitions(from: StreamState): StreamState[];
11
+ }
12
+ //# sourceMappingURL=StreamState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamState.d.ts","sourceRoot":"","sources":["../../../../src/domain/value-objects/StreamState.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,WAAW,gBAAgB;CAC5B;AAED,qBAAa,oBAAoB;WACjB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,GAAG,OAAO;WAY9D,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE;CAWtE"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamStateValidator = exports.StreamState = void 0;
4
+ var StreamState;
5
+ (function (StreamState) {
6
+ StreamState["PENDING"] = "pending";
7
+ StreamState["RUNNING"] = "running";
8
+ StreamState["STOPPED"] = "stopped";
9
+ StreamState["FAILED"] = "failed";
10
+ StreamState["RECONCILING"] = "reconciling";
11
+ })(StreamState || (exports.StreamState = StreamState = {}));
12
+ class StreamStateValidator {
13
+ static isValidTransition(from, to) {
14
+ const validTransitions = {
15
+ [StreamState.PENDING]: [StreamState.RUNNING, StreamState.FAILED],
16
+ [StreamState.RUNNING]: [StreamState.STOPPED, StreamState.FAILED, StreamState.RECONCILING],
17
+ [StreamState.STOPPED]: [StreamState.RUNNING, StreamState.PENDING],
18
+ [StreamState.FAILED]: [StreamState.PENDING, StreamState.RUNNING],
19
+ [StreamState.RECONCILING]: [StreamState.RUNNING, StreamState.FAILED, StreamState.STOPPED]
20
+ };
21
+ return validTransitions[from]?.includes(to) ?? false;
22
+ }
23
+ static getAllowedTransitions(from) {
24
+ const validTransitions = {
25
+ [StreamState.PENDING]: [StreamState.RUNNING, StreamState.FAILED],
26
+ [StreamState.RUNNING]: [StreamState.STOPPED, StreamState.FAILED, StreamState.RECONCILING],
27
+ [StreamState.STOPPED]: [StreamState.RUNNING, StreamState.PENDING],
28
+ [StreamState.FAILED]: [StreamState.PENDING, StreamState.RUNNING],
29
+ [StreamState.RECONCILING]: [StreamState.RUNNING, StreamState.FAILED, StreamState.STOPPED]
30
+ };
31
+ return validTransitions[from] ?? [];
32
+ }
33
+ }
34
+ exports.StreamStateValidator = StreamStateValidator;
35
+ //# sourceMappingURL=StreamState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamState.js","sourceRoot":"","sources":["../../../../src/domain/value-objects/StreamState.ts"],"names":[],"mappings":";;;AAAA,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,kCAAmB,CAAA;IACnB,kCAAmB,CAAA;IACnB,kCAAmB,CAAA;IACnB,gCAAiB,CAAA;IACjB,0CAA2B,CAAA;AAC7B,CAAC,EANW,WAAW,2BAAX,WAAW,QAMtB;AAED,MAAa,oBAAoB;IACxB,MAAM,CAAC,iBAAiB,CAAC,IAAiB,EAAE,EAAe;QAChE,MAAM,gBAAgB,GAAuC;YAC3D,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;YAChE,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC;YACzF,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC;YACjE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC;YAChE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC;SAC1F,CAAC;QAEF,OAAO,gBAAgB,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;IACvD,CAAC;IAEM,MAAM,CAAC,qBAAqB,CAAC,IAAiB;QACnD,MAAM,gBAAgB,GAAuC;YAC3D,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC;YAChE,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC;YACzF,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC;YACjE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC;YAChE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC;SAC1F,CAAC;QAEF,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;CACF;AAxBD,oDAwBC"}
@@ -0,0 +1,12 @@
1
+ export declare class StreamUrl {
2
+ private readonly _value;
3
+ private constructor();
4
+ static create(url: string): StreamUrl;
5
+ private validate;
6
+ get value(): string;
7
+ isRtsp(): boolean;
8
+ isHttp(): boolean;
9
+ equals(other: StreamUrl): boolean;
10
+ toString(): string;
11
+ }
12
+ //# sourceMappingURL=StreamUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamUrl.d.ts","sourceRoot":"","sources":["../../../../src/domain/value-objects/StreamUrl.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;IACA,OAAO,CAAC,QAAQ,CAAC,MAAM;IAA3C,OAAO;WAIO,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAI5C,OAAO,CAAC,QAAQ;IAqBhB,IAAW,KAAK,IAAI,MAAM,CAEzB;IAEM,MAAM,IAAI,OAAO;IAIjB,MAAM,IAAI,OAAO;IAKjB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO;IAIjC,QAAQ,IAAI,MAAM;CAG1B"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamUrl = void 0;
4
+ class StreamUrl {
5
+ constructor(_value) {
6
+ this._value = _value;
7
+ this.validate(_value);
8
+ }
9
+ static create(url) {
10
+ return new StreamUrl(url);
11
+ }
12
+ validate(url) {
13
+ if (!url || url.trim().length === 0) {
14
+ throw new Error('Stream URL cannot be empty');
15
+ }
16
+ // Basic URL validation - should start with rtsp:// or http://
17
+ const urlPattern = /^(rtsp|http|https):\/\/.+/i;
18
+ if (!urlPattern.test(url)) {
19
+ throw new Error('Invalid stream URL format. Must start with rtsp://, http://, or https://');
20
+ }
21
+ // Additional RTSP validation
22
+ if (url.toLowerCase().startsWith('rtsp://')) {
23
+ // Basic RTSP URL structure validation
24
+ const rtspPattern = /^rtsp:\/\/[^\/\s]+/i;
25
+ if (!rtspPattern.test(url)) {
26
+ throw new Error('Invalid RTSP URL format');
27
+ }
28
+ }
29
+ }
30
+ get value() {
31
+ return this._value;
32
+ }
33
+ isRtsp() {
34
+ return this._value.toLowerCase().startsWith('rtsp://');
35
+ }
36
+ isHttp() {
37
+ return this._value.toLowerCase().startsWith('http://') ||
38
+ this._value.toLowerCase().startsWith('https://');
39
+ }
40
+ equals(other) {
41
+ return this._value === other._value;
42
+ }
43
+ toString() {
44
+ return this._value;
45
+ }
46
+ }
47
+ exports.StreamUrl = StreamUrl;
48
+ //# sourceMappingURL=StreamUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamUrl.js","sourceRoot":"","sources":["../../../../src/domain/value-objects/StreamUrl.ts"],"names":[],"mappings":";;;AAAA,MAAa,SAAS;IACpB,YAAqC,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QACjD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,GAAW;QAC9B,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEO,QAAQ,CAAC,GAAW;QAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,8DAA8D;QAC9D,MAAM,UAAU,GAAG,4BAA4B,CAAC;QAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC9F,CAAC;QAED,6BAA6B;QAC7B,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,sCAAsC;YACtC,MAAM,WAAW,GAAG,qBAAqB,CAAC;YAC1C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC1D,CAAC;IAEM,MAAM,CAAC,KAAgB;QAC5B,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;IACtC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AAlDD,8BAkDC"}
@@ -0,0 +1,42 @@
1
+ export interface AppConfig {
2
+ server: {
3
+ baseUrl: string;
4
+ };
5
+ groundInfo: {
6
+ groundId: string;
7
+ };
8
+ sse: {
9
+ retryInterval: number;
10
+ maxRetries: number;
11
+ };
12
+ stream: {
13
+ persistentStateDir: string;
14
+ tempStateDir: string;
15
+ healthCheckInterval: number;
16
+ };
17
+ logging: {
18
+ level: string;
19
+ file?: string;
20
+ };
21
+ remoteLogging: {
22
+ enabled: boolean;
23
+ sourceId: string;
24
+ batchSize: number;
25
+ batchInterval: number;
26
+ maxMemoryUsage: number;
27
+ retryAttempts: number;
28
+ retryDelay: number;
29
+ };
30
+ environment: string;
31
+ }
32
+ export declare class Config {
33
+ private static instance;
34
+ private config;
35
+ private constructor();
36
+ static getInstance(): Config;
37
+ get(): AppConfig;
38
+ private loadConfig;
39
+ private getEnvVar;
40
+ validate(): void;
41
+ }
42
+ //# sourceMappingURL=Config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/config/Config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,GAAG,EAAE;QACH,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,aAAa,EAAE;QACb,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,MAAM,CAAY;IAE1B,OAAO;WAIO,WAAW,IAAI,MAAM;IAO5B,GAAG,IAAI,SAAS;IAIvB,OAAO,CAAC,UAAU;IAkDlB,OAAO,CAAC,SAAS;IAQV,QAAQ,IAAI,IAAI;CAuBxB"}
@@ -0,0 +1,113 @@
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.Config = void 0;
37
+ const dotenv = __importStar(require("dotenv"));
38
+ // Load environment variables
39
+ dotenv.config();
40
+ class Config {
41
+ constructor() {
42
+ this.config = this.loadConfig();
43
+ }
44
+ static getInstance() {
45
+ if (!Config.instance) {
46
+ Config.instance = new Config();
47
+ }
48
+ return Config.instance;
49
+ }
50
+ get() {
51
+ return this.config;
52
+ }
53
+ loadConfig() {
54
+ return {
55
+ server: {
56
+ baseUrl: this.getEnvVar("BASE_URL", "https://api.drop-shot.live/"),
57
+ },
58
+ groundInfo: {
59
+ groundId: this.getEnvVar("GROUND_ID", ""),
60
+ },
61
+ sse: {
62
+ retryInterval: parseInt(this.getEnvVar("SSE_RETRY_INTERVAL", "5000")),
63
+ maxRetries: parseInt(this.getEnvVar("SSE_MAX_RETRIES", "10")),
64
+ },
65
+ stream: {
66
+ persistentStateDir: this.getEnvVar("PERSISTENT_STATE_DIR", "/var/tmp/stream_registry"),
67
+ tempStateDir: this.getEnvVar("TEMP_STATE_DIR", "/tmp/stream_registry"),
68
+ healthCheckInterval: parseInt(this.getEnvVar("HEALTH_CHECK_INTERVAL", "30000")),
69
+ },
70
+ logging: {
71
+ level: this.getEnvVar("LOG_LEVEL", "info"),
72
+ file: process.env.LOG_FILE,
73
+ },
74
+ remoteLogging: {
75
+ enabled: this.getEnvVar("REMOTE_LOGGING_ENABLED", "false") === "true",
76
+ sourceId: this.getEnvVar("REMOTE_LOGGING_SOURCE_ID", "raspberry-pi-001"),
77
+ batchSize: parseInt(this.getEnvVar("REMOTE_LOGGING_BATCH_SIZE", "50")),
78
+ batchInterval: parseInt(this.getEnvVar("REMOTE_LOGGING_BATCH_INTERVAL", "300000")), // 5 minutes
79
+ maxMemoryUsage: parseInt(this.getEnvVar("REMOTE_LOGGING_MAX_MEMORY", "512000")), // 500KB
80
+ retryAttempts: parseInt(this.getEnvVar("REMOTE_LOGGING_RETRY_ATTEMPTS", "999999")), // Infinite for errors
81
+ retryDelay: parseInt(this.getEnvVar("REMOTE_LOGGING_RETRY_DELAY", "5000")), // 5 seconds
82
+ },
83
+ environment: this.getEnvVar("NODE_ENV", "development"),
84
+ };
85
+ }
86
+ getEnvVar(key, defaultValue) {
87
+ const value = process.env[key];
88
+ if (value === undefined) {
89
+ return defaultValue;
90
+ }
91
+ return value;
92
+ }
93
+ validate() {
94
+ const errors = [];
95
+ if (!this.config.groundInfo.groundId) {
96
+ errors.push("GROUND_ID is required");
97
+ }
98
+ if (this.config.sse.retryInterval <= 0) {
99
+ errors.push("SSE_RETRY_INTERVAL must be positive");
100
+ }
101
+ if (this.config.sse.maxRetries <= 0) {
102
+ errors.push("SSE_MAX_RETRIES must be positive");
103
+ }
104
+ if (!this.config.server.baseUrl) {
105
+ errors.push("SERVER_BASE_URL is required");
106
+ }
107
+ if (errors.length > 0) {
108
+ throw new Error(`Configuration validation failed: ${errors.join(", ")}`);
109
+ }
110
+ }
111
+ }
112
+ exports.Config = Config;
113
+ //# sourceMappingURL=Config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Config.js","sourceRoot":"","sources":["../../../../src/infrastructure/config/Config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAEjC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,EAAE,CAAC;AAkChB,MAAa,MAAM;IAIjB;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IAClC,CAAC;IAEM,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,QAAQ,GAAG,IAAI,MAAM,EAAE,CAAC;QACjC,CAAC;QACD,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEM,GAAG;QACR,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,UAAU;QAChB,OAAO;YACL,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,6BAA6B,CAAC;aACnE;YACD,UAAU,EAAE;gBACV,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;aAC1C;YACD,GAAG,EAAE;gBACH,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;gBACrE,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;aAC9D;YACD,MAAM,EAAE;gBACN,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAChC,sBAAsB,EACtB,0BAA0B,CAC3B;gBACD,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;gBACtE,mBAAmB,EAAE,QAAQ,CAC3B,IAAI,CAAC,SAAS,CAAC,uBAAuB,EAAE,OAAO,CAAC,CACjD;aACF;YACD,OAAO,EAAE;gBACP,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC;gBAC1C,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;aAC3B;YACD,aAAa,EAAE;gBACb,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,wBAAwB,EAAE,OAAO,CAAC,KAAK,MAAM;gBACrE,QAAQ,EAAE,IAAI,CAAC,SAAS,CACtB,0BAA0B,EAC1B,kBAAkB,CACnB;gBACD,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC;gBACtE,aAAa,EAAE,QAAQ,CACrB,IAAI,CAAC,SAAS,CAAC,+BAA+B,EAAE,QAAQ,CAAC,CAC1D,EAAE,YAAY;gBACf,cAAc,EAAE,QAAQ,CACtB,IAAI,CAAC,SAAS,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CACtD,EAAE,QAAQ;gBACX,aAAa,EAAE,QAAQ,CACrB,IAAI,CAAC,SAAS,CAAC,+BAA+B,EAAE,QAAQ,CAAC,CAC1D,EAAE,sBAAsB;gBACzB,UAAU,EAAE,QAAQ,CAClB,IAAI,CAAC,SAAS,CAAC,4BAA4B,EAAE,MAAM,CAAC,CACrD,EAAE,YAAY;aAChB;YACD,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,aAAa,CAAC;SACvD,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,GAAW,EAAE,YAAoB;QACjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,QAAQ;QACb,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;CACF;AApGD,wBAoGC"}
@@ -0,0 +1,12 @@
1
+ import { Logger } from "../../application/interfaces/Logger";
2
+ export declare class ConsoleLogger implements Logger {
3
+ private readonly logLevel;
4
+ constructor(logLevel?: string);
5
+ shouldLog(level: string): boolean;
6
+ private formatMessage;
7
+ info(message: string, meta?: any): void;
8
+ warn(message: string, meta?: any): void;
9
+ error(message: string, meta?: any): void;
10
+ debug(message: string, meta?: any): void;
11
+ }
12
+ //# sourceMappingURL=ConsoleLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleLogger.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/logging/ConsoleLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,qBAAa,aAAc,YAAW,MAAM;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,MAAgB;IAEvD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAOjC,OAAO,CAAC,aAAa;IAMd,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAMvC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAMvC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAMxC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;CAKhD"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConsoleLogger = void 0;
4
+ class ConsoleLogger {
5
+ constructor(logLevel = "debug") {
6
+ this.logLevel = logLevel;
7
+ }
8
+ shouldLog(level) {
9
+ const levels = ["debug", "info", "warn", "error"];
10
+ const currentLevelIndex = levels.indexOf(this.logLevel);
11
+ const messageLevelIndex = levels.indexOf(level);
12
+ return messageLevelIndex >= currentLevelIndex;
13
+ }
14
+ formatMessage(level, message, meta) {
15
+ const timestamp = new Date().toISOString();
16
+ const metaStr = meta ? ` ${JSON.stringify(meta)}` : "";
17
+ return `[${timestamp}] ${level.toUpperCase()}: ${message}${metaStr}`;
18
+ }
19
+ info(message, meta) {
20
+ if (this.shouldLog("info")) {
21
+ console.log(this.formatMessage("info", message, meta));
22
+ }
23
+ }
24
+ warn(message, meta) {
25
+ if (this.shouldLog("warn")) {
26
+ console.warn(this.formatMessage("warn", message, meta));
27
+ }
28
+ }
29
+ error(message, meta) {
30
+ if (this.shouldLog("error")) {
31
+ console.error(this.formatMessage("error", message, meta));
32
+ }
33
+ }
34
+ debug(message, meta) {
35
+ if (this.shouldLog("debug")) {
36
+ console.debug(this.formatMessage("debug", message, meta));
37
+ }
38
+ }
39
+ }
40
+ exports.ConsoleLogger = ConsoleLogger;
41
+ //# sourceMappingURL=ConsoleLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleLogger.js","sourceRoot":"","sources":["../../../../src/infrastructure/logging/ConsoleLogger.ts"],"names":[],"mappings":";;;AAEA,MAAa,aAAa;IACxB,YAA6B,WAAmB,OAAO;QAA1B,aAAQ,GAAR,QAAQ,CAAkB;IAAG,CAAC;IAE3D,SAAS,CAAC,KAAa;QACrB,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,iBAAiB,IAAI,iBAAiB,CAAC;IAChD,CAAC;IAEO,aAAa,CAAC,KAAa,EAAE,OAAe,EAAE,IAAU;QAC9D,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,SAAS,KAAK,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,GAAG,OAAO,EAAE,CAAC;IACvE,CAAC;IAEM,IAAI,CAAC,OAAe,EAAE,IAAU;QACrC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAEM,IAAI,CAAC,OAAe,EAAE,IAAU;QACrC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,OAAe,EAAE,IAAU;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,OAAe,EAAE,IAAU;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;CACF;AAvCD,sCAuCC"}
@@ -0,0 +1,20 @@
1
+ import { LogEntry, LogBufferStats } from "./types/LogTypes";
2
+ export declare class LogBuffer {
3
+ private buffer;
4
+ private totalSize;
5
+ private readonly maxSize;
6
+ private readonly maxCount;
7
+ private flushTimer?;
8
+ private readonly flushInterval;
9
+ private readonly onFlush;
10
+ constructor(maxSize: number, maxCount: number, flushInterval: number, onFlush: (logs: LogEntry[]) => Promise<void>);
11
+ add(entry: LogEntry): void;
12
+ flush(): Promise<void>;
13
+ getStats(): LogBufferStats;
14
+ destroy(): void;
15
+ private shouldFlushEarly;
16
+ private estimateLogSize;
17
+ private startFlushTimer;
18
+ private restartFlushTimer;
19
+ }
20
+ //# sourceMappingURL=LogBuffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogBuffer.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/logging/LogBuffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAe,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEzE,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;gBAG5D,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC;IASvC,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAgBpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB5B,QAAQ,IAAI,cAAc;IAW1B,OAAO,IAAI,IAAI;IActB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,iBAAiB;CAM1B"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogBuffer = void 0;
4
+ class LogBuffer {
5
+ constructor(maxSize, maxCount, flushInterval, onFlush) {
6
+ this.buffer = [];
7
+ this.totalSize = 0;
8
+ this.maxSize = maxSize;
9
+ this.maxCount = maxCount;
10
+ this.flushInterval = flushInterval;
11
+ this.onFlush = onFlush;
12
+ this.startFlushTimer();
13
+ }
14
+ add(entry) {
15
+ const estimatedSize = this.estimateLogSize(entry);
16
+ const bufferedLog = {
17
+ entry,
18
+ size: estimatedSize,
19
+ };
20
+ this.buffer.push(bufferedLog);
21
+ this.totalSize += estimatedSize;
22
+ // Check if we need to flush early due to size or count limits
23
+ if (this.shouldFlushEarly()) {
24
+ this.flush();
25
+ }
26
+ }
27
+ async flush() {
28
+ if (this.buffer.length === 0) {
29
+ return;
30
+ }
31
+ const logsToFlush = this.buffer.map((bufferedLog) => bufferedLog.entry);
32
+ this.buffer = [];
33
+ this.totalSize = 0;
34
+ try {
35
+ await this.onFlush(logsToFlush);
36
+ }
37
+ catch (error) {
38
+ // If flush fails, we don't re-add logs to avoid infinite loops
39
+ // The shipping service should handle retries
40
+ console.error("Failed to flush log buffer:", error);
41
+ }
42
+ // Restart the timer after flush
43
+ this.restartFlushTimer();
44
+ }
45
+ getStats() {
46
+ const timestamps = this.buffer.map((log) => log.entry.timestamp);
47
+ return {
48
+ count: this.buffer.length,
49
+ totalSize: this.totalSize,
50
+ oldestTimestamp: timestamps.length > 0 ? timestamps[0] : undefined,
51
+ newestTimestamp: timestamps.length > 0 ? timestamps[timestamps.length - 1] : undefined,
52
+ };
53
+ }
54
+ destroy() {
55
+ if (this.flushTimer) {
56
+ clearTimeout(this.flushTimer);
57
+ this.flushTimer = undefined;
58
+ }
59
+ // Flush any remaining logs before destroying
60
+ if (this.buffer.length > 0) {
61
+ this.flush().catch((error) => {
62
+ console.error("Failed to flush logs during buffer destruction:", error);
63
+ });
64
+ }
65
+ }
66
+ shouldFlushEarly() {
67
+ return (this.totalSize >= this.maxSize || this.buffer.length >= this.maxCount);
68
+ }
69
+ estimateLogSize(entry) {
70
+ // Rough estimation of JSON size in bytes
71
+ const baseSize = JSON.stringify({
72
+ level: entry.level,
73
+ message: entry.message,
74
+ timestamp: entry.timestamp,
75
+ }).length;
76
+ const metadataSize = entry.metadata
77
+ ? JSON.stringify(entry.metadata).length
78
+ : 0;
79
+ // Add some overhead for JSON formatting
80
+ return baseSize + metadataSize + 50;
81
+ }
82
+ startFlushTimer() {
83
+ this.flushTimer = setTimeout(() => {
84
+ this.flush();
85
+ }, this.flushInterval);
86
+ }
87
+ restartFlushTimer() {
88
+ if (this.flushTimer) {
89
+ clearTimeout(this.flushTimer);
90
+ }
91
+ this.startFlushTimer();
92
+ }
93
+ }
94
+ exports.LogBuffer = LogBuffer;
95
+ //# sourceMappingURL=LogBuffer.js.map