@vue-skuilder/db 0.1.30 → 0.1.31-b
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.cts +14 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.js +68 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +68 -4
- package/dist/core/index.mjs.map +1 -1
- package/dist/impl/couch/index.js +68 -4
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +68 -4
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.js +68 -4
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +68 -4
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.js +83 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +74 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/core/navigators/PipelineDebugger.ts +80 -0
- package/src/core/navigators/generators/elo.ts +17 -6
- package/src/study/SpacedRepetition.ts +4 -1
package/dist/index.js
CHANGED
|
@@ -966,6 +966,7 @@ var MAX_RUNS, runHistory, pipelineDebugAPI;
|
|
|
966
966
|
var init_PipelineDebugger = __esm({
|
|
967
967
|
"src/core/navigators/PipelineDebugger.ts"() {
|
|
968
968
|
"use strict";
|
|
969
|
+
init_navigators();
|
|
969
970
|
init_logger();
|
|
970
971
|
MAX_RUNS = 10;
|
|
971
972
|
runHistory = [];
|
|
@@ -1108,6 +1109,66 @@ var init_PipelineDebugger = __esm({
|
|
|
1108
1109
|
runHistory.length = 0;
|
|
1109
1110
|
logger.info("[Pipeline Debug] Run history cleared.");
|
|
1110
1111
|
},
|
|
1112
|
+
/**
|
|
1113
|
+
* Show the navigator registry: all registered classes and their roles.
|
|
1114
|
+
*
|
|
1115
|
+
* Useful for verifying that consumer-defined navigators were registered
|
|
1116
|
+
* before pipeline assembly.
|
|
1117
|
+
*/
|
|
1118
|
+
showRegistry() {
|
|
1119
|
+
const names = getRegisteredNavigatorNames();
|
|
1120
|
+
if (names.length === 0) {
|
|
1121
|
+
logger.info("[Pipeline Debug] Navigator registry is empty.");
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
console.group("\u{1F4E6} Navigator Registry");
|
|
1125
|
+
console.table(
|
|
1126
|
+
names.map((name) => {
|
|
1127
|
+
const registryRole = getRegisteredNavigatorRole(name);
|
|
1128
|
+
const builtinRole = NavigatorRoles[name];
|
|
1129
|
+
const effectiveRole = builtinRole || registryRole || "\u26A0\uFE0F NONE";
|
|
1130
|
+
const source = builtinRole ? "built-in" : registryRole ? "consumer" : "unclassified";
|
|
1131
|
+
return {
|
|
1132
|
+
name,
|
|
1133
|
+
role: effectiveRole,
|
|
1134
|
+
source,
|
|
1135
|
+
isGenerator: isGenerator(name),
|
|
1136
|
+
isFilter: isFilter(name)
|
|
1137
|
+
};
|
|
1138
|
+
})
|
|
1139
|
+
);
|
|
1140
|
+
console.groupEnd();
|
|
1141
|
+
},
|
|
1142
|
+
/**
|
|
1143
|
+
* Show strategy documents from the last pipeline run and how they mapped
|
|
1144
|
+
* to the registry.
|
|
1145
|
+
*
|
|
1146
|
+
* If no runs are captured yet, falls back to showing just the registry.
|
|
1147
|
+
*/
|
|
1148
|
+
showStrategies() {
|
|
1149
|
+
this.showRegistry();
|
|
1150
|
+
if (runHistory.length === 0) {
|
|
1151
|
+
logger.info("[Pipeline Debug] No pipeline runs captured yet \u2014 cannot show strategy doc mapping.");
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const run = runHistory[0];
|
|
1155
|
+
console.group("\u{1F50C} Pipeline Strategy Mapping (last run)");
|
|
1156
|
+
logger.info(`Generator: ${run.generatorName}`);
|
|
1157
|
+
if (run.generators && run.generators.length > 0) {
|
|
1158
|
+
for (const g of run.generators) {
|
|
1159
|
+
logger.info(` \u{1F4E5} ${g.name}: ${g.cardCount} cards (${g.newCount} new, ${g.reviewCount} reviews)`);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
if (run.filters.length > 0) {
|
|
1163
|
+
logger.info("Filters:");
|
|
1164
|
+
for (const f of run.filters) {
|
|
1165
|
+
logger.info(` \u{1F538} ${f.name}: \u2191${f.boosted} \u2193${f.penalized} =${f.passed} \u2715${f.removed}`);
|
|
1166
|
+
}
|
|
1167
|
+
} else {
|
|
1168
|
+
logger.info("Filters: (none)");
|
|
1169
|
+
}
|
|
1170
|
+
console.groupEnd();
|
|
1171
|
+
},
|
|
1111
1172
|
/**
|
|
1112
1173
|
* Show help.
|
|
1113
1174
|
*/
|
|
@@ -1120,6 +1181,8 @@ Commands:
|
|
|
1120
1181
|
.showRun(id|index) Show summary of a specific run (by index or ID suffix)
|
|
1121
1182
|
.showCard(cardId) Show provenance trail for a specific card
|
|
1122
1183
|
.explainReviews() Analyze why reviews were/weren't selected
|
|
1184
|
+
.showRegistry() Show navigator registry (classes + roles)
|
|
1185
|
+
.showStrategies() Show registry + strategy mapping from last run
|
|
1123
1186
|
.listRuns() List all captured runs in table format
|
|
1124
1187
|
.export() Export run history as JSON for bug reports
|
|
1125
1188
|
.clear() Clear run history
|
|
@@ -1382,19 +1445,20 @@ var init_elo = __esm({
|
|
|
1382
1445
|
const scored = newCards.map((c, i) => {
|
|
1383
1446
|
const cardElo = cardEloData[i]?.global?.score ?? 1e3;
|
|
1384
1447
|
const distance = Math.abs(cardElo - userGlobalElo);
|
|
1385
|
-
const
|
|
1448
|
+
const rawScore = Math.max(0, 1 - distance / 500);
|
|
1449
|
+
const samplingKey = rawScore > 0 ? Math.random() ** (1 / rawScore) : 0;
|
|
1386
1450
|
return {
|
|
1387
1451
|
cardId: c.cardID,
|
|
1388
1452
|
courseId: c.courseID,
|
|
1389
|
-
score,
|
|
1453
|
+
score: samplingKey,
|
|
1390
1454
|
provenance: [
|
|
1391
1455
|
{
|
|
1392
1456
|
strategy: "elo",
|
|
1393
1457
|
strategyName: this.strategyName || this.name,
|
|
1394
1458
|
strategyId: this.strategyId || "NAVIGATION_STRATEGY-ELO-default",
|
|
1395
1459
|
action: "generated",
|
|
1396
|
-
score,
|
|
1397
|
-
reason: `ELO distance ${Math.round(distance)} (card: ${Math.round(cardElo)}, user: ${Math.round(userGlobalElo)}),
|
|
1460
|
+
score: samplingKey,
|
|
1461
|
+
reason: `ELO distance ${Math.round(distance)} (card: ${Math.round(cardElo)}, user: ${Math.round(userGlobalElo)}), raw ${rawScore.toFixed(3)}, key ${samplingKey.toFixed(3)}`
|
|
1398
1462
|
}
|
|
1399
1463
|
]
|
|
1400
1464
|
};
|
|
@@ -8367,6 +8431,7 @@ init_couch();
|
|
|
8367
8431
|
// src/study/SpacedRepetition.ts
|
|
8368
8432
|
init_util();
|
|
8369
8433
|
var import_moment7 = __toESM(require("moment"), 1);
|
|
8434
|
+
var import_common22 = require("@vue-skuilder/common");
|
|
8370
8435
|
init_logger();
|
|
8371
8436
|
var duration = import_moment7.default.duration;
|
|
8372
8437
|
function newInterval(user, cardHistory) {
|
|
@@ -8387,7 +8452,9 @@ function newQuestionInterval(user, cardHistory) {
|
|
|
8387
8452
|
});
|
|
8388
8453
|
}
|
|
8389
8454
|
if (currentAttempt.isCorrect) {
|
|
8390
|
-
const
|
|
8455
|
+
const rawPerf = currentAttempt.performance;
|
|
8456
|
+
const numericPerf = (0, import_common22.isTaggedPerformance)(rawPerf) ? rawPerf._global : rawPerf;
|
|
8457
|
+
const skill = Math.min(1, Math.max(0, numericPerf));
|
|
8391
8458
|
logger.debug(`Demontrated skill: ${skill}`);
|
|
8392
8459
|
const interval = lastInterval * (0.75 + skill);
|
|
8393
8460
|
cardHistory.lapses = getLapses(cardHistory.records);
|
|
@@ -8478,7 +8545,7 @@ var SrsService = class {
|
|
|
8478
8545
|
};
|
|
8479
8546
|
|
|
8480
8547
|
// src/study/services/EloService.ts
|
|
8481
|
-
var
|
|
8548
|
+
var import_common23 = require("@vue-skuilder/common");
|
|
8482
8549
|
init_logger();
|
|
8483
8550
|
var EloService = class {
|
|
8484
8551
|
dataLayer;
|
|
@@ -8501,12 +8568,12 @@ var EloService = class {
|
|
|
8501
8568
|
logger.warn(`k value interpretation not currently implemented`);
|
|
8502
8569
|
}
|
|
8503
8570
|
const courseDB = this.dataLayer.getCourseDB(currentCard.card.course_id);
|
|
8504
|
-
const userElo = (0,
|
|
8571
|
+
const userElo = (0, import_common23.toCourseElo)(
|
|
8505
8572
|
userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo
|
|
8506
8573
|
);
|
|
8507
8574
|
const cardElo = (await courseDB.getCardEloData([currentCard.card.card_id]))[0];
|
|
8508
8575
|
if (cardElo && userElo) {
|
|
8509
|
-
const eloUpdate = (0,
|
|
8576
|
+
const eloUpdate = (0, import_common23.adjustCourseScores)(userElo, cardElo, userScore);
|
|
8510
8577
|
userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo = eloUpdate.userElo;
|
|
8511
8578
|
const results = await Promise.allSettled([
|
|
8512
8579
|
this.user.updateUserElo(course_id, eloUpdate.userElo),
|
|
@@ -8552,12 +8619,12 @@ var EloService = class {
|
|
|
8552
8619
|
*/
|
|
8553
8620
|
async updateUserAndCardEloPerTag(taggedPerformance, course_id, card_id, userCourseRegDoc, currentCard) {
|
|
8554
8621
|
const courseDB = this.dataLayer.getCourseDB(currentCard.card.course_id);
|
|
8555
|
-
const userElo = (0,
|
|
8622
|
+
const userElo = (0, import_common23.toCourseElo)(
|
|
8556
8623
|
userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo
|
|
8557
8624
|
);
|
|
8558
8625
|
const cardElo = (await courseDB.getCardEloData([currentCard.card.card_id]))[0];
|
|
8559
8626
|
if (cardElo && userElo) {
|
|
8560
|
-
const eloUpdate = (0,
|
|
8627
|
+
const eloUpdate = (0, import_common23.adjustCourseScoresPerTag)(userElo, cardElo, taggedPerformance);
|
|
8561
8628
|
userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo = eloUpdate.userElo;
|
|
8562
8629
|
const results = await Promise.allSettled([
|
|
8563
8630
|
this.user.updateUserElo(course_id, eloUpdate.userElo),
|
|
@@ -8597,7 +8664,7 @@ var EloService = class {
|
|
|
8597
8664
|
// src/study/services/ResponseProcessor.ts
|
|
8598
8665
|
init_core();
|
|
8599
8666
|
init_logger();
|
|
8600
|
-
var
|
|
8667
|
+
var import_common24 = require("@vue-skuilder/common");
|
|
8601
8668
|
var ResponseProcessor = class {
|
|
8602
8669
|
srsService;
|
|
8603
8670
|
eloService;
|
|
@@ -8618,7 +8685,7 @@ var ResponseProcessor = class {
|
|
|
8618
8685
|
taggedPerformance: null
|
|
8619
8686
|
};
|
|
8620
8687
|
}
|
|
8621
|
-
if ((0,
|
|
8688
|
+
if ((0, import_common24.isTaggedPerformance)(performance2)) {
|
|
8622
8689
|
return {
|
|
8623
8690
|
globalScore: performance2._global,
|
|
8624
8691
|
taggedPerformance: performance2
|
|
@@ -8826,7 +8893,7 @@ var ResponseProcessor = class {
|
|
|
8826
8893
|
};
|
|
8827
8894
|
|
|
8828
8895
|
// src/study/services/CardHydrationService.ts
|
|
8829
|
-
var
|
|
8896
|
+
var import_common25 = require("@vue-skuilder/common");
|
|
8830
8897
|
init_logger();
|
|
8831
8898
|
function parseAudioURIs(data) {
|
|
8832
8899
|
if (typeof data !== "string") return [];
|
|
@@ -8961,8 +9028,8 @@ var CardHydrationService = class {
|
|
|
8961
9028
|
try {
|
|
8962
9029
|
const courseDB = this.getCourseDB(item.courseID);
|
|
8963
9030
|
const cardData = await courseDB.getCourseDoc(item.cardID);
|
|
8964
|
-
if (!(0,
|
|
8965
|
-
cardData.elo = (0,
|
|
9031
|
+
if (!(0, import_common25.isCourseElo)(cardData.elo)) {
|
|
9032
|
+
cardData.elo = (0, import_common25.toCourseElo)(cardData.elo);
|
|
8966
9033
|
}
|
|
8967
9034
|
const view = this.getViewComponent(cardData.id_view);
|
|
8968
9035
|
const dataDocs = await Promise.all(
|
|
@@ -8986,7 +9053,7 @@ var CardHydrationService = class {
|
|
|
8986
9053
|
);
|
|
8987
9054
|
await Promise.allSettled(uniqueAudioUrls.map(prefetchAudio));
|
|
8988
9055
|
}
|
|
8989
|
-
const data = dataDocs.map(
|
|
9056
|
+
const data = dataDocs.map(import_common25.displayableDataToViewData).reverse();
|
|
8990
9057
|
this.hydratedCards.set(item.cardID, {
|
|
8991
9058
|
item,
|
|
8992
9059
|
view,
|