@vue-skuilder/db 0.2.14 → 0.2.16

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 (36) hide show
  1. package/dist/{contentSource-C-0t0y0V.d.ts → contentSource-B1p-vdz7.d.ts} +7 -0
  2. package/dist/{contentSource-jSkcOt2s.d.cts → contentSource-Brz42x7n.d.cts} +7 -0
  3. package/dist/core/index.d.cts +3 -3
  4. package/dist/core/index.d.ts +3 -3
  5. package/dist/core/index.js +6 -3
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +6 -3
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/{dataLayerProvider-BB0oi9T0.d.ts → dataLayerProvider-BWayUIoK.d.ts} +1 -1
  10. package/dist/{dataLayerProvider-BDClIrFC.d.cts → dataLayerProvider-CpwpT1rM.d.cts} +1 -1
  11. package/dist/impl/couch/index.d.cts +2 -2
  12. package/dist/impl/couch/index.d.ts +2 -2
  13. package/dist/impl/couch/index.js +6 -3
  14. package/dist/impl/couch/index.js.map +1 -1
  15. package/dist/impl/couch/index.mjs +6 -3
  16. package/dist/impl/couch/index.mjs.map +1 -1
  17. package/dist/impl/static/index.d.cts +2 -2
  18. package/dist/impl/static/index.d.ts +2 -2
  19. package/dist/impl/static/index.js +6 -3
  20. package/dist/impl/static/index.js.map +1 -1
  21. package/dist/impl/static/index.mjs +6 -3
  22. package/dist/impl/static/index.mjs.map +1 -1
  23. package/dist/index.d.cts +41 -5
  24. package/dist/index.d.ts +41 -5
  25. package/dist/index.js +18 -4
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +13 -4
  28. package/dist/index.mjs.map +1 -1
  29. package/package.json +3 -3
  30. package/src/core/interfaces/userDB.ts +8 -0
  31. package/src/impl/common/BaseUserDB.ts +2 -2
  32. package/src/impl/common/userDBHelpers.ts +14 -1
  33. package/src/index.ts +6 -0
  34. package/src/study/SessionOverlay.ts +16 -3
  35. package/src/study/index.ts +4 -0
  36. package/src/study/services/CardHydrationService.ts +9 -1
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.2.14",
7
+ "version": "0.2.16",
8
8
  "description": "Database layer for vue-skuilder",
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/index.mjs",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@nilock2/pouchdb-authentication": "^1.0.2",
51
- "@vue-skuilder/common": "0.2.14",
51
+ "@vue-skuilder/common": "0.2.16",
52
52
  "cross-fetch": "^4.1.0",
53
53
  "moment": "^2.29.4",
54
54
  "pouchdb": "^9.0.0",
@@ -62,5 +62,5 @@
62
62
  "vite": "^8.0.0",
63
63
  "vitest": "^4.1.0"
64
64
  },
65
- "stableVersion": "0.2.14"
65
+ "stableVersion": "0.2.16"
66
66
  }
@@ -55,6 +55,14 @@ export interface UserDBReader {
55
55
  */
56
56
  getPendingReviews(courseId?: string): Promise<ScheduledCard[]>;
57
57
 
58
+ /**
59
+ * Get all scheduled reviews due within the next `daysCount` days —
60
+ * including ones not yet due. `getPendingReviews` is the `daysCount = 0`
61
+ * special case: it returns only reviews already due, so a review scheduled
62
+ * moments ago (necessarily in the future) will never appear in it.
63
+ */
64
+ getReviewsForcast(daysCount: number, courseId?: string): Promise<ScheduledCard[]>;
65
+
58
66
  getActivityRecords(): Promise<ActivityRecord[]>;
59
67
 
60
68
  /**
@@ -416,9 +416,9 @@ Currently logged-in as ${this._username}.`
416
416
  .map((r) => r.doc!);
417
417
  }
418
418
 
419
- public async getReviewsForcast(daysCount: number) {
419
+ public async getReviewsForcast(daysCount: number, course_id?: string) {
420
420
  const time = moment.utc().add(daysCount, 'days');
421
- return this.getReviewstoDate(time);
421
+ return this.getReviewstoDate(time, course_id);
422
422
  }
423
423
 
424
424
  public async getPendingReviews(course_id?: string) {
@@ -7,6 +7,19 @@ import { ScheduledCard } from '@db/core/types/user';
7
7
 
8
8
  export const REVIEW_TIME_FORMAT: string = 'YYYY-MM-DD--kk:mm:ss-SSS';
9
9
 
10
+ /**
11
+ * Build a ScheduledCard `_id` for the given review time.
12
+ *
13
+ * The id suffix is not a mere uniquifier: `getReviewstoDate` PARSES the id
14
+ * (with {@link REVIEW_TIME_FORMAT}) to decide due-ness, so the id is the
15
+ * datum. Anything that writes or rewrites scheduled-card docs (scheduling,
16
+ * user-state snapshot rebasing) must construct ids through this helper —
17
+ * a hand-rolled formatter will get moment's `kk` token (01-24 hours) wrong.
18
+ */
19
+ export function makeScheduledCardId(reviewTime: string | Date | moment.Moment): string {
20
+ return DocTypePrefixes[DocType.SCHEDULED_CARD] + moment.utc(reviewTime).format(REVIEW_TIME_FORMAT);
21
+ }
22
+
10
23
  import pouch from '../couch/pouchdb-setup';
11
24
  import { getDbPath } from '../../util/dataDirectory';
12
25
 
@@ -123,7 +136,7 @@ export function scheduleCardReviewLocal(
123
136
  const now = moment.utc();
124
137
  logger.info(`Scheduling for review in: ${review.time.diff(now, 'h') / 24} days`);
125
138
  void userDB.put<ScheduledCard>({
126
- _id: DocTypePrefixes[DocType.SCHEDULED_CARD] + review.time.format(REVIEW_TIME_FORMAT),
139
+ _id: makeScheduledCardId(review.time),
127
140
  cardId: review.card_id,
128
141
  reviewTime: review.time.toISOString(),
129
142
  courseId: review.course_id,
package/src/index.ts CHANGED
@@ -9,6 +9,12 @@ export * from './study';
9
9
  export * from './util';
10
10
  export * from './factory';
11
11
 
12
+ // Scheduled-card id construction: the id embeds the review time and is parsed
13
+ // by the due-review read path, so out-of-tree writers (e.g. user-state
14
+ // snapshot rebasing) must build ids with this rather than reimplementing the
15
+ // moment format.
16
+ export { REVIEW_TIME_FORMAT, makeScheduledCardId } from './impl/common/userDBHelpers';
17
+
12
18
  // Export CouchDB user types for use in Express backend
13
19
  export type {
14
20
  UserAccountStatus,
@@ -81,6 +81,19 @@ export interface SessionDebugTarget {
81
81
  getDebugSnapshot(): SessionDebugSnapshot;
82
82
  }
83
83
 
84
+ /**
85
+ * The live-session surface available to out-of-tree callers through the
86
+ * active-controller registry: the debug snapshot, plus the small set of
87
+ * user-facing session controls a view may need without holding a ref into
88
+ * the `<StudySession>` component's internals (e.g. wiring a timer's
89
+ * add-time button from a composable). Keep this narrow — it is not a
90
+ * general escape hatch to `SessionController`.
91
+ */
92
+ export interface ActiveSessionHandle extends SessionDebugTarget {
93
+ /** Extend the session clock by `seconds`. */
94
+ addTime(seconds: number): void;
95
+ }
96
+
84
97
  // ----------------------------------------------------------------------------
85
98
  // Active-controller registry
86
99
  // ----------------------------------------------------------------------------
@@ -90,14 +103,14 @@ export interface SessionDebugTarget {
90
103
  // registrar without pulling in the overlay's DOM code or risking an import
91
104
  // cycle with SessionDebugger.
92
105
 
93
- let activeController: SessionDebugTarget | null = null;
106
+ let activeController: ActiveSessionHandle | null = null;
94
107
 
95
108
  /** Called by SessionController's constructor. Pass `null` to deregister. */
96
- export function registerActiveController(controller: SessionDebugTarget | null): void {
109
+ export function registerActiveController(controller: ActiveSessionHandle | null): void {
97
110
  activeController = controller;
98
111
  }
99
112
 
100
- export function getActiveController(): SessionDebugTarget | null {
113
+ export function getActiveController(): ActiveSessionHandle | null {
101
114
  return activeController;
102
115
  }
103
116
 
@@ -4,3 +4,7 @@ export * from './SpacedRepetition';
4
4
  export * from './TagFilteredContentSource';
5
5
  export * from './MixerDebugger';
6
6
  export * from './SessionDebugger';
7
+ // `getActiveController()` + `SessionDebugSnapshot` — the live-state read the
8
+ // SessionOverlay renders internally. Exported so hosts can build their own UI
9
+ // over the same snapshot (LettersPractice's /showHN annotated view does).
10
+ export * from './SessionOverlay';
@@ -250,8 +250,16 @@ export class CardHydrationService<TView = unknown> {
250
250
 
251
251
  const data = dataDocs.map(displayableDataToViewData).reverse();
252
252
 
253
+ // Attach the card doc's authored ELO to the item. Generators don't carry
254
+ // card ELO onto StudySessionItems (reviews couldn't know it without a
255
+ // lookup), so without this every downstream consumer of `item.elo` —
256
+ // StudySession's `card_elo`, CardViewer's modify-difficulty, session
257
+ // outcomes — fell back to the 1000 default for EVERY card. The doc is
258
+ // already fetched here, making this the one seam that covers all card
259
+ // origins for free. Copy rather than mutate: the queue holds the same
260
+ // item reference.
253
261
  this.hydratedCards.set(item.cardID, {
254
- item,
262
+ item: { ...item, elo: toCourseElo(cardData.elo).global.score },
255
263
  view,
256
264
  data,
257
265
  tags: tagsByCard.get(item.cardID) ?? [],