@vue-skuilder/standalone-ui 0.2.0 → 0.2.2

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.
@@ -27128,29 +27128,29 @@ var import___vite_browser_external, import___vite_browser_external$1, import___v
27128
27128
  }, (t) => !d.some((c) => t.cardID === c.cardID))).map((t) => ({
27129
27129
  ...t,
27130
27130
  status: "new"
27131
- })), g = m.map((t) => t.cardID), b = await this.course.getCardEloData(g), S = m.map((t, c) => {
27132
- let d = b[c]?.global?.score ?? 1e3, m = Math.abs(d - u), g = Math.max(0, 1 - m / 500), S = g > 0 ? Math.random() ** (1 / g) : 0;
27131
+ })).map((t) => {
27132
+ let c = t.elo ?? 1e3, d = Math.abs(c - u), m = Math.max(0, 1 - d / 500), g = m > 0 ? Math.random() ** (1 / m) : 0;
27133
27133
  return {
27134
27134
  cardId: t.cardID,
27135
27135
  courseId: t.courseID,
27136
- score: S,
27136
+ score: g,
27137
27137
  provenance: [{
27138
27138
  strategy: "elo",
27139
27139
  strategyName: this.strategyName || this.name,
27140
27140
  strategyId: this.strategyId || "NAVIGATION_STRATEGY-ELO-default",
27141
27141
  action: "generated",
27142
- score: S,
27143
- reason: `ELO distance ${Math.round(m)} (card: ${Math.round(d)}, user: ${Math.round(u)}), raw ${g.toFixed(3)}, key ${S.toFixed(3)}`
27142
+ score: g,
27143
+ reason: `ELO distance ${Math.round(d)} (card: ${Math.round(c)}, user: ${Math.round(u)}), raw ${m.toFixed(3)}, key ${g.toFixed(3)}`
27144
27144
  }]
27145
27145
  };
27146
27146
  });
27147
- S.sort((t, c) => c.score - t.score);
27148
- let C = S.slice(0, t);
27149
- if (C.length > 0) {
27150
- let t = C.slice(0, 3).map((t) => t.score.toFixed(2)).join(", ");
27151
- logger.info(`[ELO] Course ${this.course.getCourseID()}: ${C.length} new cards (top scores: ${t})`);
27147
+ m.sort((t, c) => c.score - t.score);
27148
+ let g = m.slice(0, t);
27149
+ if (g.length > 0) {
27150
+ let t = g.slice(0, 3).map((t) => t.score.toFixed(2)).join(", ");
27151
+ logger.info(`[ELO] Course ${this.course.getCourseID()}: ${g.length} new cards (top scores: ${t})`);
27152
27152
  } else logger.info(`[ELO] Course ${this.course.getCourseID()}: No new cards available`);
27153
- return { cards: C };
27153
+ return { cards: g };
27154
27154
  }
27155
27155
  };
27156
27156
  } }), generators_exports = {}, init_generators = __esm({ "src/core/navigators/generators/index.ts"() {} }), prescribed_exports = {}, __export(prescribed_exports, { default: () => PrescribedCardsGenerator }), init_prescribed = __esm({ "src/core/navigators/generators/prescribed.ts"() {
@@ -28392,7 +28392,7 @@ var import___vite_browser_external, import___vite_browser_external$1, import___v
28392
28392
  }
28393
28393
  }, CourseDB = class {
28394
28394
  constructor(t, c, u) {
28395
- _defineProperty$2(this, "db", void 0), _defineProperty$2(this, "remoteDB", void 0), _defineProperty$2(this, "id", void 0), _defineProperty$2(this, "_getCurrentUser", void 0), _defineProperty$2(this, "updateQueue", void 0), _defineProperty$2(this, "_pendingHints", null), this.id = t;
28395
+ _defineProperty$2(this, "db", void 0), _defineProperty$2(this, "remoteDB", void 0), _defineProperty$2(this, "id", void 0), _defineProperty$2(this, "_getCurrentUser", void 0), _defineProperty$2(this, "updateQueue", void 0), _defineProperty$2(this, "_pendingHints", null), _defineProperty$2(this, "_eloPoolCache", null), _defineProperty$2(this, "_eloPoolTtlMs", 300 * 1e3), _defineProperty$2(this, "_cachedNavigator", null), _defineProperty$2(this, "_navigatorTtlMs", 300 * 1e3), this.id = t;
28396
28396
  let d = getCourseDB2(this.id);
28397
28397
  this.remoteDB = d, this.db = u ?? d, this._getCurrentUser = c, this.updateQueue = new UpdateQueue(this.remoteDB, this.remoteDB);
28398
28398
  }
@@ -28637,7 +28637,7 @@ ${g.rows.map((t) => ` ${t.id}-${t.key}
28637
28637
  })).rows.map((t) => t.doc);
28638
28638
  }
28639
28639
  async addNavigationStrategy(t) {
28640
- return logger.debug(`[courseDB] Adding navigation strategy: ${t._id}`), this.remoteDB.put(t).then(() => {});
28640
+ return logger.debug(`[courseDB] Adding navigation strategy: ${t._id}`), this.invalidateNavigatorCache(), this.remoteDB.put(t).then(() => {});
28641
28641
  }
28642
28642
  updateNavigationStrategy(t, c) {
28643
28643
  return logger.debug(`[courseDB] Updating navigation strategy: ${t}`), logger.debug(JSON.stringify(c)), Promise.resolve();
@@ -28665,12 +28665,31 @@ ${t.stack}` : JSON.stringify(t);
28665
28665
  async getWeightedCards(t) {
28666
28666
  let c = await this._getCurrentUser();
28667
28667
  try {
28668
- let u = await this.createNavigator(c);
28669
- return this._pendingHints && (u.setEphemeralHints(this._pendingHints), this._pendingHints = null), u.getWeightedCards(t);
28668
+ let { navigator: u } = await this._getCachedNavigator(c);
28669
+ return this._pendingHints && (u.setEphemeralHints(this._pendingHints), this._pendingHints = null), await u.getWeightedCards(t);
28670
28670
  } catch (t) {
28671
28671
  throw logger.error(`[courseDB] Error getting weighted cards: ${t}`), t;
28672
28672
  }
28673
28673
  }
28674
+ async _getCachedNavigator(t) {
28675
+ let c = t.getUsername(), u = Date.now();
28676
+ if (this._cachedNavigator && this._cachedNavigator.userId === c && u - this._cachedNavigator.builtAt < this._navigatorTtlMs) return {
28677
+ navigator: this._cachedNavigator.navigator,
28678
+ cacheStatus: "hit"
28679
+ };
28680
+ let d = await this.createNavigator(t);
28681
+ return this._cachedNavigator = {
28682
+ navigator: d,
28683
+ userId: c,
28684
+ builtAt: u
28685
+ }, {
28686
+ navigator: d,
28687
+ cacheStatus: "miss"
28688
+ };
28689
+ }
28690
+ invalidateNavigatorCache() {
28691
+ this._cachedNavigator = null;
28692
+ }
28674
28693
  async getCardsCenteredAtELO(t = {
28675
28694
  limit: 99,
28676
28695
  elo: "user"
@@ -28688,11 +28707,28 @@ ${t.stack}` : JSON.stringify(t);
28688
28707
  let t = await GET_CACHED(`elo-bounds-${this.id}`, () => this.getELOBounds());
28689
28708
  u = Math.round(t.low + Math.random() * (t.high - t.low));
28690
28709
  } else u = t.elo;
28691
- let d = [], m = 4, g = -1, b = 0;
28692
- for (; d.length < t.limit && b !== g;) d = await this.getCardsByELO(u, m * t.limit), g = b, b = d.length, logger.debug(`Found ${d.length} elo neighbor cards...`), c && (d = d.filter(c), logger.debug(`Filtered to ${d.length} cards...`)), m *= 2;
28710
+ let d = Math.max(2e3, t.limit * 4), m = Date.now(), g = "hit";
28711
+ if (!this._eloPoolCache || m - this._eloPoolCache.fetchedAt > this._eloPoolTtlMs) {
28712
+ let t = await this.getCardsByELO(u, d);
28713
+ t.length > 0 && (this._eloPoolCache = {
28714
+ rows: t,
28715
+ fetchedAt: m
28716
+ }), g = "miss";
28717
+ }
28718
+ let rankAgainstCurrentElo = () => {
28719
+ let t = this._eloPoolCache?.rows ?? [];
28720
+ return (c ? t.filter((t) => c(t)) : t).map((t) => ({ ...t })).sort((t, c) => Math.abs((t.elo ?? u) - u) - Math.abs((c.elo ?? u) - u));
28721
+ }, b = rankAgainstCurrentElo();
28722
+ if (b.length < t.limit && (g === "hit" || !this._eloPoolCache)) {
28723
+ let t = await this.getCardsByELO(u, d);
28724
+ t.length > 0 && (this._eloPoolCache = {
28725
+ rows: t,
28726
+ fetchedAt: m
28727
+ }), b = rankAgainstCurrentElo(), g = "refresh";
28728
+ }
28693
28729
  let S = [];
28694
- for (; S.length < t.limit && d.length > 0;) {
28695
- let t = randIntWeightedTowardZero(d.length), c = d.splice(t, 1)[0];
28730
+ for (; S.length < t.limit && b.length > 0;) {
28731
+ let t = randIntWeightedTowardZero(b.length), c = b.splice(t, 1)[0];
28696
28732
  S.push(c);
28697
28733
  }
28698
28734
  return S.map((t) => ({
@@ -30502,9 +30538,14 @@ Currently logged-in as ${this._username}.`);
30502
30538
  },
30503
30539
  async showScheduledReviews(t) {
30504
30540
  let c = getUserDB();
30505
- if (c) try {
30541
+ if (!c) {
30542
+ logger.info("[UserDB Debug] Data layer not available");
30543
+ return;
30544
+ }
30545
+ logger.info(`[UserDB Debug] Fetching pending reviews${t ? ` for course: ${t}` : ""}...`);
30546
+ try {
30506
30547
  let u = await c.getPendingReviews(t);
30507
- if (console.group(`\u{1F4C5} Scheduled Reviews${t ? ` (${t})` : ""}`), logger.info(`Total: ${u.length}`), u.length > 0) {
30548
+ if (logger.info(`[UserDB Debug] Got ${u.length} reviews`), console.group(`\u{1F4C5} Scheduled Reviews${t ? ` (${t})` : ""}`), logger.info(`Total: ${u.length}`), u.length > 0) {
30508
30549
  let t = /* @__PURE__ */ new Map();
30509
30550
  for (let c of u) t.has(c.courseId) || t.set(c.courseId, []), t.get(c.courseId).push(c);
30510
30551
  for (let [c, u] of t) {
@@ -31934,7 +31975,7 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31934
31975
  return this._secondsRemaining - (d + m) > 20 ? (c = .5, u = .9) : this._secondsRemaining - d > 20 ? (c = .05, u = .9) : (c = .01, u = .1), this.failedQ.length === 0 && (u = 1), this.reviewQ.length === 0 && (c = u), t < c && this.newQ.length ? this.newQ.peek(0) : t < u && this.reviewQ.length ? this.reviewQ.peek(0) : this.failedQ.length ? this.failedQ.peek(0) : (this.log("No more cards available for the session!"), null);
31935
31976
  }
31936
31977
  async nextCard(t = "dismiss-success") {
31937
- if (this.dismissCurrentCard(t), this._minCardsGuarantee > 0 && (this._minCardsGuarantee--, this.log(`[CardGuarantee] ${this._minCardsGuarantee} guaranteed cards remaining`)), this._replanPromise && this.newQ.length === 0 && this.reviewQ.length === 0 && this.failedQ.length === 0 && (this.log("nextCard: queues empty, awaiting in-flight replan before drawing"), await this._replanPromise), this.newQ.length <= 1 && this._secondsRemaining > 0 && !this._replanPromise) {
31978
+ if (this.dismissCurrentCard(t), this._minCardsGuarantee > 0 && (this._minCardsGuarantee--, this.log(`[CardGuarantee] ${this._minCardsGuarantee} guaranteed cards remaining`)), this._replanPromise && this.newQ.length === 0 && this.reviewQ.length === 0 && this.failedQ.length === 0 && (this.log("nextCard: queues empty, awaiting in-flight replan before drawing"), await this._replanPromise), this.newQ.length <= _SessionController.DEPLETION_PREFETCH_THRESHOLD && this._secondsRemaining > 0 && !this._replanPromise) {
31938
31979
  this._suppressQualityReplan = !1;
31939
31980
  let t = this.reviewQ.length + this.failedQ.length;
31940
31981
  this.log(`[AutoReplan:depletion] newQ has ${this.newQ.length} card(s) (${t} in other queues) with ${this._secondsRemaining}s remaining. Triggering background replan.`), this.requestReplan();
@@ -32009,7 +32050,7 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
32009
32050
  let d = (/* @__PURE__ */ new Date()).toISOString(), m = new Date(this.startTime).toISOString();
32010
32051
  await recordUserOutcome(c, m, d, t, u);
32011
32052
  }
32012
- }, _defineProperty$2(_SessionController2, "MIN_WELL_INDICATED", 5), _defineProperty$2(_SessionController2, "WELL_INDICATED_SCORE", .1), _SessionController2), init_TagFilteredContentSource(), init_factory();
32053
+ }, _defineProperty$2(_SessionController2, "MIN_WELL_INDICATED", 5), _defineProperty$2(_SessionController2, "WELL_INDICATED_SCORE", .1), _defineProperty$2(_SessionController2, "DEPLETION_PREFETCH_THRESHOLD", 3), _SessionController2), init_TagFilteredContentSource(), init_factory();
32013
32054
  }));
32014
32055
  //#endregion
32015
32056
  //#region ../../node_modules/vue-router/dist/vue-router.mjs