@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.
- package/dist/models/Collection.d.ts +7 -8
- package/dist/models/Collection.js +12 -20
- package/dist/models/Progress.d.ts +8 -14
- package/dist/models/Progress.js +26 -44
- package/dist/models/Session.d.ts +2 -2
- package/package.json +1 -1
|
@@ -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 {
|
|
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:
|
|
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():
|
|
81
|
-
get
|
|
82
|
-
get
|
|
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
|
|
127
|
+
* Update the IRT proficiency rating.
|
|
129
128
|
*/
|
|
130
|
-
setProficiency(value:
|
|
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
|
|
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
|
|
122
|
-
this.checkDisposed("Collection.
|
|
123
|
-
return this.payload.proficiency.
|
|
118
|
+
get proficiencyMu() {
|
|
119
|
+
this.checkDisposed("Collection.proficiencyMu");
|
|
120
|
+
return this.payload.proficiency.mu;
|
|
124
121
|
}
|
|
125
|
-
get
|
|
126
|
-
this.checkDisposed("Collection.
|
|
127
|
-
return this.payload.proficiency.
|
|
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
|
|
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', '
|
|
242
|
-
batch.setPathValue(['payload', 'proficiency', '
|
|
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
|
-
|
|
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:
|
|
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():
|
|
44
|
-
|
|
45
|
-
|
|
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(
|
|
52
|
-
|
|
53
|
-
|
|
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;
|
package/dist/models/Progress.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
48
|
-
this.checkDisposed("Progress.
|
|
49
|
-
return this.payload.skill_level.
|
|
44
|
+
getSkillLevelMu() {
|
|
45
|
+
this.checkDisposed("Progress.getSkillLevelMu");
|
|
46
|
+
return this.payload.skill_level.mu;
|
|
50
47
|
}
|
|
51
|
-
|
|
52
|
-
this.checkDisposed("Progress.
|
|
53
|
-
return this.payload.skill_level.
|
|
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
|
|
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
|
|
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
|
|
74
|
-
//
|
|
75
|
-
return this.payload.skill_level.
|
|
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(
|
|
72
|
+
setSkillLevel(skillLevel) {
|
|
82
73
|
this.checkDisposed("Progress.setSkillLevel");
|
|
83
|
-
if (!shaxpir_common_1.Struct.equals(this.payload.skill_level,
|
|
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', '
|
|
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
|
-
|
|
100
|
-
this.checkDisposed("Progress.
|
|
101
|
-
if (this.payload.skill_level.
|
|
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', '
|
|
85
|
+
batch.setPathValue(['payload', 'skill_level', 'mu'], mu);
|
|
104
86
|
batch.commit();
|
|
105
87
|
}
|
|
106
88
|
}
|
|
107
|
-
|
|
108
|
-
this.checkDisposed("Progress.
|
|
109
|
-
if (this.payload.skill_level.
|
|
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', '
|
|
93
|
+
batch.setPathValue(['payload', 'skill_level', 'sigma'], sigma);
|
|
112
94
|
batch.commit();
|
|
113
95
|
}
|
|
114
96
|
}
|
package/dist/models/Session.d.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
32
|
+
skill_level: SkillLevel;
|
|
33
33
|
cognitive_load: number;
|
|
34
34
|
theta_distribution: {
|
|
35
35
|
A: number;
|