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,847 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
-
5
- <meta charset="utf-8">
6
- <title>railcontent.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">railcontent.js</h1>
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
- <section>
47
- <article>
48
- <pre class="prettyprint source linenums"><code>/**
49
- * @module Railcontent-Services
50
- */
51
- import { globalConfig } from './config.js'
52
- import { fetchJSONHandler } from '../lib/httpHelper.js'
53
-
54
- /**
55
- * Exported functions that are excluded from index generation.
56
- *
57
- * @type {string[]}
58
- */
59
- const excludeFromGeneratedIndex = [
60
- 'fetchUserLikes',
61
- 'postContentLiked',
62
- 'postContentUnliked',
63
- 'postRecordWatchSession',
64
- 'postContentStarted',
65
- 'postContentComplete',
66
- 'postContentReset',
67
- 'fetchUserPermissionsData',
68
- ]
69
-
70
- /**
71
- * Fetches the completion status of a specific lesson for the current user.
72
- *
73
- * @param {string} content_id - The ID of the lesson content to check.
74
- * @returns {Promise&lt;Object|null>} - Returns the completion status object if found, otherwise null.
75
- * @example
76
- * fetchCurrentSongComplete('user123', 'lesson456', 'csrf-token')
77
- * .then(status => console.log(status))
78
- * .catch(error => console.error(error));
79
- */
80
- export async function fetchCompletedState(content_id) {
81
- const url = `/content/user_progress/${globalConfig.sessionConfig.userId}?content_ids[]=${content_id}`
82
-
83
- const headers = {
84
- 'Content-Type': 'application/json',
85
- Accept: 'application/json',
86
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
87
- }
88
-
89
- try {
90
- const response = await fetchAbsolute(url, { headers })
91
- const result = await response.json()
92
-
93
- if (result &amp;&amp; result[content_id]) {
94
- return result[content_id] // Return the correct object
95
- } else {
96
- return null // Handle unexpected structure
97
- }
98
- } catch (error) {
99
- console.error('Fetch error:', error)
100
- return null
101
- }
102
- }
103
-
104
- /**
105
- * Fetches the completion status for multiple songs for the current user.
106
- *
107
- * @param {Array&lt;string>} contentIds - An array of content IDs to check.
108
- * @returns {Promise&lt;Object|null>} - Returns an object containing completion statuses keyed by content ID, or null if an error occurs.
109
- * @example
110
- * fetchAllCompletedStates('user123', ['song456', 'song789'], 'csrf-token')
111
- * .then(statuses => console.log(statuses))
112
- * .catch(error => console.error(error));
113
- */
114
- export async function fetchAllCompletedStates(contentIds) {
115
- const url = `/content/user_progress/${globalConfig.sessionConfig.userId}?${contentIds.map((id) => `content_ids[]=${id}`).join('&amp;')}`
116
-
117
- const headers = {
118
- 'Content-Type': 'application/json',
119
- Accept: 'application/json',
120
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
121
- }
122
-
123
- try {
124
- const response = await fetchAbsolute(url, { headers })
125
- const result = await response.json()
126
- if (result) {
127
- return result
128
- } else {
129
- console.log('result not json')
130
- }
131
- } catch (error) {
132
- console.error('Fetch error:', error)
133
- return null
134
- }
135
- }
136
-
137
- /**
138
- * Fetches a list of songs that are currently in progress for the current user.
139
- *
140
- * @param {string} brand - The brand associated with the songs.
141
- * @returns {Promise&lt;Object|null>} - Returns an object containing in-progress songs if found, otherwise null.
142
- * @example
143
- * fetchSongsInProgress('drumeo')
144
- * .then(songs => console.log(songs))
145
- * .catch(error => console.error(error));
146
- */
147
- export async function fetchSongsInProgress(brand) {
148
- const url = `/content/in_progress/${globalConfig.sessionConfig.userId}?content_type=song&amp;brand=${brand}`
149
-
150
- const headers = {
151
- 'Content-Type': 'application/json',
152
- Accept: 'application/json',
153
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
154
- }
155
-
156
- try {
157
- const response = await fetchAbsolute(url, { headers })
158
- const result = await response.json()
159
- if (result) {
160
- //console.log('fetchSongsInProgress', result);
161
- return result
162
- } else {
163
- console.log('result not json')
164
- }
165
- } catch (error) {
166
- console.error('Fetch error:', error)
167
- return null
168
- }
169
- }
170
-
171
- /**
172
- * Fetches a list of content that is currently in progress for the current user.
173
- *
174
- * @param {string} type - The content type associated with the content.
175
- * @param {string} brand - The brand associated with the content.
176
- * @param {number} [params.limit=20] - The limit of results per page.
177
- * @param {number} [params.page=1] - The page number for pagination.
178
- * @returns {Promise&lt;Object|null>} - Returns an object containing in-progress content if found, otherwise null.
179
- * @example
180
- * fetchContentInProgress('song', 'drumeo')
181
- * .then(songs => console.log(songs))
182
- * .catch(error => console.error(error));
183
- */
184
- export async function fetchContentInProgress(type = 'all', brand, { page, limit } = {}) {
185
- let url
186
- const limitString = limit ? `&amp;limit=${limit}` : ''
187
- const pageString = page ? `&amp;page=${page}` : ''
188
-
189
- if (type === 'all') {
190
- url = `/content/in_progress/${globalConfig.sessionConfig.userId}?brand=${brand}${limitString}${pageString}`
191
- } else {
192
- url = `/content/in_progress/${globalConfig.sessionConfig.userId}?content_type=${type}&amp;brand=${brand}${limitString}${pageString}`
193
- }
194
- const headers = {
195
- 'Content-Type': 'application/json',
196
- Accept: 'application/json',
197
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
198
- }
199
- try {
200
- const response = await fetchAbsolute(url, { headers })
201
- const result = await response.json()
202
- if (result) {
203
- //console.log('contentInProgress', result);
204
- return result
205
- } else {
206
- console.log('result not json')
207
- }
208
- } catch (error) {
209
- console.error('Fetch error:', error)
210
- return null
211
- }
212
- }
213
-
214
- /**
215
- * Fetches a list of content that has been completed for the current user.
216
- *
217
- * @param {string} type - The content type associated with the content.
218
- * @param {string} brand - The brand associated with the content.
219
- * @param {number} [params.limit=20] - The limit of results per page.
220
- * @param {number} [params.page=1] - The page number for pagination.
221
- * @returns {Promise&lt;Object|null>} - Returns an object containing in-progress content if found, otherwise null.
222
- * @example
223
- * fetchCompletedContent('song', 'drumeo')
224
- * .then(songs => console.log(songs))
225
- * .catch(error => console.error(error));
226
- */
227
- export async function fetchCompletedContent(type = 'all', brand, { page, limit } = {}) {
228
- let url
229
- const limitString = limit ? `&amp;limit=${limit}` : ''
230
- const pageString = page ? `&amp;page=${page}` : ''
231
-
232
- if (type === 'all') {
233
- url = `/content/completed/${globalConfig.sessionConfig.userId}?brand=${brand}${limitString}${pageString}`
234
- } else {
235
- url = `/content/completed/${globalConfig.sessionConfig.userId}?content_type=${type}&amp;brand=${brand}${limitString}${pageString}`
236
- }
237
- const headers = {
238
- 'Content-Type': 'application/json',
239
- Accept: 'application/json',
240
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
241
- }
242
- try {
243
- const response = await fetchAbsolute(url, { headers })
244
- const result = await response.json()
245
- if (result) {
246
- //console.log('completed content', result);
247
- return result
248
- } else {
249
- console.log('result not json')
250
- }
251
- } catch (error) {
252
- console.error('Fetch error:', error)
253
- return null
254
- }
255
- }
256
-
257
- /**
258
- * Fetches user context data for a specific piece of content.
259
- *
260
- * @param {int} contentId - The content id.
261
- * @returns {Promise&lt;Object|null>} - Returns an object containing user context data if found, otherwise null.
262
- * @example
263
- * fetchContentPageUserData(406548)
264
- * .then(data => console.log(data))
265
- * .catch(error => console.error(error));
266
- */
267
- export async function fetchContentPageUserData(contentId) {
268
- let url = `/api/content/v1/${contentId}/user_data/${globalConfig.sessionConfig.userId}`
269
- const headers = {
270
- 'Content-Type': 'application/json',
271
- Accept: 'application/json',
272
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
273
- }
274
-
275
- try {
276
- const response = await fetchAbsolute(url, { headers })
277
- const result = await response.json()
278
- if (result) {
279
- console.log('fetchContentPageUserData', result)
280
- return result
281
- } else {
282
- console.log('result not json')
283
- }
284
- } catch (error) {
285
- console.error('Fetch error:', error)
286
- return null
287
- }
288
- }
289
-
290
- /**
291
- * Fetches the ID and Type of the piece of content that would be the next one for the user
292
- *
293
- * @param {int} contentId - The id of the parent (method, level, or course) piece of content.
294
- * @returns {Promise&lt;Object|null>} - Returns and Object with the id and type of the next piece of content if found, otherwise null.
295
- */
296
- export async function fetchNextContentDataForParent(contentId) {
297
- let url = `/content/${contentId}/next/${globalConfig.sessionConfig.userId}`
298
- const headers = {
299
- 'Content-Type': 'application/json',
300
- 'X-CSRF-TOKEN': globalConfig.sessionConfig.token,
301
- }
302
-
303
- try {
304
- const response = await fetchAbsolute(url, { headers })
305
- const result = await response.json()
306
- if (result) {
307
- // console.log('fetchNextContentDataForParent', result);
308
- return result.next
309
- } else {
310
- console.log('fetchNextContentDataForParent result not json')
311
- return null
312
- }
313
- } catch (error) {
314
- console.error('Fetch error:', error)
315
- return null
316
- }
317
- }
318
-
319
- export async function fetchUserPermissionsData() {
320
- let url = `/content/user/permissions`
321
- // in the case of an unauthorized user, we return empty permissions
322
- return (await fetchHandler(url, 'get')) ?? []
323
- }
324
-
325
- async function fetchDataHandler(url, dataVersion, method = 'get') {
326
- return fetchHandler(url, method, dataVersion)
327
- }
328
-
329
- async function postDataHandler(url, data) {
330
- return fetchHandler(url, 'post', null, data)
331
- }
332
-
333
- async function patchDataHandler_depreciated(url, data) {
334
- throw Error('PATCH verb throws a CORS error on the FEW. Use PATCH instead')
335
- }
336
-
337
- async function putDataHandler(url, data) {
338
- return fetchHandler(url, 'put', null, data)
339
- }
340
-
341
- async function deleteDataHandler(url, data) {
342
- return fetchHandler(url, 'delete')
343
- }
344
-
345
- export async function fetchLikeCount(contendId) {
346
- const url = `/api/content/v1/content/like_count/${contendId}`
347
- return await fetchDataHandler(url)
348
- }
349
-
350
- export async function fetchUserLikes(currentVersion) {
351
- let url = `/api/content/v1/user/likes`
352
- return fetchDataHandler(url, currentVersion)
353
- }
354
-
355
- export async function postContentLiked(contentId) {
356
- let url = `/api/content/v1/user/likes/${contentId}`
357
- return await postDataHandler(url)
358
- }
359
-
360
- export async function postContentUnliked(contentId) {
361
- let url = `/api/content/v1/user/likes/${contentId}`
362
- return await deleteDataHandler(url)
363
- }
364
-
365
- export async function fetchContentProgress(currentVersion) {
366
- let url = `/content/user/progress/all`
367
- return fetchDataHandler(url, currentVersion)
368
- }
369
-
370
- export async function postPlaylistContentEngaged(playlistItemId) {
371
- let url = `/railtracker/v1/last-engaged/${playlistItemId}`
372
- return postDataHandler(url)
373
- }
374
-
375
- export async function postRecordWatchSession(
376
- contentId,
377
- mediaTypeId,
378
- mediaLengthSeconds,
379
- currentSeconds,
380
- secondsPlayed,
381
- sessionId
382
- ) {
383
- let url = `/railtracker/v2/media-playback-session`
384
- return postDataHandler(url, {
385
- content_id: contentId,
386
- media_type_id: mediaTypeId,
387
- media_length_seconds: mediaLengthSeconds,
388
- current_second: currentSeconds,
389
- seconds_played: secondsPlayed,
390
- session_id: sessionId,
391
- })
392
- }
393
-
394
- /**
395
- * Fetch the user's best award for this challenge
396
- *
397
- * @param contentId - railcontent id of the challenge
398
- * @returns {Promise&lt;any|null>} - streamed PDF
399
- */
400
- export async function fetchUserAward(contentId) {
401
- let url = `/challenges/download_award/${contentId}`
402
- return await fetchHandler(url, 'get')
403
- }
404
-
405
- /**
406
- * Fetch All Carousel Card Data
407
- *
408
- * @returns {Promise&lt;any|null>}
409
- */
410
- export async function fetchCarouselCardData(brand = null) {
411
- const brandParam = brand ? `?brand=${brand}` : ''
412
- let url = `/api/v2/content/carousel${brandParam}`
413
- return await fetchHandler(url, 'get')
414
- }
415
-
416
- /**
417
- * Fetch all completed badges for the user ordered by completion date descending
418
- *
419
- * @param {string|null} brand -
420
- * @returns {Promise&lt;any|null>}
421
- */
422
- export async function fetchUserBadges(brand = null) {
423
- let brandParam = brand ? `?brand=${brand}` : ''
424
- let url = `/challenges/user_badges/get${brandParam}`
425
- return await fetchHandler(url, 'get')
426
- }
427
-
428
- /**
429
- * complete a content's progress for a given user
430
- * @param contentId
431
- * @param collection {object|null} - the collection context of the progress. null is normal content progress
432
- * @param collection.type - the type of collection. options: ["learning-path"]
433
- * @param collection.id - the content_id of collection.
434
- * @returns {Promise&lt;any|string|null>}
435
- */
436
- export async function postContentComplete(contentId, collection = null) {
437
- let url = `/api/content/v1/user/progress/complete/${contentId}`
438
- const body = {collection: collection}
439
- return postDataHandler(url, body)
440
- }
441
-
442
- /**
443
- * start the user's progress on a content
444
- * @param contentId
445
- * @param collection {object|null} - the collection context of the progress. null is normal content progress
446
- * @param collection.type - the type of collection. options: ["learning-path"]
447
- * @param collection.id - the content_id of collection.
448
- * @returns {Promise&lt;any|string|null>}
449
- */
450
- export async function postContentStart(contentId, collection = null) {
451
- let url = `/api/content/v1/user/progress/start/${contentId}`
452
- const body = {collection: collection}
453
- return postDataHandler(url, body)
454
- }
455
-
456
- /**
457
- * resets the user's progress on a content
458
- * @param contentId
459
- * @param collection {object|null} - the collection context of the progress. null is normal content progress
460
- * @param collection.type - the type of collection. options: ["learning-path"]
461
- * @param collection.id - the content_id of collection.
462
- * @returns {Promise&lt;any|string|null>}
463
- */
464
- export async function postContentReset(contentId, collection = null) {
465
- let url = `/api/content/v1/user/progress/reset/${contentId}`
466
- const body = {collection: collection}
467
- return postDataHandler(url, body)
468
- }
469
-
470
- /**
471
- * restores the user's progress on a content
472
- * @param contentId
473
- * @returns {Promise&lt;any|string|null>}
474
- */
475
- export async function postContentRestore(contentId) {
476
- let url = `/api/content/v1/user/progress/restore/${contentId}`
477
- return postDataHandler(url)
478
- }
479
-
480
- /**
481
- * Set a user's StudentView Flag
482
- *
483
- * @param {int|string} userId - id of the user (must be currently authenticated)
484
- * @param {bool} enable - truthy value to enable student view
485
- * @returns {Promise&lt;any|null>}
486
- */
487
- export async function setStudentViewForUser(userId, enable) {
488
- let url = `/user-management-system/user/update/${userId}`
489
- let data = { use_student_view: enable ? 1 : 0 }
490
- return await putDataHandler(url, data)
491
- }
492
-
493
- /**
494
- * Fetch the top comment for a given content
495
- *
496
- * @param {int} railcontentId - The railcontent id to fetch.
497
- * @returns {Promise&lt;Object|null>} - A promise that resolves to an comment object
498
- */
499
- export async function fetchTopComment(railcontentId) {
500
- const url = `/api/content/v1/${railcontentId}/comments?filter=top`
501
- return await fetchHandler(url)
502
- }
503
-
504
- /**
505
- *
506
- * @param {int} railcontentId
507
- * @param {int} page
508
- * @param {int} limit
509
- * @returns {Promise&lt;*|null>}
510
- */
511
- export async function fetchComments(railcontentId, page = 1, limit = 20) {
512
- const url = `/api/content/v1/${railcontentId}/comments?page=${page}&amp;limit=${limit}`
513
- return await fetchHandler(url)
514
- }
515
-
516
- /**
517
- *
518
- * @param {int} commentId
519
- * @param {int} page
520
- * @param {int} limit
521
- * @returns {Promise&lt;*|null>}
522
- */
523
- export async function fetchCommentRelies(commentId, page = 1, limit = 20) {
524
- const url = `/api/content/v1/comments/${commentId}/replies?page=${page}&amp;limit=${limit}`
525
- return await fetchHandler(url)
526
- }
527
-
528
- /**
529
- * @param {int} commentId
530
- * @returns {Promise&lt;*|null>}
531
- */
532
- export async function deleteComment(commentId) {
533
- const url = `/api/content/v1/comments/${commentId}`
534
- return await fetchHandler(url, 'DELETE')
535
- }
536
-
537
- /**
538
- * @param {int} commentId
539
- * @returns {Promise&lt;*|null>}
540
- */
541
- export async function restoreComment(commentId) {
542
- const url = `/api/content/v1/comments/restore/${commentId}`
543
- return await fetchHandler(url, 'POST')
544
- }
545
-
546
- /**
547
- * @param {int} commentId
548
- * @param {string} comment
549
- * @returns {Promise&lt;*|null>}
550
- */
551
- export async function replyToComment(commentId, comment) {
552
- const data = { comment: comment }
553
- const url = `/api/content/v1/comments/${commentId}/reply`
554
- return await postDataHandler(url, data)
555
- }
556
-
557
- /**
558
- * @param {int} railcontentId
559
- * @param {string} comment
560
- * @returns {Promise&lt;*|null>}
561
- */
562
- export async function createComment(railcontentId, comment) {
563
- const data = {
564
- comment: comment,
565
- content_id: railcontentId,
566
- }
567
- const url = `/api/content/v1/comments/store`
568
- return await postDataHandler(url, data)
569
- }
570
-
571
- /**
572
- * @param {int} commentId
573
- * @returns {Promise&lt;*|null>}
574
- */
575
- export async function assignModeratorToComment(commentId) {
576
- const url = `/api/content/v1/comments/${commentId}/assign_moderator`
577
- return await postDataHandler(url)
578
- }
579
-
580
- /**
581
- * @param {int} commentId
582
- * @returns {Promise&lt;*|null>}
583
- */
584
- export async function unassignModeratorToComment(commentId) {
585
- const url = `/api/content/v1/comments/${commentId}/unassign_moderator`
586
- return await postDataHandler(url)
587
- }
588
-
589
- /**
590
- * @param {int} commentId
591
- * @returns {Promise&lt;*|null>}
592
- */
593
- export async function likeComment(commentId) {
594
- const url = `/api/content/v1/comments/${commentId}/like`
595
- return await postDataHandler(url)
596
- }
597
-
598
- /**
599
- * @param {int} commentId
600
- * @returns {Promise&lt;*|null>}
601
- */
602
- export async function unlikeComment(commentId) {
603
- const url = `/api/content/v1/comments/${commentId}/like`
604
- return await deleteDataHandler(url)
605
- }
606
-
607
- /**
608
- * @param {int} commentId
609
- * @returns {Promise&lt;*|null>}
610
- */
611
- export async function closeComment(commentId) {
612
- const url = `/api/content/v1/comments/${commentId}`
613
- const data = {
614
- conversation_status: 'closed',
615
- }
616
- return await putDataHandler(url, data)
617
- }
618
-
619
- /**
620
- * @param {int} commentId
621
- * @returns {Promise&lt;*|null>}
622
- */
623
- export async function openComment(commentId) {
624
- const url = `/api/content/v1/comments/${commentId}`
625
- const data = {
626
- conversation_status: 'open',
627
- }
628
- return await putDataHandler(url, data)
629
- }
630
-
631
- /**
632
- * @param {int} commentId
633
- * @param {string} comment
634
- * @returns {Promise&lt;*|null>}
635
- */
636
- export async function editComment(commentId, comment) {
637
- const url = `/api/content/v1/comments/${commentId}`
638
- const data = {
639
- comment: comment,
640
- }
641
- return await putDataHandler(url, data)
642
- }
643
-
644
- /**
645
- * @param {int} commentId
646
- * @param {string} issue
647
- * @returns {Promise&lt;*|null>}
648
- */
649
- export async function reportComment(commentId, issue) {
650
- const url = `/api/content/v1/comments/${commentId}/report`
651
- const data = {
652
- issue: issue,
653
- }
654
- return await postDataHandler(url, data)
655
- }
656
-
657
- /**
658
- * Fetches a single comment by its ID.
659
- *
660
- * @param {number|string} commentId - The ID of the comment to fetch.
661
- * @returns {Promise&lt;Object|null>} - A promise that resolves to the comment object if found, otherwise null.
662
- *
663
- * @example
664
- * fetchComment(123)
665
- * .then(comment => console.log(comment))
666
- * .catch(error => console.error(error));
667
- */
668
- export async function fetchComment(commentId) {
669
- const url = `/api/content/v1/comments/${commentId}`
670
- const comment = await fetchHandler(url)
671
- return comment.parent ? comment.parent : comment
672
- }
673
-
674
- export async function fetchUserPractices(currentVersion = 0, { userId } = {}) {
675
- const params = new URLSearchParams()
676
- if (userId) params.append('user_id', userId)
677
- const query = params.toString() ? `?${params.toString()}` : ''
678
- const url = `/api/user/practices/v1/practices${query}`
679
- const response = await fetchDataHandler(url, currentVersion)
680
- const { data, version } = response
681
- const userPractices = data
682
- if (!userPractices) {
683
- return { data: { practices: {} }, version }
684
- }
685
-
686
- const formattedPractices = userPractices.reduce((acc, practice) => {
687
- if (!acc[practice.day]) {
688
- acc[practice.day] = []
689
- }
690
-
691
- acc[practice.day].push({
692
- id: practice.id,
693
- duration_seconds: practice.duration_seconds,
694
- })
695
-
696
- return acc
697
- }, {})
698
-
699
- return {
700
- data: {
701
- practices: formattedPractices,
702
- },
703
- version,
704
- }
705
- }
706
-
707
- export async function logUserPractice(practiceDetails) {
708
- const url = `/api/user/practices/v1/practices`
709
- return await fetchHandler(url, 'POST', null, practiceDetails)
710
- }
711
- export async function fetchUserPracticeMeta(practiceIds, userId = null) {
712
- if (practiceIds.length == 0) {
713
- return []
714
- }
715
- const params = new URLSearchParams()
716
- practiceIds.forEach((id) => params.append('practice_ids[]', id))
717
-
718
- if (userId !== null) {
719
- params.append('user_id', userId)
720
- }
721
- const url = `/api/user/practices/v1/practices?${params.toString()}`
722
- return await fetchHandler(url, 'GET', null)
723
- }
724
-
725
- /**
726
- * Fetches user practice notes for a specific date.
727
- * @param {string} date - The date for which to fetch practice notes (format: YYYY-MM-DD).
728
- * @returns {Promise&lt;Object|null>} - A promise that resolves to an object containing the practice notes if found, otherwise null.
729
- *
730
- * @example
731
- * fetchUserPracticeNotes('2025-04-10')
732
- * .then(notes => console.log(notes))
733
- * .catch(error => console.error(error));
734
- */
735
- export async function fetchUserPracticeNotes(date) {
736
- const url = `/api/user/practices/v1/notes?date=${date}`
737
- return await fetchHandler(url, 'GET', null)
738
- }
739
-
740
- /**
741
- * Get the id and slug of last interacted child. Only valid for certain content types
742
- *
743
- * @async
744
- * @function fetchLastInteractedChild
745
- * @param {array} content_ids - Content ids of to get the last interacted child of
746
- *
747
- *
748
- * @returns {Promise&lt;Object>} - keyed object per valid content ids with the child
749
- *
750
- * @example
751
- * try {
752
- * const response = await fetchLastInteractedChild([191369, 410427]);
753
- * console.log('child id', response[191369].content_id)
754
- * console.log('child slug', response[191369].slug)
755
- * } catch (error) {
756
- * console.error('Failed to get children', error);
757
- * }
758
- */
759
- export async function fetchLastInteractedChild(content_ids) {
760
- const params = new URLSearchParams()
761
- content_ids.forEach((id) => params.append('content_ids[]', id))
762
- const url = `/api/content/v1/user/last_interacted_child?${params.toString()}`
763
- return await fetchHandler(url, 'GET', null)
764
- }
765
-
766
- /**
767
- * @typedef {Object} Activity
768
- * @property {string} id - Unique identifier for the activity.
769
- * @property {string} type - Type of activity (e.g., "lesson_completed").
770
- * @property {string} timestamp - ISO 8601 string of when the activity occurred.
771
- * @property {Object} meta - Additional metadata related to the activity.
772
- */
773
-
774
- /**
775
- * @typedef {Object} PaginatedActivities
776
- * @property {number} currentPage
777
- * @property {number} totalPages
778
- * @property {Activity[]} data
779
- */
780
-
781
- /**
782
- * Fetches a paginated list of recent user activities.
783
- * @param {Object} [params={}] - Optional parameters.
784
- * @param {number} [params.page=1] - The page number for pagination.
785
- * @param {number} [params.limit=10] - The number of results per page.
786
- * @param {string|null} [params.tabName=null] - Optional filter for activity type/tab.
787
- * @returns {Promise&lt;PaginatedActivities>} - A promise that resolves to a paginated object of user activities.
788
- *
789
- * @example
790
- * fetchRecentUserActivities({ page: 2, limit: 5 })
791
- * .then(activities => console.log(activities))
792
- * .catch(error => console.error(error));
793
- */
794
- export async function fetchRecentUserActivities({ page = 1, limit = 5, tabName = null } = {}) {
795
- let pageAndLimit = `?page=${page}&amp;limit=${limit}`
796
- let tabParam = tabName ? `&amp;tabName=${tabName}` : ''
797
- const url = `/api/user-management-system/v1/activities/all${pageAndLimit}${tabParam}`
798
- return await fetchHandler(url, 'GET', null)
799
- }
800
-
801
- function fetchAbsolute(url, params) {
802
- if (globalConfig.sessionConfig.authToken) {
803
- params.headers['Authorization'] = `Bearer ${globalConfig.sessionConfig.authToken}`
804
- }
805
-
806
- if (globalConfig.baseUrl) {
807
- if (url.startsWith('/')) {
808
- return fetch(globalConfig.baseUrl + url, params)
809
- }
810
- }
811
- return fetch(url, params)
812
- }
813
- export async function fetchHandler(url, method = 'get', dataVersion = null, body = null) {
814
- return fetchJSONHandler(
815
- url,
816
- globalConfig.sessionConfig.token,
817
- globalConfig.baseUrl,
818
- method,
819
- dataVersion,
820
- body
821
- )
822
- }
823
- </code></pre>
824
- </article>
825
- </section>
826
-
827
-
828
-
829
-
830
-
831
-
832
- </div>
833
-
834
- <br class="clear">
835
-
836
- <footer>
837
- 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.
838
- </footer>
839
-
840
- <script>prettyPrint();</script>
841
- <script src="scripts/polyfill.js"></script>
842
- <script src="scripts/linenumber.js"></script>
843
-
844
-
845
-
846
- </body>
847
- </html>