@playcademy/sdk 0.11.1-beta.1 → 0.11.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1262,6 +1262,12 @@ interface TimebackUser extends TimebackUserContext {
1262
1262
  * Call `mastery.fetch()` to get mastery progress from the server.
1263
1263
  */
1264
1264
  mastery: TimebackUserMastery;
1265
+ /**
1266
+ * Highest-grade-mastered data for the current user.
1267
+ * Call `highestGradeMastered.fetch({ subject })` to get the student's
1268
+ * highest mastered grade for a subject.
1269
+ */
1270
+ highestGradeMastered: TimebackUserHighestGradeMastered;
1265
1271
  }
1266
1272
  /**
1267
1273
  * Mastery data access for the current user.
@@ -1302,6 +1308,17 @@ interface TimebackUserMastery {
1302
1308
  */
1303
1309
  fetch(options?: GetMasteryOptions): Promise<MasteryResponse>;
1304
1310
  }
1311
+ /**
1312
+ * Highest-grade-mastered data access for the current user.
1313
+ * Results are cached for 5 seconds to avoid redundant network requests.
1314
+ */
1315
+ interface TimebackUserHighestGradeMastered {
1316
+ /**
1317
+ * Fetch the highest grade the current student has mastered for a subject.
1318
+ * Results are cached for 5 seconds (use `force: true` to bypass).
1319
+ */
1320
+ fetch(options: GetHighestGradeMasteredOptions): Promise<HighestGradeMasteredResponse>;
1321
+ }
1305
1322
  /**
1306
1323
  * Options for querying student XP.
1307
1324
  */
@@ -1328,6 +1345,15 @@ interface GetMasteryOptions {
1328
1345
  /** Bypass cache and fetch fresh data (default: false) */
1329
1346
  force?: boolean;
1330
1347
  }
1348
+ /**
1349
+ * Options for querying highest grade mastered.
1350
+ */
1351
+ interface GetHighestGradeMasteredOptions {
1352
+ /** Subject to query */
1353
+ subject: TimebackSubject;
1354
+ /** Bypass cache and fetch fresh data (default: false) */
1355
+ force?: boolean;
1356
+ }
1331
1357
  /**
1332
1358
  * XP data for a single course.
1333
1359
  */
@@ -1366,6 +1392,13 @@ interface MasteryResponse {
1366
1392
  totalMasterableUnits: number;
1367
1393
  courses?: CourseMastery[];
1368
1394
  }
1395
+ /**
1396
+ * Response from highest-grade-mastered query.
1397
+ */
1398
+ interface HighestGradeMasteredResponse {
1399
+ subject: TimebackSubject;
1400
+ highestGradeMastered: TimebackGrade | null;
1401
+ }
1369
1402
 
1370
1403
  /**
1371
1404
  * Core client configuration and lifecycle types
package/dist/index.js CHANGED
@@ -1146,6 +1146,7 @@ var TIMEBACK_ROUTES = {
1146
1146
  END_ACTIVITY: "/integrations/timeback/end-activity",
1147
1147
  GET_XP: "/integrations/timeback/xp",
1148
1148
  GET_MASTERY: "/integrations/timeback/mastery",
1149
+ GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
1149
1150
  HEARTBEAT: "/integrations/timeback/heartbeat",
1150
1151
  ADVANCE_COURSE: "/integrations/timeback/advance-course",
1151
1152
  UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
@@ -1801,6 +1802,10 @@ function createTimebackEngine(client) {
1801
1802
  ttl: 5000,
1802
1803
  keyPrefix: "game.timeback.mastery"
1803
1804
  });
1805
+ const highestGradeMasteredCache = createTTLCache({
1806
+ ttl: 5000,
1807
+ keyPrefix: "game.timeback.highestGradeMastered"
1808
+ });
1804
1809
  const enrollmentsCache = createTTLCache({
1805
1810
  ttl: 5 * 60 * 1000,
1806
1811
  keyPrefix: "game.timeback.enrollments"
@@ -1809,6 +1814,7 @@ function createTimebackEngine(client) {
1809
1814
  userCache.clear("current");
1810
1815
  enrollmentsCache.clear("current");
1811
1816
  xpCache.clear();
1817
+ highestGradeMasteredCache.clear();
1812
1818
  try {
1813
1819
  await userStore.refresh();
1814
1820
  } catch {}
@@ -1896,6 +1902,14 @@ function createTimebackEngine(client) {
1896
1902
  return client["requestGameBackend"](endpoint, "GET");
1897
1903
  }, { force: options.force });
1898
1904
  }
1905
+ },
1906
+ highestGradeMastered: {
1907
+ fetch: (options) => highestGradeMasteredCache.get(options.subject, async () => {
1908
+ const params = new URLSearchParams;
1909
+ params.set("subject", options.subject);
1910
+ const endpoint = `${TIMEBACK_ROUTES.GET_HIGHEST_GRADE_MASTERED}?${params.toString()}`;
1911
+ return client["requestGameBackend"](endpoint, "GET");
1912
+ }, { force: options.force })
1899
1913
  }
1900
1914
  },
1901
1915
  activity: {
@@ -1993,6 +2007,17 @@ function createTimebackNamespace(client) {
1993
2007
  }
1994
2008
  return engine.user.mastery.fetch(options);
1995
2009
  }
2010
+ },
2011
+ highestGradeMastered: {
2012
+ fetch: async (options) => {
2013
+ if (!options?.subject) {
2014
+ throw new Error("subject is required");
2015
+ }
2016
+ if (!isValidSubject(options.subject)) {
2017
+ throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
2018
+ }
2019
+ return engine.user.highestGradeMastered.fetch(options);
2020
+ }
1996
2021
  }
1997
2022
  };
1998
2023
  },
@@ -1110,6 +1110,12 @@ interface TimebackUser extends TimebackUserContext {
1110
1110
  * Call `mastery.fetch()` to get mastery progress from the server.
1111
1111
  */
1112
1112
  mastery: TimebackUserMastery;
1113
+ /**
1114
+ * Highest-grade-mastered data for the current user.
1115
+ * Call `highestGradeMastered.fetch({ subject })` to get the student's
1116
+ * highest mastered grade for a subject.
1117
+ */
1118
+ highestGradeMastered: TimebackUserHighestGradeMastered;
1113
1119
  }
1114
1120
  /**
1115
1121
  * Mastery data access for the current user.
@@ -1150,6 +1156,17 @@ interface TimebackUserMastery {
1150
1156
  */
1151
1157
  fetch(options?: GetMasteryOptions): Promise<MasteryResponse>;
1152
1158
  }
1159
+ /**
1160
+ * Highest-grade-mastered data access for the current user.
1161
+ * Results are cached for 5 seconds to avoid redundant network requests.
1162
+ */
1163
+ interface TimebackUserHighestGradeMastered {
1164
+ /**
1165
+ * Fetch the highest grade the current student has mastered for a subject.
1166
+ * Results are cached for 5 seconds (use `force: true` to bypass).
1167
+ */
1168
+ fetch(options: GetHighestGradeMasteredOptions): Promise<HighestGradeMasteredResponse>;
1169
+ }
1153
1170
  /**
1154
1171
  * Options for querying student XP.
1155
1172
  */
@@ -1176,6 +1193,15 @@ interface GetMasteryOptions {
1176
1193
  /** Bypass cache and fetch fresh data (default: false) */
1177
1194
  force?: boolean;
1178
1195
  }
1196
+ /**
1197
+ * Options for querying highest grade mastered.
1198
+ */
1199
+ interface GetHighestGradeMasteredOptions {
1200
+ /** Subject to query */
1201
+ subject: TimebackSubject;
1202
+ /** Bypass cache and fetch fresh data (default: false) */
1203
+ force?: boolean;
1204
+ }
1179
1205
  /**
1180
1206
  * XP data for a single course.
1181
1207
  */
@@ -1214,6 +1240,13 @@ interface MasteryResponse {
1214
1240
  totalMasterableUnits: number;
1215
1241
  courses?: CourseMastery[];
1216
1242
  }
1243
+ /**
1244
+ * Response from highest-grade-mastered query.
1245
+ */
1246
+ interface HighestGradeMasteredResponse {
1247
+ subject: TimebackSubject;
1248
+ highestGradeMastered: TimebackGrade | null;
1249
+ }
1217
1250
 
1218
1251
  /**
1219
1252
  * Core client configuration and lifecycle types
@@ -3104,4 +3137,4 @@ declare class PlaycademyInternalClient extends PlaycademyBaseClient {
3104
3137
  }
3105
3138
 
3106
3139
  export { ApiError, MessageEvents, PlaycademyInternalClient as PlaycademyClient, PlaycademyError, PlaycademyInternalClient, extractApiErrorInfo, messaging };
3107
- export type { ApiErrorCode, ApiErrorInfo, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, ClientConfig, ClientEvents, CourseMastery, CourseXp, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, ErrorResponseBody, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameRow as GameRecord, GameTokenResponse, GetMasteryOptions, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LoginResponse, MasteryResponse, MessageEventMap, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, ScoreSubmission, StartActivityOptions, StartActivityResult, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserMastery, TimebackUserRefreshField, TimebackUserRefreshOptions, TimebackUserXp, TokenRefreshPayload, TokenType, UpsertGameMetadataInput, UserRow as User, XpResponse };
3140
+ export type { ApiErrorCode, ApiErrorInfo, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, ClientConfig, ClientEvents, CourseMastery, CourseXp, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, ErrorResponseBody, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameRow as GameRecord, GameTokenResponse, GetHighestGradeMasteredOptions, GetMasteryOptions, GetXpOptions, HighestGradeMasteredResponse, HostedGame, InitErrorPayload, InitPayload, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LoginResponse, MasteryResponse, MessageEventMap, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, ScoreSubmission, StartActivityOptions, StartActivityResult, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserHighestGradeMastered, TimebackUserMastery, TimebackUserRefreshField, TimebackUserRefreshOptions, TimebackUserXp, TokenRefreshPayload, TokenType, UpsertGameMetadataInput, UserRow as User, XpResponse };
package/dist/internal.js CHANGED
@@ -1146,6 +1146,7 @@ var TIMEBACK_ROUTES = {
1146
1146
  END_ACTIVITY: "/integrations/timeback/end-activity",
1147
1147
  GET_XP: "/integrations/timeback/xp",
1148
1148
  GET_MASTERY: "/integrations/timeback/mastery",
1149
+ GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
1149
1150
  HEARTBEAT: "/integrations/timeback/heartbeat",
1150
1151
  ADVANCE_COURSE: "/integrations/timeback/advance-course",
1151
1152
  UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
@@ -1801,6 +1802,10 @@ function createTimebackEngine(client) {
1801
1802
  ttl: 5000,
1802
1803
  keyPrefix: "game.timeback.mastery"
1803
1804
  });
1805
+ const highestGradeMasteredCache = createTTLCache({
1806
+ ttl: 5000,
1807
+ keyPrefix: "game.timeback.highestGradeMastered"
1808
+ });
1804
1809
  const enrollmentsCache = createTTLCache({
1805
1810
  ttl: 5 * 60 * 1000,
1806
1811
  keyPrefix: "game.timeback.enrollments"
@@ -1809,6 +1814,7 @@ function createTimebackEngine(client) {
1809
1814
  userCache.clear("current");
1810
1815
  enrollmentsCache.clear("current");
1811
1816
  xpCache.clear();
1817
+ highestGradeMasteredCache.clear();
1812
1818
  try {
1813
1819
  await userStore.refresh();
1814
1820
  } catch {}
@@ -1896,6 +1902,14 @@ function createTimebackEngine(client) {
1896
1902
  return client["requestGameBackend"](endpoint, "GET");
1897
1903
  }, { force: options.force });
1898
1904
  }
1905
+ },
1906
+ highestGradeMastered: {
1907
+ fetch: (options) => highestGradeMasteredCache.get(options.subject, async () => {
1908
+ const params = new URLSearchParams;
1909
+ params.set("subject", options.subject);
1910
+ const endpoint = `${TIMEBACK_ROUTES.GET_HIGHEST_GRADE_MASTERED}?${params.toString()}`;
1911
+ return client["requestGameBackend"](endpoint, "GET");
1912
+ }, { force: options.force })
1899
1913
  }
1900
1914
  },
1901
1915
  activity: {
@@ -1993,6 +2007,17 @@ function createTimebackNamespace(client) {
1993
2007
  }
1994
2008
  return engine.user.mastery.fetch(options);
1995
2009
  }
2010
+ },
2011
+ highestGradeMastered: {
2012
+ fetch: async (options) => {
2013
+ if (!options?.subject) {
2014
+ throw new Error("subject is required");
2015
+ }
2016
+ if (!isValidSubject(options.subject)) {
2017
+ throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
2018
+ }
2019
+ return engine.user.highestGradeMastered.fetch(options);
2020
+ }
1996
2021
  }
1997
2022
  };
1998
2023
  },
@@ -303,6 +303,9 @@ declare class PlaycademyClient {
303
303
  subject?: string;
304
304
  include?: 'perCourse'[];
305
305
  }) => Promise<_playcademy_types.StudentMasteryResponse>;
306
+ getStudentHighestGradeMastered: (studentId: string, options: {
307
+ subject: string;
308
+ }) => Promise<_playcademy_types.StudentHighestGradeMasteredResponse>;
306
309
  };
307
310
  }
308
311
 
@@ -110,6 +110,16 @@ function createTimebackNamespace(client) {
110
110
  const queryString = params.toString();
111
111
  const endpoint = `/api/timeback/student-mastery/${studentId}?${queryString}`;
112
112
  return client["request"](endpoint, "GET");
113
+ },
114
+ getStudentHighestGradeMastered: async (studentId, options) => {
115
+ if (!isValidSubject(options.subject)) {
116
+ throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
117
+ }
118
+ const params = new URLSearchParams;
119
+ params.set("gameId", client.gameId);
120
+ params.set("subject", options.subject);
121
+ const endpoint = `/api/timeback/student-highest-grade-mastered/${encodeURIComponent(studentId)}?${params.toString()}`;
122
+ return client["request"](endpoint, "GET");
113
123
  }
114
124
  };
115
125
  }
package/dist/server.d.ts CHANGED
@@ -303,6 +303,9 @@ declare class PlaycademyClient$1 {
303
303
  subject?: string;
304
304
  include?: 'perCourse'[];
305
305
  }) => Promise<_playcademy_types.StudentMasteryResponse>;
306
+ getStudentHighestGradeMastered: (studentId: string, options: {
307
+ subject: string;
308
+ }) => Promise<_playcademy_types.StudentHighestGradeMasteredResponse>;
306
309
  };
307
310
  }
308
311
 
package/dist/server.js CHANGED
@@ -299,6 +299,16 @@ function createTimebackNamespace(client) {
299
299
  const queryString = params.toString();
300
300
  const endpoint = `/api/timeback/student-mastery/${studentId}?${queryString}`;
301
301
  return client["request"](endpoint, "GET");
302
+ },
303
+ getStudentHighestGradeMastered: async (studentId, options) => {
304
+ if (!isValidSubject(options.subject)) {
305
+ throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
306
+ }
307
+ const params = new URLSearchParams;
308
+ params.set("gameId", client.gameId);
309
+ params.set("subject", options.subject);
310
+ const endpoint = `/api/timeback/student-highest-grade-mastered/${encodeURIComponent(studentId)}?${params.toString()}`;
311
+ return client["request"](endpoint, "GET");
302
312
  }
303
313
  };
304
314
  }
package/dist/types.d.ts CHANGED
@@ -1619,6 +1619,12 @@ interface TimebackUser extends TimebackUserContext {
1619
1619
  * Call `mastery.fetch()` to get mastery progress from the server.
1620
1620
  */
1621
1621
  mastery: TimebackUserMastery;
1622
+ /**
1623
+ * Highest-grade-mastered data for the current user.
1624
+ * Call `highestGradeMastered.fetch({ subject })` to get the student's
1625
+ * highest mastered grade for a subject.
1626
+ */
1627
+ highestGradeMastered: TimebackUserHighestGradeMastered;
1622
1628
  }
1623
1629
  /**
1624
1630
  * Mastery data access for the current user.
@@ -1659,6 +1665,17 @@ interface TimebackUserMastery {
1659
1665
  */
1660
1666
  fetch(options?: GetMasteryOptions): Promise<MasteryResponse>;
1661
1667
  }
1668
+ /**
1669
+ * Highest-grade-mastered data access for the current user.
1670
+ * Results are cached for 5 seconds to avoid redundant network requests.
1671
+ */
1672
+ interface TimebackUserHighestGradeMastered {
1673
+ /**
1674
+ * Fetch the highest grade the current student has mastered for a subject.
1675
+ * Results are cached for 5 seconds (use `force: true` to bypass).
1676
+ */
1677
+ fetch(options: GetHighestGradeMasteredOptions): Promise<HighestGradeMasteredResponse>;
1678
+ }
1662
1679
  /**
1663
1680
  * Options for querying student XP.
1664
1681
  */
@@ -1685,6 +1702,15 @@ interface GetMasteryOptions {
1685
1702
  /** Bypass cache and fetch fresh data (default: false) */
1686
1703
  force?: boolean;
1687
1704
  }
1705
+ /**
1706
+ * Options for querying highest grade mastered.
1707
+ */
1708
+ interface GetHighestGradeMasteredOptions {
1709
+ /** Subject to query */
1710
+ subject: TimebackSubject;
1711
+ /** Bypass cache and fetch fresh data (default: false) */
1712
+ force?: boolean;
1713
+ }
1688
1714
  /**
1689
1715
  * XP data for a single course.
1690
1716
  */
@@ -1723,6 +1749,13 @@ interface MasteryResponse {
1723
1749
  totalMasterableUnits: number;
1724
1750
  courses?: CourseMastery[];
1725
1751
  }
1752
+ /**
1753
+ * Response from highest-grade-mastered query.
1754
+ */
1755
+ interface HighestGradeMasteredResponse {
1756
+ subject: TimebackSubject;
1757
+ highestGradeMastered: TimebackGrade | null;
1758
+ }
1726
1759
 
1727
1760
  /**
1728
1761
  * Core client configuration and lifecycle types
@@ -2148,4 +2181,4 @@ interface AssessmentBankStatus {
2148
2181
  }
2149
2182
 
2150
2183
  export { PlaycademyClient };
2151
- export type { AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, ClientConfig, ClientEvents, CourseMastery, CourseXp, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameRow as GameRecord, GameTokenResponse, GetMasteryOptions, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LoginResponse, MasteryResponse, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, ScoreSubmission, StartActivityOptions, StartActivityResult, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserMastery, TimebackUserRefreshField, TimebackUserRefreshOptions, TimebackUserXp, TokenRefreshPayload, TokenType, UpsertGameMetadataInput, UserRow as User, XpResponse };
2184
+ export type { AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, ClientConfig, ClientEvents, CourseMastery, CourseXp, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameRow as GameRecord, GameTokenResponse, GetHighestGradeMasteredOptions, GetMasteryOptions, GetXpOptions, HighestGradeMasteredResponse, HostedGame, InitErrorPayload, InitPayload, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LoginResponse, MasteryResponse, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, ScoreSubmission, StartActivityOptions, StartActivityResult, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserHighestGradeMastered, TimebackUserMastery, TimebackUserRefreshField, TimebackUserRefreshOptions, TimebackUserXp, TokenRefreshPayload, TokenType, UpsertGameMetadataInput, UserRow as User, XpResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/sdk",
3
- "version": "0.11.1-beta.1",
3
+ "version": "0.11.1-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {