@shaxpir/duiduidui-models 1.9.21 → 1.9.22

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.
@@ -3,7 +3,7 @@ import { CompactDateTime } from "@shaxpir/shaxpir-common";
3
3
  import { ShareSync } from '../repo';
4
4
  import { Conditions } from './Condition';
5
5
  import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
6
- import { UncertainValue } from './Progress';
6
+ import { SkillLevel } from './SkillLevel';
7
7
  /**
8
8
  * Display metadata for a Collection, used in the UI.
9
9
  */
@@ -23,7 +23,7 @@ export interface CollectionPayload {
23
23
  collection_key: string;
24
24
  conditions: Conditions;
25
25
  display: CollectionDisplay;
26
- proficiency: UncertainValue;
26
+ proficiency: SkillLevel;
27
27
  term_scores: {
28
28
  [termKey: string]: number;
29
29
  };
@@ -77,10 +77,9 @@ export declare class Collection extends Content {
77
77
  get description(): string;
78
78
  get icon(): string | undefined;
79
79
  get sortOrder(): number;
80
- get proficiency(): UncertainValue;
81
- get proficiencyRating(): number;
82
- get proficiencyRatingDeviation(): number;
83
- get proficiencyVolatility(): number;
80
+ get proficiency(): SkillLevel;
81
+ get proficiencyMu(): number;
82
+ get proficiencySigma(): number;
84
83
  get termScores(): {
85
84
  [termKey: string]: number;
86
85
  };
@@ -125,9 +124,9 @@ export declare class Collection extends Content {
125
124
  F: number;
126
125
  };
127
126
  /**
128
- * Update the Glicko-2 proficiency rating.
127
+ * Update the IRT proficiency rating.
129
128
  */
130
- setProficiency(value: UncertainValue): void;
129
+ setProficiency(value: SkillLevel): void;
131
130
  /**
132
131
  * Update or add a term score in the collection.
133
132
  */
@@ -7,6 +7,7 @@ const SenseRankEncoder_1 = require("../util/SenseRankEncoder");
7
7
  const Content_1 = require("./Content");
8
8
  const ContentKind_1 = require("./ContentKind");
9
9
  const Operation_1 = require("./Operation");
10
+ const SkillLevel_1 = require("./SkillLevel");
10
11
  class Collection extends Content_1.Content {
11
12
  /**
12
13
  * Generate a deterministic Collection ID from userId and collectionKey.
@@ -50,12 +51,8 @@ class Collection extends Content_1.Content {
50
51
  collection_key: params.collectionKey,
51
52
  conditions: params.conditions,
52
53
  display: params.display,
53
- // Initial Glicko-2 proficiency - high uncertainty, no data yet
54
- proficiency: {
55
- rating: 0, // Start at zero (no demonstrated skill)
56
- rating_deviation: 50, // High initial uncertainty
57
- volatility: 0.06 // Moderate initial volatility
58
- },
54
+ // Initial IRT proficiency - high uncertainty, no data yet
55
+ proficiency: SkillLevel_1.SkillLevelModel.createDefault(),
59
56
  // Empty term scores map - populated as user reviews cards
60
57
  term_scores: {},
61
58
  // Progress starts at zero
@@ -118,17 +115,13 @@ class Collection extends Content_1.Content {
118
115
  this.checkDisposed("Collection.proficiency");
119
116
  return shaxpir_common_1.Struct.clone(this.payload.proficiency);
120
117
  }
121
- get proficiencyRating() {
122
- this.checkDisposed("Collection.proficiencyRating");
123
- return this.payload.proficiency.rating;
118
+ get proficiencyMu() {
119
+ this.checkDisposed("Collection.proficiencyMu");
120
+ return this.payload.proficiency.mu;
124
121
  }
125
- get proficiencyRatingDeviation() {
126
- this.checkDisposed("Collection.proficiencyRatingDeviation");
127
- return this.payload.proficiency.rating_deviation;
128
- }
129
- get proficiencyVolatility() {
130
- this.checkDisposed("Collection.proficiencyVolatility");
131
- return this.payload.proficiency.volatility;
122
+ get proficiencySigma() {
123
+ this.checkDisposed("Collection.proficiencySigma");
124
+ return this.payload.proficiency.sigma;
132
125
  }
133
126
  // ============================================================
134
127
  // Term scores getters
@@ -232,15 +225,14 @@ class Collection extends Content_1.Content {
232
225
  // Mutators
233
226
  // ============================================================
234
227
  /**
235
- * Update the Glicko-2 proficiency rating.
228
+ * Update the IRT proficiency rating.
236
229
  */
237
230
  setProficiency(value) {
238
231
  this.checkDisposed("Collection.setProficiency");
239
232
  if (!shaxpir_common_1.Struct.equals(this.payload.proficiency, value)) {
240
233
  const batch = new Operation_1.BatchOperation(this);
241
- batch.setPathValue(['payload', 'proficiency', 'rating'], value.rating);
242
- batch.setPathValue(['payload', 'proficiency', 'rating_deviation'], value.rating_deviation);
243
- batch.setPathValue(['payload', 'proficiency', 'volatility'], value.volatility);
234
+ batch.setPathValue(['payload', 'proficiency', 'mu'], value.mu);
235
+ batch.setPathValue(['payload', 'proficiency', 'sigma'], value.sigma);
244
236
  batch.commit();
245
237
  }
246
238
  }
@@ -2,11 +2,7 @@ import { Doc } from '@shaxpir/sharedb/lib/client';
2
2
  import { CompactDate } from "@shaxpir/shaxpir-common";
3
3
  import { ShareSync } from '../repo';
4
4
  import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
5
- export interface UncertainValue {
6
- rating: number;
7
- rating_deviation: number;
8
- volatility: number;
9
- }
5
+ import { SkillLevel } from './SkillLevel';
10
6
  export interface StreakData {
11
7
  daily: {
12
8
  current: number;
@@ -26,7 +22,7 @@ export interface StreakData {
26
22
  total_days: number;
27
23
  }
28
24
  export interface ProgressPayload {
29
- skill_level: UncertainValue;
25
+ skill_level: SkillLevel;
30
26
  cognitive_load: number;
31
27
  streaks?: StreakData;
32
28
  total_review_count: number;
@@ -40,18 +36,16 @@ export declare class Progress extends Content {
40
36
  static create(userId: ContentId): Progress;
41
37
  constructor(doc: Doc, shouldAcquire: boolean, shareSync: ShareSync);
42
38
  get payload(): ProgressPayload;
43
- getSkillLevel(): UncertainValue;
44
- getSkillLevelValue(): number;
45
- getSkillLevelRatingDeviation(): number;
46
- getSkillLevelVolatility(): number;
39
+ getSkillLevel(): SkillLevel;
40
+ getSkillLevelMu(): number;
41
+ getSkillLevelSigma(): number;
47
42
  getSkillLevelLowerBound(): number;
48
43
  getSkillLevelUpperBound(): number;
49
44
  needsCalibration(): boolean;
50
45
  getCognitiveLoad(): number;
51
- setSkillLevel(uncertainValue: UncertainValue): void;
52
- setSkillLevelValue(value: number): void;
53
- setSkillLevelRatingDeviation(ratingDeviation: number): void;
54
- setSkillLevelVolatility(volatility: number): void;
46
+ setSkillLevel(skillLevel: SkillLevel): void;
47
+ setSkillLevelMu(mu: number): void;
48
+ setSkillLevelSigma(sigma: number): void;
55
49
  setCognitiveLoad(value: number): void;
56
50
  getStreaks(): StreakData | undefined;
57
51
  setStreaks(streaks: StreakData): void;
@@ -6,6 +6,7 @@ const repo_1 = require("../repo");
6
6
  const Content_1 = require("./Content");
7
7
  const ContentKind_1 = require("./ContentKind");
8
8
  const Operation_1 = require("./Operation");
9
+ const SkillLevel_1 = require("./SkillLevel");
9
10
  class Progress extends Content_1.Content {
10
11
  static makeProgressId(userId) {
11
12
  return shaxpir_common_1.CachingHasher.makeMd5Base62Hash(userId + "-" + ContentKind_1.ContentKind.PROGRESS);
@@ -23,13 +24,9 @@ class Progress extends Content_1.Content {
23
24
  updated_at: now
24
25
  },
25
26
  payload: {
26
- skill_level: {
27
- rating: 0, // Start at absolute beginner (knows ~0 characters)
28
- rating_deviation: 50, // Initial uncertainty (±100 chars at 95% CI)
29
- volatility: 0.06 // Moderate initial volatility
30
- },
27
+ skill_level: SkillLevel_1.SkillLevelModel.createDefault(),
31
28
  cognitive_load: 0,
32
- total_review_count: 0 // Start with zero lifetime reviews
29
+ total_review_count: 0
33
30
  }
34
31
  });
35
32
  }
@@ -44,71 +41,56 @@ class Progress extends Content_1.Content {
44
41
  this.checkDisposed("Progress.getSkillLevel");
45
42
  return shaxpir_common_1.Struct.clone(this.payload.skill_level);
46
43
  }
47
- getSkillLevelValue() {
48
- this.checkDisposed("Progress.getSkillLevelValue");
49
- return this.payload.skill_level.rating;
44
+ getSkillLevelMu() {
45
+ this.checkDisposed("Progress.getSkillLevelMu");
46
+ return this.payload.skill_level.mu;
50
47
  }
51
- getSkillLevelRatingDeviation() {
52
- this.checkDisposed("Progress.getSkillLevelRatingDeviation");
53
- return this.payload.skill_level.rating_deviation;
54
- }
55
- getSkillLevelVolatility() {
56
- this.checkDisposed("Progress.getSkillLevelVolatility");
57
- return this.payload.skill_level.volatility;
48
+ getSkillLevelSigma() {
49
+ this.checkDisposed("Progress.getSkillLevelSigma");
50
+ return this.payload.skill_level.sigma;
58
51
  }
59
52
  getSkillLevelLowerBound() {
60
53
  this.checkDisposed("Progress.getSkillLevelLowerBound");
61
- const { SkillLevelModel } = require('./SkillLevel');
62
- const bounds = SkillLevelModel.calculateBounds(this.payload.skill_level.rating, this.payload.skill_level.rating_deviation);
54
+ const bounds = SkillLevel_1.SkillLevelModel.calculateBounds(this.payload.skill_level.mu, this.payload.skill_level.sigma);
63
55
  return bounds.lower;
64
56
  }
65
57
  getSkillLevelUpperBound() {
66
58
  this.checkDisposed("Progress.getSkillLevelUpperBound");
67
- const { SkillLevelModel } = require('./SkillLevel');
68
- const bounds = SkillLevelModel.calculateBounds(this.payload.skill_level.rating, this.payload.skill_level.rating_deviation);
59
+ const bounds = SkillLevel_1.SkillLevelModel.calculateBounds(this.payload.skill_level.mu, this.payload.skill_level.sigma);
69
60
  return bounds.upper;
70
61
  }
71
62
  needsCalibration() {
72
63
  this.checkDisposed("Progress.needsCalibration");
73
- // High rating deviation means we need more data to calibrate user level
74
- // rating_deviation > 30 means confidence bounds are still quite wide (±60 chars at 95% CI)
75
- return this.payload.skill_level.rating_deviation > 30;
64
+ // High sigma means we need more data to calibrate user level
65
+ // sigma > 30 means confidence bounds are still quite wide (±60 chars at 95% CI)
66
+ return this.payload.skill_level.sigma > 30;
76
67
  }
77
68
  getCognitiveLoad() {
78
69
  this.checkDisposed("Progress.getCognitiveLoad");
79
70
  return this.payload.cognitive_load;
80
71
  }
81
- setSkillLevel(uncertainValue) {
72
+ setSkillLevel(skillLevel) {
82
73
  this.checkDisposed("Progress.setSkillLevel");
83
- if (!shaxpir_common_1.Struct.equals(this.payload.skill_level, uncertainValue)) {
84
- const batch = new Operation_1.BatchOperation(this);
85
- batch.setPathValue(['payload', 'skill_level', 'rating'], uncertainValue.rating);
86
- batch.setPathValue(['payload', 'skill_level', 'rating_deviation'], uncertainValue.rating_deviation);
87
- batch.setPathValue(['payload', 'skill_level', 'volatility'], uncertainValue.volatility);
88
- batch.commit();
89
- }
90
- }
91
- setSkillLevelValue(value) {
92
- this.checkDisposed("Progress.setSkillLevelValue");
93
- if (this.payload.skill_level.rating !== value) {
74
+ if (!shaxpir_common_1.Struct.equals(this.payload.skill_level, skillLevel)) {
94
75
  const batch = new Operation_1.BatchOperation(this);
95
- batch.setPathValue(['payload', 'skill_level', 'rating'], value);
76
+ batch.setPathValue(['payload', 'skill_level', 'mu'], skillLevel.mu);
77
+ batch.setPathValue(['payload', 'skill_level', 'sigma'], skillLevel.sigma);
96
78
  batch.commit();
97
79
  }
98
80
  }
99
- setSkillLevelRatingDeviation(ratingDeviation) {
100
- this.checkDisposed("Progress.setSkillLevelRatingDeviation");
101
- if (this.payload.skill_level.rating_deviation !== ratingDeviation) {
81
+ setSkillLevelMu(mu) {
82
+ this.checkDisposed("Progress.setSkillLevelMu");
83
+ if (this.payload.skill_level.mu !== mu) {
102
84
  const batch = new Operation_1.BatchOperation(this);
103
- batch.setPathValue(['payload', 'skill_level', 'rating_deviation'], ratingDeviation);
85
+ batch.setPathValue(['payload', 'skill_level', 'mu'], mu);
104
86
  batch.commit();
105
87
  }
106
88
  }
107
- setSkillLevelVolatility(volatility) {
108
- this.checkDisposed("Progress.setSkillLevelVolatility");
109
- if (this.payload.skill_level.volatility !== volatility) {
89
+ setSkillLevelSigma(sigma) {
90
+ this.checkDisposed("Progress.setSkillLevelSigma");
91
+ if (this.payload.skill_level.sigma !== sigma) {
110
92
  const batch = new Operation_1.BatchOperation(this);
111
- batch.setPathValue(['payload', 'skill_level', 'volatility'], volatility);
93
+ batch.setPathValue(['payload', 'skill_level', 'sigma'], sigma);
112
94
  batch.commit();
113
95
  }
114
96
  }
@@ -4,7 +4,7 @@ import { ShareSync } from '../repo';
4
4
  import { Conditions } from './Condition';
5
5
  import { Content, ContentBody, ContentId, ContentMeta, ContentRef } from "./Content";
6
6
  import { Review } from './Review';
7
- import { UncertainValue } from './Progress';
7
+ import { SkillLevel } from './SkillLevel';
8
8
  /**
9
9
  * How aggressively the card selection algorithm stretches the user
10
10
  * beyond their current skill level.
@@ -29,7 +29,7 @@ export interface SessionConfig {
29
29
  };
30
30
  }
31
31
  export interface SessionStats {
32
- skill_level: UncertainValue;
32
+ skill_level: SkillLevel;
33
33
  cognitive_load: number;
34
34
  theta_distribution: {
35
35
  A: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaxpir/duiduidui-models",
3
- "version": "1.9.21",
3
+ "version": "1.9.22",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shaxpir/duiduidui-models"