@@ -15,15 +15,23 @@ import { WebSocketServer, WebSocket } from "ws";
1515
1616import { Service } from "typedi" ;
1717import type { BumpgenService } from "./types" ;
18- import { success } from "../result" ;
19- import { AppConfigService } from "./AppConfigService" ;
20- import type { JobSchedulerService } from "./JobSchedulerService" ;
18+ import { success } from "../result/index.js" ;
19+ import { AppConfigService } from "./AppConfigService.js" ;
20+ import { JobSchedulerService } from "./JobSchedulerService.js" ;
21+ import { XmlTvService } from "./XmlTvService.js" ;
2122
2223type StatusEvent =
24+ | {
25+ status : "starting" ; // Fetching XML TV Data
26+ data : Record < string , never > ;
27+ }
2328 | {
2429 status : "running" ;
2530 data : {
31+ numChannels : number ;
32+ channelIndex : number ;
2633 channelId : string ;
34+ task : "starting" | "generating" ;
2735 } ;
2836 }
2937 | {
@@ -35,12 +43,22 @@ type StatusEvent =
3543 } ;
3644
3745interface StatsEvent {
38- lastRun : number ;
46+ lastRun : {
47+ time : number ;
48+ channelIds : string [ ] ;
49+ channelResults : Record <
50+ string ,
51+ {
52+ duration : number ;
53+ result : "generated" | "up-to-date" | "error" | "not-configured" ;
54+ }
55+ > ;
56+ } ;
3957}
4058
4159type Event =
42- | { name : "status" ; event : StatusEvent }
43- | { name : "stats" ; event : StatsEvent } ;
60+ | { name : "status" ; event : StatusEvent ; id : number }
61+ | { name : "stats" ; event : StatsEvent ; id : number } ;
4462
4563@Service ( )
4664export class LiveStatsService implements BumpgenService {
@@ -50,46 +68,123 @@ export class LiveStatsService implements BumpgenService {
5068 return this . _wss ;
5169 }
5270
53- private lastStatsEvent : Event | undefined ;
71+ private idCount = 0 ;
72+
73+ private latestStatusEvent : StatusEvent | undefined ;
74+ private latestStatsEvent : StatsEvent | undefined ;
5475
5576 constructor (
5677 public appConfigService : AppConfigService ,
5778 public jobSchedulerService : JobSchedulerService ,
79+ public xmlTvService : XmlTvService ,
5880 ) {
5981 this . _wss = new WebSocketServer ( { noServer : true } ) ;
6082 }
6183
62- public running = ( channelId : string ) => {
63- const event : Event = {
64- name : "status" ,
65- event : {
66- status : "running" ,
67- data : {
68- channelId,
69- } ,
84+ public channelResult = (
85+ channelId : string ,
86+ duration : number ,
87+ result : "generated" | "up-to-date" | "error" | "not-configured" ,
88+ ) => {
89+ const event : StatsEvent = this . latestStatsEvent ?? {
90+ lastRun : {
91+ time : new Date ( ) . getTime ( ) ,
92+ channelIds : this . xmlTvService . channels . map ( ( c ) => c . id ) ,
93+ channelResults : { } ,
7094 } ,
7195 } ;
72- this . emitEvent ( event ) ;
73- this . lastStatsEvent = event ;
96+
97+ this . emitStatsEvent ( {
98+ ...event ,
99+ lastRun : {
100+ ...event . lastRun ,
101+ channelResults : {
102+ ...event . lastRun . channelResults ,
103+ [ channelId ] : {
104+ duration,
105+ result,
106+ } ,
107+ } ,
108+ } ,
109+ } ) ;
110+ } ;
111+
112+ public xmlTvFetched = ( ) => {
113+ if ( this . latestStatsEvent ) {
114+ this . emitStatsEvent ( {
115+ ...this . latestStatsEvent ,
116+ lastRun : {
117+ ...this . latestStatsEvent . lastRun ,
118+ channelIds : this . xmlTvService . channels . map ( ( c ) => c . id ) ,
119+ } ,
120+ } ) ;
121+ }
122+ } ;
123+
124+ public start = ( ) => {
125+ this . emitStatusEvent ( {
126+ status : "starting" ,
127+ data : { } ,
128+ } ) ;
129+
130+ this . emitStatsEvent ( {
131+ lastRun : {
132+ time : new Date ( ) . getTime ( ) ,
133+ channelIds : this . xmlTvService . channels . map ( ( c ) => c . id ) ,
134+ channelResults : { } ,
135+ } ,
136+ } ) ;
137+ } ;
138+
139+ public running = ( channelId : string , task : "generating" | "starting" ) => {
140+ this . emitStatusEvent ( {
141+ status : "running" ,
142+ data : {
143+ numChannels : this . xmlTvService . channels . length ,
144+ channelIndex : this . xmlTvService . channels . findIndex (
145+ ( c ) => c . id === channelId ,
146+ ) ,
147+ channelId,
148+ task,
149+ } ,
150+ } ) ;
74151 } ;
75152
76153 public waiting = ( ) => {
77154 const nextRun = this . jobSchedulerService . getNextRunTime ( "main" ) ?. getTime ( ) ;
78155 if ( nextRun ) {
79- const event : Event = {
80- name : "status" ,
81- event : {
82- status : "waiting" ,
83- data : {
84- nextRun,
85- } ,
156+ this . emitStatusEvent ( {
157+ status : "waiting" ,
158+ data : {
159+ nextRun,
86160 } ,
87- } ;
88- this . emitEvent ( event ) ;
89- this . lastStatsEvent = event ;
161+ } ) ;
90162 }
91163 } ;
92164
165+ private getNextId = ( ) => {
166+ this . idCount += 1 ;
167+ return this . idCount ;
168+ } ;
169+
170+ private emitStatusEvent = ( event : StatusEvent , saveAsLatest = true ) => {
171+ this . emitEvent ( {
172+ name : "status" ,
173+ id : this . getNextId ( ) ,
174+ event,
175+ } ) ;
176+ if ( saveAsLatest ) this . latestStatusEvent = event ;
177+ } ;
178+
179+ private emitStatsEvent = ( event : StatsEvent , saveAsLatest = true ) => {
180+ this . emitEvent ( {
181+ name : "stats" ,
182+ id : this . getNextId ( ) ,
183+ event,
184+ } ) ;
185+ if ( saveAsLatest ) this . latestStatsEvent = event ;
186+ } ;
187+
93188 private emitEvent = ( event : Event ) => {
94189 this . _wss . clients . forEach ( ( client ) => {
95190 if ( client . readyState === WebSocket . OPEN ) {
@@ -99,7 +194,22 @@ export class LiveStatsService implements BumpgenService {
99194 } ;
100195
101196 private onConnect = ( client : WebSocket ) => {
102- client . send ( JSON . stringify ( this . lastStatsEvent ) ) ;
197+ if ( this . latestStatusEvent ) {
198+ const event : Event = {
199+ name : "status" ,
200+ id : 0 ,
201+ event : this . latestStatusEvent ,
202+ } ;
203+ client . send ( JSON . stringify ( event ) ) ;
204+ }
205+ if ( this . latestStatsEvent ) {
206+ const event : Event = {
207+ name : "stats" ,
208+ id : 1 ,
209+ event : this . latestStatsEvent ,
210+ } ;
211+ client . send ( JSON . stringify ( event ) ) ;
212+ }
103213 } ;
104214
105215 load = ( ) => {
0 commit comments