@vue-skuilder/db 0.1.11 → 0.1.12
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/core/index.d.mts +7 -6
- package/dist/core/index.d.ts +7 -6
- package/dist/core/index.js +146 -37
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +146 -37
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-VieuAAkV.d.mts → dataLayerProvider-BiP3kWix.d.mts} +1 -1
- package/dist/{dataLayerProvider-juuqUHOP.d.ts → dataLayerProvider-DSdeyRT3.d.ts} +1 -1
- package/dist/impl/couch/index.d.mts +3 -3
- package/dist/impl/couch/index.d.ts +3 -3
- package/dist/impl/couch/index.js +146 -37
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +146 -37
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.mts +14 -6
- package/dist/impl/static/index.d.ts +14 -6
- package/dist/impl/static/index.js +147 -39
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +147 -39
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/{index-DZyxHCcf.d.mts → index-Bmll7Xse.d.mts} +1 -1
- package/dist/{index-CWY6yhkV.d.ts → index-CD8BZz2k.d.ts} +1 -1
- package/dist/index.d.mts +119 -24
- package/dist/index.d.ts +119 -24
- package/dist/index.js +785 -261
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +789 -265
- package/dist/index.mjs.map +1 -1
- package/dist/{types-DtoI27Xh.d.ts → types-CewsN87z.d.ts} +1 -1
- package/dist/{types-Che4wTwA.d.mts → types-Dbp5DaRR.d.mts} +1 -1
- package/dist/{types-legacy-B8ahaCbj.d.mts → types-legacy-6ettoclI.d.mts} +13 -2
- package/dist/{types-legacy-B8ahaCbj.d.ts → types-legacy-6ettoclI.d.ts} +13 -2
- package/dist/{userDB-DJ8HMw83.d.mts → userDB-C4yyAnpp.d.mts} +3 -3
- package/dist/{userDB-B7zTQ123.d.ts → userDB-CD6s6ZCp.d.ts} +3 -3
- package/dist/util/packer/index.d.mts +3 -3
- package/dist/util/packer/index.d.ts +3 -3
- package/package.json +3 -3
- package/src/core/navigators/hardcodedOrder.ts +64 -0
- package/src/core/navigators/index.ts +1 -0
- package/src/core/types/contentNavigationStrategy.ts +2 -1
- package/src/core/types/types-legacy.ts +2 -2
- package/src/impl/common/BaseUserDB.ts +15 -11
- package/src/impl/couch/courseDB.ts +74 -27
- package/src/impl/couch/updateQueue.ts +8 -3
- package/src/impl/static/StaticDataLayerProvider.ts +57 -17
- package/src/impl/static/courseDB.ts +17 -12
- package/src/impl/static/coursesDB.ts +10 -6
- package/src/study/ItemQueue.ts +58 -0
- package/src/study/SessionController.ts +132 -178
- package/src/study/services/CardHydrationService.ts +153 -0
- package/src/study/services/EloService.ts +85 -0
- package/src/study/services/ResponseProcessor.ts +224 -0
- package/src/study/services/SrsService.ts +44 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { U as UserDBInterface, a as UserDBReader, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface } from './userDB-
|
|
1
|
+
import { U as UserDBInterface, a as UserDBReader, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface } from './userDB-C4yyAnpp.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Main factory interface for data access
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { U as UserDBInterface, a as UserDBReader, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface } from './userDB-
|
|
1
|
+
import { U as UserDBInterface, a as UserDBReader, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface } from './userDB-CD6s6ZCp.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Main factory interface for data access
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { T as TagStub, a as Tag, S as SkuilderCourseData, Q as QualifiedCardID } from '../../types-legacy-
|
|
1
|
+
import { T as TagStub, a as Tag, S as SkuilderCourseData, Q as QualifiedCardID } from '../../types-legacy-6ettoclI.mjs';
|
|
2
2
|
import { Moment } from 'moment';
|
|
3
|
-
import { A as AdminDBInterface, h as AssignedContent, i as StudyContentSource, j as StudentClassroomDBInterface, U as UserDBInterface, f as StudySessionReviewItem, g as ScheduledCard, S as StudySessionNewItem, T as TeacherClassroomDBInterface, b as CoursesDBInterface, C as CourseDBInterface, d as CourseInfo, D as DataLayerResult, e as ContentNavigationStrategyData, k as StudySessionItem } from '../../userDB-
|
|
4
|
-
export { p as ContentSourceID, l as StudySessionFailedItem, m as StudySessionFailedNewItem, n as StudySessionFailedReviewItem, q as getStudySource, o as isReview } from '../../userDB-
|
|
3
|
+
import { A as AdminDBInterface, h as AssignedContent, i as StudyContentSource, j as StudentClassroomDBInterface, U as UserDBInterface, f as StudySessionReviewItem, g as ScheduledCard, S as StudySessionNewItem, T as TeacherClassroomDBInterface, b as CoursesDBInterface, C as CourseDBInterface, d as CourseInfo, D as DataLayerResult, e as ContentNavigationStrategyData, k as StudySessionItem } from '../../userDB-C4yyAnpp.mjs';
|
|
4
|
+
export { p as ContentSourceID, l as StudySessionFailedItem, m as StudySessionFailedNewItem, n as StudySessionFailedReviewItem, q as getStudySource, o as isReview } from '../../userDB-C4yyAnpp.mjs';
|
|
5
5
|
import * as _vue_skuilder_common from '@vue-skuilder/common';
|
|
6
6
|
import { ClassroomConfig, DataShape, CourseElo, CourseConfig as CourseConfig$1 } from '@vue-skuilder/common';
|
|
7
7
|
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-CyATpyLQ.mjs';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { T as TagStub, a as Tag, S as SkuilderCourseData, Q as QualifiedCardID } from '../../types-legacy-
|
|
1
|
+
import { T as TagStub, a as Tag, S as SkuilderCourseData, Q as QualifiedCardID } from '../../types-legacy-6ettoclI.js';
|
|
2
2
|
import { Moment } from 'moment';
|
|
3
|
-
import { A as AdminDBInterface, h as AssignedContent, i as StudyContentSource, j as StudentClassroomDBInterface, U as UserDBInterface, f as StudySessionReviewItem, g as ScheduledCard, S as StudySessionNewItem, T as TeacherClassroomDBInterface, b as CoursesDBInterface, C as CourseDBInterface, d as CourseInfo, D as DataLayerResult, e as ContentNavigationStrategyData, k as StudySessionItem } from '../../userDB-
|
|
4
|
-
export { p as ContentSourceID, l as StudySessionFailedItem, m as StudySessionFailedNewItem, n as StudySessionFailedReviewItem, q as getStudySource, o as isReview } from '../../userDB-
|
|
3
|
+
import { A as AdminDBInterface, h as AssignedContent, i as StudyContentSource, j as StudentClassroomDBInterface, U as UserDBInterface, f as StudySessionReviewItem, g as ScheduledCard, S as StudySessionNewItem, T as TeacherClassroomDBInterface, b as CoursesDBInterface, C as CourseDBInterface, d as CourseInfo, D as DataLayerResult, e as ContentNavigationStrategyData, k as StudySessionItem } from '../../userDB-CD6s6ZCp.js';
|
|
4
|
+
export { p as ContentSourceID, l as StudySessionFailedItem, m as StudySessionFailedNewItem, n as StudySessionFailedReviewItem, q as getStudySource, o as isReview } from '../../userDB-CD6s6ZCp.js';
|
|
5
5
|
import * as _vue_skuilder_common from '@vue-skuilder/common';
|
|
6
6
|
import { ClassroomConfig, DataShape, CourseElo, CourseConfig as CourseConfig$1 } from '@vue-skuilder/common';
|
|
7
7
|
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-CyATpyLQ.js';
|
package/dist/impl/couch/index.js
CHANGED
|
@@ -172,7 +172,9 @@ var init_updateQueue = __esm({
|
|
|
172
172
|
async applyUpdates(id) {
|
|
173
173
|
logger.debug(`Applying updates on doc: ${id}`);
|
|
174
174
|
if (this.inprogressUpdates[id]) {
|
|
175
|
-
|
|
175
|
+
while (this.inprogressUpdates[id]) {
|
|
176
|
+
await new Promise((resolve) => setTimeout(resolve, Math.random() * 50));
|
|
177
|
+
}
|
|
176
178
|
return this.applyUpdates(id);
|
|
177
179
|
} else {
|
|
178
180
|
if (this.pendingUpdates[id] && this.pendingUpdates[id].length > 0) {
|
|
@@ -208,6 +210,9 @@ var init_updateQueue = __esm({
|
|
|
208
210
|
if (e.name === "conflict" && i < MAX_RETRIES - 1) {
|
|
209
211
|
logger.warn(`Conflict on update for doc ${id}, retry #${i + 1}`);
|
|
210
212
|
await new Promise((res) => setTimeout(res, 50 * Math.random()));
|
|
213
|
+
} else if (e.name === "not_found" && i === 0) {
|
|
214
|
+
logger.warn(`Update failed for ${id} - does not exist. Throwing to caller.`);
|
|
215
|
+
throw e;
|
|
211
216
|
} else {
|
|
212
217
|
delete this.inprogressUpdates[id];
|
|
213
218
|
if (this.pendingUpdates[id]) {
|
|
@@ -658,12 +663,74 @@ var init_elo = __esm({
|
|
|
658
663
|
}
|
|
659
664
|
});
|
|
660
665
|
|
|
666
|
+
// src/core/navigators/hardcodedOrder.ts
|
|
667
|
+
var hardcodedOrder_exports = {};
|
|
668
|
+
__export(hardcodedOrder_exports, {
|
|
669
|
+
default: () => HardcodedOrderNavigator
|
|
670
|
+
});
|
|
671
|
+
var HardcodedOrderNavigator;
|
|
672
|
+
var init_hardcodedOrder = __esm({
|
|
673
|
+
"src/core/navigators/hardcodedOrder.ts"() {
|
|
674
|
+
"use strict";
|
|
675
|
+
init_navigators();
|
|
676
|
+
init_logger();
|
|
677
|
+
HardcodedOrderNavigator = class extends ContentNavigator {
|
|
678
|
+
orderedCardIds = [];
|
|
679
|
+
user;
|
|
680
|
+
course;
|
|
681
|
+
constructor(user, course, strategyData) {
|
|
682
|
+
super();
|
|
683
|
+
this.user = user;
|
|
684
|
+
this.course = course;
|
|
685
|
+
if (strategyData.serializedData) {
|
|
686
|
+
try {
|
|
687
|
+
this.orderedCardIds = JSON.parse(strategyData.serializedData);
|
|
688
|
+
} catch (e) {
|
|
689
|
+
logger.error("Failed to parse serializedData for HardcodedOrderNavigator", e);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
async getPendingReviews() {
|
|
694
|
+
const reviews = await this.user.getPendingReviews(this.course.getCourseID());
|
|
695
|
+
return reviews.map((r) => {
|
|
696
|
+
return {
|
|
697
|
+
...r,
|
|
698
|
+
contentSourceType: "course",
|
|
699
|
+
contentSourceID: this.course.getCourseID(),
|
|
700
|
+
cardID: r.cardId,
|
|
701
|
+
courseID: r.courseId,
|
|
702
|
+
reviewID: r._id,
|
|
703
|
+
status: "review"
|
|
704
|
+
};
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
async getNewCards(limit = 99) {
|
|
708
|
+
const activeCardIds = (await this.user.getActiveCards()).map((c) => c.cardID);
|
|
709
|
+
const newCardIds = this.orderedCardIds.filter(
|
|
710
|
+
(cardId) => !activeCardIds.includes(cardId)
|
|
711
|
+
);
|
|
712
|
+
const cardsToReturn = newCardIds.slice(0, limit);
|
|
713
|
+
return cardsToReturn.map((cardId) => {
|
|
714
|
+
return {
|
|
715
|
+
cardID: cardId,
|
|
716
|
+
courseID: this.course.getCourseID(),
|
|
717
|
+
contentSourceType: "course",
|
|
718
|
+
contentSourceID: this.course.getCourseID(),
|
|
719
|
+
status: "new"
|
|
720
|
+
};
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
|
|
661
727
|
// import("./**/*") in src/core/navigators/index.ts
|
|
662
728
|
var globImport;
|
|
663
729
|
var init_ = __esm({
|
|
664
730
|
'import("./**/*") in src/core/navigators/index.ts'() {
|
|
665
731
|
globImport = __glob({
|
|
666
732
|
"./elo.ts": () => Promise.resolve().then(() => (init_elo(), elo_exports)),
|
|
733
|
+
"./hardcodedOrder.ts": () => Promise.resolve().then(() => (init_hardcodedOrder(), hardcodedOrder_exports)),
|
|
667
734
|
"./index.ts": () => Promise.resolve().then(() => (init_navigators(), navigators_exports))
|
|
668
735
|
});
|
|
669
736
|
}
|
|
@@ -683,6 +750,7 @@ var init_navigators = __esm({
|
|
|
683
750
|
init_();
|
|
684
751
|
Navigators = /* @__PURE__ */ ((Navigators2) => {
|
|
685
752
|
Navigators2["ELO"] = "elo";
|
|
753
|
+
Navigators2["HARDCODED"] = "hardcodedOrder";
|
|
686
754
|
return Navigators2;
|
|
687
755
|
})(Navigators || {});
|
|
688
756
|
ContentNavigator = class {
|
|
@@ -994,6 +1062,23 @@ var init_courseDB = __esm({
|
|
|
994
1062
|
if (!doc.docType || !(doc.docType === "CARD" /* CARD */)) {
|
|
995
1063
|
throw new Error(`failed to remove ${id} from course ${this.id}. id does not point to a card`);
|
|
996
1064
|
}
|
|
1065
|
+
try {
|
|
1066
|
+
const appliedTags = await this.getAppliedTags(id);
|
|
1067
|
+
const results = await Promise.allSettled(
|
|
1068
|
+
appliedTags.rows.map(async (tagRow) => {
|
|
1069
|
+
const tagId = tagRow.id;
|
|
1070
|
+
await this.removeTagFromCard(id, tagId);
|
|
1071
|
+
})
|
|
1072
|
+
);
|
|
1073
|
+
results.forEach((result, index) => {
|
|
1074
|
+
if (result.status === "rejected") {
|
|
1075
|
+
const tagId = appliedTags.rows[index].id;
|
|
1076
|
+
logger.error(`Failed to remove card ${id} from tag ${tagId}: ${result.reason}`);
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
} catch (error) {
|
|
1080
|
+
logger.error(`Error removing card ${id} from tags: ${error}`);
|
|
1081
|
+
}
|
|
997
1082
|
return this.db.remove(doc);
|
|
998
1083
|
}
|
|
999
1084
|
async getCardDisplayableDataIDs(id) {
|
|
@@ -1177,23 +1262,9 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1177
1262
|
////////////////////////////////////
|
|
1178
1263
|
getNavigationStrategy(id) {
|
|
1179
1264
|
logger.debug(`[courseDB] Getting navigation strategy: ${id}`);
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
name: "ELO",
|
|
1184
|
-
description: "ELO-based navigation strategy for ordering content by difficulty",
|
|
1185
|
-
implementingClass: "elo" /* ELO */,
|
|
1186
|
-
course: this.id,
|
|
1187
|
-
serializedData: ""
|
|
1188
|
-
// serde is a noop for ELO navigator.
|
|
1189
|
-
};
|
|
1190
|
-
return Promise.resolve(strategy);
|
|
1191
|
-
}
|
|
1192
|
-
getAllNavigationStrategies() {
|
|
1193
|
-
logger.debug("[courseDB] Returning hard-coded navigation strategies");
|
|
1194
|
-
const strategies = [
|
|
1195
|
-
{
|
|
1196
|
-
id: "ELO",
|
|
1265
|
+
if (id == "") {
|
|
1266
|
+
const strategy = {
|
|
1267
|
+
_id: "NAVIGATION_STRATEGY-ELO",
|
|
1197
1268
|
docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
|
|
1198
1269
|
name: "ELO",
|
|
1199
1270
|
description: "ELO-based navigation strategy for ordering content by difficulty",
|
|
@@ -1201,14 +1272,25 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1201
1272
|
course: this.id,
|
|
1202
1273
|
serializedData: ""
|
|
1203
1274
|
// serde is a noop for ELO navigator.
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1275
|
+
};
|
|
1276
|
+
return Promise.resolve(strategy);
|
|
1277
|
+
} else {
|
|
1278
|
+
return this.db.get(id);
|
|
1279
|
+
}
|
|
1207
1280
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1281
|
+
async getAllNavigationStrategies() {
|
|
1282
|
+
const prefix = DocTypePrefixes["NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */];
|
|
1283
|
+
const result = await this.db.allDocs({
|
|
1284
|
+
startkey: prefix,
|
|
1285
|
+
endkey: `${prefix}\uFFF0`,
|
|
1286
|
+
include_docs: true
|
|
1287
|
+
});
|
|
1288
|
+
return result.rows.map((row) => row.doc);
|
|
1289
|
+
}
|
|
1290
|
+
async addNavigationStrategy(data) {
|
|
1291
|
+
logger.debug(`[courseDB] Adding navigation strategy: ${data._id}`);
|
|
1292
|
+
return this.db.put(data).then(() => {
|
|
1293
|
+
});
|
|
1212
1294
|
}
|
|
1213
1295
|
updateNavigationStrategy(id, data) {
|
|
1214
1296
|
logger.debug(`[courseDB] Updating navigation strategy: ${id}`);
|
|
@@ -1216,9 +1298,32 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1216
1298
|
return Promise.resolve();
|
|
1217
1299
|
}
|
|
1218
1300
|
async surfaceNavigationStrategy() {
|
|
1301
|
+
try {
|
|
1302
|
+
const config = await this.getCourseConfig();
|
|
1303
|
+
if (config.defaultNavigationStrategyId) {
|
|
1304
|
+
try {
|
|
1305
|
+
const strategy = await this.getNavigationStrategy(config.defaultNavigationStrategyId);
|
|
1306
|
+
if (strategy) {
|
|
1307
|
+
logger.debug(`Surfacing strategy ${strategy.name} from course config`);
|
|
1308
|
+
return strategy;
|
|
1309
|
+
}
|
|
1310
|
+
} catch (e) {
|
|
1311
|
+
logger.warn(
|
|
1312
|
+
// @ts-expect-error tmp: defaultNavigationStrategyId property does not yet exist
|
|
1313
|
+
`Failed to load strategy '${config.defaultNavigationStrategyId}' specified in course config. Falling back to ELO.`,
|
|
1314
|
+
e
|
|
1315
|
+
);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
} catch (e) {
|
|
1319
|
+
logger.warn(
|
|
1320
|
+
"Could not retrieve course config to determine navigation strategy. Falling back to ELO.",
|
|
1321
|
+
e
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1219
1324
|
logger.warn(`Returning hard-coded default ELO navigator`);
|
|
1220
1325
|
const ret = {
|
|
1221
|
-
|
|
1326
|
+
_id: "NAVIGATION_STRATEGY-ELO",
|
|
1222
1327
|
docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
|
|
1223
1328
|
name: "ELO",
|
|
1224
1329
|
description: "ELO-based navigation strategy",
|
|
@@ -2595,17 +2700,21 @@ Currently logged-in as ${this._username}.`
|
|
|
2595
2700
|
} catch (e) {
|
|
2596
2701
|
const reason = e;
|
|
2597
2702
|
if (reason.status === 404) {
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2703
|
+
try {
|
|
2704
|
+
const initCardHistory = {
|
|
2705
|
+
_id: cardHistoryID,
|
|
2706
|
+
cardID: record.cardID,
|
|
2707
|
+
courseID: record.courseID,
|
|
2708
|
+
records: [record],
|
|
2709
|
+
lapses: 0,
|
|
2710
|
+
streak: 0,
|
|
2711
|
+
bestInterval: 0
|
|
2712
|
+
};
|
|
2713
|
+
const putResult = await this.writeDB.put(initCardHistory);
|
|
2714
|
+
return { ...initCardHistory, _rev: putResult.rev };
|
|
2715
|
+
} catch (creationError) {
|
|
2716
|
+
throw new Error(`Failed to create CardHistory for ${cardHistoryID}. Reason: ${creationError}`);
|
|
2717
|
+
}
|
|
2609
2718
|
} else {
|
|
2610
2719
|
throw new Error(`putCardRecord failed because of:
|
|
2611
2720
|
name:${reason.name}
|