@shaxpir/duiduidui-models 1.6.18 → 1.7.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.
- package/dist/models/Progress.d.ts +22 -0
- package/dist/models/Progress.js +12 -0
- package/dist/models/Session.d.ts +61 -0
- package/dist/models/Session.js +56 -0
- package/dist/repo/ShareSync.js +23 -2
- package/package.json +1 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Doc } from '@shaxpir/sharedb/lib/client';
|
|
2
|
+
import { CompactDate } from "@shaxpir/shaxpir-common";
|
|
2
3
|
import { ShareSync } from '../repo';
|
|
3
4
|
import { Bounds } from './BayesianScore';
|
|
4
5
|
import { Content, ContentBody, ContentId, ContentMeta } from "./Content";
|
|
@@ -7,9 +8,28 @@ export interface UncertainValue {
|
|
|
7
8
|
uncertainty: number;
|
|
8
9
|
bounds: Bounds;
|
|
9
10
|
}
|
|
11
|
+
export interface StreakData {
|
|
12
|
+
daily: {
|
|
13
|
+
current: number;
|
|
14
|
+
longest: number;
|
|
15
|
+
};
|
|
16
|
+
weekly: {
|
|
17
|
+
current: number;
|
|
18
|
+
};
|
|
19
|
+
monthly: {
|
|
20
|
+
current: number;
|
|
21
|
+
};
|
|
22
|
+
last_activity: {
|
|
23
|
+
date: CompactDate;
|
|
24
|
+
week: string;
|
|
25
|
+
month: string;
|
|
26
|
+
};
|
|
27
|
+
total_days: number;
|
|
28
|
+
}
|
|
10
29
|
export interface ProgressPayload {
|
|
11
30
|
skill_level: UncertainValue;
|
|
12
31
|
cognitive_load: number;
|
|
32
|
+
streaks?: StreakData;
|
|
13
33
|
}
|
|
14
34
|
export interface ProgressBody extends ContentBody {
|
|
15
35
|
meta: ContentMeta;
|
|
@@ -33,4 +53,6 @@ export declare class Progress extends Content {
|
|
|
33
53
|
setSkillLevelLowerBound(lowerBound: number): void;
|
|
34
54
|
setSkillLevelUpperBound(upperBound: number): void;
|
|
35
55
|
setCognitiveLoad(value: number): void;
|
|
56
|
+
getStreaks(): StreakData | undefined;
|
|
57
|
+
setStreaks(streaks: StreakData): void;
|
|
36
58
|
}
|
package/dist/models/Progress.js
CHANGED
|
@@ -122,5 +122,17 @@ class Progress extends Content_1.Content {
|
|
|
122
122
|
batch.commit();
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
+
getStreaks() {
|
|
126
|
+
this.checkDisposed("Progress.getStreaks");
|
|
127
|
+
return this.payload.streaks ? shaxpir_common_1.Struct.clone(this.payload.streaks) : undefined;
|
|
128
|
+
}
|
|
129
|
+
setStreaks(streaks) {
|
|
130
|
+
this.checkDisposed("Progress.setStreaks");
|
|
131
|
+
if (!shaxpir_common_1.Struct.equals(this.payload.streaks, streaks)) {
|
|
132
|
+
const batch = new Operation_1.BatchOperation(this);
|
|
133
|
+
batch.setPathValue(['payload', 'streaks'], streaks);
|
|
134
|
+
batch.commit();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
125
137
|
}
|
|
126
138
|
exports.Progress = Progress;
|
package/dist/models/Session.d.ts
CHANGED
|
@@ -1,8 +1,54 @@
|
|
|
1
1
|
import { Doc } from '@shaxpir/sharedb/lib/client';
|
|
2
2
|
import { MultiTime } from "@shaxpir/shaxpir-common";
|
|
3
3
|
import { ShareSync } from '../repo';
|
|
4
|
+
import { ConditionFilters } from './Condition';
|
|
4
5
|
import { Content, ContentBody, ContentId, ContentMeta, ContentRef } from "./Content";
|
|
5
6
|
import { Review } from './Review';
|
|
7
|
+
import { UncertainValue } from './Progress';
|
|
8
|
+
export interface SessionConfig {
|
|
9
|
+
version: number;
|
|
10
|
+
constraints?: {
|
|
11
|
+
card_limit?: number | null;
|
|
12
|
+
time_limit?: number;
|
|
13
|
+
};
|
|
14
|
+
selection?: {
|
|
15
|
+
difficulty_ramp?: number;
|
|
16
|
+
filters?: ConditionFilters;
|
|
17
|
+
strategy?: {
|
|
18
|
+
name: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
constants?: Record<string, any>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
display?: {
|
|
24
|
+
show_pinyin?: boolean;
|
|
25
|
+
auto_play_speech?: boolean;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface SessionMetrics {
|
|
29
|
+
skill_level: UncertainValue;
|
|
30
|
+
cognitive_load: number;
|
|
31
|
+
theta_distribution: {
|
|
32
|
+
A: number;
|
|
33
|
+
B: number;
|
|
34
|
+
C: number;
|
|
35
|
+
D: number;
|
|
36
|
+
F: number;
|
|
37
|
+
};
|
|
38
|
+
streaks: {
|
|
39
|
+
daily: {
|
|
40
|
+
current: number;
|
|
41
|
+
longest: number;
|
|
42
|
+
};
|
|
43
|
+
weekly: {
|
|
44
|
+
current: number;
|
|
45
|
+
};
|
|
46
|
+
monthly: {
|
|
47
|
+
current: number;
|
|
48
|
+
};
|
|
49
|
+
total_days: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
6
52
|
export interface SessionPayload {
|
|
7
53
|
start: MultiTime;
|
|
8
54
|
end: MultiTime;
|
|
@@ -11,6 +57,12 @@ export interface SessionPayload {
|
|
|
11
57
|
duration_minutes: number;
|
|
12
58
|
reviews: Review[];
|
|
13
59
|
review_count: number;
|
|
60
|
+
config?: SessionConfig;
|
|
61
|
+
metrics?: {
|
|
62
|
+
before?: SessionMetrics;
|
|
63
|
+
after?: SessionMetrics;
|
|
64
|
+
};
|
|
65
|
+
is_complete?: boolean;
|
|
14
66
|
}
|
|
15
67
|
export interface SessionBody extends ContentBody {
|
|
16
68
|
meta: ContentMeta;
|
|
@@ -32,5 +84,14 @@ export declare class Session extends Content {
|
|
|
32
84
|
get reviews(): Review[];
|
|
33
85
|
get reviewCount(): number;
|
|
34
86
|
addReview(review: Review): void;
|
|
87
|
+
get config(): SessionConfig | undefined;
|
|
88
|
+
setConfig(config: SessionConfig): void;
|
|
89
|
+
get isComplete(): boolean;
|
|
90
|
+
markComplete(): void;
|
|
91
|
+
get metricsBefore(): SessionMetrics | undefined;
|
|
92
|
+
setMetricsBefore(metrics: SessionMetrics): void;
|
|
93
|
+
get metricsAfter(): SessionMetrics | undefined;
|
|
94
|
+
setMetricsAfter(metrics: SessionMetrics): void;
|
|
95
|
+
isActive(): boolean;
|
|
35
96
|
modelUpdated(): Promise<void>;
|
|
36
97
|
}
|
package/dist/models/Session.js
CHANGED
|
@@ -106,6 +106,62 @@ class Session extends Content_1.Content {
|
|
|
106
106
|
batch.setPathValue(['payload', 'review_count'], this._reviewsView.length);
|
|
107
107
|
batch.commit();
|
|
108
108
|
}
|
|
109
|
+
get config() {
|
|
110
|
+
this.checkDisposed("Session.config");
|
|
111
|
+
return this.payload.config;
|
|
112
|
+
}
|
|
113
|
+
setConfig(config) {
|
|
114
|
+
this.checkDisposed("Session.setConfig");
|
|
115
|
+
const batch = new Operation_1.BatchOperation(this);
|
|
116
|
+
batch.setPathValue(['payload', 'config'], config);
|
|
117
|
+
batch.commit();
|
|
118
|
+
}
|
|
119
|
+
get isComplete() {
|
|
120
|
+
this.checkDisposed("Session.isComplete");
|
|
121
|
+
return this.payload.is_complete || false;
|
|
122
|
+
}
|
|
123
|
+
markComplete() {
|
|
124
|
+
this.checkDisposed("Session.markComplete");
|
|
125
|
+
const batch = new Operation_1.BatchOperation(this);
|
|
126
|
+
batch.setPathValue(['payload', 'is_complete'], true);
|
|
127
|
+
batch.commit();
|
|
128
|
+
}
|
|
129
|
+
get metricsBefore() {
|
|
130
|
+
this.checkDisposed("Session.metricsBefore");
|
|
131
|
+
return this.payload.metrics?.before;
|
|
132
|
+
}
|
|
133
|
+
setMetricsBefore(metrics) {
|
|
134
|
+
this.checkDisposed("Session.setMetricsBefore");
|
|
135
|
+
const batch = new Operation_1.BatchOperation(this);
|
|
136
|
+
if (!this.payload.metrics) {
|
|
137
|
+
batch.setPathValue(['payload', 'metrics'], {});
|
|
138
|
+
}
|
|
139
|
+
batch.setPathValue(['payload', 'metrics', 'before'], metrics);
|
|
140
|
+
batch.commit();
|
|
141
|
+
}
|
|
142
|
+
get metricsAfter() {
|
|
143
|
+
this.checkDisposed("Session.metricsAfter");
|
|
144
|
+
return this.payload.metrics?.after;
|
|
145
|
+
}
|
|
146
|
+
setMetricsAfter(metrics) {
|
|
147
|
+
this.checkDisposed("Session.setMetricsAfter");
|
|
148
|
+
const batch = new Operation_1.BatchOperation(this);
|
|
149
|
+
if (!this.payload.metrics) {
|
|
150
|
+
batch.setPathValue(['payload', 'metrics'], {});
|
|
151
|
+
}
|
|
152
|
+
batch.setPathValue(['payload', 'metrics', 'after'], metrics);
|
|
153
|
+
batch.commit();
|
|
154
|
+
}
|
|
155
|
+
isActive() {
|
|
156
|
+
this.checkDisposed("Session.isActive");
|
|
157
|
+
// Session is active if not completed and not expired
|
|
158
|
+
if (this.isComplete) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const now = shaxpir_common_1.ClockService.getClock().now();
|
|
162
|
+
const fifteenMinutesAgo = shaxpir_common_1.Time.plus(now.utc_time, -15, 'minutes');
|
|
163
|
+
return shaxpir_common_1.Time.isDateTimeAfter(this.updatedAt.utc_time, fifteenMinutesAgo);
|
|
164
|
+
}
|
|
109
165
|
async modelUpdated() {
|
|
110
166
|
this.checkDisposed("Session.modelUpdated");
|
|
111
167
|
await super.modelUpdated();
|
package/dist/repo/ShareSync.js
CHANGED
|
@@ -156,7 +156,17 @@ class ShareSync {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
createConnectionWithDurableStore(socket, options) {
|
|
159
|
-
|
|
159
|
+
const shareSync = this;
|
|
160
|
+
// Create a wrapper callback that ensures it's called even when offline
|
|
161
|
+
let readyCallbackInvoked = false;
|
|
162
|
+
const wrappedCallback = options.onReadyCallback ? function () {
|
|
163
|
+
if (!readyCallbackInvoked) {
|
|
164
|
+
readyCallbackInvoked = true;
|
|
165
|
+
shareSync._debug && console.log('[ShareSync] DurableStore ready, invoking onReadyCallback');
|
|
166
|
+
options.onReadyCallback();
|
|
167
|
+
}
|
|
168
|
+
} : undefined;
|
|
169
|
+
const connection = new client_1.Connection(socket, {
|
|
160
170
|
durableStore: {
|
|
161
171
|
storage: this._storage,
|
|
162
172
|
debug: this._debug,
|
|
@@ -170,9 +180,20 @@ class ShareSync {
|
|
|
170
180
|
}
|
|
171
181
|
return null;
|
|
172
182
|
},
|
|
173
|
-
onReadyCallback:
|
|
183
|
+
onReadyCallback: wrappedCallback
|
|
174
184
|
}
|
|
175
185
|
});
|
|
186
|
+
// Add a fallback timeout to ensure the callback fires even if the DurableStore
|
|
187
|
+
// ready event doesn't properly trigger when offline
|
|
188
|
+
if (wrappedCallback && !shareSync._socketIsOpen) {
|
|
189
|
+
setTimeout(function () {
|
|
190
|
+
if (!readyCallbackInvoked) {
|
|
191
|
+
console.warn('[ShareSync] Socket offline - forcing onReadyCallback after timeout');
|
|
192
|
+
wrappedCallback();
|
|
193
|
+
}
|
|
194
|
+
}, 100); // Small delay to allow normal initialization first
|
|
195
|
+
}
|
|
196
|
+
return connection;
|
|
176
197
|
}
|
|
177
198
|
async initializeDurableStore(options) {
|
|
178
199
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shaxpir/duiduidui-models",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/shaxpir/duiduidui-models"
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"@shaxpir/shaxpir-common": "1.4.0",
|
|
22
22
|
"ot-json1": "1.0.1",
|
|
23
23
|
"ot-text-unicode": "4.0.0",
|
|
24
|
-
"react-native-popover-view": "^6.1.0",
|
|
25
24
|
"reconnecting-websocket": "4.4.0"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|