@vue-skuilder/db 0.1.11-7 → 0.1.11
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 +5 -5
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +212 -50
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +212 -50
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-DqtNroSh.d.ts → dataLayerProvider-VieuAAkV.d.mts} +8 -1
- package/dist/{dataLayerProvider-BInqI_RF.d.mts → dataLayerProvider-juuqUHOP.d.ts} +8 -1
- package/dist/impl/couch/index.d.mts +19 -7
- package/dist/impl/couch/index.d.ts +19 -7
- package/dist/impl/couch/index.js +229 -63
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +228 -62
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.mts +13 -6
- package/dist/impl/static/index.d.ts +13 -6
- package/dist/impl/static/index.js +142 -46
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +142 -46
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/{index-CLL31bEy.d.ts → index-CWY6yhkV.d.ts} +1 -1
- package/dist/{index-CUNnL38E.d.mts → index-DZyxHCcf.d.mts} +1 -1
- package/dist/index.d.mts +28 -20
- package/dist/index.d.ts +28 -20
- package/dist/index.js +374 -108
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +378 -108
- package/dist/index.mjs.map +1 -1
- package/dist/pouch/index.d.mts +1 -0
- package/dist/pouch/index.d.ts +1 -0
- package/dist/pouch/index.js +49 -0
- package/dist/pouch/index.js.map +1 -0
- package/dist/pouch/index.mjs +16 -0
- package/dist/pouch/index.mjs.map +1 -0
- package/dist/{types-DC-ckZug.d.mts → types-Che4wTwA.d.mts} +1 -1
- package/dist/{types-BefDGkKa.d.ts → types-DtoI27Xh.d.ts} +1 -1
- package/dist/{types-legacy-Birv-Jx6.d.mts → types-legacy-B8ahaCbj.d.mts} +5 -1
- package/dist/{types-legacy-Birv-Jx6.d.ts → types-legacy-B8ahaCbj.d.ts} +5 -1
- package/dist/{userDB-C33Hzjgn.d.mts → userDB-B7zTQ123.d.ts} +88 -55
- package/dist/{userDB-DusL7OXe.d.ts → userDB-DJ8HMw83.d.mts} +88 -55
- 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/interfaces/contentSource.ts +3 -2
- package/src/core/interfaces/courseDB.ts +26 -3
- package/src/core/interfaces/dataLayerProvider.ts +9 -1
- package/src/core/interfaces/userDB.ts +80 -64
- package/src/core/navigators/elo.ts +10 -7
- package/src/core/navigators/index.ts +1 -1
- package/src/core/types/types-legacy.ts +5 -0
- package/src/impl/common/BaseUserDB.ts +45 -3
- package/src/impl/couch/CouchDBSyncStrategy.ts +2 -2
- package/src/impl/couch/PouchDataLayerProvider.ts +21 -0
- package/src/impl/couch/adminDB.ts +2 -2
- package/src/impl/couch/auth.ts +13 -4
- package/src/impl/couch/classroomDB.ts +10 -12
- package/src/impl/couch/courseAPI.ts +2 -2
- package/src/impl/couch/courseDB.ts +130 -11
- package/src/impl/couch/courseLookupDB.ts +4 -3
- package/src/impl/couch/index.ts +36 -4
- package/src/impl/couch/pouchdb-setup.ts +3 -3
- package/src/impl/couch/updateQueue.ts +51 -33
- package/src/impl/static/StaticDataLayerProvider.ts +11 -0
- package/src/impl/static/courseDB.ts +47 -8
- package/src/pouch/index.ts +2 -0
- package/src/study/SessionController.ts +168 -51
- package/src/study/SpacedRepetition.ts +1 -1
- package/tsup.config.ts +1 -0
package/dist/impl/couch/index.js
CHANGED
|
@@ -112,9 +112,9 @@ var init_pouchdb_setup = __esm({
|
|
|
112
112
|
import_pouchdb.default.plugin(import_pouchdb_find.default);
|
|
113
113
|
import_pouchdb.default.plugin(import_pouchdb_authentication.default);
|
|
114
114
|
import_pouchdb.default.defaults({
|
|
115
|
-
ajax: {
|
|
116
|
-
|
|
117
|
-
}
|
|
115
|
+
// ajax: {
|
|
116
|
+
// timeout: 60000,
|
|
117
|
+
// },
|
|
118
118
|
});
|
|
119
119
|
pouchdb_setup_default = import_pouchdb.default;
|
|
120
120
|
}
|
|
@@ -177,37 +177,48 @@ var init_updateQueue = __esm({
|
|
|
177
177
|
} else {
|
|
178
178
|
if (this.pendingUpdates[id] && this.pendingUpdates[id].length > 0) {
|
|
179
179
|
this.inprogressUpdates[id] = true;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
180
|
+
const MAX_RETRIES = 5;
|
|
181
|
+
for (let i = 0; i < MAX_RETRIES; i++) {
|
|
182
|
+
try {
|
|
183
|
+
const doc = await this.readDB.get(id);
|
|
184
|
+
logger.debug(`Retrieved doc: ${id}`);
|
|
185
|
+
let updatedDoc = { ...doc };
|
|
186
|
+
const updatesToApply = [...this.pendingUpdates[id]];
|
|
187
|
+
for (const update of updatesToApply) {
|
|
188
|
+
if (typeof update === "function") {
|
|
189
|
+
updatedDoc = { ...updatedDoc, ...update(updatedDoc) };
|
|
190
|
+
} else {
|
|
191
|
+
updatedDoc = {
|
|
192
|
+
...updatedDoc,
|
|
193
|
+
...update
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
await this.writeDB.put(updatedDoc);
|
|
198
|
+
logger.debug(`Put doc: ${id}`);
|
|
199
|
+
this.pendingUpdates[id].splice(0, updatesToApply.length);
|
|
200
|
+
if (this.pendingUpdates[id].length === 0) {
|
|
201
|
+
this.inprogressUpdates[id] = false;
|
|
202
|
+
delete this.inprogressUpdates[id];
|
|
187
203
|
} else {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
204
|
+
return this.applyUpdates(id);
|
|
205
|
+
}
|
|
206
|
+
return updatedDoc;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
if (e.name === "conflict" && i < MAX_RETRIES - 1) {
|
|
209
|
+
logger.warn(`Conflict on update for doc ${id}, retry #${i + 1}`);
|
|
210
|
+
await new Promise((res) => setTimeout(res, 50 * Math.random()));
|
|
211
|
+
} else {
|
|
212
|
+
delete this.inprogressUpdates[id];
|
|
213
|
+
if (this.pendingUpdates[id]) {
|
|
214
|
+
delete this.pendingUpdates[id];
|
|
215
|
+
}
|
|
216
|
+
logger.error(`Error on attemped update (retry ${i}): ${JSON.stringify(e)}`);
|
|
217
|
+
throw e;
|
|
192
218
|
}
|
|
193
219
|
}
|
|
194
|
-
await this.writeDB.put(doc);
|
|
195
|
-
logger.debug(`Put doc: ${id}`);
|
|
196
|
-
if (this.pendingUpdates[id].length === 0) {
|
|
197
|
-
this.inprogressUpdates[id] = false;
|
|
198
|
-
delete this.inprogressUpdates[id];
|
|
199
|
-
} else {
|
|
200
|
-
return this.applyUpdates(id);
|
|
201
|
-
}
|
|
202
|
-
return doc;
|
|
203
|
-
} catch (e) {
|
|
204
|
-
delete this.inprogressUpdates[id];
|
|
205
|
-
if (this.pendingUpdates[id]) {
|
|
206
|
-
delete this.pendingUpdates[id];
|
|
207
|
-
}
|
|
208
|
-
logger.error(`Error on attemped update: ${JSON.stringify(e)}`);
|
|
209
|
-
throw e;
|
|
210
220
|
}
|
|
221
|
+
throw new Error(`UpdateQueue failed for doc ${id} after ${MAX_RETRIES} retries.`);
|
|
211
222
|
} else {
|
|
212
223
|
throw new Error(`Empty Updates Queue Triggered`);
|
|
213
224
|
}
|
|
@@ -430,7 +441,7 @@ function getCourseDB(courseID) {
|
|
|
430
441
|
const dbName = `coursedb-${courseID}`;
|
|
431
442
|
return new pouchdb_setup_default(
|
|
432
443
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
433
|
-
|
|
444
|
+
createPouchDBConfig()
|
|
434
445
|
);
|
|
435
446
|
}
|
|
436
447
|
var import_common, import_common2, import_common3, import_uuid, AlreadyTaggedErr;
|
|
@@ -556,6 +567,7 @@ var init_courseLookupDB = __esm({
|
|
|
556
567
|
const doc = await _CourseLookup._db.get(courseID);
|
|
557
568
|
return await _CourseLookup._db.remove(doc);
|
|
558
569
|
}
|
|
570
|
+
// [ ] rename to allCourses()
|
|
559
571
|
static async allCourseWare() {
|
|
560
572
|
const resp = await _CourseLookup._db.allDocs({
|
|
561
573
|
include_docs: true
|
|
@@ -626,13 +638,16 @@ var init_elo = __esm({
|
|
|
626
638
|
}
|
|
627
639
|
async getNewCards(limit = 99) {
|
|
628
640
|
const activeCards = await this.user.getActiveCards();
|
|
629
|
-
return (await this.course.getCardsCenteredAtELO(
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
641
|
+
return (await this.course.getCardsCenteredAtELO(
|
|
642
|
+
{ limit, elo: "user" },
|
|
643
|
+
(c) => {
|
|
644
|
+
if (activeCards.some((ac) => c.cardID === ac.cardID)) {
|
|
645
|
+
return false;
|
|
646
|
+
} else {
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
634
649
|
}
|
|
635
|
-
|
|
650
|
+
)).map((c) => {
|
|
636
651
|
return {
|
|
637
652
|
...c,
|
|
638
653
|
status: "new"
|
|
@@ -680,7 +695,7 @@ var init_navigators = __esm({
|
|
|
680
695
|
static async create(user, course, strategyData) {
|
|
681
696
|
const implementingClass = strategyData.implementingClass;
|
|
682
697
|
let NavigatorImpl;
|
|
683
|
-
const variations = ["", ".js", "
|
|
698
|
+
const variations = [".ts", ".js", ""];
|
|
684
699
|
for (const ext of variations) {
|
|
685
700
|
try {
|
|
686
701
|
const module2 = await globImport(`./${implementingClass}${ext}`);
|
|
@@ -1026,7 +1041,13 @@ var init_courseDB = __esm({
|
|
|
1026
1041
|
} else {
|
|
1027
1042
|
return s;
|
|
1028
1043
|
}
|
|
1029
|
-
}).map((c) =>
|
|
1044
|
+
}).map((c) => {
|
|
1045
|
+
return {
|
|
1046
|
+
courseID: this.id,
|
|
1047
|
+
cardID: c.id,
|
|
1048
|
+
elo: c.key
|
|
1049
|
+
};
|
|
1050
|
+
});
|
|
1030
1051
|
const str = `below:
|
|
1031
1052
|
${below.rows.map((r) => ` ${r.id}-${r.key}
|
|
1032
1053
|
`)}
|
|
@@ -1081,7 +1102,13 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1081
1102
|
}
|
|
1082
1103
|
}
|
|
1083
1104
|
async addTagToCard(cardId, tagId, updateELO) {
|
|
1084
|
-
return await addTagToCard(
|
|
1105
|
+
return await addTagToCard(
|
|
1106
|
+
this.id,
|
|
1107
|
+
cardId,
|
|
1108
|
+
tagId,
|
|
1109
|
+
(await this._getCurrentUser()).getUsername(),
|
|
1110
|
+
updateELO
|
|
1111
|
+
);
|
|
1085
1112
|
}
|
|
1086
1113
|
async removeTagFromCard(cardId, tagId) {
|
|
1087
1114
|
return await removeTagFromCard(this.id, cardId, tagId);
|
|
@@ -1274,17 +1301,93 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
|
|
|
1274
1301
|
selectedCards.push(card);
|
|
1275
1302
|
}
|
|
1276
1303
|
return selectedCards.map((c) => {
|
|
1277
|
-
const split = c.split("-");
|
|
1278
1304
|
return {
|
|
1279
1305
|
courseID: this.id,
|
|
1280
|
-
cardID:
|
|
1281
|
-
qualifiedID: `${split[0]}-${split[1]}`,
|
|
1306
|
+
cardID: c.cardID,
|
|
1282
1307
|
contentSourceType: "course",
|
|
1283
1308
|
contentSourceID: this.id,
|
|
1309
|
+
elo: c.elo,
|
|
1284
1310
|
status: "new"
|
|
1285
1311
|
};
|
|
1286
1312
|
});
|
|
1287
1313
|
}
|
|
1314
|
+
// Admin search methods
|
|
1315
|
+
async searchCards(query) {
|
|
1316
|
+
logger.log(`[CourseDB ${this.id}] Searching for: "${query}"`);
|
|
1317
|
+
let displayableData;
|
|
1318
|
+
try {
|
|
1319
|
+
displayableData = await this.db.find({
|
|
1320
|
+
selector: {
|
|
1321
|
+
docType: "DISPLAYABLE_DATA",
|
|
1322
|
+
"data.0.data": { $regex: `.*${query}.*` }
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
logger.log(`[CourseDB ${this.id}] Regex search on data[0].data successful`);
|
|
1326
|
+
} catch (regexError) {
|
|
1327
|
+
logger.log(
|
|
1328
|
+
`[CourseDB ${this.id}] Regex search failed, falling back to manual search:`,
|
|
1329
|
+
regexError
|
|
1330
|
+
);
|
|
1331
|
+
const allDisplayable = await this.db.find({
|
|
1332
|
+
selector: {
|
|
1333
|
+
docType: "DISPLAYABLE_DATA"
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
1336
|
+
logger.log(
|
|
1337
|
+
`[CourseDB ${this.id}] Retrieved ${allDisplayable.docs.length} documents for manual filtering`
|
|
1338
|
+
);
|
|
1339
|
+
displayableData = {
|
|
1340
|
+
docs: allDisplayable.docs.filter((doc) => {
|
|
1341
|
+
const docString = JSON.stringify(doc).toLowerCase();
|
|
1342
|
+
const match = docString.includes(query.toLowerCase());
|
|
1343
|
+
if (match) {
|
|
1344
|
+
logger.log(`[CourseDB ${this.id}] Manual match found in document: ${doc._id}`);
|
|
1345
|
+
}
|
|
1346
|
+
return match;
|
|
1347
|
+
})
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
logger.log(
|
|
1351
|
+
`[CourseDB ${this.id}] Found ${displayableData.docs.length} displayable data documents`
|
|
1352
|
+
);
|
|
1353
|
+
if (displayableData.docs.length === 0) {
|
|
1354
|
+
const allDisplayableData = await this.db.find({
|
|
1355
|
+
selector: {
|
|
1356
|
+
docType: "DISPLAYABLE_DATA"
|
|
1357
|
+
},
|
|
1358
|
+
limit: 5
|
|
1359
|
+
// Just sample a few
|
|
1360
|
+
});
|
|
1361
|
+
logger.log(
|
|
1362
|
+
`[CourseDB ${this.id}] Sample displayable data:`,
|
|
1363
|
+
allDisplayableData.docs.map((d) => ({
|
|
1364
|
+
id: d._id,
|
|
1365
|
+
docType: d.docType,
|
|
1366
|
+
dataStructure: d.data ? Object.keys(d.data) : "no data field",
|
|
1367
|
+
dataContent: d.data,
|
|
1368
|
+
fullDoc: d
|
|
1369
|
+
}))
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
1372
|
+
const allResults = [];
|
|
1373
|
+
for (const dd of displayableData.docs) {
|
|
1374
|
+
const cards = await this.db.find({
|
|
1375
|
+
selector: {
|
|
1376
|
+
docType: "CARD",
|
|
1377
|
+
id_displayable_data: { $in: [dd._id] }
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
logger.log(
|
|
1381
|
+
`[CourseDB ${this.id}] Displayable data ${dd._id} linked to ${cards.docs.length} cards`
|
|
1382
|
+
);
|
|
1383
|
+
allResults.push(...cards.docs);
|
|
1384
|
+
}
|
|
1385
|
+
logger.log(`[CourseDB ${this.id}] Total cards found: ${allResults.length}`);
|
|
1386
|
+
return allResults;
|
|
1387
|
+
}
|
|
1388
|
+
async find(request) {
|
|
1389
|
+
return this.db.find(request);
|
|
1390
|
+
}
|
|
1288
1391
|
};
|
|
1289
1392
|
}
|
|
1290
1393
|
});
|
|
@@ -1295,7 +1398,7 @@ function getClassroomDB(classID, version) {
|
|
|
1295
1398
|
logger.info(`Retrieving classroom db: ${dbName}`);
|
|
1296
1399
|
return new pouchdb_setup_default(
|
|
1297
1400
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
1298
|
-
|
|
1401
|
+
createPouchDBConfig()
|
|
1299
1402
|
);
|
|
1300
1403
|
}
|
|
1301
1404
|
async function getClassroomConfig(classID) {
|
|
@@ -1361,7 +1464,7 @@ var init_classroomDB2 = __esm({
|
|
|
1361
1464
|
const dbName = `classdb-student-${this._id}`;
|
|
1362
1465
|
this._db = new pouchdb_setup_default(
|
|
1363
1466
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
1364
|
-
|
|
1467
|
+
createPouchDBConfig()
|
|
1365
1468
|
);
|
|
1366
1469
|
try {
|
|
1367
1470
|
const cfg = await this._db.get(CLASSROOM_CONFIG);
|
|
@@ -1430,9 +1533,11 @@ var init_classroomDB2 = __esm({
|
|
|
1430
1533
|
ret.push(await getCourseDB2(content.courseID).get(content.cardID));
|
|
1431
1534
|
}
|
|
1432
1535
|
}
|
|
1433
|
-
logger.info(
|
|
1536
|
+
logger.info(
|
|
1537
|
+
`New Cards from classroom ${this._cfg.name}: ${ret.map((c) => `${c.courseID}-${c.cardID}`)}`
|
|
1538
|
+
);
|
|
1434
1539
|
return ret.filter((c) => {
|
|
1435
|
-
if (activeCards.some((ac) => c.
|
|
1540
|
+
if (activeCards.some((ac) => c.cardID === ac.cardID)) {
|
|
1436
1541
|
return false;
|
|
1437
1542
|
} else {
|
|
1438
1543
|
return true;
|
|
@@ -1451,11 +1556,11 @@ var init_classroomDB2 = __esm({
|
|
|
1451
1556
|
const stuDbName = `classdb-student-${this._id}`;
|
|
1452
1557
|
this._db = new pouchdb_setup_default(
|
|
1453
1558
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
1454
|
-
|
|
1559
|
+
createPouchDBConfig()
|
|
1455
1560
|
);
|
|
1456
1561
|
this._stuDb = new pouchdb_setup_default(
|
|
1457
1562
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + stuDbName,
|
|
1458
|
-
|
|
1563
|
+
createPouchDBConfig()
|
|
1459
1564
|
);
|
|
1460
1565
|
try {
|
|
1461
1566
|
return this._db.get(CLASSROOM_CONFIG).then((cfg) => {
|
|
@@ -2042,6 +2147,9 @@ Currently logged-in as ${this._username}.`
|
|
|
2042
2147
|
await this.init();
|
|
2043
2148
|
return ret;
|
|
2044
2149
|
}
|
|
2150
|
+
async get(id) {
|
|
2151
|
+
return this.localDB.get(id);
|
|
2152
|
+
}
|
|
2045
2153
|
update(id, update) {
|
|
2046
2154
|
return this.updateQueue.update(id, update);
|
|
2047
2155
|
}
|
|
@@ -2088,7 +2196,12 @@ Currently logged-in as ${this._username}.`
|
|
|
2088
2196
|
endkey: keys.endkey,
|
|
2089
2197
|
include_docs: true
|
|
2090
2198
|
});
|
|
2091
|
-
return reviews.rows.map((r) =>
|
|
2199
|
+
return reviews.rows.map((r) => {
|
|
2200
|
+
return {
|
|
2201
|
+
courseID: r.doc.courseId,
|
|
2202
|
+
cardID: r.doc.cardId
|
|
2203
|
+
};
|
|
2204
|
+
});
|
|
2092
2205
|
}
|
|
2093
2206
|
async getActivityRecords() {
|
|
2094
2207
|
try {
|
|
@@ -2368,8 +2481,18 @@ Currently logged-in as ${this._username}.`
|
|
|
2368
2481
|
}
|
|
2369
2482
|
this.setDBandQ();
|
|
2370
2483
|
this.syncStrategy.startSync(this.localDB, this.remoteDB);
|
|
2371
|
-
|
|
2372
|
-
|
|
2484
|
+
this.applyDesignDocs().catch((error) => {
|
|
2485
|
+
log3(`Error in applyDesignDocs background task: ${error}`);
|
|
2486
|
+
if (error && typeof error === "object") {
|
|
2487
|
+
log3(`Full error details in applyDesignDocs: ${JSON.stringify(error)}`);
|
|
2488
|
+
}
|
|
2489
|
+
});
|
|
2490
|
+
this.deduplicateReviews().catch((error) => {
|
|
2491
|
+
log3(`Error in deduplicateReviews background task: ${error}`);
|
|
2492
|
+
if (error && typeof error === "object") {
|
|
2493
|
+
log3(`Full error details in background task: ${JSON.stringify(error)}`);
|
|
2494
|
+
}
|
|
2495
|
+
});
|
|
2373
2496
|
_BaseUser._initialized = true;
|
|
2374
2497
|
}
|
|
2375
2498
|
static designDocs = [
|
|
@@ -2387,10 +2510,15 @@ Currently logged-in as ${this._username}.`
|
|
|
2387
2510
|
}
|
|
2388
2511
|
];
|
|
2389
2512
|
async applyDesignDocs() {
|
|
2513
|
+
log3(`Starting applyDesignDocs for user: ${this._username}`);
|
|
2514
|
+
log3(`Remote DB name: ${this.remoteDB.name || "unknown"}`);
|
|
2390
2515
|
if (this._username === "admin") {
|
|
2516
|
+
log3("Skipping design docs for admin user");
|
|
2391
2517
|
return;
|
|
2392
2518
|
}
|
|
2519
|
+
log3(`Applying ${_BaseUser.designDocs.length} design docs`);
|
|
2393
2520
|
for (const doc of _BaseUser.designDocs) {
|
|
2521
|
+
log3(`Applying design doc: ${doc._id}`);
|
|
2394
2522
|
try {
|
|
2395
2523
|
try {
|
|
2396
2524
|
const existingDoc = await this.remoteDB.get(doc._id);
|
|
@@ -2489,8 +2617,13 @@ Currently logged-in as ${this._username}.`
|
|
|
2489
2617
|
async deduplicateReviews() {
|
|
2490
2618
|
try {
|
|
2491
2619
|
log3("Starting deduplication of scheduled reviews...");
|
|
2620
|
+
log3(`Remote DB name: ${this.remoteDB.name || "unknown"}`);
|
|
2621
|
+
log3(`Write DB name: ${this.writeDB.name || "unknown"}`);
|
|
2492
2622
|
const reviewsMap = {};
|
|
2493
2623
|
const duplicateDocIds = [];
|
|
2624
|
+
log3(
|
|
2625
|
+
`Attempting to query remoteDB for reviewCards/reviewCards. Database: ${this.remoteDB.name || "unknown"}`
|
|
2626
|
+
);
|
|
2494
2627
|
const scheduledReviews = await this.remoteDB.query("reviewCards/reviewCards");
|
|
2495
2628
|
log3(`Found ${scheduledReviews.rows.length} scheduled reviews to process`);
|
|
2496
2629
|
scheduledReviews.rows.forEach((r) => {
|
|
@@ -2525,6 +2658,17 @@ Currently logged-in as ${this._username}.`
|
|
|
2525
2658
|
}
|
|
2526
2659
|
} catch (error) {
|
|
2527
2660
|
log3(`Error during review deduplication: ${error}`);
|
|
2661
|
+
if (error && typeof error === "object" && "status" in error && error.status === 404) {
|
|
2662
|
+
log3(
|
|
2663
|
+
`Database not found (404) during review deduplication. Database: ${this.remoteDB.name || "unknown"}`
|
|
2664
|
+
);
|
|
2665
|
+
log3(
|
|
2666
|
+
`This might indicate the user database doesn't exist or the reviewCards view isn't available`
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
if (error && typeof error === "object") {
|
|
2670
|
+
log3(`Full error details: ${JSON.stringify(error)}`);
|
|
2671
|
+
}
|
|
2528
2672
|
}
|
|
2529
2673
|
}
|
|
2530
2674
|
/**
|
|
@@ -2717,7 +2861,7 @@ var init_adminDB2 = __esm({
|
|
|
2717
2861
|
constructor() {
|
|
2718
2862
|
this.usersDB = new pouchdb_setup_default(
|
|
2719
2863
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + "_users",
|
|
2720
|
-
|
|
2864
|
+
createPouchDBConfig()
|
|
2721
2865
|
);
|
|
2722
2866
|
}
|
|
2723
2867
|
async getUsers() {
|
|
@@ -2778,9 +2922,10 @@ var init_adminDB2 = __esm({
|
|
|
2778
2922
|
async function getCurrentSession() {
|
|
2779
2923
|
try {
|
|
2780
2924
|
if (ENV.COUCHDB_SERVER_URL === NOT_SET || ENV.COUCHDB_SERVER_PROTOCOL === NOT_SET) {
|
|
2781
|
-
throw new Error(
|
|
2925
|
+
throw new Error(`CouchDB server configuration not properly initialized. Protocol: "${ENV.COUCHDB_SERVER_PROTOCOL}", URL: "${ENV.COUCHDB_SERVER_URL}"`);
|
|
2782
2926
|
}
|
|
2783
|
-
const
|
|
2927
|
+
const baseUrl = ENV.COUCHDB_SERVER_URL.endsWith("/") ? ENV.COUCHDB_SERVER_URL.slice(0, -1) : ENV.COUCHDB_SERVER_URL;
|
|
2928
|
+
const url = `${ENV.COUCHDB_SERVER_PROTOCOL}://${baseUrl}/_session`;
|
|
2784
2929
|
logger.debug(`Attempting session check at: ${url}`);
|
|
2785
2930
|
const response = await (0, import_cross_fetch.default)(url, {
|
|
2786
2931
|
method: "GET",
|
|
@@ -2792,8 +2937,10 @@ async function getCurrentSession() {
|
|
|
2792
2937
|
const resp = await response.json();
|
|
2793
2938
|
return resp;
|
|
2794
2939
|
} catch (error) {
|
|
2795
|
-
|
|
2796
|
-
|
|
2940
|
+
const baseUrl = ENV.COUCHDB_SERVER_URL.endsWith("/") ? ENV.COUCHDB_SERVER_URL.slice(0, -1) : ENV.COUCHDB_SERVER_URL;
|
|
2941
|
+
const url = `${ENV.COUCHDB_SERVER_PROTOCOL}://${baseUrl}/_session`;
|
|
2942
|
+
logger.error(`Session check error attempting to connect to: ${url} - ${error}`);
|
|
2943
|
+
throw new Error(`Session check failed connecting to ${url}: ${error}`);
|
|
2797
2944
|
}
|
|
2798
2945
|
}
|
|
2799
2946
|
async function getLoggedInUsername() {
|
|
@@ -2984,7 +3131,7 @@ var init_CouchDBSyncStrategy = __esm({
|
|
|
2984
3131
|
log4(`Fetching user database: ${dbName} (${username})`);
|
|
2985
3132
|
const ret = new pouchdb_setup_default(
|
|
2986
3133
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
2987
|
-
|
|
3134
|
+
createPouchDBConfig()
|
|
2988
3135
|
);
|
|
2989
3136
|
if (guestAccount) {
|
|
2990
3137
|
updateGuestAccountExpirationDate(ret);
|
|
@@ -3009,6 +3156,7 @@ __export(couch_exports, {
|
|
|
3009
3156
|
TeacherClassroomDB: () => TeacherClassroomDB,
|
|
3010
3157
|
addNote55: () => addNote55,
|
|
3011
3158
|
addTagToCard: () => addTagToCard,
|
|
3159
|
+
createPouchDBConfig: () => createPouchDBConfig,
|
|
3012
3160
|
createTag: () => createTag,
|
|
3013
3161
|
deleteTag: () => deleteTag,
|
|
3014
3162
|
filterAllDocsByPrefix: () => filterAllDocsByPrefix,
|
|
@@ -3035,7 +3183,6 @@ __export(couch_exports, {
|
|
|
3035
3183
|
hexEncode: () => hexEncode2,
|
|
3036
3184
|
isReview: () => isReview,
|
|
3037
3185
|
localUserDB: () => localUserDB,
|
|
3038
|
-
pouchDBincludeCredentialsConfig: () => pouchDBincludeCredentialsConfig,
|
|
3039
3186
|
removeTagFromCard: () => removeTagFromCard,
|
|
3040
3187
|
scheduleCardReview: () => scheduleCardReview,
|
|
3041
3188
|
updateCardElo: () => updateCardElo2,
|
|
@@ -3054,16 +3201,35 @@ function hexEncode2(str) {
|
|
|
3054
3201
|
}
|
|
3055
3202
|
return returnStr;
|
|
3056
3203
|
}
|
|
3204
|
+
function createPouchDBConfig() {
|
|
3205
|
+
const hasExplicitCredentials = ENV.COUCHDB_USERNAME && ENV.COUCHDB_PASSWORD;
|
|
3206
|
+
const isNodeEnvironment = typeof window === "undefined";
|
|
3207
|
+
if (hasExplicitCredentials && isNodeEnvironment) {
|
|
3208
|
+
return {
|
|
3209
|
+
fetch(url, opts = {}) {
|
|
3210
|
+
const basicAuth = btoa(`${ENV.COUCHDB_USERNAME}:${ENV.COUCHDB_PASSWORD}`);
|
|
3211
|
+
const headers = new Headers(opts.headers || {});
|
|
3212
|
+
headers.set("Authorization", `Basic ${basicAuth}`);
|
|
3213
|
+
const newOpts = {
|
|
3214
|
+
...opts,
|
|
3215
|
+
headers
|
|
3216
|
+
};
|
|
3217
|
+
return pouchdb_setup_default.fetch(url, newOpts);
|
|
3218
|
+
}
|
|
3219
|
+
};
|
|
3220
|
+
}
|
|
3221
|
+
return pouchDBincludeCredentialsConfig;
|
|
3222
|
+
}
|
|
3057
3223
|
function getCouchDB(dbName) {
|
|
3058
3224
|
return new pouchdb_setup_default(
|
|
3059
3225
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
3060
|
-
|
|
3226
|
+
createPouchDBConfig()
|
|
3061
3227
|
);
|
|
3062
3228
|
}
|
|
3063
3229
|
function getCourseDB2(courseID) {
|
|
3064
3230
|
return new pouchdb_setup_default(
|
|
3065
3231
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + "coursedb-" + courseID,
|
|
3066
|
-
|
|
3232
|
+
createPouchDBConfig()
|
|
3067
3233
|
);
|
|
3068
3234
|
}
|
|
3069
3235
|
async function getLatestVersion() {
|
|
@@ -3148,7 +3314,7 @@ function getCouchUserDB(username) {
|
|
|
3148
3314
|
log(`Fetching user database: ${dbName} (${username})`);
|
|
3149
3315
|
const ret = new pouchdb_setup_default(
|
|
3150
3316
|
ENV.COUCHDB_SERVER_PROTOCOL + "://" + ENV.COUCHDB_SERVER_URL + dbName,
|
|
3151
|
-
|
|
3317
|
+
createPouchDBConfig()
|
|
3152
3318
|
);
|
|
3153
3319
|
if (guestAccount) {
|
|
3154
3320
|
updateGuestAccountExpirationDate2(ret);
|
|
@@ -3231,6 +3397,7 @@ init_couch();
|
|
|
3231
3397
|
TeacherClassroomDB,
|
|
3232
3398
|
addNote55,
|
|
3233
3399
|
addTagToCard,
|
|
3400
|
+
createPouchDBConfig,
|
|
3234
3401
|
createTag,
|
|
3235
3402
|
deleteTag,
|
|
3236
3403
|
filterAllDocsByPrefix,
|
|
@@ -3257,7 +3424,6 @@ init_couch();
|
|
|
3257
3424
|
hexEncode,
|
|
3258
3425
|
isReview,
|
|
3259
3426
|
localUserDB,
|
|
3260
|
-
pouchDBincludeCredentialsConfig,
|
|
3261
3427
|
removeTagFromCard,
|
|
3262
3428
|
scheduleCardReview,
|
|
3263
3429
|
updateCardElo,
|