@aneuhold/core-ts-db-lib 4.1.1 → 4.1.2

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 🔖 [4.1.2] (2026-02-15)
9
+
10
+ ### ✅ Added
11
+
12
+ - Added `generatePlateWeightOptions()` method to `WorkoutEquipmentTypeService` to generate all achievable weight combinations from a bar and plate pairs.
13
+ - Added `get1RMRaw()` static method to `WorkoutExerciseCalibrationService` for calculating 1RM from weight and reps.
14
+
15
+ ### 🏗️ Changed
16
+
17
+ - Refactored `generateSessionsForMicrocycle()` in `WorkoutMicrocycleService` to support creating more sessions than available non-rest days by distributing sessions chronologically across days.
18
+
8
19
  ## 🔖 [4.1.1] (2026-02-06)
9
20
 
10
21
  ### 🏗️ Changed
@@ -214,6 +225,7 @@ Updated dependency: now requires `@aneuhold/core-ts-lib@^2.3.11`.
214
225
 
215
226
  <!-- Link References -->
216
227
 
228
+ [4.1.2]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.1...core-ts-db-lib-v4.1.2
217
229
  [4.1.1]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.1.0...core-ts-db-lib-v4.1.1
218
230
  [4.1.0]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.0.4...core-ts-db-lib-v4.1.0
219
231
  [4.0.4]: https://github.com/aneuhold/ts-libs/compare/core-ts-db-lib-v4.0.3...core-ts-db-lib-v4.0.4
@@ -9,14 +9,27 @@ export default class WorkoutEquipmentTypeService {
9
9
  * Starts at minWeight (e.g., the bar weight), increments by increment (e.g., 2.5, 5, 10 lbs),
10
10
  * and continues until maxWeight is reached or exceeded.
11
11
  *
12
- * This may be refactored / maybe a new method will be created in the future to handle a given
13
- * set of weight plates to generate all possible combinations.
14
- *
15
12
  * @param minWeight The minimum weight (e.g., bar weight).
16
13
  * @param increment The weight increment.
17
14
  * @param maxWeight The maximum weight.
18
15
  */
19
16
  static generateWeightOptions(minWeight: number, increment: number, maxWeight: number): number[];
17
+ /**
18
+ * Generates all achievable weights from a bar weight and a set of plate pairs.
19
+ *
20
+ * Each plate entry specifies a plate weight and the number of pairs available.
21
+ * Plates are added in pairs (both sides of the bar), so each plate adds
22
+ * `weight * 2` to the total. All combinations of plates are computed to
23
+ * produce the full set of achievable weights.
24
+ *
25
+ * @param barWeight The weight of the bar alone.
26
+ * @param plates Array of plate entries, each with a `weight` and `pairs` count.
27
+ * @returns Sorted, deduplicated array of all achievable weights.
28
+ */
29
+ static generatePlateWeightOptions(barWeight: number, plates: Array<{
30
+ weight: number;
31
+ pairs: number;
32
+ }>): number[];
20
33
  /**
21
34
  * Finds the nearest available weight from equipmentType.weightOptions.
22
35
  *
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutEquipmentTypeService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/EquipmentType/WorkoutEquipmentTypeService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAE/F;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,2BAA2B;IAC9C;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAY/F;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,iBAAiB,CACtB,aAAa,EAAE,oBAAoB,EACnC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GACjE,MAAM,GAAG,IAAI;CAyCjB"}
1
+ {"version":3,"file":"WorkoutEquipmentTypeService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/EquipmentType/WorkoutEquipmentTypeService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAE/F;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,2BAA2B;IAC9C;;;;;;;;;OASG;IACH,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAY/F;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,0BAA0B,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAC/C,MAAM,EAAE;IAoBX;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,iBAAiB,CACtB,aAAa,EAAE,oBAAoB,EACnC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GACjE,MAAM,GAAG,IAAI;CAyCjB"}
@@ -8,9 +8,6 @@ export default class WorkoutEquipmentTypeService {
8
8
  * Starts at minWeight (e.g., the bar weight), increments by increment (e.g., 2.5, 5, 10 lbs),
9
9
  * and continues until maxWeight is reached or exceeded.
10
10
  *
11
- * This may be refactored / maybe a new method will be created in the future to handle a given
12
- * set of weight plates to generate all possible combinations.
13
- *
14
11
  * @param minWeight The minimum weight (e.g., bar weight).
15
12
  * @param increment The weight increment.
16
13
  * @param maxWeight The maximum weight.
@@ -24,6 +21,39 @@ export default class WorkoutEquipmentTypeService {
24
21
  }
25
22
  return weights;
26
23
  }
24
+ /**
25
+ * Generates all achievable weights from a bar weight and a set of plate pairs.
26
+ *
27
+ * Each plate entry specifies a plate weight and the number of pairs available.
28
+ * Plates are added in pairs (both sides of the bar), so each plate adds
29
+ * `weight * 2` to the total. All combinations of plates are computed to
30
+ * produce the full set of achievable weights.
31
+ *
32
+ * @param barWeight The weight of the bar alone.
33
+ * @param plates Array of plate entries, each with a `weight` and `pairs` count.
34
+ * @returns Sorted, deduplicated array of all achievable weights.
35
+ */
36
+ static generatePlateWeightOptions(barWeight, plates) {
37
+ let additions = new Set([0]);
38
+ for (const plate of plates) {
39
+ if (plate.weight <= 0 || plate.pairs <= 0)
40
+ continue;
41
+ const expanded = [];
42
+ for (const existing of additions) {
43
+ for (let count = 1; count <= plate.pairs; count++) {
44
+ expanded.push(existing + plate.weight * 2 * count);
45
+ }
46
+ }
47
+ additions = new Set([...additions, ...expanded]);
48
+ if (additions.size > 1000)
49
+ break;
50
+ }
51
+ const weights = [...additions]
52
+ .map((a) => barWeight + a)
53
+ .filter((w) => w >= 0)
54
+ .sort((a, b) => a - b);
55
+ return [...new Set(weights)];
56
+ }
27
57
  /**
28
58
  * Finds the nearest available weight from equipmentType.weightOptions.
29
59
  *
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutEquipmentTypeService.js","sourceRoot":"","sources":["../../../../src/services/workout/EquipmentType/WorkoutEquipmentTypeService.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,2BAA2B;IAC9C;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,qBAAqB,CAAC,SAAiB,EAAE,SAAiB,EAAE,SAAiB;QAClF,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,aAAa,GAAG,SAAS,CAAC;QAE9B,OAAO,aAAa,IAAI,SAAS,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC5B,aAAa,IAAI,SAAS,CAAC;QAC7B,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,iBAAiB,CACtB,aAAmC,EACnC,YAAoB,EACpB,SAAkE;QAElE,IAAI,CAAC,aAAa,CAAC,aAAa,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE7E,gDAAgD;QAChD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,IAAI,CAAC;QAChF,MAAM,UAAU,GACd,aAAa;aACV,KAAK,EAAE;aACP,OAAO,EAAE;aACT,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,IAAI,CAAC;QAEtD,wBAAwB;QACxB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;YAChC,OAAO,UAAU,IAAI,QAAQ,CAAC;QAChC,CAAC;QAED,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;YAC9B,OAAO,QAAQ,IAAI,UAAU,CAAC;QAChC,CAAC;QAED,0BAA0B;QAC1B,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,UAAU,CAAC;QACzC,IAAI,UAAU,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;QAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,QAAQ,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC;QAErD,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;IACpD,CAAC;CACF"}
1
+ {"version":3,"file":"WorkoutEquipmentTypeService.js","sourceRoot":"","sources":["../../../../src/services/workout/EquipmentType/WorkoutEquipmentTypeService.ts"],"names":[],"mappings":"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"}
@@ -10,9 +10,6 @@ export default class WorkoutEquipmentTypeService {
10
10
  * Starts at minWeight (e.g., the bar weight), increments by increment (e.g., 2.5, 5, 10 lbs),
11
11
  * and continues until maxWeight is reached or exceeded.
12
12
  *
13
- * This may be refactored / maybe a new method will be created in the future to handle a given
14
- * set of weight plates to generate all possible combinations.
15
- *
16
13
  * @param minWeight The minimum weight (e.g., bar weight).
17
14
  * @param increment The weight increment.
18
15
  * @param maxWeight The maximum weight.
@@ -29,6 +26,41 @@ export default class WorkoutEquipmentTypeService {
29
26
  return weights;
30
27
  }
31
28
 
29
+ /**
30
+ * Generates all achievable weights from a bar weight and a set of plate pairs.
31
+ *
32
+ * Each plate entry specifies a plate weight and the number of pairs available.
33
+ * Plates are added in pairs (both sides of the bar), so each plate adds
34
+ * `weight * 2` to the total. All combinations of plates are computed to
35
+ * produce the full set of achievable weights.
36
+ *
37
+ * @param barWeight The weight of the bar alone.
38
+ * @param plates Array of plate entries, each with a `weight` and `pairs` count.
39
+ * @returns Sorted, deduplicated array of all achievable weights.
40
+ */
41
+ static generatePlateWeightOptions(
42
+ barWeight: number,
43
+ plates: Array<{ weight: number; pairs: number }>
44
+ ): number[] {
45
+ let additions = new Set<number>([0]);
46
+ for (const plate of plates) {
47
+ if (plate.weight <= 0 || plate.pairs <= 0) continue;
48
+ const expanded: number[] = [];
49
+ for (const existing of additions) {
50
+ for (let count = 1; count <= plate.pairs; count++) {
51
+ expanded.push(existing + plate.weight * 2 * count);
52
+ }
53
+ }
54
+ additions = new Set([...additions, ...expanded]);
55
+ if (additions.size > 1000) break;
56
+ }
57
+ const weights = [...additions]
58
+ .map((a) => barWeight + a)
59
+ .filter((w) => w >= 0)
60
+ .sort((a, b) => a - b);
61
+ return [...new Set(weights)];
62
+ }
63
+
32
64
  /**
33
65
  * Finds the nearest available weight from equipmentType.weightOptions.
34
66
  *
@@ -11,6 +11,13 @@ export default class WorkoutExerciseCalibrationService {
11
11
  * @param calibration The workout exercise calibration.
12
12
  */
13
13
  static get1RM(calibration: WorkoutExerciseCalibration): number;
14
+ /**
15
+ * Calculates the 1 Rep Max using the NASM formula based on provided weight and reps.
16
+ *
17
+ * @param weight The weight lifted.
18
+ * @param reps The number of reps performed.
19
+ */
20
+ static get1RMRaw(weight: number, reps: number): number;
14
21
  /**
15
22
  * Calculates the target weight for a set based on target reps and 1RM.
16
23
  *
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutExerciseCalibrationService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAE3G;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iCAAiC;IACpD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,0BAA0B,GAAG,MAAM;IAI9D;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,0BAA0B,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAM3F;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAGnC"}
1
+ {"version":3,"file":"WorkoutExerciseCalibrationService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AAE3G;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iCAAiC;IACpD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,0BAA0B,GAAG,MAAM;IAI9D;;;;;OAKG;IACH,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAItD;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,0BAA0B,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAM3F;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAGnC"}
@@ -10,7 +10,16 @@ export default class WorkoutExerciseCalibrationService {
10
10
  * @param calibration The workout exercise calibration.
11
11
  */
12
12
  static get1RM(calibration) {
13
- return (calibration.weight * calibration.reps) / 30.48 + calibration.weight;
13
+ return this.get1RMRaw(calibration.weight, calibration.reps);
14
+ }
15
+ /**
16
+ * Calculates the 1 Rep Max using the NASM formula based on provided weight and reps.
17
+ *
18
+ * @param weight The weight lifted.
19
+ * @param reps The number of reps performed.
20
+ */
21
+ static get1RMRaw(weight, reps) {
22
+ return (weight * reps) / 30.48 + weight;
14
23
  }
15
24
  /**
16
25
  * Calculates the target weight for a set based on target reps and 1RM.
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutExerciseCalibrationService.js","sourceRoot":"","sources":["../../../../src/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iCAAiC;IACpD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,WAAuC;QACnD,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC;IAC9E,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,WAAuC,EAAE,UAAkB;QAChF,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9C,CAAC;IAED;;;;;;;;OAQG;IACK,MAAM,CAAC,mBAAmB,CAAC,UAAkB;QACnD,OAAO,EAAE,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACrC,CAAC;CACF"}
1
+ {"version":3,"file":"WorkoutExerciseCalibrationService.js","sourceRoot":"","sources":["../../../../src/services/workout/ExerciseCalibration/WorkoutExerciseCalibrationService.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iCAAiC;IACpD;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,WAAuC;QACnD,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,SAAS,CAAC,MAAc,EAAE,IAAY;QAC3C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1C,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,WAAuC,EAAE,UAAkB;QAChF,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9C,CAAC;IAED;;;;;;;;OAQG;IACK,MAAM,CAAC,mBAAmB,CAAC,UAAkB;QACnD,OAAO,EAAE,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACrC,CAAC;CACF"}
@@ -12,7 +12,17 @@ export default class WorkoutExerciseCalibrationService {
12
12
  * @param calibration The workout exercise calibration.
13
13
  */
14
14
  static get1RM(calibration: WorkoutExerciseCalibration): number {
15
- return (calibration.weight * calibration.reps) / 30.48 + calibration.weight;
15
+ return this.get1RMRaw(calibration.weight, calibration.reps);
16
+ }
17
+
18
+ /**
19
+ * Calculates the 1 Rep Max using the NASM formula based on provided weight and reps.
20
+ *
21
+ * @param weight The weight lifted.
22
+ * @param reps The number of reps performed.
23
+ */
24
+ static get1RMRaw(weight: number, reps: number): number {
25
+ return (weight * reps) / 30.48 + weight;
16
26
  }
17
27
 
18
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMicrocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Microcycle/WorkoutMicrocycleService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,0DAA0D,CAAC;AAElE,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAI3F;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,wBAAwB;IAC3C;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAAC,EACnC,OAAO,EACP,eAAe,EACf,SAAS,EACT,kBAAkB,EACnB,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IAwDR;;;;;;;OAOG;IACH,MAAM,CAAC,iCAAiC,CACtC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,EACrD,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,GACtC,uBAAuB,EAAE,EAAE;CAuI/B"}
1
+ {"version":3,"file":"WorkoutMicrocycleService.d.ts","sourceRoot":"","sources":["../../../../src/services/workout/Microcycle/WorkoutMicrocycleService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,0DAA0D,CAAC;AAElE,OAAO,KAAK,2BAA2B,MAAM,6CAA6C,CAAC;AAI3F;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,wBAAwB;IAC3C;;OAEG;IACH,MAAM,CAAC,6BAA6B,CAAC,EACnC,OAAO,EACP,eAAe,EACf,SAAS,EACT,kBAAkB,EACnB,EAAE;QACD,OAAO,EAAE,2BAA2B,CAAC;QACrC,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,IAAI;IA8DR;;;;;;;OAOG;IACH,MAAM,CAAC,iCAAiC,CACtC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,EACrD,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,GACtC,uBAAuB,EAAE,EAAE;CAuI/B"}
@@ -21,31 +21,38 @@ export default class WorkoutMicrocycleService {
21
21
  }
22
22
  const sessionsToExerciseSessionsArray = context.plannedSessionExercisePairs;
23
23
  const setPlan = WorkoutVolumePlanningService.calculateSetPlanForMicrocycle(context, microcycleIndex, isDeloadMicrocycle);
24
- let currentSessionDate = new Date(microcycle.startDate);
25
- let sessionIndex = 0;
24
+ // Build list of non-rest day dates
25
+ const nonRestDayDates = [];
26
+ let currentDate = new Date(microcycle.startDate);
26
27
  for (let day = 0; day < mesocycle.plannedMicrocycleLengthInDays; day++) {
27
- // Skip rest days
28
- if (mesocycle.plannedMicrocycleRestDays.includes(day)) {
29
- currentSessionDate = DateService.addDays(currentSessionDate, 1);
30
- continue;
28
+ if (!mesocycle.plannedMicrocycleRestDays.includes(day)) {
29
+ nonRestDayDates.push(new Date(currentDate));
31
30
  }
32
- // Stop if we've created all planned sessions
33
- if (sessionIndex >= mesocycle.plannedSessionCountPerMicrocycle) {
34
- break;
31
+ currentDate = DateService.addDays(currentDate, 1);
32
+ }
33
+ // Distribute sessions across non-rest days chronologically. If there are
34
+ // more sessions than non-rest days, the earliest days get extra sessions.
35
+ const totalSessions = mesocycle.plannedSessionCountPerMicrocycle;
36
+ const dayCount = nonRestDayDates.length;
37
+ const basePerDay = Math.floor(totalSessions / dayCount);
38
+ const remainder = totalSessions % dayCount;
39
+ let sessionIndex = 0;
40
+ for (let dayIndex = 0; dayIndex < dayCount; dayIndex++) {
41
+ const sessionsOnThisDay = basePerDay + (dayIndex < remainder ? 1 : 0);
42
+ for (let s = 0; s < sessionsOnThisDay; s++) {
43
+ const sessionExerciseList = sessionsToExerciseSessionsArray[sessionIndex] || [];
44
+ WorkoutSessionService.generateSession({
45
+ context,
46
+ microcycleIndex,
47
+ sessionIndex,
48
+ sessionStartDate: nonRestDayDates[dayIndex],
49
+ sessionExerciseList,
50
+ targetRir,
51
+ isDeloadMicrocycle,
52
+ setPlan
53
+ });
54
+ sessionIndex++;
35
55
  }
36
- const sessionExerciseList = sessionsToExerciseSessionsArray[sessionIndex] || [];
37
- WorkoutSessionService.generateSession({
38
- context,
39
- microcycleIndex,
40
- sessionIndex,
41
- sessionStartDate: currentSessionDate,
42
- sessionExerciseList,
43
- targetRir,
44
- isDeloadMicrocycle,
45
- setPlan
46
- });
47
- sessionIndex++;
48
- currentSessionDate = DateService.addDays(currentSessionDate, 1);
49
56
  }
50
57
  }
51
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"WorkoutMicrocycleService.js","sourceRoot":"","sources":["../../../../src/services/workout/Microcycle/WorkoutMicrocycleService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkoutMicrocycleService.js","sourceRoot":"","sources":["../../../../src/services/workout/Microcycle/WorkoutMicrocycleService.ts"],"names":[],"mappings":"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"}
@@ -53,36 +53,42 @@ export default class WorkoutMicrocycleService {
53
53
  isDeloadMicrocycle
54
54
  );
55
55
 
56
- let currentSessionDate = new Date(microcycle.startDate);
57
- let sessionIndex = 0;
58
-
56
+ // Build list of non-rest day dates
57
+ const nonRestDayDates: Date[] = [];
58
+ let currentDate = new Date(microcycle.startDate);
59
59
  for (let day = 0; day < mesocycle.plannedMicrocycleLengthInDays; day++) {
60
- // Skip rest days
61
- if (mesocycle.plannedMicrocycleRestDays.includes(day)) {
62
- currentSessionDate = DateService.addDays(currentSessionDate, 1);
63
- continue;
64
- }
65
-
66
- // Stop if we've created all planned sessions
67
- if (sessionIndex >= mesocycle.plannedSessionCountPerMicrocycle) {
68
- break;
60
+ if (!mesocycle.plannedMicrocycleRestDays.includes(day)) {
61
+ nonRestDayDates.push(new Date(currentDate));
69
62
  }
63
+ currentDate = DateService.addDays(currentDate, 1);
64
+ }
70
65
 
71
- const sessionExerciseList = sessionsToExerciseSessionsArray[sessionIndex] || [];
72
-
73
- WorkoutSessionService.generateSession({
74
- context,
75
- microcycleIndex,
76
- sessionIndex,
77
- sessionStartDate: currentSessionDate,
78
- sessionExerciseList,
79
- targetRir,
80
- isDeloadMicrocycle,
81
- setPlan
82
- });
66
+ // Distribute sessions across non-rest days chronologically. If there are
67
+ // more sessions than non-rest days, the earliest days get extra sessions.
68
+ const totalSessions = mesocycle.plannedSessionCountPerMicrocycle;
69
+ const dayCount = nonRestDayDates.length;
70
+ const basePerDay = Math.floor(totalSessions / dayCount);
71
+ const remainder = totalSessions % dayCount;
83
72
 
84
- sessionIndex++;
85
- currentSessionDate = DateService.addDays(currentSessionDate, 1);
73
+ let sessionIndex = 0;
74
+ for (let dayIndex = 0; dayIndex < dayCount; dayIndex++) {
75
+ const sessionsOnThisDay = basePerDay + (dayIndex < remainder ? 1 : 0);
76
+ for (let s = 0; s < sessionsOnThisDay; s++) {
77
+ const sessionExerciseList = sessionsToExerciseSessionsArray[sessionIndex] || [];
78
+
79
+ WorkoutSessionService.generateSession({
80
+ context,
81
+ microcycleIndex,
82
+ sessionIndex,
83
+ sessionStartDate: nonRestDayDates[dayIndex],
84
+ sessionExerciseList,
85
+ targetRir,
86
+ isDeloadMicrocycle,
87
+ setPlan
88
+ });
89
+
90
+ sessionIndex++;
91
+ }
86
92
  }
87
93
  }
88
94
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@aneuhold/core-ts-db-lib",
3
3
  "author": "Anton G. Neuhold Jr.",
4
4
  "license": "MIT",
5
- "version": "4.1.1",
5
+ "version": "4.1.2",
6
6
  "description": "A core database library used for personal projects",
7
7
  "packageManager": "pnpm@10.25.0",
8
8
  "type": "module",