@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
|
@@ -279,7 +279,9 @@ var init_updateQueue = __esm({
|
|
|
279
279
|
async applyUpdates(id) {
|
|
280
280
|
logger.debug(`Applying updates on doc: ${id}`);
|
|
281
281
|
if (this.inprogressUpdates[id]) {
|
|
282
|
-
|
|
282
|
+
while (this.inprogressUpdates[id]) {
|
|
283
|
+
await new Promise((resolve) => setTimeout(resolve, Math.random() * 50));
|
|
284
|
+
}
|
|
283
285
|
return this.applyUpdates(id);
|
|
284
286
|
} else {
|
|
285
287
|
if (this.pendingUpdates[id] && this.pendingUpdates[id].length > 0) {
|
|
@@ -315,6 +317,9 @@ var init_updateQueue = __esm({
|
|
|
315
317
|
if (e.name === "conflict" && i < MAX_RETRIES - 1) {
|
|
316
318
|
logger.warn(`Conflict on update for doc ${id}, retry #${i + 1}`);
|
|
317
319
|
await new Promise((res) => setTimeout(res, 50 * Math.random()));
|
|
320
|
+
} else if (e.name === "not_found" && i === 0) {
|
|
321
|
+
logger.warn(`Update failed for ${id} - does not exist. Throwing to caller.`);
|
|
322
|
+
throw e;
|
|
318
323
|
} else {
|
|
319
324
|
delete this.inprogressUpdates[id];
|
|
320
325
|
if (this.pendingUpdates[id]) {
|
|
@@ -510,12 +515,74 @@ var init_elo = __esm({
|
|
|
510
515
|
}
|
|
511
516
|
});
|
|
512
517
|
|
|
518
|
+
// src/core/navigators/hardcodedOrder.ts
|
|
519
|
+
var hardcodedOrder_exports = {};
|
|
520
|
+
__export(hardcodedOrder_exports, {
|
|
521
|
+
default: () => HardcodedOrderNavigator
|
|
522
|
+
});
|
|
523
|
+
var HardcodedOrderNavigator;
|
|
524
|
+
var init_hardcodedOrder = __esm({
|
|
525
|
+
"src/core/navigators/hardcodedOrder.ts"() {
|
|
526
|
+
"use strict";
|
|
527
|
+
init_navigators();
|
|
528
|
+
init_logger();
|
|
529
|
+
HardcodedOrderNavigator = class extends ContentNavigator {
|
|
530
|
+
orderedCardIds = [];
|
|
531
|
+
user;
|
|
532
|
+
course;
|
|
533
|
+
constructor(user, course, strategyData) {
|
|
534
|
+
super();
|
|
535
|
+
this.user = user;
|
|
536
|
+
this.course = course;
|
|
537
|
+
if (strategyData.serializedData) {
|
|
538
|
+
try {
|
|
539
|
+
this.orderedCardIds = JSON.parse(strategyData.serializedData);
|
|
540
|
+
} catch (e) {
|
|
541
|
+
logger.error("Failed to parse serializedData for HardcodedOrderNavigator", e);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
async getPendingReviews() {
|
|
546
|
+
const reviews = await this.user.getPendingReviews(this.course.getCourseID());
|
|
547
|
+
return reviews.map((r) => {
|
|
548
|
+
return {
|
|
549
|
+
...r,
|
|
550
|
+
contentSourceType: "course",
|
|
551
|
+
contentSourceID: this.course.getCourseID(),
|
|
552
|
+
cardID: r.cardId,
|
|
553
|
+
courseID: r.courseId,
|
|
554
|
+
reviewID: r._id,
|
|
555
|
+
status: "review"
|
|
556
|
+
};
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
async getNewCards(limit = 99) {
|
|
560
|
+
const activeCardIds = (await this.user.getActiveCards()).map((c) => c.cardID);
|
|
561
|
+
const newCardIds = this.orderedCardIds.filter(
|
|
562
|
+
(cardId) => !activeCardIds.includes(cardId)
|
|
563
|
+
);
|
|
564
|
+
const cardsToReturn = newCardIds.slice(0, limit);
|
|
565
|
+
return cardsToReturn.map((cardId) => {
|
|
566
|
+
return {
|
|
567
|
+
cardID: cardId,
|
|
568
|
+
courseID: this.course.getCourseID(),
|
|
569
|
+
contentSourceType: "course",
|
|
570
|
+
contentSourceID: this.course.getCourseID(),
|
|
571
|
+
status: "new"
|
|
572
|
+
};
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
|
|
513
579
|
// import("./**/*") in src/core/navigators/index.ts
|
|
514
580
|
var globImport;
|
|
515
581
|
var init_ = __esm({
|
|
516
582
|
'import("./**/*") in src/core/navigators/index.ts'() {
|
|
517
583
|
globImport = __glob({
|
|
518
584
|
"./elo.ts": () => Promise.resolve().then(() => (init_elo(), elo_exports)),
|
|
585
|
+
"./hardcodedOrder.ts": () => Promise.resolve().then(() => (init_hardcodedOrder(), hardcodedOrder_exports)),
|
|
519
586
|
"./index.ts": () => Promise.resolve().then(() => (init_navigators(), navigators_exports))
|
|
520
587
|
});
|
|
521
588
|
}
|
|
@@ -535,6 +602,7 @@ var init_navigators = __esm({
|
|
|
535
602
|
init_();
|
|
536
603
|
Navigators = /* @__PURE__ */ ((Navigators2) => {
|
|
537
604
|
Navigators2["ELO"] = "elo";
|
|
605
|
+
Navigators2["HARDCODED"] = "hardcodedOrder";
|
|
538
606
|
return Navigators2;
|
|
539
607
|
})(Navigators || {});
|
|
540
608
|
ContentNavigator = class {
|
|
@@ -1369,17 +1437,21 @@ Currently logged-in as ${this._username}.`
|
|
|
1369
1437
|
} catch (e) {
|
|
1370
1438
|
const reason = e;
|
|
1371
1439
|
if (reason.status === 404) {
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1440
|
+
try {
|
|
1441
|
+
const initCardHistory = {
|
|
1442
|
+
_id: cardHistoryID,
|
|
1443
|
+
cardID: record.cardID,
|
|
1444
|
+
courseID: record.courseID,
|
|
1445
|
+
records: [record],
|
|
1446
|
+
lapses: 0,
|
|
1447
|
+
streak: 0,
|
|
1448
|
+
bestInterval: 0
|
|
1449
|
+
};
|
|
1450
|
+
const putResult = await this.writeDB.put(initCardHistory);
|
|
1451
|
+
return { ...initCardHistory, _rev: putResult.rev };
|
|
1452
|
+
} catch (creationError) {
|
|
1453
|
+
throw new Error(`Failed to create CardHistory for ${cardHistoryID}. Reason: ${creationError}`);
|
|
1454
|
+
}
|
|
1383
1455
|
} else {
|
|
1384
1456
|
throw new Error(`putCardRecord failed because of:
|
|
1385
1457
|
name:${reason.name}
|
|
@@ -2167,16 +2239,20 @@ var init_courseDB3 = __esm({
|
|
|
2167
2239
|
async updateCardElo(cardId, _elo) {
|
|
2168
2240
|
return { ok: true, id: cardId, rev: "1-static" };
|
|
2169
2241
|
}
|
|
2170
|
-
async getNewCards(limit) {
|
|
2171
|
-
const
|
|
2172
|
-
return
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2242
|
+
async getNewCards(limit = 99) {
|
|
2243
|
+
const activeCards = await this.userDB.getActiveCards();
|
|
2244
|
+
return (await this.getCardsCenteredAtELO({ limit, elo: "user" }, (c) => {
|
|
2245
|
+
if (activeCards.some((ac) => c.cardID === ac.cardID)) {
|
|
2246
|
+
return false;
|
|
2247
|
+
} else {
|
|
2248
|
+
return true;
|
|
2249
|
+
}
|
|
2250
|
+
})).map((c) => {
|
|
2251
|
+
return {
|
|
2252
|
+
...c,
|
|
2253
|
+
status: "new"
|
|
2254
|
+
};
|
|
2255
|
+
});
|
|
2180
2256
|
}
|
|
2181
2257
|
async getCardsCenteredAtELO(options, filter) {
|
|
2182
2258
|
let targetElo = typeof options.elo === "number" ? options.elo : 1e3;
|
|
@@ -2357,7 +2433,7 @@ var init_courseDB3 = __esm({
|
|
|
2357
2433
|
// Navigation Strategy Manager implementation
|
|
2358
2434
|
async getNavigationStrategy(_id) {
|
|
2359
2435
|
return {
|
|
2360
|
-
|
|
2436
|
+
_id: "NAVIGATION_STRATEGY-ELO",
|
|
2361
2437
|
docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
|
|
2362
2438
|
name: "ELO",
|
|
2363
2439
|
description: "ELO-based navigation strategy",
|
|
@@ -2422,11 +2498,17 @@ var init_coursesDB = __esm({
|
|
|
2422
2498
|
this.manifests = manifests;
|
|
2423
2499
|
}
|
|
2424
2500
|
async getCourseConfig(courseId) {
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2501
|
+
const manifest = this.manifests[courseId];
|
|
2502
|
+
if (!manifest) {
|
|
2503
|
+
logger.warn(`Course manifest for ${courseId} not found`);
|
|
2504
|
+
throw new Error(`Course ${courseId} not found`);
|
|
2505
|
+
}
|
|
2506
|
+
if (manifest.courseConfig) {
|
|
2507
|
+
return manifest.courseConfig;
|
|
2508
|
+
} else {
|
|
2509
|
+
logger.warn(`Course config not found in manifest for course ${courseId}`);
|
|
2510
|
+
throw new Error(`Course config not found for course ${courseId}`);
|
|
2428
2511
|
}
|
|
2429
|
-
return {};
|
|
2430
2512
|
}
|
|
2431
2513
|
async getCourseList() {
|
|
2432
2514
|
return Object.keys(this.manifests).map(
|
|
@@ -2514,23 +2596,49 @@ var init_StaticDataLayerProvider = __esm({
|
|
|
2514
2596
|
config;
|
|
2515
2597
|
initialized = false;
|
|
2516
2598
|
courseUnpackers = /* @__PURE__ */ new Map();
|
|
2599
|
+
manifests = {};
|
|
2517
2600
|
constructor(config) {
|
|
2518
2601
|
this.config = {
|
|
2519
|
-
staticContentPath: config.staticContentPath || "/static-courses",
|
|
2520
2602
|
localStoragePrefix: config.localStoragePrefix || "skuilder-static",
|
|
2521
|
-
|
|
2603
|
+
rootManifest: config.rootManifest || { dependencies: {} },
|
|
2604
|
+
rootManifestUrl: config.rootManifestUrl || "/"
|
|
2522
2605
|
};
|
|
2523
2606
|
}
|
|
2607
|
+
async resolveCourseDependencies() {
|
|
2608
|
+
logger.info("[StaticDataLayerProvider] Starting course dependency resolution...");
|
|
2609
|
+
const rootManifest = this.config.rootManifest;
|
|
2610
|
+
for (const [courseName, courseUrl] of Object.entries(rootManifest.dependencies || {})) {
|
|
2611
|
+
try {
|
|
2612
|
+
logger.debug(`[StaticDataLayerProvider] Resolving dependency: ${courseName} from ${courseUrl}`);
|
|
2613
|
+
const courseManifestUrl = new URL(courseUrl, this.config.rootManifestUrl).href;
|
|
2614
|
+
const courseJsonResponse = await fetch(courseManifestUrl);
|
|
2615
|
+
if (!courseJsonResponse.ok) {
|
|
2616
|
+
throw new Error(`Failed to fetch course manifest for ${courseName}`);
|
|
2617
|
+
}
|
|
2618
|
+
const courseJson = await courseJsonResponse.json();
|
|
2619
|
+
if (courseJson.content && courseJson.content.manifest) {
|
|
2620
|
+
const baseUrl = new URL(".", courseManifestUrl).href;
|
|
2621
|
+
const finalManifestUrl = new URL(courseJson.content.manifest, courseManifestUrl).href;
|
|
2622
|
+
const finalManifestResponse = await fetch(finalManifestUrl);
|
|
2623
|
+
if (!finalManifestResponse.ok) {
|
|
2624
|
+
throw new Error(`Failed to fetch final content manifest for ${courseName} at ${finalManifestUrl}`);
|
|
2625
|
+
}
|
|
2626
|
+
const finalManifest = await finalManifestResponse.json();
|
|
2627
|
+
this.manifests[courseName] = finalManifest;
|
|
2628
|
+
const unpacker = new StaticDataUnpacker(finalManifest, baseUrl);
|
|
2629
|
+
this.courseUnpackers.set(courseName, unpacker);
|
|
2630
|
+
logger.info(`[StaticDataLayerProvider] Successfully resolved and prepared course: ${courseName}`);
|
|
2631
|
+
}
|
|
2632
|
+
} catch (e) {
|
|
2633
|
+
logger.error(`[StaticDataLayerProvider] Failed to resolve dependency ${courseName}:`, e);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
logger.info("[StaticDataLayerProvider] Course dependency resolution complete.");
|
|
2637
|
+
}
|
|
2524
2638
|
async initialize() {
|
|
2525
2639
|
if (this.initialized) return;
|
|
2526
2640
|
logger.info("Initializing static data layer provider");
|
|
2527
|
-
|
|
2528
|
-
const unpacker = new StaticDataUnpacker(
|
|
2529
|
-
manifest,
|
|
2530
|
-
`${this.config.staticContentPath}/${courseId}`
|
|
2531
|
-
);
|
|
2532
|
-
this.courseUnpackers.set(courseId, unpacker);
|
|
2533
|
-
}
|
|
2641
|
+
await this.resolveCourseDependencies();
|
|
2534
2642
|
this.initialized = true;
|
|
2535
2643
|
}
|
|
2536
2644
|
async teardown() {
|
|
@@ -2544,13 +2652,13 @@ var init_StaticDataLayerProvider = __esm({
|
|
|
2544
2652
|
getCourseDB(courseId) {
|
|
2545
2653
|
const unpacker = this.courseUnpackers.get(courseId);
|
|
2546
2654
|
if (!unpacker) {
|
|
2547
|
-
throw new Error(`Course ${courseId} not found in static data
|
|
2655
|
+
throw new Error(`Course ${courseId} not found or failed to initialize in static data layer.`);
|
|
2548
2656
|
}
|
|
2549
|
-
const manifest = this.
|
|
2657
|
+
const manifest = this.manifests[courseId];
|
|
2550
2658
|
return new StaticCourseDB(courseId, unpacker, this.getUserDB(), manifest);
|
|
2551
2659
|
}
|
|
2552
2660
|
getCoursesDB() {
|
|
2553
|
-
return new StaticCoursesDB(this.
|
|
2661
|
+
return new StaticCoursesDB(this.manifests);
|
|
2554
2662
|
}
|
|
2555
2663
|
async getClassroomDB(_classId, _type) {
|
|
2556
2664
|
throw new Error("Classrooms not supported in static mode");
|