|  |  | @ -10,6 +10,20 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |   /** @type {Workout[]} */ | 
			
		
	
		
			
				
					|  |  |  |   let workouts = []; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   function activeData(id) { | 
			
		
	
		
			
				
					|  |  |  |     const workout = workouts.find(w2 => w2.id === id); | 
			
		
	
		
			
				
					|  |  |  |     if (workout == null) { | 
			
		
	
		
			
				
					|  |  |  |       return { | 
			
		
	
		
			
				
					|  |  |  |         active: false, | 
			
		
	
		
			
				
					|  |  |  |       }; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     return { | 
			
		
	
		
			
				
					|  |  |  |       active: true, | 
			
		
	
		
			
				
					|  |  |  |       state: workout.state, | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   router.get("/", async(req, res) => { | 
			
		
	
		
			
				
					|  |  |  |     if (req.query.active === "true") { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json(workouts.map(w => ({ | 
			
		
	
	
		
			
				
					|  |  | @ -17,7 +31,7 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |         bike: w.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: w.program, | 
			
		
	
		
			
				
					|  |  |  |         date: w.date, | 
			
		
	
		
			
				
					|  |  |  |         active: true, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(w.id), | 
			
		
	
		
			
				
					|  |  |  |       }))); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -25,7 +39,7 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |       const dbWorkouts = await repo.listWorkouts(); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json(dbWorkouts.map(w => ({ | 
			
		
	
		
			
				
					|  |  |  |         ...w, | 
			
		
	
		
			
				
					|  |  |  |         active: workouts.find(w2 => w2.id === w.id) != null, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(w.id), | 
			
		
	
		
			
				
					|  |  |  |       }))); | 
			
		
	
		
			
				
					|  |  |  |     } catch (err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(400).json({code: 400, message: err.message || err})       | 
			
		
	
	
		
			
				
					|  |  | @ -35,7 +49,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |   router.get("/:id", async(req, res) => { | 
			
		
	
		
			
				
					|  |  |  |     let workout = workouts.find(w => w.id == req.params.id); | 
			
		
	
		
			
				
					|  |  |  |     if (workout != null) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date, active: true}) | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program, | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(w.id), | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
	
		
			
				
					|  |  | @ -70,7 +90,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |       const workout = await Workout.create(repo, bikeId, programId); | 
			
		
	
		
			
				
					|  |  |  |       workouts.push(workout); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program, | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(workout.id),         | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch (err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(400).json({code: 400, message: err.message || err}); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -86,7 +112,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |       workout = await Workout.continue(repo, req.params.id); | 
			
		
	
		
			
				
					|  |  |  |       workouts.push(workout); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program, | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(w.id), | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch (err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(400).json({code: 400, message: err.message || err})       | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -100,7 +132,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
		
			
				
					|  |  |  |       await workout.connect(); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program,  | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(workout.id),       | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch(err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(500).json({code: 500, message: err.message || err}); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -114,7 +152,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
		
			
				
					|  |  |  |       await workout.start(); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program,  | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(workout.id),       | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch(err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(500).json({code: 500, message: err.message || err}); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -128,7 +172,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
		
			
				
					|  |  |  |       await workout.pause(); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program,  | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(workout.id),       | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch(err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(500).json({code: 500, message: err.message || err}); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -148,7 +198,13 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |       workouts = workouts.filter(w => w !== workout); | 
			
		
	
		
			
				
					|  |  |  |       await workout.destroy(); | 
			
		
	
		
			
				
					|  |  |  |    | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date});   | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program,  | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(workout.id),       | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch(err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(500).json({code: 500, message: err.message || err}); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -168,15 +224,19 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |    | 
			
		
	
		
			
				
					|  |  |  |       await repo.deleteWorkout(workout); | 
			
		
	
		
			
				
					|  |  |  |    | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json(workout); | 
			
		
	
		
			
				
					|  |  |  |       return res.status(200).json({ | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
		
			
				
					|  |  |  |         program: workout.program,  | 
			
		
	
		
			
				
					|  |  |  |         date: workout.date, | 
			
		
	
		
			
				
					|  |  |  |         ...activeData(workout.id),       | 
			
		
	
		
			
				
					|  |  |  |       }); | 
			
		
	
		
			
				
					|  |  |  |     } catch (err) { | 
			
		
	
		
			
				
					|  |  |  |       return res.status(500).json({code: 500, message: err.message || err})       | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   router.ws("/:id/subscribe", (ws, req) => { | 
			
		
	
		
			
				
					|  |  |  |     console.log("HELLO!") | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const workout = workouts.find(w => w.id === req.params.id); | 
			
		
	
		
			
				
					|  |  |  |     if (workout == null) { | 
			
		
	
		
			
				
					|  |  |  |       ws.send(JSON.stringify({error: "workout not found"})); | 
			
		
	
	
		
			
				
					|  |  | @ -184,6 +244,8 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     workout.listMeasurements().then((list) => { | 
			
		
	
		
			
				
					|  |  |  |       list = list.map(v => {delete v.id; delete v.workoutId; return v}); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       for (let i = 0; i < list.length; i += 240) { | 
			
		
	
		
			
				
					|  |  |  |         ws.send(JSON.stringify({workoutStatusBackfill: list.slice(i, i+240)})); | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
	
		
			
				
					|  |  | @ -192,21 +254,28 @@ module.exports = function workoutRouter(repo) { | 
			
		
	
		
			
				
					|  |  |  |       ws.close(); | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     const handler = (workotuStatus) => { | 
			
		
	
		
			
				
					|  |  |  |       workotuStatus = {...workotuStatus}; | 
			
		
	
		
			
				
					|  |  |  |       delete workotuStatus.id; | 
			
		
	
		
			
				
					|  |  |  |     const onWorkoutStatus = (workoutStatus) => { | 
			
		
	
		
			
				
					|  |  |  |       workoutStatus = {...workoutStatus}; | 
			
		
	
		
			
				
					|  |  |  |       delete workoutStatus.id; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |       ws.send(JSON.stringify({workoutStatus})) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     workout.events.on("workoutStatus", onWorkoutStatus); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |       ws.send(JSON.stringify({workotuStatus})) | 
			
		
	
		
			
				
					|  |  |  |     const onState = (state) => {     | 
			
		
	
		
			
				
					|  |  |  |       ws.send(JSON.stringify({state})) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     workout.events.on("state", onState); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     workout.events.on("workoutStatus", handler); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     ws.onclose = () => { | 
			
		
	
		
			
				
					|  |  |  |       workout.events.removeListener("workoutStatus", handler); | 
			
		
	
		
			
				
					|  |  |  |       workout.events.removeListener("workoutStatus", onWorkoutStatus); | 
			
		
	
		
			
				
					|  |  |  |       workout.events.removeListener("state", onState); | 
			
		
	
		
			
				
					|  |  |  |       ws.removeAllListeners(); | 
			
		
	
		
			
				
					|  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     ws.send(JSON.stringify({ | 
			
		
	
		
			
				
					|  |  |  |       state: workout.state, | 
			
		
	
		
			
				
					|  |  |  |       workout: { | 
			
		
	
		
			
				
					|  |  |  |         id: workout.id, | 
			
		
	
		
			
				
					|  |  |  |         bike: workout.bike, | 
			
		
	
	
		
			
				
					|  |  | 
 |