@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,21 +1,29 @@
|
|
|
1
|
-
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionNewItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as StudySessionReviewItem, g as ScheduledCard } from '../../userDB-
|
|
2
|
-
import { D as DataLayerProvider } from '../../dataLayerProvider-
|
|
3
|
-
import { S as StaticCourseManifest } from '../../types-
|
|
1
|
+
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionNewItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as StudySessionReviewItem, g as ScheduledCard } from '../../userDB-C4yyAnpp.mjs';
|
|
2
|
+
import { D as DataLayerProvider } from '../../dataLayerProvider-BiP3kWix.mjs';
|
|
3
|
+
import { S as StaticCourseManifest } from '../../types-Dbp5DaRR.mjs';
|
|
4
4
|
import { CourseConfig, CourseElo, DataShape } from '@vue-skuilder/common';
|
|
5
|
-
import { S as SkuilderCourseData, Q as QualifiedCardID, T as TagStub, a as Tag } from '../../types-legacy-
|
|
5
|
+
import { S as SkuilderCourseData, Q as QualifiedCardID, T as TagStub, a as Tag } from '../../types-legacy-6ettoclI.mjs';
|
|
6
6
|
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-CyATpyLQ.mjs';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
9
|
+
interface SkuilderManifest {
|
|
10
|
+
name?: string;
|
|
11
|
+
version?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
dependencies?: Record<string, string>;
|
|
14
|
+
}
|
|
9
15
|
interface StaticDataLayerConfig {
|
|
10
|
-
staticContentPath: string;
|
|
11
16
|
localStoragePrefix?: string;
|
|
12
|
-
|
|
17
|
+
rootManifest: SkuilderManifest;
|
|
18
|
+
rootManifestUrl: string;
|
|
13
19
|
}
|
|
14
20
|
declare class StaticDataLayerProvider implements DataLayerProvider {
|
|
15
21
|
private config;
|
|
16
22
|
private initialized;
|
|
17
23
|
private courseUnpackers;
|
|
24
|
+
private manifests;
|
|
18
25
|
constructor(config: Partial<StaticDataLayerConfig>);
|
|
26
|
+
private resolveCourseDependencies;
|
|
19
27
|
initialize(): Promise<void>;
|
|
20
28
|
teardown(): Promise<void>;
|
|
21
29
|
getUserDB(): UserDBInterface;
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionNewItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as StudySessionReviewItem, g as ScheduledCard } from '../../userDB-
|
|
2
|
-
import { D as DataLayerProvider } from '../../dataLayerProvider-
|
|
3
|
-
import { S as StaticCourseManifest } from '../../types-
|
|
1
|
+
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionNewItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as StudySessionReviewItem, g as ScheduledCard } from '../../userDB-CD6s6ZCp.js';
|
|
2
|
+
import { D as DataLayerProvider } from '../../dataLayerProvider-DSdeyRT3.js';
|
|
3
|
+
import { S as StaticCourseManifest } from '../../types-CewsN87z.js';
|
|
4
4
|
import { CourseConfig, CourseElo, DataShape } from '@vue-skuilder/common';
|
|
5
|
-
import { S as SkuilderCourseData, Q as QualifiedCardID, T as TagStub, a as Tag } from '../../types-legacy-
|
|
5
|
+
import { S as SkuilderCourseData, Q as QualifiedCardID, T as TagStub, a as Tag } from '../../types-legacy-6ettoclI.js';
|
|
6
6
|
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-CyATpyLQ.js';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
9
|
+
interface SkuilderManifest {
|
|
10
|
+
name?: string;
|
|
11
|
+
version?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
dependencies?: Record<string, string>;
|
|
14
|
+
}
|
|
9
15
|
interface StaticDataLayerConfig {
|
|
10
|
-
staticContentPath: string;
|
|
11
16
|
localStoragePrefix?: string;
|
|
12
|
-
|
|
17
|
+
rootManifest: SkuilderManifest;
|
|
18
|
+
rootManifestUrl: string;
|
|
13
19
|
}
|
|
14
20
|
declare class StaticDataLayerProvider implements DataLayerProvider {
|
|
15
21
|
private config;
|
|
16
22
|
private initialized;
|
|
17
23
|
private courseUnpackers;
|
|
24
|
+
private manifests;
|
|
18
25
|
constructor(config: Partial<StaticDataLayerConfig>);
|
|
26
|
+
private resolveCourseDependencies;
|
|
19
27
|
initialize(): Promise<void>;
|
|
20
28
|
teardown(): Promise<void>;
|
|
21
29
|
getUserDB(): UserDBInterface;
|
|
@@ -302,7 +302,9 @@ var init_updateQueue = __esm({
|
|
|
302
302
|
async applyUpdates(id) {
|
|
303
303
|
logger.debug(`Applying updates on doc: ${id}`);
|
|
304
304
|
if (this.inprogressUpdates[id]) {
|
|
305
|
-
|
|
305
|
+
while (this.inprogressUpdates[id]) {
|
|
306
|
+
await new Promise((resolve) => setTimeout(resolve, Math.random() * 50));
|
|
307
|
+
}
|
|
306
308
|
return this.applyUpdates(id);
|
|
307
309
|
} else {
|
|
308
310
|
if (this.pendingUpdates[id] && this.pendingUpdates[id].length > 0) {
|
|
@@ -338,6 +340,9 @@ var init_updateQueue = __esm({
|
|
|
338
340
|
if (e.name === "conflict" && i < MAX_RETRIES - 1) {
|
|
339
341
|
logger.warn(`Conflict on update for doc ${id}, retry #${i + 1}`);
|
|
340
342
|
await new Promise((res) => setTimeout(res, 50 * Math.random()));
|
|
343
|
+
} else if (e.name === "not_found" && i === 0) {
|
|
344
|
+
logger.warn(`Update failed for ${id} - does not exist. Throwing to caller.`);
|
|
345
|
+
throw e;
|
|
341
346
|
} else {
|
|
342
347
|
delete this.inprogressUpdates[id];
|
|
343
348
|
if (this.pendingUpdates[id]) {
|
|
@@ -534,12 +539,74 @@ var init_elo = __esm({
|
|
|
534
539
|
}
|
|
535
540
|
});
|
|
536
541
|
|
|
542
|
+
// src/core/navigators/hardcodedOrder.ts
|
|
543
|
+
var hardcodedOrder_exports = {};
|
|
544
|
+
__export(hardcodedOrder_exports, {
|
|
545
|
+
default: () => HardcodedOrderNavigator
|
|
546
|
+
});
|
|
547
|
+
var HardcodedOrderNavigator;
|
|
548
|
+
var init_hardcodedOrder = __esm({
|
|
549
|
+
"src/core/navigators/hardcodedOrder.ts"() {
|
|
550
|
+
"use strict";
|
|
551
|
+
init_navigators();
|
|
552
|
+
init_logger();
|
|
553
|
+
HardcodedOrderNavigator = class extends ContentNavigator {
|
|
554
|
+
orderedCardIds = [];
|
|
555
|
+
user;
|
|
556
|
+
course;
|
|
557
|
+
constructor(user, course, strategyData) {
|
|
558
|
+
super();
|
|
559
|
+
this.user = user;
|
|
560
|
+
this.course = course;
|
|
561
|
+
if (strategyData.serializedData) {
|
|
562
|
+
try {
|
|
563
|
+
this.orderedCardIds = JSON.parse(strategyData.serializedData);
|
|
564
|
+
} catch (e) {
|
|
565
|
+
logger.error("Failed to parse serializedData for HardcodedOrderNavigator", e);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
async getPendingReviews() {
|
|
570
|
+
const reviews = await this.user.getPendingReviews(this.course.getCourseID());
|
|
571
|
+
return reviews.map((r) => {
|
|
572
|
+
return {
|
|
573
|
+
...r,
|
|
574
|
+
contentSourceType: "course",
|
|
575
|
+
contentSourceID: this.course.getCourseID(),
|
|
576
|
+
cardID: r.cardId,
|
|
577
|
+
courseID: r.courseId,
|
|
578
|
+
reviewID: r._id,
|
|
579
|
+
status: "review"
|
|
580
|
+
};
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
async getNewCards(limit = 99) {
|
|
584
|
+
const activeCardIds = (await this.user.getActiveCards()).map((c) => c.cardID);
|
|
585
|
+
const newCardIds = this.orderedCardIds.filter(
|
|
586
|
+
(cardId) => !activeCardIds.includes(cardId)
|
|
587
|
+
);
|
|
588
|
+
const cardsToReturn = newCardIds.slice(0, limit);
|
|
589
|
+
return cardsToReturn.map((cardId) => {
|
|
590
|
+
return {
|
|
591
|
+
cardID: cardId,
|
|
592
|
+
courseID: this.course.getCourseID(),
|
|
593
|
+
contentSourceType: "course",
|
|
594
|
+
contentSourceID: this.course.getCourseID(),
|
|
595
|
+
status: "new"
|
|
596
|
+
};
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
|
|
537
603
|
// import("./**/*") in src/core/navigators/index.ts
|
|
538
604
|
var globImport;
|
|
539
605
|
var init_ = __esm({
|
|
540
606
|
'import("./**/*") in src/core/navigators/index.ts'() {
|
|
541
607
|
globImport = __glob({
|
|
542
608
|
"./elo.ts": () => Promise.resolve().then(() => (init_elo(), elo_exports)),
|
|
609
|
+
"./hardcodedOrder.ts": () => Promise.resolve().then(() => (init_hardcodedOrder(), hardcodedOrder_exports)),
|
|
543
610
|
"./index.ts": () => Promise.resolve().then(() => (init_navigators(), navigators_exports))
|
|
544
611
|
});
|
|
545
612
|
}
|
|
@@ -559,6 +626,7 @@ var init_navigators = __esm({
|
|
|
559
626
|
init_();
|
|
560
627
|
Navigators = /* @__PURE__ */ ((Navigators2) => {
|
|
561
628
|
Navigators2["ELO"] = "elo";
|
|
629
|
+
Navigators2["HARDCODED"] = "hardcodedOrder";
|
|
562
630
|
return Navigators2;
|
|
563
631
|
})(Navigators || {});
|
|
564
632
|
ContentNavigator = class {
|
|
@@ -1392,17 +1460,21 @@ Currently logged-in as ${this._username}.`
|
|
|
1392
1460
|
} catch (e) {
|
|
1393
1461
|
const reason = e;
|
|
1394
1462
|
if (reason.status === 404) {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1463
|
+
try {
|
|
1464
|
+
const initCardHistory = {
|
|
1465
|
+
_id: cardHistoryID,
|
|
1466
|
+
cardID: record.cardID,
|
|
1467
|
+
courseID: record.courseID,
|
|
1468
|
+
records: [record],
|
|
1469
|
+
lapses: 0,
|
|
1470
|
+
streak: 0,
|
|
1471
|
+
bestInterval: 0
|
|
1472
|
+
};
|
|
1473
|
+
const putResult = await this.writeDB.put(initCardHistory);
|
|
1474
|
+
return { ...initCardHistory, _rev: putResult.rev };
|
|
1475
|
+
} catch (creationError) {
|
|
1476
|
+
throw new Error(`Failed to create CardHistory for ${cardHistoryID}. Reason: ${creationError}`);
|
|
1477
|
+
}
|
|
1406
1478
|
} else {
|
|
1407
1479
|
throw new Error(`putCardRecord failed because of:
|
|
1408
1480
|
name:${reason.name}
|
|
@@ -2191,16 +2263,20 @@ var init_courseDB3 = __esm({
|
|
|
2191
2263
|
async updateCardElo(cardId, _elo) {
|
|
2192
2264
|
return { ok: true, id: cardId, rev: "1-static" };
|
|
2193
2265
|
}
|
|
2194
|
-
async getNewCards(limit) {
|
|
2195
|
-
const
|
|
2196
|
-
return
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2266
|
+
async getNewCards(limit = 99) {
|
|
2267
|
+
const activeCards = await this.userDB.getActiveCards();
|
|
2268
|
+
return (await this.getCardsCenteredAtELO({ limit, elo: "user" }, (c) => {
|
|
2269
|
+
if (activeCards.some((ac) => c.cardID === ac.cardID)) {
|
|
2270
|
+
return false;
|
|
2271
|
+
} else {
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
})).map((c) => {
|
|
2275
|
+
return {
|
|
2276
|
+
...c,
|
|
2277
|
+
status: "new"
|
|
2278
|
+
};
|
|
2279
|
+
});
|
|
2204
2280
|
}
|
|
2205
2281
|
async getCardsCenteredAtELO(options, filter) {
|
|
2206
2282
|
let targetElo = typeof options.elo === "number" ? options.elo : 1e3;
|
|
@@ -2381,7 +2457,7 @@ var init_courseDB3 = __esm({
|
|
|
2381
2457
|
// Navigation Strategy Manager implementation
|
|
2382
2458
|
async getNavigationStrategy(_id) {
|
|
2383
2459
|
return {
|
|
2384
|
-
|
|
2460
|
+
_id: "NAVIGATION_STRATEGY-ELO",
|
|
2385
2461
|
docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
|
|
2386
2462
|
name: "ELO",
|
|
2387
2463
|
description: "ELO-based navigation strategy",
|
|
@@ -2446,11 +2522,17 @@ var init_coursesDB = __esm({
|
|
|
2446
2522
|
this.manifests = manifests;
|
|
2447
2523
|
}
|
|
2448
2524
|
async getCourseConfig(courseId) {
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2525
|
+
const manifest = this.manifests[courseId];
|
|
2526
|
+
if (!manifest) {
|
|
2527
|
+
logger.warn(`Course manifest for ${courseId} not found`);
|
|
2528
|
+
throw new Error(`Course ${courseId} not found`);
|
|
2529
|
+
}
|
|
2530
|
+
if (manifest.courseConfig) {
|
|
2531
|
+
return manifest.courseConfig;
|
|
2532
|
+
} else {
|
|
2533
|
+
logger.warn(`Course config not found in manifest for course ${courseId}`);
|
|
2534
|
+
throw new Error(`Course config not found for course ${courseId}`);
|
|
2452
2535
|
}
|
|
2453
|
-
return {};
|
|
2454
2536
|
}
|
|
2455
2537
|
async getCourseList() {
|
|
2456
2538
|
return Object.keys(this.manifests).map(
|
|
@@ -2538,23 +2620,49 @@ var init_StaticDataLayerProvider = __esm({
|
|
|
2538
2620
|
config;
|
|
2539
2621
|
initialized = false;
|
|
2540
2622
|
courseUnpackers = /* @__PURE__ */ new Map();
|
|
2623
|
+
manifests = {};
|
|
2541
2624
|
constructor(config) {
|
|
2542
2625
|
this.config = {
|
|
2543
|
-
staticContentPath: config.staticContentPath || "/static-courses",
|
|
2544
2626
|
localStoragePrefix: config.localStoragePrefix || "skuilder-static",
|
|
2545
|
-
|
|
2627
|
+
rootManifest: config.rootManifest || { dependencies: {} },
|
|
2628
|
+
rootManifestUrl: config.rootManifestUrl || "/"
|
|
2546
2629
|
};
|
|
2547
2630
|
}
|
|
2631
|
+
async resolveCourseDependencies() {
|
|
2632
|
+
logger.info("[StaticDataLayerProvider] Starting course dependency resolution...");
|
|
2633
|
+
const rootManifest = this.config.rootManifest;
|
|
2634
|
+
for (const [courseName, courseUrl] of Object.entries(rootManifest.dependencies || {})) {
|
|
2635
|
+
try {
|
|
2636
|
+
logger.debug(`[StaticDataLayerProvider] Resolving dependency: ${courseName} from ${courseUrl}`);
|
|
2637
|
+
const courseManifestUrl = new URL(courseUrl, this.config.rootManifestUrl).href;
|
|
2638
|
+
const courseJsonResponse = await fetch(courseManifestUrl);
|
|
2639
|
+
if (!courseJsonResponse.ok) {
|
|
2640
|
+
throw new Error(`Failed to fetch course manifest for ${courseName}`);
|
|
2641
|
+
}
|
|
2642
|
+
const courseJson = await courseJsonResponse.json();
|
|
2643
|
+
if (courseJson.content && courseJson.content.manifest) {
|
|
2644
|
+
const baseUrl = new URL(".", courseManifestUrl).href;
|
|
2645
|
+
const finalManifestUrl = new URL(courseJson.content.manifest, courseManifestUrl).href;
|
|
2646
|
+
const finalManifestResponse = await fetch(finalManifestUrl);
|
|
2647
|
+
if (!finalManifestResponse.ok) {
|
|
2648
|
+
throw new Error(`Failed to fetch final content manifest for ${courseName} at ${finalManifestUrl}`);
|
|
2649
|
+
}
|
|
2650
|
+
const finalManifest = await finalManifestResponse.json();
|
|
2651
|
+
this.manifests[courseName] = finalManifest;
|
|
2652
|
+
const unpacker = new StaticDataUnpacker(finalManifest, baseUrl);
|
|
2653
|
+
this.courseUnpackers.set(courseName, unpacker);
|
|
2654
|
+
logger.info(`[StaticDataLayerProvider] Successfully resolved and prepared course: ${courseName}`);
|
|
2655
|
+
}
|
|
2656
|
+
} catch (e) {
|
|
2657
|
+
logger.error(`[StaticDataLayerProvider] Failed to resolve dependency ${courseName}:`, e);
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
logger.info("[StaticDataLayerProvider] Course dependency resolution complete.");
|
|
2661
|
+
}
|
|
2548
2662
|
async initialize() {
|
|
2549
2663
|
if (this.initialized) return;
|
|
2550
2664
|
logger.info("Initializing static data layer provider");
|
|
2551
|
-
|
|
2552
|
-
const unpacker = new StaticDataUnpacker(
|
|
2553
|
-
manifest,
|
|
2554
|
-
`${this.config.staticContentPath}/${courseId}`
|
|
2555
|
-
);
|
|
2556
|
-
this.courseUnpackers.set(courseId, unpacker);
|
|
2557
|
-
}
|
|
2665
|
+
await this.resolveCourseDependencies();
|
|
2558
2666
|
this.initialized = true;
|
|
2559
2667
|
}
|
|
2560
2668
|
async teardown() {
|
|
@@ -2568,13 +2676,13 @@ var init_StaticDataLayerProvider = __esm({
|
|
|
2568
2676
|
getCourseDB(courseId) {
|
|
2569
2677
|
const unpacker = this.courseUnpackers.get(courseId);
|
|
2570
2678
|
if (!unpacker) {
|
|
2571
|
-
throw new Error(`Course ${courseId} not found in static data
|
|
2679
|
+
throw new Error(`Course ${courseId} not found or failed to initialize in static data layer.`);
|
|
2572
2680
|
}
|
|
2573
|
-
const manifest = this.
|
|
2681
|
+
const manifest = this.manifests[courseId];
|
|
2574
2682
|
return new StaticCourseDB(courseId, unpacker, this.getUserDB(), manifest);
|
|
2575
2683
|
}
|
|
2576
2684
|
getCoursesDB() {
|
|
2577
|
-
return new StaticCoursesDB(this.
|
|
2685
|
+
return new StaticCoursesDB(this.manifests);
|
|
2578
2686
|
}
|
|
2579
2687
|
async getClassroomDB(_classId, _type) {
|
|
2580
2688
|
throw new Error("Classrooms not supported in static mode");
|