@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.
Files changed (53) hide show
  1. package/dist/core/index.d.mts +7 -6
  2. package/dist/core/index.d.ts +7 -6
  3. package/dist/core/index.js +146 -37
  4. package/dist/core/index.js.map +1 -1
  5. package/dist/core/index.mjs +146 -37
  6. package/dist/core/index.mjs.map +1 -1
  7. package/dist/{dataLayerProvider-VieuAAkV.d.mts → dataLayerProvider-BiP3kWix.d.mts} +1 -1
  8. package/dist/{dataLayerProvider-juuqUHOP.d.ts → dataLayerProvider-DSdeyRT3.d.ts} +1 -1
  9. package/dist/impl/couch/index.d.mts +3 -3
  10. package/dist/impl/couch/index.d.ts +3 -3
  11. package/dist/impl/couch/index.js +146 -37
  12. package/dist/impl/couch/index.js.map +1 -1
  13. package/dist/impl/couch/index.mjs +146 -37
  14. package/dist/impl/couch/index.mjs.map +1 -1
  15. package/dist/impl/static/index.d.mts +14 -6
  16. package/dist/impl/static/index.d.ts +14 -6
  17. package/dist/impl/static/index.js +147 -39
  18. package/dist/impl/static/index.js.map +1 -1
  19. package/dist/impl/static/index.mjs +147 -39
  20. package/dist/impl/static/index.mjs.map +1 -1
  21. package/dist/{index-DZyxHCcf.d.mts → index-Bmll7Xse.d.mts} +1 -1
  22. package/dist/{index-CWY6yhkV.d.ts → index-CD8BZz2k.d.ts} +1 -1
  23. package/dist/index.d.mts +119 -24
  24. package/dist/index.d.ts +119 -24
  25. package/dist/index.js +785 -261
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +789 -265
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/{types-DtoI27Xh.d.ts → types-CewsN87z.d.ts} +1 -1
  30. package/dist/{types-Che4wTwA.d.mts → types-Dbp5DaRR.d.mts} +1 -1
  31. package/dist/{types-legacy-B8ahaCbj.d.mts → types-legacy-6ettoclI.d.mts} +13 -2
  32. package/dist/{types-legacy-B8ahaCbj.d.ts → types-legacy-6ettoclI.d.ts} +13 -2
  33. package/dist/{userDB-DJ8HMw83.d.mts → userDB-C4yyAnpp.d.mts} +3 -3
  34. package/dist/{userDB-B7zTQ123.d.ts → userDB-CD6s6ZCp.d.ts} +3 -3
  35. package/dist/util/packer/index.d.mts +3 -3
  36. package/dist/util/packer/index.d.ts +3 -3
  37. package/package.json +3 -3
  38. package/src/core/navigators/hardcodedOrder.ts +64 -0
  39. package/src/core/navigators/index.ts +1 -0
  40. package/src/core/types/contentNavigationStrategy.ts +2 -1
  41. package/src/core/types/types-legacy.ts +2 -2
  42. package/src/impl/common/BaseUserDB.ts +15 -11
  43. package/src/impl/couch/courseDB.ts +74 -27
  44. package/src/impl/couch/updateQueue.ts +8 -3
  45. package/src/impl/static/StaticDataLayerProvider.ts +57 -17
  46. package/src/impl/static/courseDB.ts +17 -12
  47. package/src/impl/static/coursesDB.ts +10 -6
  48. package/src/study/ItemQueue.ts +58 -0
  49. package/src/study/SessionController.ts +132 -178
  50. package/src/study/services/CardHydrationService.ts +153 -0
  51. package/src/study/services/EloService.ts +85 -0
  52. package/src/study/services/ResponseProcessor.ts +224 -0
  53. package/src/study/services/SrsService.ts +44 -0
@@ -320,7 +320,9 @@ var init_updateQueue = __esm({
320
320
  async applyUpdates(id) {
321
321
  logger.debug(`Applying updates on doc: ${id}`);
322
322
  if (this.inprogressUpdates[id]) {
323
- await this.readDB.info();
323
+ while (this.inprogressUpdates[id]) {
324
+ await new Promise((resolve) => setTimeout(resolve, Math.random() * 50));
325
+ }
324
326
  return this.applyUpdates(id);
325
327
  } else {
326
328
  if (this.pendingUpdates[id] && this.pendingUpdates[id].length > 0) {
@@ -356,6 +358,9 @@ var init_updateQueue = __esm({
356
358
  if (e.name === "conflict" && i < MAX_RETRIES - 1) {
357
359
  logger.warn(`Conflict on update for doc ${id}, retry #${i + 1}`);
358
360
  await new Promise((res) => setTimeout(res, 50 * Math.random()));
361
+ } else if (e.name === "not_found" && i === 0) {
362
+ logger.warn(`Update failed for ${id} - does not exist. Throwing to caller.`);
363
+ throw e;
359
364
  } else {
360
365
  delete this.inprogressUpdates[id];
361
366
  if (this.pendingUpdates[id]) {
@@ -721,12 +726,74 @@ var init_elo = __esm({
721
726
  }
722
727
  });
723
728
 
729
+ // src/core/navigators/hardcodedOrder.ts
730
+ var hardcodedOrder_exports = {};
731
+ __export(hardcodedOrder_exports, {
732
+ default: () => HardcodedOrderNavigator
733
+ });
734
+ var HardcodedOrderNavigator;
735
+ var init_hardcodedOrder = __esm({
736
+ "src/core/navigators/hardcodedOrder.ts"() {
737
+ "use strict";
738
+ init_navigators();
739
+ init_logger();
740
+ HardcodedOrderNavigator = class extends ContentNavigator {
741
+ orderedCardIds = [];
742
+ user;
743
+ course;
744
+ constructor(user, course, strategyData) {
745
+ super();
746
+ this.user = user;
747
+ this.course = course;
748
+ if (strategyData.serializedData) {
749
+ try {
750
+ this.orderedCardIds = JSON.parse(strategyData.serializedData);
751
+ } catch (e) {
752
+ logger.error("Failed to parse serializedData for HardcodedOrderNavigator", e);
753
+ }
754
+ }
755
+ }
756
+ async getPendingReviews() {
757
+ const reviews = await this.user.getPendingReviews(this.course.getCourseID());
758
+ return reviews.map((r) => {
759
+ return {
760
+ ...r,
761
+ contentSourceType: "course",
762
+ contentSourceID: this.course.getCourseID(),
763
+ cardID: r.cardId,
764
+ courseID: r.courseId,
765
+ reviewID: r._id,
766
+ status: "review"
767
+ };
768
+ });
769
+ }
770
+ async getNewCards(limit = 99) {
771
+ const activeCardIds = (await this.user.getActiveCards()).map((c) => c.cardID);
772
+ const newCardIds = this.orderedCardIds.filter(
773
+ (cardId) => !activeCardIds.includes(cardId)
774
+ );
775
+ const cardsToReturn = newCardIds.slice(0, limit);
776
+ return cardsToReturn.map((cardId) => {
777
+ return {
778
+ cardID: cardId,
779
+ courseID: this.course.getCourseID(),
780
+ contentSourceType: "course",
781
+ contentSourceID: this.course.getCourseID(),
782
+ status: "new"
783
+ };
784
+ });
785
+ }
786
+ };
787
+ }
788
+ });
789
+
724
790
  // import("./**/*") in src/core/navigators/index.ts
725
791
  var globImport;
726
792
  var init_ = __esm({
727
793
  'import("./**/*") in src/core/navigators/index.ts'() {
728
794
  globImport = __glob({
729
795
  "./elo.ts": () => Promise.resolve().then(() => (init_elo(), elo_exports)),
796
+ "./hardcodedOrder.ts": () => Promise.resolve().then(() => (init_hardcodedOrder(), hardcodedOrder_exports)),
730
797
  "./index.ts": () => Promise.resolve().then(() => (init_navigators(), navigators_exports))
731
798
  });
732
799
  }
@@ -746,6 +813,7 @@ var init_navigators = __esm({
746
813
  init_();
747
814
  Navigators = /* @__PURE__ */ ((Navigators2) => {
748
815
  Navigators2["ELO"] = "elo";
816
+ Navigators2["HARDCODED"] = "hardcodedOrder";
749
817
  return Navigators2;
750
818
  })(Navigators || {});
751
819
  ContentNavigator = class {
@@ -975,6 +1043,23 @@ var init_courseDB = __esm({
975
1043
  if (!doc.docType || !(doc.docType === "CARD" /* CARD */)) {
976
1044
  throw new Error(`failed to remove ${id} from course ${this.id}. id does not point to a card`);
977
1045
  }
1046
+ try {
1047
+ const appliedTags = await this.getAppliedTags(id);
1048
+ const results = await Promise.allSettled(
1049
+ appliedTags.rows.map(async (tagRow) => {
1050
+ const tagId = tagRow.id;
1051
+ await this.removeTagFromCard(id, tagId);
1052
+ })
1053
+ );
1054
+ results.forEach((result, index) => {
1055
+ if (result.status === "rejected") {
1056
+ const tagId = appliedTags.rows[index].id;
1057
+ logger.error(`Failed to remove card ${id} from tag ${tagId}: ${result.reason}`);
1058
+ }
1059
+ });
1060
+ } catch (error) {
1061
+ logger.error(`Error removing card ${id} from tags: ${error}`);
1062
+ }
978
1063
  return this.db.remove(doc);
979
1064
  }
980
1065
  async getCardDisplayableDataIDs(id) {
@@ -1158,23 +1243,9 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
1158
1243
  ////////////////////////////////////
1159
1244
  getNavigationStrategy(id) {
1160
1245
  logger.debug(`[courseDB] Getting navigation strategy: ${id}`);
1161
- const strategy = {
1162
- id: "ELO",
1163
- docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
1164
- name: "ELO",
1165
- description: "ELO-based navigation strategy for ordering content by difficulty",
1166
- implementingClass: "elo" /* ELO */,
1167
- course: this.id,
1168
- serializedData: ""
1169
- // serde is a noop for ELO navigator.
1170
- };
1171
- return Promise.resolve(strategy);
1172
- }
1173
- getAllNavigationStrategies() {
1174
- logger.debug("[courseDB] Returning hard-coded navigation strategies");
1175
- const strategies = [
1176
- {
1177
- id: "ELO",
1246
+ if (id == "") {
1247
+ const strategy = {
1248
+ _id: "NAVIGATION_STRATEGY-ELO",
1178
1249
  docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
1179
1250
  name: "ELO",
1180
1251
  description: "ELO-based navigation strategy for ordering content by difficulty",
@@ -1182,14 +1253,25 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
1182
1253
  course: this.id,
1183
1254
  serializedData: ""
1184
1255
  // serde is a noop for ELO navigator.
1185
- }
1186
- ];
1187
- return Promise.resolve(strategies);
1256
+ };
1257
+ return Promise.resolve(strategy);
1258
+ } else {
1259
+ return this.db.get(id);
1260
+ }
1188
1261
  }
1189
- addNavigationStrategy(data) {
1190
- logger.debug(`[courseDB] Adding navigation strategy: ${data.id}`);
1191
- logger.debug(JSON.stringify(data));
1192
- return Promise.resolve();
1262
+ async getAllNavigationStrategies() {
1263
+ const prefix = DocTypePrefixes["NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */];
1264
+ const result = await this.db.allDocs({
1265
+ startkey: prefix,
1266
+ endkey: `${prefix}\uFFF0`,
1267
+ include_docs: true
1268
+ });
1269
+ return result.rows.map((row) => row.doc);
1270
+ }
1271
+ async addNavigationStrategy(data) {
1272
+ logger.debug(`[courseDB] Adding navigation strategy: ${data._id}`);
1273
+ return this.db.put(data).then(() => {
1274
+ });
1193
1275
  }
1194
1276
  updateNavigationStrategy(id, data) {
1195
1277
  logger.debug(`[courseDB] Updating navigation strategy: ${id}`);
@@ -1197,9 +1279,32 @@ ${above.rows.map((r) => ` ${r.id}-${r.key}
1197
1279
  return Promise.resolve();
1198
1280
  }
1199
1281
  async surfaceNavigationStrategy() {
1282
+ try {
1283
+ const config = await this.getCourseConfig();
1284
+ if (config.defaultNavigationStrategyId) {
1285
+ try {
1286
+ const strategy = await this.getNavigationStrategy(config.defaultNavigationStrategyId);
1287
+ if (strategy) {
1288
+ logger.debug(`Surfacing strategy ${strategy.name} from course config`);
1289
+ return strategy;
1290
+ }
1291
+ } catch (e) {
1292
+ logger.warn(
1293
+ // @ts-expect-error tmp: defaultNavigationStrategyId property does not yet exist
1294
+ `Failed to load strategy '${config.defaultNavigationStrategyId}' specified in course config. Falling back to ELO.`,
1295
+ e
1296
+ );
1297
+ }
1298
+ }
1299
+ } catch (e) {
1300
+ logger.warn(
1301
+ "Could not retrieve course config to determine navigation strategy. Falling back to ELO.",
1302
+ e
1303
+ );
1304
+ }
1200
1305
  logger.warn(`Returning hard-coded default ELO navigator`);
1201
1306
  const ret = {
1202
- id: "ELO",
1307
+ _id: "NAVIGATION_STRATEGY-ELO",
1203
1308
  docType: "NAVIGATION_STRATEGY" /* NAVIGATION_STRATEGY */,
1204
1309
  name: "ELO",
1205
1310
  description: "ELO-based navigation strategy",
@@ -2319,17 +2424,21 @@ Currently logged-in as ${this._username}.`
2319
2424
  } catch (e) {
2320
2425
  const reason = e;
2321
2426
  if (reason.status === 404) {
2322
- const initCardHistory = {
2323
- _id: cardHistoryID,
2324
- cardID: record.cardID,
2325
- courseID: record.courseID,
2326
- records: [record],
2327
- lapses: 0,
2328
- streak: 0,
2329
- bestInterval: 0
2330
- };
2331
- const putResult = await this.writeDB.put(initCardHistory);
2332
- return { ...initCardHistory, _rev: putResult.rev };
2427
+ try {
2428
+ const initCardHistory = {
2429
+ _id: cardHistoryID,
2430
+ cardID: record.cardID,
2431
+ courseID: record.courseID,
2432
+ records: [record],
2433
+ lapses: 0,
2434
+ streak: 0,
2435
+ bestInterval: 0
2436
+ };
2437
+ const putResult = await this.writeDB.put(initCardHistory);
2438
+ return { ...initCardHistory, _rev: putResult.rev };
2439
+ } catch (creationError) {
2440
+ throw new Error(`Failed to create CardHistory for ${cardHistoryID}. Reason: ${creationError}`);
2441
+ }
2333
2442
  } else {
2334
2443
  throw new Error(`putCardRecord failed because of:
2335
2444
  name:${reason.name}