musora-content-services 2.90.0 → 2.92.6

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.
Files changed (177) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/package.json +11 -3
  3. package/src/index.d.ts +9 -31
  4. package/src/index.js +12 -34
  5. package/src/services/content-org/learning-paths.ts +33 -3
  6. package/src/services/contentAggregator.js +2 -2
  7. package/src/services/contentLikes.js +6 -39
  8. package/src/services/contentProgress.js +181 -479
  9. package/src/services/dataContext.js +0 -2
  10. package/src/services/progress-row/method-card.js +2 -1
  11. package/src/services/railcontent.js +12 -135
  12. package/src/services/sentry/.indexignore +0 -0
  13. package/src/services/sentry/index.ts +23 -0
  14. package/src/services/sync/.indexignore +0 -0
  15. package/src/services/sync/adapters/factory.ts +26 -0
  16. package/src/services/sync/adapters/lokijs.ts +1 -0
  17. package/src/services/sync/adapters/sqlite.ts +1 -0
  18. package/src/services/sync/concurrency-safety.ts +4 -0
  19. package/src/services/sync/context/index.ts +43 -0
  20. package/src/services/sync/context/providers/base.ts +4 -0
  21. package/src/services/sync/context/providers/connectivity.ts +14 -0
  22. package/src/services/sync/context/providers/durability.ts +5 -0
  23. package/src/services/sync/context/providers/index.ts +5 -0
  24. package/src/services/sync/context/providers/session.ts +8 -0
  25. package/src/services/sync/context/providers/tabs.ts +18 -0
  26. package/src/services/sync/context/providers/visibility.ts +14 -0
  27. package/src/services/sync/database/factory.ts +10 -0
  28. package/src/services/sync/errors/boundary.ts +45 -0
  29. package/src/services/sync/errors/index.ts +49 -0
  30. package/src/services/sync/fetch.ts +313 -0
  31. package/src/services/sync/index.ts +80 -0
  32. package/src/services/sync/manager.ts +139 -0
  33. package/src/services/sync/models/Base.ts +47 -0
  34. package/src/services/sync/models/ContentLike.ts +16 -0
  35. package/src/services/sync/models/ContentProgress.ts +69 -0
  36. package/src/services/sync/models/Practice.ts +72 -0
  37. package/src/services/sync/models/PracticeDayNote.ts +23 -0
  38. package/src/services/sync/models/index.ts +4 -0
  39. package/src/services/sync/repositories/base.ts +247 -0
  40. package/src/services/sync/repositories/content-likes.ts +26 -0
  41. package/src/services/sync/repositories/content-progress.ts +160 -0
  42. package/src/services/sync/repositories/index.ts +4 -0
  43. package/src/services/sync/repositories/practice-day-notes.ts +4 -0
  44. package/src/services/sync/repositories/practices.ts +52 -0
  45. package/src/services/sync/repository-proxy.ts +48 -0
  46. package/src/services/sync/resolver.ts +84 -0
  47. package/src/services/sync/retry.ts +88 -0
  48. package/src/services/sync/run-scope.ts +30 -0
  49. package/src/services/sync/schema/index.ts +66 -0
  50. package/src/services/sync/serializers/index.ts +2 -0
  51. package/src/services/sync/serializers/model.ts +32 -0
  52. package/src/services/sync/serializers/raw.ts +21 -0
  53. package/src/services/sync/store/index.ts +779 -0
  54. package/src/services/sync/store/push-coalescer.ts +57 -0
  55. package/src/services/sync/store-configs.ts +41 -0
  56. package/src/services/sync/strategies/base.ts +21 -0
  57. package/src/services/sync/strategies/index.ts +12 -0
  58. package/src/services/sync/strategies/initial.ts +11 -0
  59. package/src/services/sync/strategies/polling.ts +54 -0
  60. package/src/services/sync/telemetry/index.ts +140 -0
  61. package/src/services/sync/telemetry/sampling.ts +91 -0
  62. package/src/services/sync/utils/event-emitter.ts +24 -0
  63. package/src/services/sync/utils/index.ts +1 -0
  64. package/src/services/sync/utils/throttle.ts +93 -0
  65. package/src/services/sync/utils/timers.ts +9 -0
  66. package/src/services/userActivity.js +83 -148
  67. package/test/contentProgress.test.js +6 -39
  68. package/test/live/contentProgressLive.test.js +2 -31
  69. package/tools/generate-index.cjs +10 -4
  70. package/babel.config.cjs +0 -3
  71. package/docs/Content.html +0 -269
  72. package/docs/ContentOrganization.html +0 -245
  73. package/docs/Forums.html +0 -269
  74. package/docs/Gamification.html +0 -245
  75. package/docs/TestUser.html +0 -260
  76. package/docs/UserManagementSystem.html +0 -317
  77. package/docs/api_types.js.html +0 -97
  78. package/docs/config.js.html +0 -140
  79. package/docs/content-org_content-org.js.html +0 -76
  80. package/docs/content-org_guided-courses.ts.html +0 -110
  81. package/docs/content-org_learning-paths.ts.html +0 -379
  82. package/docs/content-org_playlists-types.js.html +0 -128
  83. package/docs/content-org_playlists.js.html +0 -440
  84. package/docs/content.js.html +0 -603
  85. package/docs/content_artist.ts.html +0 -206
  86. package/docs/content_content.ts.html +0 -77
  87. package/docs/content_genre.ts.html +0 -209
  88. package/docs/content_instructor.ts.html +0 -206
  89. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  90. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  91. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  92. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  93. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  94. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  95. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  96. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  97. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  98. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -978
  99. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  100. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  101. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  102. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  103. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -1049
  104. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  105. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  106. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  107. package/docs/forums_categories.ts.html +0 -156
  108. package/docs/forums_discussions.js.html +0 -95
  109. package/docs/forums_forum.js.html +0 -95
  110. package/docs/forums_forums.ts.html +0 -160
  111. package/docs/forums_posts.ts.html +0 -284
  112. package/docs/forums_threads.ts.html +0 -284
  113. package/docs/gamification_awards.js.html +0 -165
  114. package/docs/gamification_awards.ts.html +0 -195
  115. package/docs/gamification_gamification.js.html +0 -76
  116. package/docs/gamification_types.js.html +0 -80
  117. package/docs/global.html +0 -6019
  118. package/docs/index.html +0 -167
  119. package/docs/liveTesting.ts.html +0 -103
  120. package/docs/module-Accounts.html +0 -2283
  121. package/docs/module-Artist.html +0 -993
  122. package/docs/module-Awards.html +0 -836
  123. package/docs/module-Categories.html +0 -711
  124. package/docs/module-Config.html +0 -431
  125. package/docs/module-Content-Services-V2.html +0 -2998
  126. package/docs/module-ForumCategories.html +0 -687
  127. package/docs/module-ForumDiscussions.html +0 -370
  128. package/docs/module-Forums.html +0 -16599
  129. package/docs/module-Genre.html +0 -981
  130. package/docs/module-GuidedCourses.html +0 -108
  131. package/docs/module-Instructor.html +0 -929
  132. package/docs/module-Interests.html +0 -1066
  133. package/docs/module-LearningPaths.html +0 -2298
  134. package/docs/module-Onboarding.html +0 -882
  135. package/docs/module-Payments.html +0 -392
  136. package/docs/module-Permissions.html +0 -406
  137. package/docs/module-Playlists.html +0 -3030
  138. package/docs/module-ProgressRow.html +0 -108
  139. package/docs/module-Railcontent-Services.html +0 -6735
  140. package/docs/module-Sanity-Services.html +0 -8244
  141. package/docs/module-Sessions.html +0 -575
  142. package/docs/module-Threads.html +0 -1119
  143. package/docs/module-UserActivity.html +0 -4580
  144. package/docs/module-UserChat.html +0 -410
  145. package/docs/module-UserManagement.html +0 -1932
  146. package/docs/module-UserMemberships.html +0 -829
  147. package/docs/module-UserNotifications.html +0 -2595
  148. package/docs/module-UserProfile.html +0 -370
  149. package/docs/progress-row_method-card.js.html +0 -183
  150. package/docs/railcontent.js.html +0 -847
  151. package/docs/sanity.js.html +0 -2322
  152. package/docs/scripts/collapse.js +0 -39
  153. package/docs/scripts/commonNav.js +0 -28
  154. package/docs/scripts/linenumber.js +0 -25
  155. package/docs/scripts/nav.js +0 -12
  156. package/docs/scripts/polyfill.js +0 -4
  157. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  158. package/docs/scripts/prettify/lang-css.js +0 -2
  159. package/docs/scripts/prettify/prettify.js +0 -28
  160. package/docs/scripts/search.js +0 -99
  161. package/docs/styles/jsdoc.css +0 -776
  162. package/docs/styles/prettify.css +0 -80
  163. package/docs/userActivity.js.html +0 -1577
  164. package/docs/user_account.ts.html +0 -265
  165. package/docs/user_chat.js.html +0 -98
  166. package/docs/user_interests.js.html +0 -150
  167. package/docs/user_management.js.html +0 -258
  168. package/docs/user_memberships.js.html +0 -144
  169. package/docs/user_memberships.ts.html +0 -292
  170. package/docs/user_notifications.js.html +0 -374
  171. package/docs/user_onboarding.ts.html +0 -325
  172. package/docs/user_payments.ts.html +0 -146
  173. package/docs/user_permissions.js.html +0 -110
  174. package/docs/user_profile.js.html +0 -115
  175. package/docs/user_sessions.js.html +0 -170
  176. package/docs/user_types.js.html +0 -224
  177. package/docs/user_user-management-system.js.html +0 -79
@@ -1,603 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
-
5
- <meta charset="utf-8">
6
- <title>content.js - Documentation</title>
7
-
8
-
9
- <script src="scripts/prettify/prettify.js"></script>
10
- <script src="scripts/prettify/lang-css.js"></script>
11
- <!--[if lt IE 9]>
12
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13
- <![endif]-->
14
- <link type="text/css" rel="stylesheet" href="styles/prettify.css">
15
- <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
16
- <script src="scripts/nav.js" defer></script>
17
-
18
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
- </head>
20
- <body>
21
-
22
- <input type="checkbox" id="nav-trigger" class="nav-trigger" />
23
- <label for="nav-trigger" class="navicon-button x">
24
- <div class="navicon"></div>
25
- </label>
26
-
27
- <label for="nav-trigger" class="overlay"></label>
28
-
29
- <nav >
30
-
31
-
32
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-Accounts.html">Accounts</a><ul class='methods'><li data-type='method'><a href="module-Accounts.html#~confirmEmailChange">confirmEmailChange</a></li><li data-type='method'><a href="module-Accounts.html#~deleteAccount">deleteAccount</a></li><li data-type='method'><a href="module-Accounts.html#~numberOfActiveUsers">numberOfActiveUsers</a></li><li data-type='method'><a href="module-Accounts.html#~requestEmailChange">requestEmailChange</a></li><li data-type='method'><a href="module-Accounts.html#~resetPassword">resetPassword</a></li><li data-type='method'><a href="module-Accounts.html#~sendAccountSetupEmail">sendAccountSetupEmail</a></li><li data-type='method'><a href="module-Accounts.html#~sendPasswordResetEmail">sendPasswordResetEmail</a></li><li data-type='method'><a href="module-Accounts.html#~setupAccount">setupAccount</a></li><li data-type='method'><a href="module-Accounts.html#~status">status</a></li><li data-type='method'><a href="module-Accounts.html#~toggleStudentView">toggleStudentView</a></li></ul></li><li><a href="module-Artist.html">Artist</a><ul class='methods'><li data-type='method'><a href="module-Artist.html#~fetchArtistBySlug">fetchArtistBySlug</a></li><li data-type='method'><a href="module-Artist.html#~fetchArtistLessons">fetchArtistLessons</a></li><li data-type='method'><a href="module-Artist.html#~fetchArtists">fetchArtists</a></li></ul></li><li><a href="module-Awards.html">Awards</a><ul class='methods'><li data-type='method'><a href="module-Awards.html#~fetchAwardsForUser">fetchAwardsForUser</a></li><li data-type='method'><a href="module-Awards.html#~fetchCertificate">fetchCertificate</a></li><li data-type='method'><a href="module-Awards.html#~getAwardDataForGuidedContent">getAwardDataForGuidedContent</a></li></ul></li><li><a href="module-Config.html">Config</a><ul class='methods'><li data-type='method'><a href="module-Config.html#.initializeService">initializeService</a></li></ul></li><li><a href="module-Content-Services-V2.html">Content-Services-V2</a><ul class='methods'><li data-type='method'><a href="module-Content-Services-V2.html#.getContentRows">getContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getLegacyMethods">getLegacyMethods</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getNewAndUpcoming">getNewAndUpcoming</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getOwnedContent">getOwnedContent</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecent">getRecent</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getRecommendedForYou">getRecommendedForYou</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getScheduleContentRows">getScheduleContentRows</a></li><li data-type='method'><a href="module-Content-Services-V2.html#.getTabResults">getTabResults</a></li></ul></li><li><a href="module-Forums.html">Forums</a><ul class='methods'><li data-type='method'><a href="module-Forums.html#~createForumCategory">createForumCategory</a></li><li data-type='method'><a href="module-Forums.html#~createPost">createPost</a></li><li data-type='method'><a href="module-Forums.html#~createThread">createThread</a></li><li data-type='method'><a href="module-Forums.html#~deleteForumCategory">deleteForumCategory</a></li><li data-type='method'><a href="module-Forums.html#~deletePost">deletePost</a></li><li data-type='method'><a href="module-Forums.html#~deleteThread">deleteThread</a></li><li data-type='method'><a href="module-Forums.html#~fetchCommunityGuidelines">fetchCommunityGuidelines</a></li><li data-type='method'><a href="module-Forums.html#~fetchFollowedThreads">fetchFollowedThreads</a></li><li data-type='method'><a href="module-Forums.html#~fetchForumCategories">fetchForumCategories</a></li><li data-type='method'><a href="module-Forums.html#~fetchLatestThreads">fetchLatestThreads</a></li><li data-type='method'><a href="module-Forums.html#~fetchPosts">fetchPosts</a></li><li data-type='method'><a href="module-Forums.html#~fetchThreads">fetchThreads</a></li><li data-type='method'><a href="module-Forums.html#~followThread">followThread</a></li><li data-type='method'><a href="module-Forums.html#~jumpToPost">jumpToPost</a></li><li data-type='method'><a href="module-Forums.html#~likePost">likePost</a></li><li data-type='method'><a href="module-Forums.html#~lockThread">lockThread</a></li><li data-type='method'><a href="module-Forums.html#~markThreadAsRead">markThreadAsRead</a></li><li data-type='method'><a href="module-Forums.html#~pinThread">pinThread</a></li><li data-type='method'><a href="module-Forums.html#~search">search</a></li><li data-type='method'><a href="module-Forums.html#~unfollowThread">unfollowThread</a></li><li data-type='method'><a href="module-Forums.html#~unlikePost">unlikePost</a></li><li data-type='method'><a href="module-Forums.html#~unlockThread">unlockThread</a></li><li data-type='method'><a href="module-Forums.html#~unpinThread">unpinThread</a></li><li data-type='method'><a href="module-Forums.html#~updateForumCategory">updateForumCategory</a></li><li data-type='method'><a href="module-Forums.html#~updatePost">updatePost</a></li><li data-type='method'><a href="module-Forums.html#~updateThread">updateThread</a></li></ul></li><li></li><li></li><li><a href="module-Genre.html">Genre</a><ul class='methods'><li data-type='method'><a href="module-Genre.html#~fetchGenreBySlug">fetchGenreBySlug</a></li><li data-type='method'><a href="module-Genre.html#~fetchGenreLessons">fetchGenreLessons</a></li><li data-type='method'><a href="module-Genre.html#~fetchGenres">fetchGenres</a></li></ul></li><li><a href="module-GuidedCourses.html">GuidedCourses</a></li><li><a href="module-Instructor.html">Instructor</a><ul class='methods'><li data-type='method'><a href="module-Instructor.html#~fetchInstructorBySlug">fetchInstructorBySlug</a></li><li data-type='method'><a href="module-Instructor.html#~fetchInstructorLessons">fetchInstructorLessons</a></li><li data-type='method'><a href="module-Instructor.html#~fetchInstructors">fetchInstructors</a></li></ul></li><li><a href="module-Interests.html">Interests</a><ul class='methods'><li data-type='method'><a href="module-Interests.html#.fetchInterests">fetchInterests</a></li><li data-type='method'><a href="module-Interests.html#.fetchUninterests">fetchUninterests</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsInterested">markContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.markContentAsNotInterested">markContentAsNotInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsInterested">removeContentAsInterested</a></li><li data-type='method'><a href="module-Interests.html#.removeContentAsNotInterested">removeContentAsNotInterested</a></li></ul></li><li><a href="module-LearningPaths.html">LearningPaths</a><ul class='methods'><li data-type='method'><a href="module-LearningPaths.html#~completeLearningPathIntroVideo">completeLearningPathIntroVideo</a></li><li data-type='method'><a href="module-LearningPaths.html#~completeMethodIntroVideo">completeMethodIntroVideo</a></li><li data-type='method'><a href="module-LearningPaths.html#~fetchLearningPathLessons">fetchLearningPathLessons</a></li><li data-type='method'><a href="module-LearningPaths.html#~getActivePath">getActivePath</a></li><li data-type='method'><a href="module-LearningPaths.html#~getDailySession">getDailySession</a></li><li data-type='method'><a href="module-LearningPaths.html#~getEnrichedLearningPath">getEnrichedLearningPath</a></li><li data-type='method'><a href="module-LearningPaths.html#~getLearningPathLessonsByIds">getLearningPathLessonsByIds</a></li><li data-type='method'><a href="module-LearningPaths.html#~mapContentToParent">mapContentToParent</a></li><li data-type='method'><a href="module-LearningPaths.html#~resetAllLearningPaths">resetAllLearningPaths</a></li><li data-type='method'><a href="module-LearningPaths.html#~startLearningPath">startLearningPath</a></li><li data-type='method'><a href="module-LearningPaths.html#~updateActivePath">updateActivePath</a></li><li data-type='method'><a href="module-LearningPaths.html#~updateDailySession">updateDailySession</a></li></ul></li><li><a href="module-Onboarding.html">Onboarding</a><ul class='methods'><li data-type='method'><a href="module-Onboarding.html#~getOnboardingRecommendedContent">getOnboardingRecommendedContent</a></li><li data-type='method'><a href="module-Onboarding.html#~startOnboarding">startOnboarding</a></li><li data-type='method'><a href="module-Onboarding.html#~updateOnboarding">updateOnboarding</a></li><li data-type='method'><a href="module-Onboarding.html#~userOnboardingForBrand">userOnboardingForBrand</a></li></ul></li><li><a href="module-Payments.html">Payments</a><ul class='methods'><li data-type='method'><a href="module-Payments.html#~fetchCustomerPayments">fetchCustomerPayments</a></li></ul></li><li><a href="module-Permissions.html">Permissions</a><ul class='methods'><li data-type='method'><a href="module-Permissions.html#.fetchUserPermissions">fetchUserPermissions</a></li><li data-type='method'><a href="module-Permissions.html#.reset">reset</a></li></ul></li><li><a href="module-Playlists.html">Playlists</a><ul class='methods'><li data-type='method'><a href="module-Playlists.html#.addItemToPlaylist">addItemToPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.createPlaylist">createPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.deletePlaylist">deletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.duplicatePlaylist">duplicatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylist">fetchPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.fetchPlaylistItems">fetchPlaylistItems</a></li><li data-type='method'><a href="module-Playlists.html#.fetchUserPlaylists">fetchUserPlaylists</a></li><li data-type='method'><a href="module-Playlists.html#.togglePlaylistPrivate">togglePlaylistPrivate</a></li><li data-type='method'><a href="module-Playlists.html#.undeletePlaylist">undeletePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#.updatePlaylist">updatePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~deleteItemsFromPlaylist">deleteItemsFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~likePlaylist">likePlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~reportPlaylist">reportPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~restoreItemFromPlaylist">restoreItemFromPlaylist</a></li><li data-type='method'><a href="module-Playlists.html#~unlikePlaylist">unlikePlaylist</a></li></ul></li><li><a href="module-ProgressRow.html">ProgressRow</a></li><li><a href="module-Railcontent-Services.html">Railcontent-Services</a><ul class='methods'><li data-type='method'><a href="module-Railcontent-Services.html#.assignModeratorToComment">assignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.closeComment">closeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.createComment">createComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.deleteComment">deleteComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.editComment">editComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchAllCompletedStates">fetchAllCompletedStates</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCarouselCardData">fetchCarouselCardData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComment">fetchComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCommentRelies">fetchCommentRelies</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchComments">fetchComments</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedContent">fetchCompletedContent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchCompletedState">fetchCompletedState</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentInProgress">fetchContentInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchContentPageUserData">fetchContentPageUserData</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchNextContentDataForParent">fetchNextContentDataForParent</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchRecentUserActivities">fetchRecentUserActivities</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchSongsInProgress">fetchSongsInProgress</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchTopComment">fetchTopComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserAward">fetchUserAward</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserBadges">fetchUserBadges</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.fetchUserPracticeNotes">fetchUserPracticeNotes</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.likeComment">likeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.openComment">openComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentComplete">postContentComplete</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentReset">postContentReset</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentRestore">postContentRestore</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.postContentStart">postContentStart</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.replyToComment">replyToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.reportComment">reportComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.restoreComment">restoreComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.setStudentViewForUser">setStudentViewForUser</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unassignModeratorToComment">unassignModeratorToComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#.unlikeComment">unlikeComment</a></li><li data-type='method'><a href="module-Railcontent-Services.html#~fetchLastInteractedChild">fetchLastInteractedChild</a></li></ul></li><li><a href="module-Sanity-Services.html">Sanity-Services</a><ul class='methods'><li data-type='method'><a href="module-Sanity-Services.html#.fetchAll">fetchAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllFilterOptions">fetchAllFilterOptions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchAllPacks">fetchAllPacks</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentId">fetchByRailContentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByRailContentIds">fetchByRailContentIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchByReference">fetchByReference</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchComingSoon">fetchComingSoon</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchCommentModContentData">fetchCommentModContentData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchFoundation">fetchFoundation</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLeaving">fetchLeaving</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonContent">fetchLessonContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchLessonsFeaturingThisContent">fetchLessonsFeaturingThisContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMetadata">fetchMetadata</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethod">fetchMethod</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildren">fetchMethodChildren</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodChildrenIds">fetchMethodChildrenIds</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodPreviousNextLesson">fetchMethodPreviousNextLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodV2IntroVideo">fetchMethodV2IntroVideo</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodV2Structure">fetchMethodV2Structure</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchMethodV2StructureFromId">fetchMethodV2StructureFromId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNewReleases">fetchNewReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchNextPreviousLesson">fetchNextPreviousLesson</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchOtherSongVersions">fetchOtherSongVersions</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchOwnedContent">fetchOwnedContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackAll">fetchPackAll</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchPackData">fetchPackData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedLessons">fetchRelatedLessons</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedRecommendedContent">fetchRelatedRecommendedContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchRelatedSongs">fetchRelatedSongs</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchReturning">fetchReturning</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSanity">fetchSanity</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchScheduledReleases">fetchScheduledReleases</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchShowsData">fetchShowsData</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSiblingContent">fetchSiblingContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongArtistCount">fetchSongArtistCount</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchSongById">fetchSongById</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchTopLevelParentId">fetchTopLevelParentId</a></li><li data-type='method'><a href="module-Sanity-Services.html#.fetchUpcomingEvents">fetchUpcomingEvents</a></li><li data-type='method'><a href="module-Sanity-Services.html#.jumpToContinueContent">jumpToContinueContent</a></li><li data-type='method'><a href="module-Sanity-Services.html#~fetchRelatedByLicense">fetchRelatedByLicense</a></li><li data-type='method'><a href="module-Sanity-Services.html#~getQueryFromPage">getQueryFromPage</a></li></ul></li><li><a href="module-Sessions.html">Sessions</a><ul class='methods'><li data-type='method'><a href="module-Sessions.html#.login">login</a></li><li data-type='method'><a href="module-Sessions.html#.logout">logout</a></li></ul></li><li><a href="module-UserActivity.html">UserActivity</a><ul class='methods'><li data-type='method'><a href="module-UserActivity.html#.calculateLongestStreaks">calculateLongestStreaks</a></li><li data-type='method'><a href="module-UserActivity.html#.createPracticeNotes">createPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.deletePracticeSession">deletePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.deleteUserActivity">deleteUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeNotes">getPracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.getPracticeSessions">getPracticeSessions</a></li><li data-type='method'><a href="module-UserActivity.html#.getProgressRows">getProgressRows</a></li><li data-type='method'><a href="module-UserActivity.html#.getRecentActivity">getRecentActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserMonthlyStats">getUserMonthlyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.getUserWeeklyStats">getUserWeeklyStats</a></li><li data-type='method'><a href="module-UserActivity.html#.pinProgressRow">pinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserActivity">recordUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.recordUserPractice">recordUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.removeUserPractice">removeUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.restorePracticeSession">restorePracticeSession</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserActivity">restoreUserActivity</a></li><li data-type='method'><a href="module-UserActivity.html#.restoreUserPractice">restoreUserPractice</a></li><li data-type='method'><a href="module-UserActivity.html#.unpinProgressRow">unpinProgressRow</a></li><li data-type='method'><a href="module-UserActivity.html#.updatePracticeNotes">updatePracticeNotes</a></li><li data-type='method'><a href="module-UserActivity.html#.updateUserPractice">updateUserPractice</a></li></ul></li><li><a href="module-UserChat.html">UserChat</a><ul class='methods'><li data-type='method'><a href="module-UserChat.html#.fetchChatSettings">fetchChatSettings</a></li></ul></li><li><a href="module-UserManagement.html">UserManagement</a><ul class='methods'><li data-type='method'><a href="module-UserManagement.html#.blockUser">blockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.blockedUsers">blockedUsers</a></li><li data-type='method'><a href="module-UserManagement.html#.deletePicture">deletePicture</a></li><li data-type='method'><a href="module-UserManagement.html#.getUserData">getUserData</a></li><li data-type='method'><a href="module-UserManagement.html#.getUserSignature">getUserSignature</a></li><li data-type='method'><a href="module-UserManagement.html#.isUsernameAvailable">isUsernameAvailable</a></li><li data-type='method'><a href="module-UserManagement.html#.setUserSignature">setUserSignature</a></li><li data-type='method'><a href="module-UserManagement.html#.toggleSignaturePrivate">toggleSignaturePrivate</a></li><li data-type='method'><a href="module-UserManagement.html#.unblockUser">unblockUser</a></li><li data-type='method'><a href="module-UserManagement.html#.updateDisplayName">updateDisplayName</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPicture">uploadPicture</a></li><li data-type='method'><a href="module-UserManagement.html#.uploadPictureFromS3">uploadPictureFromS3</a></li></ul></li><li><a href="module-UserMemberships.html">UserMemberships</a><ul class='methods'><li data-type='method'><a href="module-UserMemberships.html#~fetchMemberships">fetchMemberships</a></li><li data-type='method'><a href="module-UserMemberships.html#~fetchRechargeTokens">fetchRechargeTokens</a></li><li data-type='method'><a href="module-UserMemberships.html#~restorePurchases">restorePurchases</a></li><li data-type='method'><a href="module-UserMemberships.html#~upgradeSubscription">upgradeSubscription</a></li></ul></li><li><a href="module-UserNotifications.html">UserNotifications</a><ul class='methods'><li data-type='method'><a href="module-UserNotifications.html#.deleteNotification">deleteNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchLiveEventPollingState">fetchLiveEventPollingState</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotificationSettings">fetchNotificationSettings</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchNotifications">fetchNotifications</a></li><li data-type='method'><a href="module-UserNotifications.html#.fetchUnreadCount">fetchUnreadCount</a></li><li data-type='method'><a href="module-UserNotifications.html#.markAllNotificationsAsRead">markAllNotificationsAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsRead">markNotificationAsRead</a></li><li data-type='method'><a href="module-UserNotifications.html#.markNotificationAsUnread">markNotificationAsUnread</a></li><li data-type='method'><a href="module-UserNotifications.html#.pauseLiveEventPolling">pauseLiveEventPolling</a></li><li data-type='method'><a href="module-UserNotifications.html#.restoreNotification">restoreNotification</a></li><li data-type='method'><a href="module-UserNotifications.html#.startLiveEventPolling">startLiveEventPolling</a></li><li data-type='method'><a href="module-UserNotifications.html#.updateNotificationSetting">updateNotificationSetting</a></li></ul></li><li><a href="module-UserProfile.html">UserProfile</a><ul class='methods'><li data-type='method'><a href="module-UserProfile.html#.deleteProfilePicture">deleteProfilePicture</a></li><li data-type='method'><a href="module-UserProfile.html#.otherStats">otherStats</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="ContentOrganization.html">ContentOrganization</a></li><li><a href="Forums.html">Forums</a></li><li><a href="Gamification.html">Gamification</a></li><li><a href="UserManagementSystem.html">UserManagementSystem</a></li></ul><h3>Interfaces</h3><ul><li><a href="TestUser.html">TestUser</a></li></ul><h3>Global</h3><ul><li><a href="global.html#createTestUser">createTestUser</a></li></ul>
33
-
34
- </nav>
35
-
36
- <div id="main">
37
-
38
- <h1 class="page-title">content.js</h1>
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- <section>
47
- <article>
48
- <pre class="prettyprint source linenums"><code>/**
49
- * @module Content-Services-V2
50
- */
51
-
52
- import {
53
- fetchByRailContentIds,
54
- fetchMetadata,
55
- fetchRecent,
56
- fetchTabData,
57
- fetchNewReleases,
58
- fetchUpcomingEvents,
59
- fetchScheduledReleases,
60
- fetchReturning,
61
- fetchLeaving, fetchScheduledAndNewReleases, fetchContentRows, fetchOwnedContent
62
- } from './sanity.js'
63
- import {TabResponseType, Tabs, capitalizeFirstLetter} from '../contentMetaData.js'
64
- import {recommendations, rankCategories, rankItems} from "./recommendations";
65
- import {addContextToContent} from "./contentAggregator.js";
66
- import {globalConfig} from "./config";
67
- import {getUserData} from "./user/management";
68
- import {filterTypes, ownedContentTypes} from "../contentTypeConfig";
69
-
70
-
71
- export async function getLessonContentRows (brand='drumeo', pageName = 'lessons') {
72
- const [recentContentIds, rawContentRows, userData] = await Promise.all([
73
- fetchRecent(brand, pageName, { progress: 'recent', limit: 10 }),
74
- getContentRows(brand, pageName),
75
- getUserData()
76
- ])
77
-
78
- const contentRows = Array.isArray(rawContentRows) ? rawContentRows : []
79
-
80
- // Only fetch owned content if user has no active membership
81
- if (!userData?.has_active_membership) {
82
- const type = ownedContentTypes[pageName] || []
83
-
84
- const ownedContent = await fetchOwnedContent(brand, { type })
85
- if (ownedContent?.entity &amp;&amp; ownedContent.entity.length > 0) {
86
- contentRows.unshift({
87
- id: 'owned',
88
- title: 'Owned ' + capitalizeFirstLetter(pageName),
89
- items: ownedContent.entity
90
- })
91
- }
92
- }
93
-
94
- // Add recent content row
95
- contentRows.unshift({
96
- id: 'recent',
97
- title: 'Recent ' + capitalizeFirstLetter(pageName),
98
- items: recentContentIds || []
99
- })
100
-
101
- const results = await Promise.all(
102
- contentRows.map(async (row) => {
103
- return { id: row.id, title: row.title, items: row.items }
104
- })
105
- )
106
-
107
- return results
108
- }
109
-
110
- /**
111
- * Get data that should be displayed for a specific tab with pagination
112
- * @param {string} brand - The brand for which to fetch data.
113
- * @param {string} pageName - The page name (e.g., 'lessons', 'songs').
114
- * @param {string} tabName - The name for the selected tab. Should be same name received from fetchMetadata (e.g., 'Individuals', 'Collections','For You').
115
- * @param {Object} params - Parameters for pagination, sorting, and filter.
116
- * @param {number} [params.page=1] - The page number for pagination.
117
- * @param {number} [params.limit=10] - The number of items per page.
118
- * @param {string} [params.sort="-published_on"] - The field to sort the data by.
119
- * @param {Array&lt;string>} [params.selectedFilters=[]] - The selected filter.
120
- * @returns {Promise&lt;Object|null>} - The fetched content data or null if not found.
121
- *
122
- * @example
123
- * getTabResults('drumeo', 'lessons','Singles', {
124
- * page: 2,
125
- * limit: 20,
126
- * sort: '-popularity',
127
- * includedFields: ['difficulty,Intermediate'],
128
- * })
129
- * .then(content => console.log(content))
130
- * .catch(error => console.error(error));
131
- */
132
- export async function getTabResults(brand, pageName, tabName, {
133
- page = 1,
134
- limit = 10,
135
- sort = 'recommended',
136
- selectedFilters = []
137
- } = {}) {
138
- // Extract and handle 'progress' filter separately
139
- const progressFilter = selectedFilters.find(f => f.startsWith('progress,')) || 'progress,all';
140
- const progressValue = progressFilter.split(',')[1].toLowerCase();
141
- const filteredSelectedFilters = selectedFilters.filter(f => !f.startsWith('progress,'));
142
-
143
- // Prepare included fields
144
- const mergedIncludedFields = [...filteredSelectedFilters, `tab,${tabName.toLowerCase()}`];
145
-
146
- // Fetch data
147
- let results
148
- if( tabName === Tabs.ForYou.name ) {
149
- results = await addContextToContent(getLessonContentRows, brand, pageName, {
150
- dataField: 'items',
151
- addNextLesson: true,
152
- addNavigateTo: true,
153
- addProgressPercentage: true,
154
- addProgressStatus: true
155
- })
156
- } else {
157
- let temp = await fetchTabData(brand, pageName, { page, limit, sort, includedFields: mergedIncludedFields, progress: progressValue });
158
-
159
- const [ranking, contextResults] = await Promise.all([
160
- sort === 'recommended' ? rankItems(brand, temp.entity.map(e => e.id)) : [],
161
- addContextToContent(() => temp.entity, {
162
- addNextLesson: true,
163
- addNavigateTo: true,
164
- addProgressPercentage: true,
165
- addProgressStatus: true
166
- })
167
- ]);
168
-
169
- results = ranking.length === 0 ? contextResults : contextResults.sort((a, b) => {
170
- const indexA = ranking.indexOf(a.id);
171
- const indexB = ranking.indexOf(b.id);
172
- return (indexA === -1 ? Infinity : indexA) - (indexB === -1 ? Infinity : indexB);
173
- })
174
- }
175
-
176
-
177
- // Fetch metadata
178
- const metaData = await fetchMetadata(brand, pageName);
179
-
180
- // Process filters
181
- const filters = (metaData.filters ?? []).map(filter => ({
182
- ...filter,
183
- items: filter.items.map(item => {
184
- const value = item.value.split(',')[1];
185
- return {
186
- ...item,
187
- selected: selectedFilters.includes(`${filter.key},${value}`) ||
188
- (filter.key === 'progress' &amp;&amp; value === 'all' &amp;&amp; !selectedFilters.some(f => f.startsWith('progress,')))
189
- };
190
- })
191
- }));
192
-
193
- // Process sort options
194
- const sortOptions = {
195
- title: metaData.sort?.title ?? 'Sort By',
196
- type: metaData.sort?.type ?? 'radio',
197
- items: (metaData.sort?.items ?? []).map(option => ({
198
- ...option,
199
- selected: option.value === sort
200
- }))
201
- };
202
-
203
- return {
204
- type: tabName === Tabs.ForYou.name ? TabResponseType.SECTIONS : TabResponseType.CATALOG,
205
- data: results,
206
- meta: { filters, sort: sortOptions }
207
- };
208
- }
209
-
210
- /**
211
- * Fetches recent content for a given brand and page with pagination.
212
- *
213
- * @param {string} brand - The brand for which to fetch data.
214
- * @param {string} pageName - The page name (e.g., 'all', 'incomplete', 'completed').
215
- * @param {string} [tabName='all'] - The tab name (defaults to 'all' for recent content).
216
- * @param {Object} params - Parameters for pagination and sorting.
217
- * @param {number} [params.page=1] - The page number for pagination.
218
- * @param {number} [params.limit=10] - The number of items per page.
219
- * @param {string} [params.sort="-published_on"] - The field to sort the data by.
220
- * @returns {Promise&lt;Object>} - The fetched content data.
221
- *
222
- * @example
223
- * getRecent('drumeo', 'lessons', 'all', {
224
- * page: 2,
225
- * limit: 15,
226
- * sort: '-popularity'
227
- * })
228
- * .then(content => console.log(content))
229
- * .catch(error => console.error(error));
230
- */
231
- export async function getRecent(brand, pageName, tabName = 'all', {
232
- page = 1,
233
- limit = 10,
234
- sort = '-published_on',
235
- } = {}) {
236
- const progress = tabName.toLowerCase() == 'all' ? 'recent':tabName.toLowerCase();
237
- const recentContentIds = await fetchRecent(brand, pageName, { page:page, limit:limit, progress: progress });
238
- const metaData = await fetchMetadata(brand, 'recent');
239
- return {
240
- type: TabResponseType.CATALOG,
241
- data: recentContentIds,
242
- meta: { tabs: metaData.tabs }
243
- };
244
- }
245
-
246
- /**
247
- * Fetches content rows for a given brand and page with optional filtering by content row slug.
248
- *
249
- * @param {string} brand - The brand for which to fetch content rows.
250
- * @param {string} pageName - The page name (e.g., 'lessons', 'songs').
251
- * @param {string|null} contentRowSlug - The specific content row ID to fetch.
252
- * @param {Object} params - Parameters for pagination.
253
- * @param {number} [params.page=1] - The page number for pagination.
254
- * @param {number} [params.limit=10] - The maximum number of content items per row.
255
- * @returns {Promise&lt;Object>} - The fetched content rows with complete Sanity data instead of just content IDs.
256
- * When contentRowId is provided, returns an object with type, data, and meta properties.
257
- *
258
- * @example
259
- * getContentRows('drumeo', 'lessons', 'Your-Daily-Warmup', {
260
- * page: 1,
261
- * limit: 5
262
- * })
263
- * .then(content => console.log(content))
264
- * .catch(error => console.error(error));
265
- */
266
- export async function getContentRows(brand, pageName, contentRowSlug = null, {
267
- page = 1,
268
- limit = 10
269
- } = {}) {
270
- const sanityData = await fetchContentRows(brand, pageName, contentRowSlug)
271
- if (!sanityData) {
272
- return []
273
- }
274
- let contentMap = {}
275
- let recData = {}
276
- let slugNameMap = {}
277
- for (const category of sanityData) {
278
- recData[category.slug] = category.content.map(item => item.id)
279
- for (const content of category.content) {
280
- contentMap[content.id] = content
281
- }
282
- slugNameMap[category.slug] = category.name
283
- }
284
-
285
- const start = (page - 1) * limit
286
- const end = start + limit
287
- const sortedData = await rankCategories(brand, recData)
288
- let finalData = []
289
- for (const category of sortedData) {
290
- finalData.push( {
291
- id: category.slug,
292
- title: slugNameMap[category.slug],
293
- items: category.items.slice(start, end).map(id => contentMap[id])})
294
- }
295
-
296
- return contentRowSlug ?
297
- {
298
- type: TabResponseType.CATALOG,
299
- data: finalData[0].items,
300
- meta: {}
301
- }
302
- : finalData
303
- }
304
-
305
- /**
306
- * Fetches new and upcoming releases for a given brand with pagination options.
307
- *
308
- * @param {string} brand - The brand for which to fetch new and upcoming releases.
309
- * @param {Object} [params={}] - Pagination parameters.
310
- * @param {number} [params.page=1] - The page number for pagination.
311
- * @param {number} [params.limit=10] - The maximum number of content items to fetch.
312
- * @returns {Promise&lt;{ data: Object[] } | null>} - A promise that resolves to the fetched content data or `null` if no data is found.
313
- *
314
- * @example
315
- * // Fetch the first page with 10 results
316
- * getNewAndUpcoming('drumeo')
317
- * .then(response => console.log(response))
318
- * .catch(error => console.error(error));
319
- *
320
- * @example
321
- * // Fetch the second page with 20 results
322
- * getNewAndUpcoming('drumeo', { page: 2, limit: 20 })
323
- * .then(response => console.log(response))
324
- * .catch(error => console.error(error));
325
- */
326
- export async function getNewAndUpcoming(brand, {
327
- page = 1,
328
- limit = 10,
329
- } = {}) {
330
-
331
- const data = await fetchScheduledAndNewReleases(brand, {page: page, limit: limit});
332
- if (!data) {
333
- return null;
334
- }
335
-
336
- return {
337
- data: data,
338
- };
339
- }
340
-
341
- /**
342
- * Fetches scheduled content rows for a given brand with optional filtering by content row ID.
343
- *
344
- * @param {string} brand - The brand for which to fetch content rows.
345
- * @param {string} [contentRowId=null] - The specific content row ID to fetch (optional).
346
- * @param {Object} [params={}] - Pagination parameters.
347
- * @param {number} [params.page=1] - The page number for pagination.
348
- * @param {number} [params.limit=10] - The maximum number of content items per row.
349
- * @returns {Promise&lt;Object>} - A promise that resolves to the fetched content rows.
350
- *
351
- * @example
352
- * // Fetch all sections with default pagination
353
- * getScheduleContentRows('drumeo')
354
- * .then(content => console.log(content))
355
- * .catch(error => console.error(error));
356
- *
357
- * @example
358
- * // Fetch only the 'New-Releases' section with custom pagination
359
- * getScheduleContentRows('drumeo', 'New-Releases', { page: 1, limit: 30 })
360
- * .then(content => console.log(content))
361
- * .catch(error => console.error(error));
362
- *
363
- * @example
364
- * // Fetch only the 'Live-Streams' section with unlimited results
365
- * getScheduleContentRows('drumeo', 'Live-Streams')
366
- * .then(content => console.log(content))
367
- * .catch(error => console.error(error));
368
- */
369
- export async function getScheduleContentRows(brand, contentRowId = null, { page = 1, limit = 10 } = {}) {
370
- const sections = {
371
- 'New-Releases': {
372
- title: 'New Releases',
373
- fetchMethod: fetchNewReleases
374
- },
375
- 'Live-Streams': {
376
- title: 'Live Streams',
377
- fetchMethod: fetchUpcomingEvents
378
- },
379
- 'Upcoming-Releases': {
380
- title: 'Upcoming Releases',
381
- fetchMethod: fetchScheduledReleases
382
- },
383
- 'Returning-Soon': {
384
- title: 'Returning Soon',
385
- fetchMethod: fetchReturning
386
- },
387
- 'Leaving-Soon': {
388
- title: 'Leaving Soon',
389
- fetchMethod: fetchLeaving
390
- }
391
- };
392
-
393
- if (contentRowId) {
394
- if (!sections[contentRowId]) {
395
- return null; // Return null if the requested section does not exist
396
- }
397
-
398
- const items = await sections[contentRowId].fetchMethod(brand, { page, limit });
399
-
400
- // Fetch only the requested section
401
- const result = {
402
- id: contentRowId,
403
- title: sections[contentRowId].title,
404
- // TODO: Remove content after FE/MA updates the existing code to use items
405
- content: items,
406
- items: items
407
- };
408
-
409
- return {
410
- type: TabResponseType.CATALOG,
411
- data: result,
412
- meta: {}
413
- };
414
- }
415
-
416
- // If no specific contentRowId, fetch all sections
417
- const results = await Promise.all(
418
- Object.entries(sections).map(async ([id, section]) => {
419
- // Apply special pagination rules
420
- const isNewReleases = id === 'New-Releases';
421
- const pagination = isNewReleases ? { page: 1, limit: 30 } : { page: 1, limit: Number.MAX_SAFE_INTEGER };
422
- const items = await section.fetchMethod(brand, pagination)
423
-
424
- return {
425
- id,
426
- title: section.title,
427
- // TODO: Remove content after FE/MA updates the existing code to use items
428
- content: items,
429
- items: items
430
- };
431
- })
432
- );
433
-
434
- return {
435
- type: TabResponseType.SECTIONS,
436
- data: results,
437
- meta: {}
438
- };
439
- }
440
-
441
- /**
442
- * Fetches recommended content for a given brand with pagination support.
443
- *
444
- * @param {string} brand - The brand for which to fetch recommended content.
445
- * @param {Object} [params={}] - Pagination parameters.
446
- * @param {number} [params.page=1] - The page number for pagination.
447
- * @param {number} [params.limit=10] - The maximum number of recommended content items per page.
448
- * @returns {Promise&lt;Object>} - A promise that resolves to an object containing recommended content.
449
- *
450
- * @example
451
- * // Fetch recommended content for a brand with default pagination
452
- * getRecommendedForYou('drumeo')
453
- * .then(content => console.log(content))
454
- * .catch(error => console.error(error));
455
- *
456
- * @example
457
- * // Fetch recommended content for a brand with custom pagination
458
- * getRecommendedForYou('drumeo', { page: 2, limit: 5 })
459
- * .then(content => console.log(content))
460
- * .catch(error => console.error(error));
461
- */
462
- export async function getRecommendedForYou(brand, rowId = null, {
463
- page = 1,
464
- limit = 10,
465
- } = {}) {
466
- const requiredItems = page * limit;
467
- const data = await recommendations( brand, {limit: requiredItems})
468
- if (!data || !data.length) {
469
- return { id: 'recommended', title: 'Recommended For You', items: [] };
470
- }
471
-
472
- // Apply pagination before calling fetchByRailContentIds
473
- const startIndex = (page - 1) * limit;
474
- const paginatedData = data.slice(startIndex, startIndex + limit);
475
- const contents = await addContextToContent(fetchByRailContentIds, paginatedData, 'tab-data', brand, true,
476
- {
477
- addNextLesson: true,
478
- addNavigateTo: true,
479
- })
480
- if (rowId) {
481
- return {
482
- type: TabResponseType.CATALOG,
483
- data: contents,
484
- meta: {}
485
- };
486
- }
487
-
488
- return { id: 'recommended', title: 'Recommended For You', items: contents }
489
- }
490
-
491
-
492
- /**
493
- * Fetches legacy methods for a given brand by permission.
494
- *
495
- * @param {string} brand - The brand for which to fetch legacy methods.
496
- * @returns {Promise&lt;Object>} - A promise that resolves to an object containing legacy methods.
497
- *
498
- * @example
499
- * // Fetch legacy methods for a brand by permission
500
- * getLegacyMethods('drumeo')
501
- * .then(content => console.log(content))
502
- * .catch(error => console.error(error));
503
- */
504
- export async function getLegacyMethods(brand) {
505
-
506
- // TODO: Replace with real data from Sanity when available with permissions
507
-
508
- return [
509
- {
510
- id: 1,
511
- title: '2020 Method',
512
- type: 'pack',
513
- child_count: 12,
514
- },
515
- {
516
- id: 2,
517
- title: '2016 Foundations',
518
- type: 'pack',
519
- child_count: 12,
520
- },
521
- ]
522
- }
523
-
524
- /**
525
- * Fetches content owned by the user (excluding membership content).
526
- * Shows only content accessible through purchases/entitlements, not through membership.
527
- *
528
- * @param {string} brand - The brand for which to fetch owned content.
529
- * @param {Object} [params={}] - Parameters for pagination and sorting.
530
- * @param {Array&lt;string>} [params.type=[]] - Content type(s) to filter (optional array).
531
- * @param {number} [params.page=1] - The page number for pagination.
532
- * @param {number} [params.limit=10] - The number of items per page.
533
- * @param {string} [params.sort='-published_on'] - The field to sort the data by.
534
- * @returns {Promise&lt;Object>} - The fetched owned content with entity array and total count.
535
- *
536
- * @example
537
- * // Fetch all owned content with default pagination
538
- * getOwnedContent('drumeo')
539
- * .then(content => console.log(content))
540
- * .catch(error => console.error(error));
541
- *
542
- * @example
543
- * // Fetch owned content with custom pagination and sorting
544
- * getOwnedContent('drumeo', {
545
- * page: 2,
546
- * limit: 20,
547
- * sort: '-published_on'
548
- * })
549
- * .then(content => console.log(content))
550
- * .catch(error => console.error(error));
551
- *
552
- * @example
553
- * // Fetch owned content filtered by types
554
- * getOwnedContent('drumeo', {
555
- * type: ['course', 'pack'],
556
- * page: 1,
557
- * limit: 10
558
- * })
559
- * .then(content => console.log(content))
560
- * .catch(error => console.error(error));
561
- */
562
- export async function getOwnedContent(brand, {
563
- type = [],
564
- page = 1,
565
- limit = 10,
566
- sort = '-published_on',
567
- } = {}) {
568
- const data = await fetchOwnedContent(brand, { type, page, limit, sort });
569
-
570
- if (!data) {
571
- return {
572
- entity: [],
573
- total: 0
574
- };
575
- }
576
-
577
- return data;
578
- }
579
- </code></pre>
580
- </article>
581
- </section>
582
-
583
-
584
-
585
-
586
-
587
-
588
- </div>
589
-
590
- <br class="clear">
591
-
592
- <footer>
593
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Tue Nov 25 2025 19:26:53 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
594
- </footer>
595
-
596
- <script>prettyPrint();</script>
597
- <script src="scripts/polyfill.js"></script>
598
- <script src="scripts/linenumber.js"></script>
599
-
600
-
601
-
602
- </body>
603
- </html>