@contractspec/module.learning-journey 1.57.0 → 1.58.0

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 (140) hide show
  1. package/dist/browser/contracts/index.js +578 -0
  2. package/dist/browser/contracts/models.js +193 -0
  3. package/dist/browser/contracts/onboarding.js +417 -0
  4. package/dist/browser/contracts/operations.js +326 -0
  5. package/dist/browser/contracts/shared.js +5 -0
  6. package/dist/browser/docs/index.js +124 -0
  7. package/dist/browser/docs/learning-journey.docblock.js +124 -0
  8. package/dist/browser/engines/index.js +526 -0
  9. package/dist/browser/engines/srs.js +198 -0
  10. package/dist/browser/engines/streak.js +159 -0
  11. package/dist/browser/engines/xp.js +171 -0
  12. package/dist/browser/entities/ai.js +343 -0
  13. package/dist/browser/entities/course.js +276 -0
  14. package/dist/browser/entities/flashcard.js +222 -0
  15. package/dist/browser/entities/gamification.js +340 -0
  16. package/dist/browser/entities/index.js +2136 -0
  17. package/dist/browser/entities/learner.js +329 -0
  18. package/dist/browser/entities/onboarding.js +301 -0
  19. package/dist/browser/entities/quiz.js +304 -0
  20. package/dist/browser/events.js +423 -0
  21. package/dist/browser/index.js +3833 -0
  22. package/dist/browser/learning-journey.capability.js +40 -0
  23. package/dist/browser/learning-journey.feature.js +56 -0
  24. package/dist/browser/track-spec.js +0 -0
  25. package/dist/contracts/index.d.ts +5 -5
  26. package/dist/contracts/index.d.ts.map +1 -0
  27. package/dist/contracts/index.js +578 -5
  28. package/dist/contracts/models.d.ts +426 -431
  29. package/dist/contracts/models.d.ts.map +1 -1
  30. package/dist/contracts/models.js +178 -372
  31. package/dist/contracts/onboarding.d.ts +621 -627
  32. package/dist/contracts/onboarding.d.ts.map +1 -1
  33. package/dist/contracts/onboarding.js +404 -388
  34. package/dist/contracts/operations.d.ts +243 -249
  35. package/dist/contracts/operations.d.ts.map +1 -1
  36. package/dist/contracts/operations.js +324 -148
  37. package/dist/contracts/shared.d.ts +1 -4
  38. package/dist/contracts/shared.d.ts.map +1 -1
  39. package/dist/contracts/shared.js +6 -6
  40. package/dist/docs/index.d.ts +2 -1
  41. package/dist/docs/index.d.ts.map +1 -0
  42. package/dist/docs/index.js +125 -1
  43. package/dist/docs/learning-journey.docblock.d.ts +2 -1
  44. package/dist/docs/learning-journey.docblock.d.ts.map +1 -0
  45. package/dist/docs/learning-journey.docblock.js +47 -58
  46. package/dist/engines/index.d.ts +4 -4
  47. package/dist/engines/index.d.ts.map +1 -0
  48. package/dist/engines/index.js +526 -4
  49. package/dist/engines/srs.d.ts +89 -92
  50. package/dist/engines/srs.d.ts.map +1 -1
  51. package/dist/engines/srs.js +197 -217
  52. package/dist/engines/streak.d.ts +84 -87
  53. package/dist/engines/streak.d.ts.map +1 -1
  54. package/dist/engines/streak.js +158 -192
  55. package/dist/engines/xp.d.ts +80 -83
  56. package/dist/engines/xp.d.ts.map +1 -1
  57. package/dist/engines/xp.js +170 -211
  58. package/dist/entities/ai.d.ts +199 -204
  59. package/dist/entities/ai.d.ts.map +1 -1
  60. package/dist/entities/ai.js +336 -368
  61. package/dist/entities/course.d.ts +149 -154
  62. package/dist/entities/course.d.ts.map +1 -1
  63. package/dist/entities/course.js +267 -306
  64. package/dist/entities/flashcard.d.ts +144 -149
  65. package/dist/entities/flashcard.d.ts.map +1 -1
  66. package/dist/entities/flashcard.js +217 -243
  67. package/dist/entities/gamification.d.ts +197 -202
  68. package/dist/entities/gamification.d.ts.map +1 -1
  69. package/dist/entities/gamification.js +331 -382
  70. package/dist/entities/index.d.ts +613 -618
  71. package/dist/entities/index.d.ts.map +1 -1
  72. package/dist/entities/index.js +2135 -43
  73. package/dist/entities/learner.d.ts +191 -196
  74. package/dist/entities/learner.d.ts.map +1 -1
  75. package/dist/entities/learner.js +322 -357
  76. package/dist/entities/onboarding.d.ts +164 -169
  77. package/dist/entities/onboarding.d.ts.map +1 -1
  78. package/dist/entities/onboarding.js +296 -301
  79. package/dist/entities/quiz.d.ts +184 -189
  80. package/dist/entities/quiz.d.ts.map +1 -1
  81. package/dist/entities/quiz.js +296 -361
  82. package/dist/events.d.ts +608 -614
  83. package/dist/events.d.ts.map +1 -1
  84. package/dist/events.js +421 -687
  85. package/dist/index.d.ts +8 -20
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +3834 -22
  88. package/dist/learning-journey.capability.d.ts +3 -8
  89. package/dist/learning-journey.capability.d.ts.map +1 -1
  90. package/dist/learning-journey.capability.js +41 -46
  91. package/dist/learning-journey.feature.d.ts +1 -6
  92. package/dist/learning-journey.feature.d.ts.map +1 -1
  93. package/dist/learning-journey.feature.js +55 -155
  94. package/dist/node/contracts/index.js +578 -0
  95. package/dist/node/contracts/models.js +193 -0
  96. package/dist/node/contracts/onboarding.js +417 -0
  97. package/dist/node/contracts/operations.js +326 -0
  98. package/dist/node/contracts/shared.js +5 -0
  99. package/dist/node/docs/index.js +124 -0
  100. package/dist/node/docs/learning-journey.docblock.js +124 -0
  101. package/dist/node/engines/index.js +526 -0
  102. package/dist/node/engines/srs.js +198 -0
  103. package/dist/node/engines/streak.js +159 -0
  104. package/dist/node/engines/xp.js +171 -0
  105. package/dist/node/entities/ai.js +343 -0
  106. package/dist/node/entities/course.js +276 -0
  107. package/dist/node/entities/flashcard.js +222 -0
  108. package/dist/node/entities/gamification.js +340 -0
  109. package/dist/node/entities/index.js +2136 -0
  110. package/dist/node/entities/learner.js +329 -0
  111. package/dist/node/entities/onboarding.js +301 -0
  112. package/dist/node/entities/quiz.js +304 -0
  113. package/dist/node/events.js +423 -0
  114. package/dist/node/index.js +3833 -0
  115. package/dist/node/learning-journey.capability.js +40 -0
  116. package/dist/node/learning-journey.feature.js +56 -0
  117. package/dist/node/track-spec.js +0 -0
  118. package/dist/track-spec.d.ts +115 -118
  119. package/dist/track-spec.d.ts.map +1 -1
  120. package/dist/track-spec.js +1 -0
  121. package/package.json +237 -60
  122. package/dist/contracts/models.js.map +0 -1
  123. package/dist/contracts/onboarding.js.map +0 -1
  124. package/dist/contracts/operations.js.map +0 -1
  125. package/dist/contracts/shared.js.map +0 -1
  126. package/dist/docs/learning-journey.docblock.js.map +0 -1
  127. package/dist/engines/srs.js.map +0 -1
  128. package/dist/engines/streak.js.map +0 -1
  129. package/dist/engines/xp.js.map +0 -1
  130. package/dist/entities/ai.js.map +0 -1
  131. package/dist/entities/course.js.map +0 -1
  132. package/dist/entities/flashcard.js.map +0 -1
  133. package/dist/entities/gamification.js.map +0 -1
  134. package/dist/entities/index.js.map +0 -1
  135. package/dist/entities/learner.js.map +0 -1
  136. package/dist/entities/onboarding.js.map +0 -1
  137. package/dist/entities/quiz.js.map +0 -1
  138. package/dist/events.js.map +0 -1
  139. package/dist/learning-journey.capability.js.map +0 -1
  140. package/dist/learning-journey.feature.js.map +0 -1
@@ -1,97 +1,94 @@
1
- //#region src/engines/xp.d.ts
2
1
  /**
3
2
  * XP (Experience Points) Engine
4
3
  *
5
4
  * Calculates XP rewards for various learning activities.
6
5
  */
7
- type XPActivityType = 'lesson_complete' | 'quiz_pass' | 'quiz_perfect' | 'flashcard_review' | 'course_complete' | 'module_complete' | 'streak_bonus' | 'achievement_unlock' | 'daily_goal_complete' | 'first_lesson' | 'onboarding_step' | 'onboarding_complete';
8
- interface XPCalculationInput {
9
- /** Type of activity */
10
- activity: XPActivityType;
11
- /** Base XP for the activity (from content config) */
12
- baseXp?: number;
13
- /** Score achieved (0-100) for scored activities */
14
- score?: number;
15
- /** Current streak (for streak bonuses) */
16
- currentStreak?: number;
17
- /** Time spent in seconds */
18
- timeSpent?: number;
19
- /** Attempt number (for quizzes) */
20
- attemptNumber?: number;
21
- /** Whether this is a retry */
22
- isRetry?: boolean;
6
+ export type XPActivityType = 'lesson_complete' | 'quiz_pass' | 'quiz_perfect' | 'flashcard_review' | 'course_complete' | 'module_complete' | 'streak_bonus' | 'achievement_unlock' | 'daily_goal_complete' | 'first_lesson' | 'onboarding_step' | 'onboarding_complete';
7
+ export interface XPCalculationInput {
8
+ /** Type of activity */
9
+ activity: XPActivityType;
10
+ /** Base XP for the activity (from content config) */
11
+ baseXp?: number;
12
+ /** Score achieved (0-100) for scored activities */
13
+ score?: number;
14
+ /** Current streak (for streak bonuses) */
15
+ currentStreak?: number;
16
+ /** Time spent in seconds */
17
+ timeSpent?: number;
18
+ /** Attempt number (for quizzes) */
19
+ attemptNumber?: number;
20
+ /** Whether this is a retry */
21
+ isRetry?: boolean;
23
22
  }
24
- interface XPResult {
25
- /** Total XP earned */
26
- totalXp: number;
27
- /** Base XP before bonuses */
28
- baseXp: number;
29
- /** Breakdown of XP sources */
30
- breakdown: XPBreakdown[];
23
+ export interface XPResult {
24
+ /** Total XP earned */
25
+ totalXp: number;
26
+ /** Base XP before bonuses */
27
+ baseXp: number;
28
+ /** Breakdown of XP sources */
29
+ breakdown: XPBreakdown[];
31
30
  }
32
- interface XPBreakdown {
33
- /** Source of XP */
34
- source: string;
35
- /** XP amount */
36
- amount: number;
37
- /** Multiplier applied */
38
- multiplier?: number;
31
+ export interface XPBreakdown {
32
+ /** Source of XP */
33
+ source: string;
34
+ /** XP amount */
35
+ amount: number;
36
+ /** Multiplier applied */
37
+ multiplier?: number;
39
38
  }
40
- interface XPConfig {
41
- /** Base XP values for each activity */
42
- baseValues: Record<XPActivityType, number>;
43
- /** Score thresholds for bonus XP */
44
- scoreThresholds: {
45
- min: number;
46
- multiplier: number;
47
- }[];
48
- /** Streak bonus tiers */
49
- streakTiers: {
50
- days: number;
51
- bonus: number;
52
- }[];
53
- /** Perfect score bonus multiplier */
54
- perfectScoreMultiplier: number;
55
- /** First attempt bonus */
56
- firstAttemptBonus: number;
57
- /** Retry penalty multiplier */
58
- retryPenalty: number;
59
- /** Speed bonus (complete under expected time) */
60
- speedBonusMultiplier: number;
61
- /** Speed bonus threshold (percentage of expected time) */
62
- speedBonusThreshold: number;
39
+ export interface XPConfig {
40
+ /** Base XP values for each activity */
41
+ baseValues: Record<XPActivityType, number>;
42
+ /** Score thresholds for bonus XP */
43
+ scoreThresholds: {
44
+ min: number;
45
+ multiplier: number;
46
+ }[];
47
+ /** Streak bonus tiers */
48
+ streakTiers: {
49
+ days: number;
50
+ bonus: number;
51
+ }[];
52
+ /** Perfect score bonus multiplier */
53
+ perfectScoreMultiplier: number;
54
+ /** First attempt bonus */
55
+ firstAttemptBonus: number;
56
+ /** Retry penalty multiplier */
57
+ retryPenalty: number;
58
+ /** Speed bonus (complete under expected time) */
59
+ speedBonusMultiplier: number;
60
+ /** Speed bonus threshold (percentage of expected time) */
61
+ speedBonusThreshold: number;
63
62
  }
64
- declare const DEFAULT_XP_CONFIG: XPConfig;
65
- declare class XPEngine {
66
- private config;
67
- constructor(config?: Partial<XPConfig>);
68
- /**
69
- * Calculate XP for an activity.
70
- */
71
- calculate(input: XPCalculationInput): XPResult;
72
- /**
73
- * Calculate streak bonus XP.
74
- */
75
- calculateStreakBonus(currentStreak: number): XPResult;
76
- /**
77
- * Calculate XP needed for a level.
78
- */
79
- getXpForLevel(level: number): number;
80
- /**
81
- * Get level from total XP.
82
- */
83
- getLevelFromXp(totalXp: number): {
84
- level: number;
85
- xpInLevel: number;
86
- xpForNextLevel: number;
87
- };
88
- private getScoreMultiplier;
89
- private getStreakBonus;
63
+ export declare const DEFAULT_XP_CONFIG: XPConfig;
64
+ export declare class XPEngine {
65
+ private config;
66
+ constructor(config?: Partial<XPConfig>);
67
+ /**
68
+ * Calculate XP for an activity.
69
+ */
70
+ calculate(input: XPCalculationInput): XPResult;
71
+ /**
72
+ * Calculate streak bonus XP.
73
+ */
74
+ calculateStreakBonus(currentStreak: number): XPResult;
75
+ /**
76
+ * Calculate XP needed for a level.
77
+ */
78
+ getXpForLevel(level: number): number;
79
+ /**
80
+ * Get level from total XP.
81
+ */
82
+ getLevelFromXp(totalXp: number): {
83
+ level: number;
84
+ xpInLevel: number;
85
+ xpForNextLevel: number;
86
+ };
87
+ private getScoreMultiplier;
88
+ private getStreakBonus;
90
89
  }
91
90
  /**
92
91
  * Default XP engine instance.
93
92
  */
94
- declare const xpEngine: XPEngine;
95
- //#endregion
96
- export { DEFAULT_XP_CONFIG, XPActivityType, XPBreakdown, XPCalculationInput, XPConfig, XPEngine, XPResult, xpEngine };
93
+ export declare const xpEngine: XPEngine;
97
94
  //# sourceMappingURL=xp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"xp.d.ts","names":[],"sources":["../../src/engines/xp.ts"],"mappings":";;AAQA;;;;KAAY,cAAA;AAAA,UAcK,kBAAA;EAAkB;EAEjC,QAAA,EAAU,cAAA;EAAc;EAExB,MAAA;EAFU;EAIV,KAAA;EAAA;EAEA,aAAA;EAEA;EAAA,SAAA;EAIA;EAFA,aAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGe,QAAA;EAMO;EAJtB,OAAA;EAEA;EAAA,MAAA;EAEW;EAAX,SAAA,EAAW,WAAA;AAAA;AAAA,UAGI,WAAA;EAAW;EAE1B,MAAA;EAF0B;EAI1B,MAAA;EAAA;EAEA,UAAA;AAAA;AAAA,UAGe,QAAA;EAAA;EAEf,UAAA,EAAY,MAAA,CAAO,cAAA;;EAEnB,eAAA;IAAmB,GAAA;IAAa,UAAA;EAAA;EAAhC;EAEA,WAAA;IAAe,IAAA;IAAc,KAAA;EAAA;EAAA;EAE7B,sBAAA;EAEA;EAAA,iBAAA;EAIA;EAFA,YAAA;EAImB;EAFnB,oBAAA;EAOW;EALX,mBAAA;AAAA;AAAA,cAKW,iBAAA,EAAmB,QAAA;AAAA,cAyCnB,QAAA;EAAA,QACH,MAAA;cAEI,MAAA,GAAQ,OAAA,CAAQ,QAAA;;;;EAc5B,SAAA,CAAU,KAAA,EAAO,kBAAA,GAAqB,QAAA;EAAA;;;EAsFtC,oBAAA,CAAqB,aAAA,WAAwB,QAAA;EAtGrC;;;EAuHR,aAAA,CAAc,KAAA;EArHF;;;EAkIZ,cAAA,CAAe,OAAA;IACb,KAAA;IACA,SAAA;IACA,cAAA;EAAA;EAAA,QAsBM,kBAAA;EAAA,QASA,cAAA;AAAA;;;;cAaG,QAAA,EAAQ,QAAA"}
1
+ {"version":3,"file":"xp.d.ts","sourceRoot":"","sources":["../../src/engines/xp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,WAAW,GACX,cAAc,GACd,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,cAAc,GACd,oBAAoB,GACpB,qBAAqB,GACrB,cAAc,GACd,iBAAiB,GACjB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,QAAQ,EAAE,cAAc,CAAC;IACzB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC3C,oCAAoC;IACpC,eAAe,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,yBAAyB;IACzB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/C,qCAAqC;IACrC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,0BAA0B;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAID,eAAO,MAAM,iBAAiB,EAAE,QAqC/B,CAAC;AAIF,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAW;gBAEb,MAAM,GAAE,OAAO,CAAC,QAAQ,CAAM;IAW1C;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,QAAQ;IAmF9C;;OAEG;IACH,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ;IAcrD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAUpC;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB;IAqBD,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,cAAc;CAQvB;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,UAAiB,CAAC"}
@@ -1,213 +1,172 @@
1
- //#region src/engines/xp.ts
2
- const DEFAULT_XP_CONFIG = {
3
- baseValues: {
4
- lesson_complete: 10,
5
- quiz_pass: 20,
6
- quiz_perfect: 50,
7
- flashcard_review: 1,
8
- course_complete: 200,
9
- module_complete: 50,
10
- streak_bonus: 5,
11
- achievement_unlock: 0,
12
- daily_goal_complete: 15,
13
- first_lesson: 25,
14
- onboarding_step: 5,
15
- onboarding_complete: 50
16
- },
17
- scoreThresholds: [
18
- {
19
- min: 90,
20
- multiplier: 1.5
21
- },
22
- {
23
- min: 80,
24
- multiplier: 1.25
25
- },
26
- {
27
- min: 70,
28
- multiplier: 1
29
- },
30
- {
31
- min: 60,
32
- multiplier: .75
33
- },
34
- {
35
- min: 0,
36
- multiplier: .5
37
- }
38
- ],
39
- streakTiers: [
40
- {
41
- days: 365,
42
- bonus: 50
43
- },
44
- {
45
- days: 180,
46
- bonus: 30
47
- },
48
- {
49
- days: 90,
50
- bonus: 20
51
- },
52
- {
53
- days: 30,
54
- bonus: 15
55
- },
56
- {
57
- days: 14,
58
- bonus: 10
59
- },
60
- {
61
- days: 7,
62
- bonus: 5
63
- },
64
- {
65
- days: 3,
66
- bonus: 2
67
- },
68
- {
69
- days: 1,
70
- bonus: 0
71
- }
72
- ],
73
- perfectScoreMultiplier: 1.5,
74
- firstAttemptBonus: 10,
75
- retryPenalty: .5,
76
- speedBonusMultiplier: 1.2,
77
- speedBonusThreshold: .8
1
+ // @bun
2
+ // src/engines/xp.ts
3
+ var DEFAULT_XP_CONFIG = {
4
+ baseValues: {
5
+ lesson_complete: 10,
6
+ quiz_pass: 20,
7
+ quiz_perfect: 50,
8
+ flashcard_review: 1,
9
+ course_complete: 200,
10
+ module_complete: 50,
11
+ streak_bonus: 5,
12
+ achievement_unlock: 0,
13
+ daily_goal_complete: 15,
14
+ first_lesson: 25,
15
+ onboarding_step: 5,
16
+ onboarding_complete: 50
17
+ },
18
+ scoreThresholds: [
19
+ { min: 90, multiplier: 1.5 },
20
+ { min: 80, multiplier: 1.25 },
21
+ { min: 70, multiplier: 1 },
22
+ { min: 60, multiplier: 0.75 },
23
+ { min: 0, multiplier: 0.5 }
24
+ ],
25
+ streakTiers: [
26
+ { days: 365, bonus: 50 },
27
+ { days: 180, bonus: 30 },
28
+ { days: 90, bonus: 20 },
29
+ { days: 30, bonus: 15 },
30
+ { days: 14, bonus: 10 },
31
+ { days: 7, bonus: 5 },
32
+ { days: 3, bonus: 2 },
33
+ { days: 1, bonus: 0 }
34
+ ],
35
+ perfectScoreMultiplier: 1.5,
36
+ firstAttemptBonus: 10,
37
+ retryPenalty: 0.5,
38
+ speedBonusMultiplier: 1.2,
39
+ speedBonusThreshold: 0.8
78
40
  };
79
- var XPEngine = class {
80
- config;
81
- constructor(config = {}) {
82
- this.config = {
83
- ...DEFAULT_XP_CONFIG,
84
- ...config,
85
- baseValues: {
86
- ...DEFAULT_XP_CONFIG.baseValues,
87
- ...config.baseValues
88
- },
89
- scoreThresholds: config.scoreThresholds || DEFAULT_XP_CONFIG.scoreThresholds,
90
- streakTiers: config.streakTiers || DEFAULT_XP_CONFIG.streakTiers
91
- };
92
- }
93
- /**
94
- * Calculate XP for an activity.
95
- */
96
- calculate(input) {
97
- const breakdown = [];
98
- const baseXp = input.baseXp ?? this.config.baseValues[input.activity];
99
- let totalXp = baseXp;
100
- breakdown.push({
101
- source: "base",
102
- amount: baseXp
103
- });
104
- if (input.score !== void 0) {
105
- const scoreMultiplier = this.getScoreMultiplier(input.score);
106
- if (scoreMultiplier !== 1) {
107
- const scoreBonus = Math.round(baseXp * (scoreMultiplier - 1));
108
- totalXp += scoreBonus;
109
- breakdown.push({
110
- source: "score_bonus",
111
- amount: scoreBonus,
112
- multiplier: scoreMultiplier
113
- });
114
- }
115
- if (input.score === 100) {
116
- const perfectBonus = Math.round(baseXp * (this.config.perfectScoreMultiplier - 1));
117
- totalXp += perfectBonus;
118
- breakdown.push({
119
- source: "perfect_score",
120
- amount: perfectBonus,
121
- multiplier: this.config.perfectScoreMultiplier
122
- });
123
- }
124
- }
125
- if (input.attemptNumber === 1 && !input.isRetry) {
126
- totalXp += this.config.firstAttemptBonus;
127
- breakdown.push({
128
- source: "first_attempt",
129
- amount: this.config.firstAttemptBonus
130
- });
131
- }
132
- if (input.isRetry) {
133
- const penalty = Math.round(totalXp * (1 - this.config.retryPenalty));
134
- totalXp -= penalty;
135
- breakdown.push({
136
- source: "retry_penalty",
137
- amount: -penalty,
138
- multiplier: this.config.retryPenalty
139
- });
140
- }
141
- if (input.currentStreak && input.currentStreak > 0) {
142
- const streakBonus = this.getStreakBonus(input.currentStreak);
143
- if (streakBonus > 0) {
144
- totalXp += streakBonus;
145
- breakdown.push({
146
- source: "streak_bonus",
147
- amount: streakBonus
148
- });
149
- }
150
- }
151
- if (baseXp > 0) totalXp = Math.max(1, totalXp);
152
- return {
153
- totalXp: Math.round(totalXp),
154
- baseXp,
155
- breakdown
156
- };
157
- }
158
- /**
159
- * Calculate streak bonus XP.
160
- */
161
- calculateStreakBonus(currentStreak) {
162
- const bonus = this.getStreakBonus(currentStreak);
163
- return {
164
- totalXp: bonus,
165
- baseXp: bonus,
166
- breakdown: [{
167
- source: "streak_bonus",
168
- amount: bonus
169
- }]
170
- };
171
- }
172
- /**
173
- * Calculate XP needed for a level.
174
- */
175
- getXpForLevel(level) {
176
- if (level <= 1) return 0;
177
- return Math.round(100 * Math.pow(level - 1, 1.5));
178
- }
179
- /**
180
- * Get level from total XP.
181
- */
182
- getLevelFromXp(totalXp) {
183
- let level = 1;
184
- let xpRequired = this.getXpForLevel(level + 1);
185
- while (totalXp >= xpRequired && level < 1e3) {
186
- level++;
187
- xpRequired = this.getXpForLevel(level + 1);
188
- }
189
- const xpForCurrentLevel = this.getXpForLevel(level);
190
- const xpForNextLevel = this.getXpForLevel(level + 1);
191
- return {
192
- level,
193
- xpInLevel: totalXp - xpForCurrentLevel,
194
- xpForNextLevel: xpForNextLevel - xpForCurrentLevel
195
- };
196
- }
197
- getScoreMultiplier(score) {
198
- for (const threshold of this.config.scoreThresholds) if (score >= threshold.min) return threshold.multiplier;
199
- return 1;
200
- }
201
- getStreakBonus(streak) {
202
- for (const tier of this.config.streakTiers) if (streak >= tier.days) return tier.bonus;
203
- return 0;
204
- }
205
- };
206
- /**
207
- * Default XP engine instance.
208
- */
209
- const xpEngine = new XPEngine();
210
41
 
211
- //#endregion
212
- export { DEFAULT_XP_CONFIG, XPEngine, xpEngine };
213
- //# sourceMappingURL=xp.js.map
42
+ class XPEngine {
43
+ config;
44
+ constructor(config = {}) {
45
+ this.config = {
46
+ ...DEFAULT_XP_CONFIG,
47
+ ...config,
48
+ baseValues: { ...DEFAULT_XP_CONFIG.baseValues, ...config.baseValues },
49
+ scoreThresholds: config.scoreThresholds || DEFAULT_XP_CONFIG.scoreThresholds,
50
+ streakTiers: config.streakTiers || DEFAULT_XP_CONFIG.streakTiers
51
+ };
52
+ }
53
+ calculate(input) {
54
+ const breakdown = [];
55
+ const baseXp = input.baseXp ?? this.config.baseValues[input.activity];
56
+ let totalXp = baseXp;
57
+ breakdown.push({
58
+ source: "base",
59
+ amount: baseXp
60
+ });
61
+ if (input.score !== undefined) {
62
+ const scoreMultiplier = this.getScoreMultiplier(input.score);
63
+ if (scoreMultiplier !== 1) {
64
+ const scoreBonus = Math.round(baseXp * (scoreMultiplier - 1));
65
+ totalXp += scoreBonus;
66
+ breakdown.push({
67
+ source: "score_bonus",
68
+ amount: scoreBonus,
69
+ multiplier: scoreMultiplier
70
+ });
71
+ }
72
+ if (input.score === 100) {
73
+ const perfectBonus = Math.round(baseXp * (this.config.perfectScoreMultiplier - 1));
74
+ totalXp += perfectBonus;
75
+ breakdown.push({
76
+ source: "perfect_score",
77
+ amount: perfectBonus,
78
+ multiplier: this.config.perfectScoreMultiplier
79
+ });
80
+ }
81
+ }
82
+ if (input.attemptNumber === 1 && !input.isRetry) {
83
+ totalXp += this.config.firstAttemptBonus;
84
+ breakdown.push({
85
+ source: "first_attempt",
86
+ amount: this.config.firstAttemptBonus
87
+ });
88
+ }
89
+ if (input.isRetry) {
90
+ const penalty = Math.round(totalXp * (1 - this.config.retryPenalty));
91
+ totalXp -= penalty;
92
+ breakdown.push({
93
+ source: "retry_penalty",
94
+ amount: -penalty,
95
+ multiplier: this.config.retryPenalty
96
+ });
97
+ }
98
+ if (input.currentStreak && input.currentStreak > 0) {
99
+ const streakBonus = this.getStreakBonus(input.currentStreak);
100
+ if (streakBonus > 0) {
101
+ totalXp += streakBonus;
102
+ breakdown.push({
103
+ source: "streak_bonus",
104
+ amount: streakBonus
105
+ });
106
+ }
107
+ }
108
+ if (baseXp > 0) {
109
+ totalXp = Math.max(1, totalXp);
110
+ }
111
+ return {
112
+ totalXp: Math.round(totalXp),
113
+ baseXp,
114
+ breakdown
115
+ };
116
+ }
117
+ calculateStreakBonus(currentStreak) {
118
+ const bonus = this.getStreakBonus(currentStreak);
119
+ return {
120
+ totalXp: bonus,
121
+ baseXp: bonus,
122
+ breakdown: [
123
+ {
124
+ source: "streak_bonus",
125
+ amount: bonus
126
+ }
127
+ ]
128
+ };
129
+ }
130
+ getXpForLevel(level) {
131
+ if (level <= 1)
132
+ return 0;
133
+ return Math.round(100 * Math.pow(level - 1, 1.5));
134
+ }
135
+ getLevelFromXp(totalXp) {
136
+ let level = 1;
137
+ let xpRequired = this.getXpForLevel(level + 1);
138
+ while (totalXp >= xpRequired && level < 1000) {
139
+ level++;
140
+ xpRequired = this.getXpForLevel(level + 1);
141
+ }
142
+ const xpForCurrentLevel = this.getXpForLevel(level);
143
+ const xpForNextLevel = this.getXpForLevel(level + 1);
144
+ return {
145
+ level,
146
+ xpInLevel: totalXp - xpForCurrentLevel,
147
+ xpForNextLevel: xpForNextLevel - xpForCurrentLevel
148
+ };
149
+ }
150
+ getScoreMultiplier(score) {
151
+ for (const threshold of this.config.scoreThresholds) {
152
+ if (score >= threshold.min) {
153
+ return threshold.multiplier;
154
+ }
155
+ }
156
+ return 1;
157
+ }
158
+ getStreakBonus(streak) {
159
+ for (const tier of this.config.streakTiers) {
160
+ if (streak >= tier.days) {
161
+ return tier.bonus;
162
+ }
163
+ }
164
+ return 0;
165
+ }
166
+ }
167
+ var xpEngine = new XPEngine;
168
+ export {
169
+ xpEngine,
170
+ XPEngine,
171
+ DEFAULT_XP_CONFIG
172
+ };