musora-content-services 1.3.14 → 1.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/package.json +1 -1
- package/src/index.d.ts +15 -0
- package/src/index.js +15 -0
- package/src/services/config.js +12 -3
- package/src/services/recommendations.js +155 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.3.15](https://github.com/railroadmedia/musora-content-services/compare/v1.3.14...v1.3.15) (2025-03-10)
|
|
6
|
+
|
|
5
7
|
### [1.3.14](https://github.com/railroadmedia/musora-content-services/compare/v1.3.13...v1.3.14) (2025-03-06)
|
|
6
8
|
|
|
7
9
|
### [1.3.13](https://github.com/railroadmedia/musora-content-services/compare/v1.3.12...v1.3.13) (2025-03-06)
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ import {
|
|
|
50
50
|
fetchChallengeLessonData,
|
|
51
51
|
fetchChallengeMetadata,
|
|
52
52
|
fetchChallengeUserActiveChallenges,
|
|
53
|
+
fetchCommentRelies,
|
|
54
|
+
fetchComments,
|
|
53
55
|
fetchCompletedChallenges,
|
|
54
56
|
fetchCompletedContent,
|
|
55
57
|
fetchCompletedState,
|
|
@@ -64,6 +66,7 @@ import {
|
|
|
64
66
|
fetchPlaylistItem,
|
|
65
67
|
fetchPlaylistItems,
|
|
66
68
|
fetchSongsInProgress,
|
|
69
|
+
fetchTopComment,
|
|
67
70
|
fetchUserAward,
|
|
68
71
|
fetchUserBadges,
|
|
69
72
|
fetchUserChallengeProgress,
|
|
@@ -94,6 +97,12 @@ import {
|
|
|
94
97
|
updatePlaylistItem
|
|
95
98
|
} from './services/railcontent.js';
|
|
96
99
|
|
|
100
|
+
import {
|
|
101
|
+
rankCategories,
|
|
102
|
+
rankItems,
|
|
103
|
+
similarItems
|
|
104
|
+
} from './services/recommendations.js';
|
|
105
|
+
|
|
97
106
|
import {
|
|
98
107
|
fetchAll,
|
|
99
108
|
fetchAllFilterOptions,
|
|
@@ -174,6 +183,8 @@ declare module 'musora-content-services' {
|
|
|
174
183
|
fetchCoachLessons,
|
|
175
184
|
fetchComingSoon,
|
|
176
185
|
fetchCommentModContentData,
|
|
186
|
+
fetchCommentRelies,
|
|
187
|
+
fetchComments,
|
|
177
188
|
fetchCompletedChallenges,
|
|
178
189
|
fetchCompletedContent,
|
|
179
190
|
fetchCompletedState,
|
|
@@ -213,6 +224,7 @@ declare module 'musora-content-services' {
|
|
|
213
224
|
fetchSongArtistCount,
|
|
214
225
|
fetchSongById,
|
|
215
226
|
fetchSongsInProgress,
|
|
227
|
+
fetchTopComment,
|
|
216
228
|
fetchTopLevelParentId,
|
|
217
229
|
fetchUpcomingEvents,
|
|
218
230
|
fetchUserAward,
|
|
@@ -253,11 +265,14 @@ declare module 'musora-content-services' {
|
|
|
253
265
|
postContentReset,
|
|
254
266
|
postContentUnliked,
|
|
255
267
|
postRecordWatchSession,
|
|
268
|
+
rankCategories,
|
|
269
|
+
rankItems,
|
|
256
270
|
recordWatchSession,
|
|
257
271
|
reportPlaylist,
|
|
258
272
|
reset,
|
|
259
273
|
setLastUpdatedTime,
|
|
260
274
|
setStudentViewForUser,
|
|
275
|
+
similarItems,
|
|
261
276
|
unlikeContent,
|
|
262
277
|
unpinPlaylist,
|
|
263
278
|
updatePlaylist,
|
package/src/index.js
CHANGED
|
@@ -50,6 +50,8 @@ import {
|
|
|
50
50
|
fetchChallengeLessonData,
|
|
51
51
|
fetchChallengeMetadata,
|
|
52
52
|
fetchChallengeUserActiveChallenges,
|
|
53
|
+
fetchCommentRelies,
|
|
54
|
+
fetchComments,
|
|
53
55
|
fetchCompletedChallenges,
|
|
54
56
|
fetchCompletedContent,
|
|
55
57
|
fetchCompletedState,
|
|
@@ -64,6 +66,7 @@ import {
|
|
|
64
66
|
fetchPlaylistItem,
|
|
65
67
|
fetchPlaylistItems,
|
|
66
68
|
fetchSongsInProgress,
|
|
69
|
+
fetchTopComment,
|
|
67
70
|
fetchUserAward,
|
|
68
71
|
fetchUserBadges,
|
|
69
72
|
fetchUserChallengeProgress,
|
|
@@ -94,6 +97,12 @@ import {
|
|
|
94
97
|
updatePlaylistItem
|
|
95
98
|
} from './services/railcontent.js';
|
|
96
99
|
|
|
100
|
+
import {
|
|
101
|
+
rankCategories,
|
|
102
|
+
rankItems,
|
|
103
|
+
similarItems
|
|
104
|
+
} from './services/recommendations.js';
|
|
105
|
+
|
|
97
106
|
import {
|
|
98
107
|
fetchAll,
|
|
99
108
|
fetchAllFilterOptions,
|
|
@@ -173,6 +182,8 @@ export {
|
|
|
173
182
|
fetchCoachLessons,
|
|
174
183
|
fetchComingSoon,
|
|
175
184
|
fetchCommentModContentData,
|
|
185
|
+
fetchCommentRelies,
|
|
186
|
+
fetchComments,
|
|
176
187
|
fetchCompletedChallenges,
|
|
177
188
|
fetchCompletedContent,
|
|
178
189
|
fetchCompletedState,
|
|
@@ -212,6 +223,7 @@ export {
|
|
|
212
223
|
fetchSongArtistCount,
|
|
213
224
|
fetchSongById,
|
|
214
225
|
fetchSongsInProgress,
|
|
226
|
+
fetchTopComment,
|
|
215
227
|
fetchTopLevelParentId,
|
|
216
228
|
fetchUpcomingEvents,
|
|
217
229
|
fetchUserAward,
|
|
@@ -252,11 +264,14 @@ export {
|
|
|
252
264
|
postContentReset,
|
|
253
265
|
postContentUnliked,
|
|
254
266
|
postRecordWatchSession,
|
|
267
|
+
rankCategories,
|
|
268
|
+
rankItems,
|
|
255
269
|
recordWatchSession,
|
|
256
270
|
reportPlaylist,
|
|
257
271
|
reset,
|
|
258
272
|
setLastUpdatedTime,
|
|
259
273
|
setStudentViewForUser,
|
|
274
|
+
similarItems,
|
|
260
275
|
unlikeContent,
|
|
261
276
|
unpinPlaylist,
|
|
262
277
|
updatePlaylist,
|
package/src/services/config.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
export let globalConfig = {
|
|
6
6
|
sanityConfig: {},
|
|
7
7
|
railcontentConfig: {},
|
|
8
|
+
recommendationsConfig: {},
|
|
8
9
|
localStorage: null,
|
|
9
10
|
isMA: false,
|
|
10
11
|
localTimezoneString: null, // In format: America/Vancouver
|
|
@@ -35,6 +36,8 @@ const excludeFromGeneratedIndex = []
|
|
|
35
36
|
* @param {string} config.railcontentConfig.userId - The user ID for fetching user-specific data.
|
|
36
37
|
* @param {string} config.railcontentConfig.baseUrl - The url for the environment.
|
|
37
38
|
* @param {string} config.railcontentConfig.authToken - The bearer authorization token.
|
|
39
|
+
* @param {string} config.recommendationsConfig.token - The token for authenticating recommendation requests.
|
|
40
|
+
* @param {string} config.recommendationsConfig.baseUrl - The url for the recommendation server.
|
|
38
41
|
* @param {Object} config.localStorage - Cache to use for localStorage
|
|
39
42
|
* @param {boolean} config.isMA - Variable that tells if the library is used by MA or FEW
|
|
40
43
|
* @param {string} config.localTimezoneString - The local timezone string in format: America/Vancouver
|
|
@@ -49,15 +52,20 @@ const excludeFromGeneratedIndex = []
|
|
|
49
52
|
* dataset: 'your-dataset-name',
|
|
50
53
|
* version: '2021-06-07',
|
|
51
54
|
* debug: true,
|
|
52
|
-
* useCachedAPI: false
|
|
55
|
+
* useCachedAPI: false,
|
|
53
56
|
* },
|
|
54
57
|
* railcontentConfig: {
|
|
55
58
|
* token: 'your-user-api-token',
|
|
56
59
|
* userId: 'current-user-id',
|
|
57
|
-
* baseUrl: 'https://web-staging-one.musora.com'
|
|
60
|
+
* baseUrl: 'https://web-staging-one.musora.com',
|
|
61
|
+
* authToken 'your-auth-token',
|
|
62
|
+
* },
|
|
63
|
+
* recommendationsConfig: {
|
|
64
|
+
* token: 'your-user-api-token',
|
|
65
|
+
* baseUrl: 'https://MusoraProductDepartment-PWGenerator.hf.space',
|
|
58
66
|
* },
|
|
59
67
|
* localStorage: localStorage,
|
|
60
|
-
* isMA: false
|
|
68
|
+
* isMA: false,
|
|
61
69
|
* });
|
|
62
70
|
*/
|
|
63
71
|
export function initializeService(config) {
|
|
@@ -66,4 +74,5 @@ export function initializeService(config) {
|
|
|
66
74
|
globalConfig.localStorage = config.localStorage
|
|
67
75
|
globalConfig.isMA = config.isMA || false
|
|
68
76
|
globalConfig.localTimezoneString = config.localTimezoneString || null
|
|
77
|
+
globalConfig.recommendationsConfig = config.recommendationsConfig
|
|
69
78
|
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Railcontent-Services
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { globalConfig } from './config.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Exported functions that are excluded from index generation.
|
|
9
|
+
*
|
|
10
|
+
* @type {string[]}
|
|
11
|
+
*/
|
|
12
|
+
const excludeFromGeneratedIndex = []
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Fetches similar content to the provided content id
|
|
16
|
+
*
|
|
17
|
+
* @param {brand} brand - brand of the content to filter
|
|
18
|
+
* @param {integer} content_id - The ID of the content to find similar items for
|
|
19
|
+
* @param {integer} count - number of items to return
|
|
20
|
+
* @returns {Promise<Object|null>} - Returns the content_ids sorted by rank (most significant first)
|
|
21
|
+
* @example
|
|
22
|
+
* rankItems('drumeo', 1113)
|
|
23
|
+
* .then(status => console.log(status))
|
|
24
|
+
* .catch(error => console.error(error));
|
|
25
|
+
*/
|
|
26
|
+
export async function similarItems(brand, content_id, count = 10) {
|
|
27
|
+
if (!content_id) {
|
|
28
|
+
return []
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let data = {
|
|
32
|
+
'brand': brand,
|
|
33
|
+
'content_ids': content_id,
|
|
34
|
+
'num_similar': count,
|
|
35
|
+
}
|
|
36
|
+
const url = `/similar_items/`
|
|
37
|
+
try {
|
|
38
|
+
const response = await fetchHandler(url, 'POST', data)
|
|
39
|
+
return response['similar_items']
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('Fetch error:', error)
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Sorts the provided categories based on the user's match
|
|
48
|
+
*
|
|
49
|
+
* @param {brand} brand - brand of the content to filter
|
|
50
|
+
* @param {Object} categories - Keyed arrays of content ids
|
|
51
|
+
* @param {boolean} rankEachCategory - flag to sort each category by user's match
|
|
52
|
+
* @returns {Promise<Object|null>} - Returns the content_ids sorted by rank (most significant first)
|
|
53
|
+
* @example
|
|
54
|
+
* rankCategories('drumeo', {
|
|
55
|
+
* 1: [111222, 23120, 402199],
|
|
56
|
+
* 2: [2222, 33333, 44444]
|
|
57
|
+
* }
|
|
58
|
+
* )
|
|
59
|
+
* .then(status => console.log(status))
|
|
60
|
+
* .catch(error => console.error(error));
|
|
61
|
+
*/
|
|
62
|
+
export async function rankCategories(brand, categories, rankEachCategory = true) {
|
|
63
|
+
if (categories.length === 0) {
|
|
64
|
+
return []
|
|
65
|
+
}
|
|
66
|
+
let data = {
|
|
67
|
+
'brand': brand,
|
|
68
|
+
'user_id': globalConfig.railcontentConfig.userId,
|
|
69
|
+
'playlists': categories,
|
|
70
|
+
'rank_each_list': Boolean(rankEachCategory),
|
|
71
|
+
}
|
|
72
|
+
const url = `/rank_playlists/`
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetchHandler(url, 'POST', data)
|
|
75
|
+
let rankedCategories = {}
|
|
76
|
+
response['ranked_playlists'].forEach((category) => rankedCategories[category['playlist_id']] = categories[category['playlist_id']])
|
|
77
|
+
return rankedCategories
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error('Fetch error:', error)
|
|
80
|
+
return null
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Fetches the completion status of a specific lesson for the current user.
|
|
86
|
+
*
|
|
87
|
+
* @param {brand} brand - brand of the content to filter
|
|
88
|
+
* @param {Array<string>} content_ids - The IDs of the content to rank
|
|
89
|
+
* @returns {Promise<Object|null>} - Returns the content_ids sorted by rank (most significant first)
|
|
90
|
+
* @example
|
|
91
|
+
* rankItems('drumeo', ([111222, 23120, 402199])
|
|
92
|
+
* .then(status => console.log(status))
|
|
93
|
+
* .catch(error => console.error(error));
|
|
94
|
+
*/
|
|
95
|
+
export async function rankItems(brand, content_ids) {
|
|
96
|
+
if (content_ids.length === 0) {
|
|
97
|
+
return []
|
|
98
|
+
}
|
|
99
|
+
let data = {
|
|
100
|
+
'brand': brand,
|
|
101
|
+
'user_id': globalConfig.railcontentConfig.userId,
|
|
102
|
+
'content_ids': content_ids,
|
|
103
|
+
}
|
|
104
|
+
const url = `/rank_items/`
|
|
105
|
+
try {
|
|
106
|
+
const response = await fetchHandler(url, 'POST', data)
|
|
107
|
+
return response['ranked_content_ids']
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error('Fetch error:', error)
|
|
110
|
+
return null
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function fetchHandler(url, method = 'get', body = null) {
|
|
115
|
+
|
|
116
|
+
let headers = {
|
|
117
|
+
'Content-Type': 'application/json',
|
|
118
|
+
Accept: 'application/json',
|
|
119
|
+
'X-CSRF-TOKEN': globalConfig.recommendationsConfig.token,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const options = {
|
|
123
|
+
method,
|
|
124
|
+
headers,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (body) {
|
|
128
|
+
options.body = JSON.stringify(body)
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const response = await fetchAbsolute(url, options)
|
|
132
|
+
if (response.ok) {
|
|
133
|
+
return await response.json()
|
|
134
|
+
} else {
|
|
135
|
+
console.error(`Fetch error: ${method} ${url} ${response.status} ${response.statusText}`)
|
|
136
|
+
console.log(response)
|
|
137
|
+
}
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.error('Fetch error:', error)
|
|
140
|
+
}
|
|
141
|
+
return null
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
function fetchAbsolute(url, params) {
|
|
146
|
+
if (globalConfig.recommendationsConfig.token) {
|
|
147
|
+
params.headers['Authorization'] = `Bearer ${globalConfig.recommendationsConfig.token}`
|
|
148
|
+
}
|
|
149
|
+
if (globalConfig.recommendationsConfig.baseUrl) {
|
|
150
|
+
if (url.startsWith('/')) {
|
|
151
|
+
return fetch(globalConfig.recommendationsConfig.baseUrl + url, params)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return fetch(url, params)
|
|
155
|
+
}
|