@sunsteel/contracts 0.64.0 → 0.66.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.
package/dist/index.cjs CHANGED
@@ -44,6 +44,13 @@ __export(index_exports, {
44
44
  COMEBACK_REQUIRED_ACTIVE_DAYS: () => COMEBACK_REQUIRED_ACTIVE_DAYS,
45
45
  COMEBACK_SESSION_LOOKBACK: () => COMEBACK_SESSION_LOOKBACK,
46
46
  COMEBACK_WINDOW_DAYS: () => COMEBACK_WINDOW_DAYS,
47
+ DELOAD_DEFAULT_DAYS: () => DELOAD_DEFAULT_DAYS,
48
+ DELOAD_DEFAULT_LOAD_REDUCTION: () => DELOAD_DEFAULT_LOAD_REDUCTION,
49
+ DELOAD_DEFAULT_SET_MODE: () => DELOAD_DEFAULT_SET_MODE,
50
+ DELOAD_LOAD_REDUCTIONS: () => DELOAD_LOAD_REDUCTIONS,
51
+ DELOAD_MAX_DAYS: () => DELOAD_MAX_DAYS,
52
+ DELOAD_NOT_LIGHTER: () => DELOAD_NOT_LIGHTER,
53
+ DELOAD_SET_MODES: () => DELOAD_SET_MODES,
47
54
  EXERCISE_EQUIPMENT: () => EXERCISE_EQUIPMENT,
48
55
  EXERCISE_MECHANICS: () => EXERCISE_MECHANICS,
49
56
  FEATURED_PROFILE_ITEMS_MAX: () => FEATURED_PROFILE_ITEMS_MAX,
@@ -132,6 +139,8 @@ __export(index_exports, {
132
139
  SHARED_ROUTINE_SOURCES: () => SHARED_ROUTINE_SOURCES,
133
140
  STARRED_EXERCISES_MAX: () => STARRED_EXERCISES_MAX,
134
141
  STREAK_MAX_GAP_DAYS: () => STREAK_MAX_GAP_DAYS,
142
+ TEMPORARY_OVERRIDE_KINDS: () => TEMPORARY_OVERRIDE_KINDS,
143
+ TEMPORARY_OVERRIDE_SOURCE_KINDS: () => TEMPORARY_OVERRIDE_SOURCE_KINDS,
135
144
  TRAINING_DISCIPLINE_VALUES: () => TRAINING_DISCIPLINE_VALUES,
136
145
  TRAINING_EVENT_TYPES: () => TRAINING_EVENT_TYPES,
137
146
  TRAINING_EXPERIENCE_LEVEL_VALUES: () => TRAINING_EXPERIENCE_LEVEL_VALUES,
@@ -148,6 +157,8 @@ __export(index_exports, {
148
157
  WEIGHT_UNITS: () => WEIGHT_UNITS,
149
158
  WORKOUT_SESSION_STATUSES: () => WORKOUT_SESSION_STATUSES,
150
159
  accountExportFileName: () => accountExportFileName,
160
+ applyDeload: () => applyDeload,
161
+ deloadLengthDays: () => deloadLengthDays,
151
162
  isWithinQuietHours: () => isWithinQuietHours,
152
163
  matchesDeletionConfirmation: () => matchesDeletionConfirmation,
153
164
  resolveActiveTrainingBlock: () => resolveActiveTrainingBlock,
@@ -532,8 +543,34 @@ function resolveActiveTrainingBlock(blocks, date) {
532
543
  }
533
544
  function resolveRoutinePlan(routine, date) {
534
545
  const block = resolveActiveTrainingBlock(routine.trainingBlocks, date);
546
+ const deload = resolveActiveTrainingBlock(routine.temporaryOverrides, date);
547
+ const blockInForce = block ? {
548
+ id: block.id,
549
+ seriesId: block.seriesId,
550
+ revision: block.revision,
551
+ name: block.name,
552
+ startDate: block.startDate,
553
+ endDate: block.endDate
554
+ } : null;
555
+ if (deload) {
556
+ return {
557
+ block: blockInForce,
558
+ override: {
559
+ id: deload.id,
560
+ kind: deload.kind,
561
+ startDate: deload.startDate,
562
+ endDate: deload.endDate
563
+ },
564
+ scheduleMode: deload.scheduleMode,
565
+ restDays: deload.restDays,
566
+ rotationWeekdays: deload.rotationWeekdays,
567
+ nextRotationDayId: deload.nextRotationDayId,
568
+ days: deload.days
569
+ };
570
+ }
535
571
  if (block) {
536
572
  return {
573
+ override: null,
537
574
  block: {
538
575
  id: block.id,
539
576
  seriesId: block.seriesId,
@@ -551,6 +588,7 @@ function resolveRoutinePlan(routine, date) {
551
588
  }
552
589
  return {
553
590
  block: null,
591
+ override: null,
554
592
  scheduleMode: routine.scheduleMode,
555
593
  restDays: routine.restDays,
556
594
  rotationWeekdays: routine.rotationWeekdays ?? [],
@@ -559,6 +597,57 @@ function resolveRoutinePlan(routine, date) {
559
597
  };
560
598
  }
561
599
 
600
+ // src/deloads.ts
601
+ var DELOAD_MAX_DAYS = 14;
602
+ var DELOAD_DEFAULT_DAYS = 7;
603
+ var DELOAD_LOAD_REDUCTIONS = [0, 10, 20, 30, 40];
604
+ var DELOAD_DEFAULT_LOAD_REDUCTION = 10;
605
+ var DELOAD_SET_MODES = ["ALL", "HALF"];
606
+ var DELOAD_DEFAULT_SET_MODE = "HALF";
607
+ var TEMPORARY_OVERRIDE_KINDS = ["DELOAD"];
608
+ var TEMPORARY_OVERRIDE_SOURCE_KINDS = [
609
+ "BASELINE",
610
+ "TRAINING_BLOCK"
611
+ ];
612
+ var DELOAD_NOT_LIGHTER = "Those options leave every set as it is: choose a lighter load or fewer sets";
613
+ var lighterOnGrid = (original, target, increment) => {
614
+ const step = increment > 0 ? increment : 2.5;
615
+ const stepped = Math.round(Math.round(target / step) * step * 1e3) / 1e3;
616
+ return stepped > 0 && stepped < original ? stepped : original;
617
+ };
618
+ function applyDeload(setup, options) {
619
+ const factor = 1 - options.loadReductionPercent / 100;
620
+ let lighter = false;
621
+ const days = setup.days.map((day) => ({
622
+ ...day,
623
+ exercises: day.exercises.map((exercise) => {
624
+ const kept = options.setMode === "HALF" ? exercise.sets.slice(0, Math.ceil(exercise.sets.length / 2)) : exercise.sets;
625
+ if (kept.length < exercise.sets.length) lighter = true;
626
+ return {
627
+ ...exercise,
628
+ sets: kept.map((set) => {
629
+ if (typeof set.weight !== "number" || set.weight <= 0) {
630
+ return { ...set };
631
+ }
632
+ if (factor === 1) return { ...set };
633
+ const weight = lighterOnGrid(
634
+ set.weight,
635
+ set.weight * factor,
636
+ exercise.minWeightIncrement
637
+ );
638
+ if (weight < set.weight) lighter = true;
639
+ return { ...set, weight };
640
+ })
641
+ };
642
+ })
643
+ }));
644
+ return lighter ? { ...setup, days } : null;
645
+ }
646
+ function deloadLengthDays(startDate, endDate) {
647
+ const ms = (date) => Date.parse(`${date}T00:00:00Z`);
648
+ return Math.round((ms(endDate) - ms(startDate)) / 864e5) + 1;
649
+ }
650
+
562
651
  // src/routine-sharing.ts
563
652
  var ROUTINE_VISIBILITY_VALUES = [
564
653
  "PRIVATE",
@@ -698,7 +787,10 @@ var NOTIFICATION_KINDS = [
698
787
  // addressing you, which is why it is worth a notification at all.
699
788
  "ACTIVITY_COMMENT",
700
789
  // SOC-09: one of four fixed, permissioned prompts from an active partner.
701
- "TRAINING_PARTNER_ENCOURAGEMENT"
790
+ "TRAINING_PARTNER_ENCOURAGEMENT",
791
+ // NOTIF-07: selected activity from a partner who currently shares it.
792
+ "TRAINING_PARTNER_SESSION",
793
+ "TRAINING_PARTNER_ACHIEVEMENT"
702
794
  ];
703
795
  var NOTIFICATIONS_LOOKBACK_DAYS = 30;
704
796
  var NOTIFICATIONS_RETENTION_DAYS = 90;
@@ -709,7 +801,9 @@ var PUSH_SUBSCRIPTIONS_MAX = 10;
709
801
  var PUSH_PAYLOAD_KINDS = [
710
802
  "REST_ALERT",
711
803
  "TRAINING_REMINDER",
712
- "STREAK_AT_RISK"
804
+ "STREAK_AT_RISK",
805
+ "TRAINING_PARTNER_SESSION",
806
+ "TRAINING_PARTNER_ACHIEVEMENT"
713
807
  ];
714
808
  var REST_ALERT_MAX_LEAD_SECONDS = 3600;
715
809
  var REST_ALERT_MIN_LEAD_SECONDS = 5;
@@ -730,7 +824,9 @@ var REST_ALERT_REFUSALS = [
730
824
  var NOTIFICATION_CATEGORIES = [
731
825
  "REST_ALERT",
732
826
  "TRAINING_REMINDER",
733
- "STREAK_AT_RISK"
827
+ "STREAK_AT_RISK",
828
+ "TRAINING_PARTNER_SESSION",
829
+ "TRAINING_PARTNER_ACHIEVEMENT"
734
830
  ];
735
831
  var MINUTES_IN_DAY = 1440;
736
832
  function isWithinQuietHours(minuteOfDay, quietHours) {
@@ -798,6 +894,13 @@ function accountExportFileName(username, exportedAt) {
798
894
  COMEBACK_REQUIRED_ACTIVE_DAYS,
799
895
  COMEBACK_SESSION_LOOKBACK,
800
896
  COMEBACK_WINDOW_DAYS,
897
+ DELOAD_DEFAULT_DAYS,
898
+ DELOAD_DEFAULT_LOAD_REDUCTION,
899
+ DELOAD_DEFAULT_SET_MODE,
900
+ DELOAD_LOAD_REDUCTIONS,
901
+ DELOAD_MAX_DAYS,
902
+ DELOAD_NOT_LIGHTER,
903
+ DELOAD_SET_MODES,
801
904
  EXERCISE_EQUIPMENT,
802
905
  EXERCISE_MECHANICS,
803
906
  FEATURED_PROFILE_ITEMS_MAX,
@@ -886,6 +989,8 @@ function accountExportFileName(username, exportedAt) {
886
989
  SHARED_ROUTINE_SOURCES,
887
990
  STARRED_EXERCISES_MAX,
888
991
  STREAK_MAX_GAP_DAYS,
992
+ TEMPORARY_OVERRIDE_KINDS,
993
+ TEMPORARY_OVERRIDE_SOURCE_KINDS,
889
994
  TRAINING_DISCIPLINE_VALUES,
890
995
  TRAINING_EVENT_TYPES,
891
996
  TRAINING_EXPERIENCE_LEVEL_VALUES,
@@ -902,6 +1007,8 @@ function accountExportFileName(username, exportedAt) {
902
1007
  WEIGHT_UNITS,
903
1008
  WORKOUT_SESSION_STATUSES,
904
1009
  accountExportFileName,
1010
+ applyDeload,
1011
+ deloadLengthDays,
905
1012
  isWithinQuietHours,
906
1013
  matchesDeletionConfirmation,
907
1014
  resolveActiveTrainingBlock,