musora-content-services 2.3.21 → 2.3.22

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
@@ -2,6 +2,8 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [2.3.22](https://github.com/railroadmedia/musora-content-services/compare/v2.3.21...v2.3.22) (2025-05-05)
6
+
5
7
  ### [2.3.21](https://github.com/railroadmedia/musora-content-services/compare/v2.3.20...v2.3.21) (2025-05-02)
6
8
 
7
9
  ### [2.3.20](https://github.com/railroadmedia/musora-content-services/compare/v2.3.19...v2.3.20) (2025-04-30)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musora-content-services",
3
- "version": "2.3.21",
3
+ "version": "2.3.22",
4
4
  "description": "A package for Musoras content services ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/index.d.ts CHANGED
@@ -53,6 +53,10 @@ import {
53
53
  recordWatchSession
54
54
  } from './services/contentProgress.js';
55
55
 
56
+ import {
57
+ addContextToContent
58
+ } from './contentAggregator.js';
59
+
56
60
  import {
57
61
  verifyLocalDataContext
58
62
  } from './services/dataContext.js';
@@ -215,6 +219,7 @@ import {
215
219
  } from './services/user/sessions.js';
216
220
 
217
221
  import {
222
+ calculateLongestStreaks,
218
223
  createPracticeNotes,
219
224
  deletePracticeSession,
220
225
  getPracticeNotes,
@@ -233,6 +238,7 @@ import {
233
238
  declare module 'musora-content-services' {
234
239
  export {
235
240
  addItemToPlaylist,
241
+ addContextToContent,
236
242
  applyCloudflareWrapper,
237
243
  applySanityTransformations,
238
244
  assignModeratorToComment,
@@ -240,6 +246,7 @@ declare module 'musora-content-services' {
240
246
  assignmentStatusReset,
241
247
  blockUser,
242
248
  buildImageSRC,
249
+ calculateLongestStreaks,
243
250
  closeComment,
244
251
  contentStatusCompleted,
245
252
  contentStatusReset,
package/src/index.js CHANGED
@@ -84,6 +84,9 @@ import {
84
84
  isBucketUrl,
85
85
  verifyImageSRC
86
86
  } from './services/imageSRCVerify.js';
87
+ import {
88
+ addContextToContent
89
+ } from './contentAggregator.js';
87
90
 
88
91
  import {
89
92
  assignModeratorToComment,
@@ -215,6 +218,7 @@ import {
215
218
  } from './services/user/sessions.js';
216
219
 
217
220
  import {
221
+ calculateLongestStreaks,
218
222
  createPracticeNotes,
219
223
  deletePracticeSession,
220
224
  getPracticeNotes,
@@ -239,6 +243,7 @@ export {
239
243
  assignmentStatusReset,
240
244
  blockUser,
241
245
  buildImageSRC,
246
+ calculateLongestStreaks,
242
247
  closeComment,
243
248
  contentStatusCompleted,
244
249
  contentStatusReset,
@@ -407,4 +412,5 @@ export {
407
412
  updateUserPractice,
408
413
  verifyImageSRC,
409
414
  verifyLocalDataContext,
415
+ addContextToContent
410
416
  };
@@ -290,6 +290,10 @@ async function patchDataHandler(url, data) {
290
290
  return fetchHandler(url, 'patch', null, data)
291
291
  }
292
292
 
293
+ async function putDataHandler(url, data) {
294
+ return fetchHandler(url, 'put', null, data)
295
+ }
296
+
293
297
  async function deleteDataHandler(url, data) {
294
298
  return fetchHandler(url, 'delete')
295
299
  }
@@ -726,7 +730,7 @@ export async function editComment(commentId, comment) {
726
730
  const data = {
727
731
  comment: comment,
728
732
  }
729
- return await patchDataHandler(url, data)
733
+ return await putDataHandler(url, data)
730
734
  }
731
735
 
732
736
  /**
@@ -688,6 +688,87 @@ function calculateStreaks(practices, includeStreakMessage = false) {
688
688
  return { currentDailyStreak, currentWeeklyStreak, streakMessage };
689
689
  }
690
690
 
691
+ /**
692
+ * Calculates the longest daily, weekly streaks and totalPracticeSeconds from user practice dates.
693
+ * @returns {{ longestDailyStreak: number, longestWeeklyStreak: number, totalPracticeSeconds:number }}
694
+ */
695
+ export async function calculateLongestStreaks() {
696
+ let data = await userActivityContext.getData()
697
+ let practices = data?.[DATA_KEY_PRACTICES] ?? {}
698
+ let totalPracticeSeconds = 0;
699
+ // Calculate total practice duration
700
+ for (const date in practices) {
701
+ for (const entry of practices[date]) {
702
+ totalPracticeSeconds += entry.duration_seconds;
703
+ }
704
+ }
705
+
706
+ let practiceDates = Object.keys(practices)
707
+ .map(dateStr => {
708
+ const [y, m, d] = dateStr.split('-').map(Number);
709
+ const newDate = new Date();
710
+ newDate.setFullYear(y, m - 1, d);
711
+ return newDate;
712
+ })
713
+ .sort((a, b) => a - b);
714
+
715
+ if (!practiceDates || practiceDates.length === 0) {
716
+ return {longestDailyStreak: 0, longestWeeklyStreak: 0, totalPracticeSeconds: 0};
717
+ }
718
+
719
+ // Normalize to Date objects
720
+ const normalizedDates = [
721
+ ...new Set(practiceDates.map(d => {
722
+ const date = new Date(d);
723
+ date.setHours(0, 0, 0, 0);
724
+ return date.getTime();
725
+ }))
726
+ ].sort((a, b) => a - b);
727
+
728
+ // ----- Daily Streak -----
729
+ let longestDailyStreak = 1;
730
+ let currentDailyStreak = 1;
731
+ for (let i = 1; i < normalizedDates.length; i++) {
732
+ const diffInDays = (normalizedDates[i] - normalizedDates[i - 1]) / (1000 * 60 * 60 * 24);
733
+ if (diffInDays === 1) {
734
+ currentDailyStreak++;
735
+ longestDailyStreak = Math.max(longestDailyStreak, currentDailyStreak);
736
+ } else {
737
+ currentDailyStreak = 1;
738
+ }
739
+ }
740
+
741
+ // ----- Weekly Streak -----
742
+ const weekStartDates = [
743
+ ...new Set(normalizedDates.map(ts => {
744
+ const d = new Date(ts);
745
+ const day = d.getDay();
746
+ const diff = d.getDate() - day + (day === 0 ? -6 : 1); // adjust to Monday
747
+ d.setDate(diff);
748
+ return d.getTime(); // timestamp for Monday
749
+ }))
750
+ ].sort((a, b) => a - b);
751
+
752
+ let longestWeeklyStreak = 1;
753
+ let currentWeeklyStreak = 1;
754
+
755
+ for (let i = 1; i < weekStartDates.length; i++) {
756
+ const diffInWeeks = (weekStartDates[i] - weekStartDates[i - 1]) / (1000 * 60 * 60 * 24 * 7);
757
+ if (diffInWeeks === 1) {
758
+ currentWeeklyStreak++;
759
+ longestWeeklyStreak = Math.max(longestWeeklyStreak, currentWeeklyStreak);
760
+ } else {
761
+ currentWeeklyStreak = 1;
762
+ }
763
+ }
764
+
765
+ return {
766
+ longestDailyStreak,
767
+ longestWeeklyStreak,
768
+ totalPracticeSeconds
769
+ };
770
+ }
771
+
691
772
 
692
773
 
693
774