@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
|
@@ -150,7 +150,9 @@ var init_updateQueue = __esm({
|
|
|
150
150
|
async applyUpdates(id) {
|
|
151
151
|
logger.debug(`Applying updates on doc: ${id}`);
|
|
152
152
|
if (this.inprogressUpdates[id]) {
|
|
153
|
-
|
|
153
|
+
while (this.inprogressUpdates[id]) {
|
|
154
|
+
await new Promise((resolve) => setTimeout(resolve, Math.random() * 50));
|
|
155
|
+
}
|
|
154
156
|
return this.applyUpdates(id);
|
|
155
157
|
} else {
|
|
156
158
|
if (this.pendingUpdates[id] && this.pendingUpdates[id].length > 0) {
|
|
@@ -186,6 +188,9 @@ var init_updateQueue = __esm({
|
|
|
186
188
|
if (e.name === "conflict" && i < MAX_RETRIES - 1) {
|
|
187
189
|
logger.warn(`Conflict on update for doc ${id}, retry #${i + 1}`);
|
|
188
190
|
await new Promise((res) => setTimeout(res, 50 * Math.random()));
|
|
191
|
+
} else if (e.name === "not_found" && i === 0) {
|
|
192
|
+
logger.warn(`Update failed for ${id} - does not exist. Throwing to caller.`);
|
|
193
|
+
throw e;
|
|
189
194
|
} else {
|
|
190
195
|
delete this.inprogressUpdates[id];
|
|
191
196
|
if (this.pendingUpdates[id]) {
|
|
@@ -636,12 +641,74 @@ var init_elo = __esm({
|
|
|
636
641
|
}
|
|
637
642
|
});
|
|
638
643
|
|
|
644
|
+
// src/core/navigators/hardcodedOrder.ts
|
|
645
|
+
var hardcodedOrder_exports = {};
|
|
646
|
+
__export(hardcodedOrder_exports, {
|
|
647
|
+
default: () => HardcodedOrderNavigator
|
|
648
|
+
});
|
|
649
|
+
var HardcodedOrderNavigator;
|
|
650
|
+
var init_hardcodedOrder = __esm({
|
|
651
|
+
"src/core/navigators/hardcodedOrder.ts"() {
|
|
652
|
+
"use strict";
|
|
653
|
+
init_navigators();
|
|
654
|
+
init_logger();
|
|
655
|
+
HardcodedOrderNavigator = class extends ContentNavigator {
|
|
656
|
+
orderedCardIds = [];
|
|
657
|
+
user;
|
|
658
|
+
course;
|
|
659
|
+
constructor(user, course, strategyData) {
|
|
660
|
+
super();
|
|
661
|
+
this.user = user;
|
|
662
|
+
this.course = course;
|
|
663
|
+
if (strategyData.serializedData) {
|
|
664
|
+
try {
|
|
665
|
+
this.orderedCardIds = JSON.parse(strategyData.serializedData);
|
|
666
|
+
} catch (e) {
|
|
667
|
+
logger.error("Failed to parse serializedData for HardcodedOrderNavigator", e);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
async getPendingReviews() {
|
|
672
|
+
const reviews = await this.user.getPendingReviews(this.course.getCourseID());
|
|
673
|
+
return reviews.map((r) => {
|
|
674
|
+
return {
|
|
675
|
+
...r,
|
|
676
|
+
contentSourceType: "course",
|
|
677
|
+
contentSourceID: this.course.getCourseID(),
|
|
678
|
+
cardID: r.cardId,
|
|
679
|
+
courseID: r.courseId,
|
|
680
|
+
reviewID: r._id,
|
|
681
|
+
status: "review"
|
|
682
|
+
};
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
async getNewCards(limit = 99) {
|
|
686
|
+
const activeCardIds = (await this.user.getActiveCards()).map((c) => c.cardID);
|
|
687
|
+
const newCardIds = this.orderedCardIds.filter(
|
|
688
|
+
(cardId) => !activeCardIds.includes(cardId)
|
|
689
|
+
);
|
|
690
|
+
const cardsToReturn = newCardIds.slice(0, limit);
|
|
691
|
+
return cardsToReturn.map((cardId) => {
|
|
692
|
+
return {
|
|
693
|
+
cardID: cardId,
|
|
694
|
+
courseID: this.course.getCourseID(),
|
|
695
|
+
contentSourceType: "course",
|
|
696
|
+
contentSourceID: this.course.getCourseID(),
|
|
697
|
+
status: "new"
|
|
698
|
+
};
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
|
|
639
705
|
// import("./**/*") in src/core/navigators/index.ts
|
|
640
706
|
var globImport;
|
|
641
707
|
var init_ = __esm({
|
|
642
708
|
'import("./**/*") in src/core/navigators/index.ts'() {
|
|
643
709
|
globImport = __glob({
|
|
644
710
|
"./elo.ts": () => Promise.resolve().then(() => (init_elo(), elo_exports)),
|
|
711
|
+
"./hardcodedOrder.ts": () => Promise.resolve().then(() => (init_hardcodedOrder(), hardcodedOrder_exports)),
|
|
645
712
|
"./index.ts": () => Promise.resolve().then(() => (init_navigators(), navigators_exports))
|
|
646
713
|
});
|
|
647
714
|
}
|
|
@@ -661,6 +728,7 @@ var init_navigators = __esm({
|
|
|
661
728
|
init_();
|
|
662
729
|
Navigators = /* @__PURE__ */ ((Navigators2) => {
|
|
663
730
|
Navigators2["ELO"] = "elo";
|
|
731
|
+
Navigators2["HARDCODED"] = "hardcodedOrder";
|
|
664
732
|
return Navigators2;
|
|
665
733
|
})(Navigators || {});
|
|
666
734
|
ContentNavigator = class {
|
|
@@ -977,6 +1045,23 @@ var init_courseDB = __esm({
|
|
|
977
1045
|
if (!doc.docType || !(doc.docType === "CARD" /* CARD */)) {
|
|
978
1046
|
throw new Error(`failed to remove ${id} from course ${this.id}. id does not point to a card`);
|
|
979
1047
|
}
|
|
1048
|
+
try {
|
|
1049
|
+
const appliedTags = await this.getAppliedTags(id);
|
|
1050
|
+
const results = await Promise.allSettled(
|
|
1051
|
+
appliedTags.rows.map(async (tagRow) => {
|
|
1052
|
+
const tagId = tagRow.id;
|
|
1053
|
+
await this.removeTagFromCard(id, tagId);
|
|
1054
|
+
})
|
|
1055
|
+
);
|
|
1056
|
+
results.forEach((result, index) => {
|
|
1057
|
+
if (result.status === "rejected") {
|
|
1058
|
+
const tagId = appliedTags.rows[index].id;
|
|
1059
|
+
logger.error(`Failed to remove card ${id} from tag ${tagId}: ${result.reason}`);
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
} catch (error) {
|
|
1063
|
+
logger.error(`Error removing card ${id} from tags: ${error}`);
|
|
1064
|
+
}
|
|
980
1065
|
return this.db.remove(doc);
|
|
981
1066
|
}
|
|
982
1067
|
async getCardDisplayableDataIDs(id) {
|
|
@@ -1160,23 +1245,9 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1160
1245
|
////////////////////////////////////
|
|
1161
1246
|
getNavigationStrategy(id) {
|
|
1162
1247
|
logger.debug(`[courseDB] Getting navigation strategy: ${id}`);
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
name: "ELO",
|
|
1167
|
-
description: "ELO-based navigation strategy for ordering content by difficulty",
|
|
1168
|
-
implementingClass: "elo" /* ELO */,
|
|
1169
|
-
course: this.id,
|
|
1170
|
-
serializedData: ""
|
|
1171
|
-
// serde is a noop for ELO navigator.
|
|
1172
|
-
};
|
|
1173
|
-
return Promise.resolve(strategy);
|
|
1174
|
-
}
|
|
1175
|
-
getAllNavigationStrategies() {
|
|
1176
|
-
logger.debug("[courseDB] Returning hard-coded navigation strategies");
|
|
1177
|
-
const strategies = [
|
|
1178
|
-
{
|
|
1179
|
-
id: "ELO",
|
|
1248
|
+
if (id == "") {
|
|
1249
|
+
const strategy = {
|
|
1250
|
+
_id: "NAVIGATION_STRATEGY-ELO",
|
|
1180
1251
|
docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
|
|
1181
1252
|
name: "ELO",
|
|
1182
1253
|
description: "ELO-based navigation strategy for ordering content by difficulty",
|
|
@@ -1184,14 +1255,25 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1184
1255
|
course: this.id,
|
|
1185
1256
|
serializedData: ""
|
|
1186
1257
|
// serde is a noop for ELO navigator.
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1258
|
+
};
|
|
1259
|
+
return Promise.resolve(strategy);
|
|
1260
|
+
} else {
|
|
1261
|
+
return this.db.get(id);
|
|
1262
|
+
}
|
|
1190
1263
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1264
|
+
async getAllNavigationStrategies() {
|
|
1265
|
+
const prefix = DocTypePrefixes["NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */];
|
|
1266
|
+
const result = await this.db.allDocs({
|
|
1267
|
+
startkey: prefix,
|
|
1268
|
+
endkey: `${prefix}\uFFF0`,
|
|
1269
|
+
include_docs: true
|
|
1270
|
+
});
|
|
1271
|
+
return result.rows.map((row) => row.doc);
|
|
1272
|
+
}
|
|
1273
|
+
async addNavigationStrategy(data) {
|
|
1274
|
+
logger.debug(`[courseDB] Adding navigation strategy: ${data._id}`);
|
|
1275
|
+
return this.db.put(data).then(() => {
|
|
1276
|
+
});
|
|
1195
1277
|
}
|
|
1196
1278
|
updateNavigationStrategy(id, data) {
|
|
1197
1279
|
logger.debug(`[courseDB] Updating navigation strategy: ${id}`);
|
|
@@ -1199,9 +1281,32 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1199
1281
|
return Promise.resolve();
|
|
1200
1282
|
}
|
|
1201
1283
|
async surfaceNavigationStrategy() {
|
|
1284
|
+
try {
|
|
1285
|
+
const config = await this.getCourseConfig();
|
|
1286
|
+
if (config.defaultNavigationStrategyId) {
|
|
1287
|
+
try {
|
|
1288
|
+
const strategy = await this.getNavigationStrategy(config.defaultNavigationStrategyId);
|
|
1289
|
+
if (strategy) {
|
|
1290
|
+
logger.debug(`Surfacing strategy ${strategy.name} from course config`);
|
|
1291
|
+
return strategy;
|
|
1292
|
+
}
|
|
1293
|
+
} catch (e) {
|
|
1294
|
+
logger.warn(
|
|
1295
|
+
// @ts-expect-error tmp: defaultNavigationStrategyId property does not yet exist
|
|
1296
|
+
`Failed to load strategy '${config.defaultNavigationStrategyId}' specified in course config. Falling back to ELO.`,
|
|
1297
|
+
e
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
} catch (e) {
|
|
1302
|
+
logger.warn(
|
|
1303
|
+
"Could not retrieve course config to determine navigation strategy. Falling back to ELO.",
|
|
1304
|
+
e
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1202
1307
|
logger.warn(`Returning hard-coded default ELO navigator`);
|
|
1203
1308
|
const ret = {
|
|
1204
|
-
|
|
1309
|
+
_id: "NAVIGATION_STRATEGY-ELO",
|
|
1205
1310
|
docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
|
|
1206
1311
|
name: "ELO",
|
|
1207
1312
|
description: "ELO-based navigation strategy",
|
|
@@ -2576,17 +2681,21 @@ Currently logged-in as ${this._username}.`
|
|
|
2576
2681
|
} catch (e) {
|
|
2577
2682
|
const reason = e;
|
|
2578
2683
|
if (reason.status === 404) {
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2684
|
+
try {
|
|
2685
|
+
const initCardHistory = {
|
|
2686
|
+
_id: cardHistoryID,
|
|
2687
|
+
cardID: record.cardID,
|
|
2688
|
+
courseID: record.courseID,
|
|
2689
|
+
records: [record],
|
|
2690
|
+
lapses: 0,
|
|
2691
|
+
streak: 0,
|
|
2692
|
+
bestInterval: 0
|
|
2693
|
+
};
|
|
2694
|
+
const putResult = await this.writeDB.put(initCardHistory);
|
|
2695
|
+
return { ...initCardHistory, _rev: putResult.rev };
|
|
2696
|
+
} catch (creationError) {
|
|
2697
|
+
throw new Error(`Failed to create CardHistory for ${cardHistoryID}. Reason: ${creationError}`);
|
|
2698
|
+
}
|
|
2590
2699
|
} else {
|
|
2591
2700
|
throw new Error(`putCardRecord failed because of:
|
|
2592
2701
|
name:${reason.name}
|