@playcademy/sdk 0.7.3 → 0.7.4-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.js CHANGED
@@ -1692,34 +1692,47 @@ function createTimebackActivityTracker(client) {
1692
1692
  activity.windowPausedAtStart = pausedAtReset;
1693
1693
  startHeartbeatInterval(activity);
1694
1694
  }
1695
- function armPausedHeartbeatTimeout(activity) {
1695
+ function markPausedHeartbeatTimedOut(activity) {
1696
+ activity.pausedHeartbeatTimeoutId = null;
1697
+ activity.pausedHeartbeatTimedOut = true;
1698
+ stopHeartbeatInterval(activity);
1699
+ }
1700
+ function armPausedHeartbeatTimeout(activity, startedAt = Date.now()) {
1696
1701
  if (activity.pausedHeartbeatTimeoutMs === Infinity) {
1697
1702
  return;
1698
1703
  }
1699
1704
  clearPausedHeartbeatTimeout(activity);
1705
+ const now = Date.now();
1706
+ const elapsedPauseMs = Math.max(0, now - Math.min(startedAt, now));
1707
+ const remainingTimeoutMs = activity.pausedHeartbeatTimeoutMs - elapsedPauseMs;
1708
+ if (remainingTimeoutMs <= 0) {
1709
+ markPausedHeartbeatTimedOut(activity);
1710
+ return;
1711
+ }
1700
1712
  const trackedActivity = activity;
1701
1713
  activity.pausedHeartbeatTimeoutId = setTimeout(() => {
1702
1714
  if (currentActivity !== trackedActivity) {
1703
1715
  return;
1704
1716
  }
1705
- trackedActivity.pausedHeartbeatTimeoutId = null;
1706
- trackedActivity.pausedHeartbeatTimedOut = true;
1707
- stopHeartbeatInterval(trackedActivity);
1708
- }, activity.pausedHeartbeatTimeoutMs);
1717
+ markPausedHeartbeatTimedOut(trackedActivity);
1718
+ }, remainingTimeoutMs);
1709
1719
  }
1710
- function addPauseReason(reason) {
1720
+ function addPauseReason(reason, startedAt = Date.now()) {
1711
1721
  if (!currentActivity) {
1712
1722
  return;
1713
1723
  }
1724
+ if (reason !== "inactivity") {
1725
+ applyOverdueInactivity();
1726
+ }
1714
1727
  const wasPaused = currentActivity.pauseReasons.size > 0;
1715
1728
  const wasAutoPaused = hasAutoPauseReason(currentActivity);
1716
1729
  const alreadyHadReason = currentActivity.pauseReasons.has(reason);
1717
1730
  currentActivity.pauseReasons.add(reason);
1718
1731
  if (!wasPaused && currentActivity.pauseReasons.size > 0) {
1719
- currentActivity.pauseStartTime = Date.now();
1732
+ currentActivity.pauseStartTime = Math.min(startedAt, Date.now());
1720
1733
  }
1721
1734
  if (isAutoPauseReason(reason) && !alreadyHadReason && !wasAutoPaused) {
1722
- armPausedHeartbeatTimeout(currentActivity);
1735
+ armPausedHeartbeatTimeout(currentActivity, startedAt);
1723
1736
  }
1724
1737
  syncInactivityTracking();
1725
1738
  }
@@ -1772,16 +1785,31 @@ function createTimebackActivityTracker(client) {
1772
1785
  }
1773
1786
  clearInactivityTimeout(activity);
1774
1787
  const trackedActivity = activity;
1775
- activity.inactivityTimerStartedAt = Date.now();
1788
+ const timerStartedAt = Date.now();
1789
+ const inactivityStartedAt = timerStartedAt + trackedActivity.remainingInactivityMs;
1790
+ activity.inactivityTimerStartedAt = timerStartedAt;
1776
1791
  activity.inactivityTimeoutId = setTimeout(() => {
1777
1792
  if (currentActivity !== trackedActivity) {
1778
1793
  return;
1779
1794
  }
1780
1795
  trackedActivity.remainingInactivityMs = 0;
1781
1796
  clearInactivityTimeout(trackedActivity);
1782
- addPauseReason("inactivity");
1797
+ addPauseReason("inactivity", inactivityStartedAt);
1783
1798
  }, trackedActivity.remainingInactivityMs);
1784
1799
  }
1800
+ function applyOverdueInactivity(now = Date.now()) {
1801
+ const activity = currentActivity;
1802
+ if (!activity || activity.inactivityTimerStartedAt === null || activity.pauseReasons.has("inactivity")) {
1803
+ return;
1804
+ }
1805
+ const inactivityStartedAt = activity.inactivityTimerStartedAt + activity.remainingInactivityMs;
1806
+ if (now < inactivityStartedAt) {
1807
+ return;
1808
+ }
1809
+ activity.remainingInactivityMs = 0;
1810
+ clearInactivityTimeout(activity);
1811
+ addPauseReason("inactivity", inactivityStartedAt);
1812
+ }
1785
1813
  function syncInactivityTracking() {
1786
1814
  const activity = currentActivity;
1787
1815
  if (!activity) {
@@ -1802,6 +1830,7 @@ function createTimebackActivityTracker(client) {
1802
1830
  activity.remainingInactivityMs = activity.inactivityTimeoutMs;
1803
1831
  }
1804
1832
  function handleUserInteraction() {
1833
+ applyOverdueInactivity();
1805
1834
  const activity = currentActivity;
1806
1835
  if (!activity || activity.inactivityTimeoutMs === Infinity || isDocumentHidden()) {
1807
1836
  return;
@@ -1840,6 +1869,7 @@ function createTimebackActivityTracker(client) {
1840
1869
  };
1841
1870
  }
1842
1871
  async function flushHeartbeat(isFinal) {
1872
+ applyOverdueInactivity();
1843
1873
  const activity = currentActivity;
1844
1874
  if (!activity) {
1845
1875
  return;
@@ -1860,6 +1890,7 @@ function createTimebackActivityTracker(client) {
1860
1890
  });
1861
1891
  }
1862
1892
  function handlePageHide() {
1893
+ applyOverdueInactivity();
1863
1894
  const activity = currentActivity;
1864
1895
  if (!activity) {
1865
1896
  return;
@@ -1999,6 +2030,7 @@ function createTimebackActivityTracker(client) {
1999
2030
  throw new Error("No activity in progress. Call startActivity() before endActivity().");
2000
2031
  }
2001
2032
  const activity = currentActivity;
2033
+ applyOverdueInactivity();
2002
2034
  cleanupListeners();
2003
2035
  await flushHeartbeat(true);
2004
2036
  if (activity.pauseStartTime !== null) {
@@ -733,6 +733,53 @@ interface QtiTestQuestionsResponse {
733
733
  questions: QtiTestQuestionRef[];
734
734
  }
735
735
 
736
+ /**
737
+ * Game-side learning metrics for a single student.
738
+ *
739
+ * Returned by opted-in game workers from their reserved
740
+ * `/__playcademy/metrics` route.
741
+ */
742
+ interface GameMetricsResponse {
743
+ /** Student identifier (Playcademy user ID). */
744
+ studentId: string;
745
+ /** Student email, when available to the game. */
746
+ email?: string;
747
+ /** Per-course metrics grouped by TimeBack grade and subject. */
748
+ courses: GameCourseMetrics[];
749
+ }
750
+ interface GameCourseMetrics {
751
+ /** Grade level matching the game's TimeBack integration. */
752
+ grade: TimebackGrade;
753
+ /** Subject matching the game's TimeBack integration. */
754
+ subject: TimebackSubject;
755
+ /** Total XP the game has recorded for this student in this course. */
756
+ totalXp: number;
757
+ /** Mastered units the game has recorded for this course. */
758
+ masteredUnits: number;
759
+ /** Total active time in seconds the game has recorded for this course. */
760
+ activeTimeSeconds: number;
761
+ /** Optional per-activity breakdown. */
762
+ activities?: GameActivityMetrics[];
763
+ }
764
+ interface GameActivityMetrics {
765
+ activityId: string;
766
+ activityName?: string;
767
+ totalXp: number;
768
+ masteredUnits: number;
769
+ activeTimeSeconds: number;
770
+ completionCount: number;
771
+ lastCompletedAt?: string;
772
+ }
773
+ type GameMetricsUnsupportedReason = 'no_timeback_integration' | 'no_active_deployment' | 'route_not_implemented' | 'fetch_failed' | 'invalid_response';
774
+ type GameMetricsProxyResponse = {
775
+ supported: true;
776
+ metrics: GameMetricsResponse;
777
+ } | {
778
+ supported: false;
779
+ reason: GameMetricsUnsupportedReason;
780
+ details?: string;
781
+ };
782
+
736
783
  /**
737
784
  * Achievement Types
738
785
  *
@@ -7757,4 +7804,4 @@ declare class PlaycademyInternalClient extends PlaycademyBaseClient {
7757
7804
  }
7758
7805
 
7759
7806
  export { AchievementCompletionType, ApiError, ConnectionManager, ConnectionMonitor, MessageEvents, NotificationStatus, NotificationType, PlaycademyInternalClient as PlaycademyClient, PlaycademyError, PlaycademyInternalClient, extractApiErrorInfo, messaging };
7760
- export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, ApiErrorCode, ApiErrorInfo, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionMonitorConfig, ConnectionState, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, ErrorResponseBody, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, MessageEventMap, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, QtiTestQuestionRef, QtiTestQuestionsResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
7807
+ export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, ApiErrorCode, ApiErrorInfo, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionMonitorConfig, ConnectionState, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, ErrorResponseBody, EventListeners, ExternalGame, FetchedGame, Game, GameActivityMetrics, GameContextPayload, GameCourseMetrics, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, MessageEventMap, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, QtiTestQuestionRef, QtiTestQuestionsResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
package/dist/internal.js CHANGED
@@ -1692,34 +1692,47 @@ function createTimebackActivityTracker(client) {
1692
1692
  activity.windowPausedAtStart = pausedAtReset;
1693
1693
  startHeartbeatInterval(activity);
1694
1694
  }
1695
- function armPausedHeartbeatTimeout(activity) {
1695
+ function markPausedHeartbeatTimedOut(activity) {
1696
+ activity.pausedHeartbeatTimeoutId = null;
1697
+ activity.pausedHeartbeatTimedOut = true;
1698
+ stopHeartbeatInterval(activity);
1699
+ }
1700
+ function armPausedHeartbeatTimeout(activity, startedAt = Date.now()) {
1696
1701
  if (activity.pausedHeartbeatTimeoutMs === Infinity) {
1697
1702
  return;
1698
1703
  }
1699
1704
  clearPausedHeartbeatTimeout(activity);
1705
+ const now = Date.now();
1706
+ const elapsedPauseMs = Math.max(0, now - Math.min(startedAt, now));
1707
+ const remainingTimeoutMs = activity.pausedHeartbeatTimeoutMs - elapsedPauseMs;
1708
+ if (remainingTimeoutMs <= 0) {
1709
+ markPausedHeartbeatTimedOut(activity);
1710
+ return;
1711
+ }
1700
1712
  const trackedActivity = activity;
1701
1713
  activity.pausedHeartbeatTimeoutId = setTimeout(() => {
1702
1714
  if (currentActivity !== trackedActivity) {
1703
1715
  return;
1704
1716
  }
1705
- trackedActivity.pausedHeartbeatTimeoutId = null;
1706
- trackedActivity.pausedHeartbeatTimedOut = true;
1707
- stopHeartbeatInterval(trackedActivity);
1708
- }, activity.pausedHeartbeatTimeoutMs);
1717
+ markPausedHeartbeatTimedOut(trackedActivity);
1718
+ }, remainingTimeoutMs);
1709
1719
  }
1710
- function addPauseReason(reason) {
1720
+ function addPauseReason(reason, startedAt = Date.now()) {
1711
1721
  if (!currentActivity) {
1712
1722
  return;
1713
1723
  }
1724
+ if (reason !== "inactivity") {
1725
+ applyOverdueInactivity();
1726
+ }
1714
1727
  const wasPaused = currentActivity.pauseReasons.size > 0;
1715
1728
  const wasAutoPaused = hasAutoPauseReason(currentActivity);
1716
1729
  const alreadyHadReason = currentActivity.pauseReasons.has(reason);
1717
1730
  currentActivity.pauseReasons.add(reason);
1718
1731
  if (!wasPaused && currentActivity.pauseReasons.size > 0) {
1719
- currentActivity.pauseStartTime = Date.now();
1732
+ currentActivity.pauseStartTime = Math.min(startedAt, Date.now());
1720
1733
  }
1721
1734
  if (isAutoPauseReason(reason) && !alreadyHadReason && !wasAutoPaused) {
1722
- armPausedHeartbeatTimeout(currentActivity);
1735
+ armPausedHeartbeatTimeout(currentActivity, startedAt);
1723
1736
  }
1724
1737
  syncInactivityTracking();
1725
1738
  }
@@ -1772,16 +1785,31 @@ function createTimebackActivityTracker(client) {
1772
1785
  }
1773
1786
  clearInactivityTimeout(activity);
1774
1787
  const trackedActivity = activity;
1775
- activity.inactivityTimerStartedAt = Date.now();
1788
+ const timerStartedAt = Date.now();
1789
+ const inactivityStartedAt = timerStartedAt + trackedActivity.remainingInactivityMs;
1790
+ activity.inactivityTimerStartedAt = timerStartedAt;
1776
1791
  activity.inactivityTimeoutId = setTimeout(() => {
1777
1792
  if (currentActivity !== trackedActivity) {
1778
1793
  return;
1779
1794
  }
1780
1795
  trackedActivity.remainingInactivityMs = 0;
1781
1796
  clearInactivityTimeout(trackedActivity);
1782
- addPauseReason("inactivity");
1797
+ addPauseReason("inactivity", inactivityStartedAt);
1783
1798
  }, trackedActivity.remainingInactivityMs);
1784
1799
  }
1800
+ function applyOverdueInactivity(now = Date.now()) {
1801
+ const activity = currentActivity;
1802
+ if (!activity || activity.inactivityTimerStartedAt === null || activity.pauseReasons.has("inactivity")) {
1803
+ return;
1804
+ }
1805
+ const inactivityStartedAt = activity.inactivityTimerStartedAt + activity.remainingInactivityMs;
1806
+ if (now < inactivityStartedAt) {
1807
+ return;
1808
+ }
1809
+ activity.remainingInactivityMs = 0;
1810
+ clearInactivityTimeout(activity);
1811
+ addPauseReason("inactivity", inactivityStartedAt);
1812
+ }
1785
1813
  function syncInactivityTracking() {
1786
1814
  const activity = currentActivity;
1787
1815
  if (!activity) {
@@ -1802,6 +1830,7 @@ function createTimebackActivityTracker(client) {
1802
1830
  activity.remainingInactivityMs = activity.inactivityTimeoutMs;
1803
1831
  }
1804
1832
  function handleUserInteraction() {
1833
+ applyOverdueInactivity();
1805
1834
  const activity = currentActivity;
1806
1835
  if (!activity || activity.inactivityTimeoutMs === Infinity || isDocumentHidden()) {
1807
1836
  return;
@@ -1840,6 +1869,7 @@ function createTimebackActivityTracker(client) {
1840
1869
  };
1841
1870
  }
1842
1871
  async function flushHeartbeat(isFinal) {
1872
+ applyOverdueInactivity();
1843
1873
  const activity = currentActivity;
1844
1874
  if (!activity) {
1845
1875
  return;
@@ -1860,6 +1890,7 @@ function createTimebackActivityTracker(client) {
1860
1890
  });
1861
1891
  }
1862
1892
  function handlePageHide() {
1893
+ applyOverdueInactivity();
1863
1894
  const activity = currentActivity;
1864
1895
  if (!activity) {
1865
1896
  return;
@@ -1999,6 +2030,7 @@ function createTimebackActivityTracker(client) {
1999
2030
  throw new Error("No activity in progress. Call startActivity() before endActivity().");
2000
2031
  }
2001
2032
  const activity = currentActivity;
2033
+ applyOverdueInactivity();
2002
2034
  cleanupListeners();
2003
2035
  await flushHeartbeat(true);
2004
2036
  if (activity.pauseStartTime !== null) {
package/dist/types.d.ts CHANGED
@@ -401,6 +401,53 @@ interface QtiTestQuestionsResponse {
401
401
  questions: QtiTestQuestionRef[];
402
402
  }
403
403
 
404
+ /**
405
+ * Game-side learning metrics for a single student.
406
+ *
407
+ * Returned by opted-in game workers from their reserved
408
+ * `/__playcademy/metrics` route.
409
+ */
410
+ interface GameMetricsResponse {
411
+ /** Student identifier (Playcademy user ID). */
412
+ studentId: string;
413
+ /** Student email, when available to the game. */
414
+ email?: string;
415
+ /** Per-course metrics grouped by TimeBack grade and subject. */
416
+ courses: GameCourseMetrics[];
417
+ }
418
+ interface GameCourseMetrics {
419
+ /** Grade level matching the game's TimeBack integration. */
420
+ grade: TimebackGrade;
421
+ /** Subject matching the game's TimeBack integration. */
422
+ subject: TimebackSubject;
423
+ /** Total XP the game has recorded for this student in this course. */
424
+ totalXp: number;
425
+ /** Mastered units the game has recorded for this course. */
426
+ masteredUnits: number;
427
+ /** Total active time in seconds the game has recorded for this course. */
428
+ activeTimeSeconds: number;
429
+ /** Optional per-activity breakdown. */
430
+ activities?: GameActivityMetrics[];
431
+ }
432
+ interface GameActivityMetrics {
433
+ activityId: string;
434
+ activityName?: string;
435
+ totalXp: number;
436
+ masteredUnits: number;
437
+ activeTimeSeconds: number;
438
+ completionCount: number;
439
+ lastCompletedAt?: string;
440
+ }
441
+ type GameMetricsUnsupportedReason = 'no_timeback_integration' | 'no_active_deployment' | 'route_not_implemented' | 'fetch_failed' | 'invalid_response';
442
+ type GameMetricsProxyResponse = {
443
+ supported: true;
444
+ metrics: GameMetricsResponse;
445
+ } | {
446
+ supported: false;
447
+ reason: GameMetricsUnsupportedReason;
448
+ details?: string;
449
+ };
450
+
404
451
  /**
405
452
  * @fileoverview Server SDK Type Definitions
406
453
  *
@@ -6103,4 +6150,4 @@ interface AssessmentBankStatus {
6103
6150
  }
6104
6151
 
6105
6152
  export { AchievementCompletionType, NotificationStatus, NotificationType, PlaycademyClient };
6106
- export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, QtiTestQuestionRef, QtiTestQuestionsResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
6153
+ export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameActivityMetrics, GameContextPayload, GameCourseMetrics, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, QtiTestQuestionRef, QtiTestQuestionsResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/sdk",
3
- "version": "0.7.3",
3
+ "version": "0.7.4-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {