@vue-skuilder/db 0.1.31-b → 0.1.31

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 (49) hide show
  1. package/dist/{contentSource-ygoFw9oV.d.ts → contentSource-Bdwkvqa8.d.ts} +16 -0
  2. package/dist/{contentSource-B7nXusjk.d.cts → contentSource-DF1nUbPQ.d.cts} +16 -0
  3. package/dist/core/index.d.cts +34 -3
  4. package/dist/core/index.d.ts +34 -3
  5. package/dist/core/index.js +510 -50
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +510 -50
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/{dataLayerProvider-BW7HvkMt.d.cts → dataLayerProvider-BKmVoyJR.d.ts} +20 -1
  10. package/dist/{dataLayerProvider-BfXUVDuG.d.ts → dataLayerProvider-BQdfJuBN.d.cts} +20 -1
  11. package/dist/impl/couch/index.d.cts +156 -4
  12. package/dist/impl/couch/index.d.ts +156 -4
  13. package/dist/impl/couch/index.js +730 -41
  14. package/dist/impl/couch/index.js.map +1 -1
  15. package/dist/impl/couch/index.mjs +729 -41
  16. package/dist/impl/couch/index.mjs.map +1 -1
  17. package/dist/impl/static/index.d.cts +3 -2
  18. package/dist/impl/static/index.d.ts +3 -2
  19. package/dist/impl/static/index.js +467 -31
  20. package/dist/impl/static/index.js.map +1 -1
  21. package/dist/impl/static/index.mjs +467 -31
  22. package/dist/impl/static/index.mjs.map +1 -1
  23. package/dist/index.d.cts +64 -3
  24. package/dist/index.d.ts +64 -3
  25. package/dist/index.js +948 -72
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +948 -72
  28. package/dist/index.mjs.map +1 -1
  29. package/package.json +3 -3
  30. package/src/core/interfaces/contentSource.ts +6 -0
  31. package/src/core/interfaces/courseDB.ts +6 -0
  32. package/src/core/interfaces/dataLayerProvider.ts +20 -0
  33. package/src/core/navigators/Pipeline.ts +414 -9
  34. package/src/core/navigators/PipelineAssembler.ts +23 -18
  35. package/src/core/navigators/PipelineDebugger.ts +35 -1
  36. package/src/core/navigators/filters/hierarchyDefinition.ts +78 -8
  37. package/src/core/navigators/generators/prescribed.ts +95 -0
  38. package/src/core/navigators/index.ts +12 -0
  39. package/src/impl/common/BaseUserDB.ts +4 -1
  40. package/src/impl/couch/CourseSyncService.ts +356 -0
  41. package/src/impl/couch/PouchDataLayerProvider.ts +21 -1
  42. package/src/impl/couch/courseDB.ts +60 -13
  43. package/src/impl/couch/index.ts +1 -0
  44. package/src/impl/static/courseDB.ts +5 -0
  45. package/src/study/ItemQueue.ts +42 -0
  46. package/src/study/SessionController.ts +195 -22
  47. package/src/study/SpacedRepetition.ts +3 -1
  48. package/tests/core/navigators/Pipeline.test.ts +1 -1
  49. package/tests/core/navigators/PipelineAssembler.test.ts +15 -14
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource, C as CourseDBInterface } from './contentSource-B7nXusjk.cjs';
2
- export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, a8 as DocumentUpdater, a2 as LearnableWeight, N as NavigatorConstructor, _ as NavigatorRole, $ as NavigatorRoles, Z as Navigators, a3 as OrchestrationContext, j as ScheduledCard, H as SessionTrackingData, X as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, L as UserOutcomeRecord, B as UsrCrsDataInterface, a4 as computeDeviation, a6 as computeEffectiveWeight, a5 as computeSpread, a7 as createOrchestrationContext, Y as getCardOrigin, O as getRegisteredNavigator, R as getRegisteredNavigatorNames, Q as getRegisteredNavigatorRole, r as getStudySource, P as hasRegisteredNavigator, V as initializeNavigatorRegistry, a1 as isFilter, a0 as isGenerator, p as isReview, a9 as newInterval, M as registerNavigator } from './contentSource-B7nXusjk.cjs';
3
- import { D as DataLayerProvider } from './dataLayerProvider-BW7HvkMt.cjs';
1
+ import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource, C as CourseDBInterface } from './contentSource-DF1nUbPQ.cjs';
2
+ export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, a8 as DocumentUpdater, a2 as LearnableWeight, N as NavigatorConstructor, _ as NavigatorRole, $ as NavigatorRoles, Z as Navigators, a3 as OrchestrationContext, j as ScheduledCard, H as SessionTrackingData, X as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, L as UserOutcomeRecord, B as UsrCrsDataInterface, a4 as computeDeviation, a6 as computeEffectiveWeight, a5 as computeSpread, a7 as createOrchestrationContext, Y as getCardOrigin, O as getRegisteredNavigator, R as getRegisteredNavigatorNames, Q as getRegisteredNavigatorRole, r as getStudySource, P as hasRegisteredNavigator, V as initializeNavigatorRegistry, a1 as isFilter, a0 as isGenerator, p as isReview, a9 as newInterval, M as registerNavigator } from './contentSource-DF1nUbPQ.cjs';
3
+ import { D as DataLayerProvider } from './dataLayerProvider-BQdfJuBN.cjs';
4
4
  import { C as CardHistory, c as CardRecord } from './types-legacy-JXDxinpU.cjs';
5
5
  export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, i as QuestionRecord, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-JXDxinpU.cjs';
6
6
  import { Loggable } from './core/index.cjs';
@@ -344,6 +344,18 @@ declare class SessionController<TView = unknown> extends Loggable {
344
344
  private reviewQ;
345
345
  private newQ;
346
346
  private failedQ;
347
+ /**
348
+ * Promise tracking a currently in-progress replan, or null if idle.
349
+ * Used by nextCard() to await completion before drawing from queues.
350
+ */
351
+ private _replanPromise;
352
+ /**
353
+ * Number of well-indicated new cards remaining before the queue
354
+ * degrades to poorly-indicated content. Decremented on each newQ
355
+ * draw; when it hits 0, a replan is triggered automatically
356
+ * (user state has changed from completing good cards).
357
+ */
358
+ private _wellIndicatedRemaining;
347
359
  private startTime;
348
360
  private endTime;
349
361
  private _secondsRemaining;
@@ -374,6 +386,41 @@ declare class SessionController<TView = unknown> extends Loggable {
374
386
  */
375
387
  private estimateReviewTime;
376
388
  prepareSession(): Promise<void>;
389
+ /**
390
+ * Request a mid-session replan. Re-runs the pipeline with current user state
391
+ * and atomically replaces the newQ contents. Safe to call at any time during
392
+ * a session — if called while a replan is already in progress, returns the
393
+ * existing replan promise (no duplicate work).
394
+ *
395
+ * Does NOT affect reviewQ or failedQ.
396
+ *
397
+ * If nextCard() is called while a replan is in flight, it will automatically
398
+ * await the replan before drawing from queues, ensuring the user always sees
399
+ * cards scored against their latest state.
400
+ *
401
+ * Typical trigger: application-level code (e.g. after a GPC intro completion)
402
+ * calls this to ensure newly-unlocked content appears in the session.
403
+ */
404
+ requestReplan(hints?: Record<string, unknown>): Promise<void>;
405
+ /** Minimum well-indicated cards before an additive retry is attempted */
406
+ private static readonly MIN_WELL_INDICATED;
407
+ /**
408
+ * Score threshold for considering a card "well-indicated."
409
+ * Cards below this score are treated as fallback filler — present only
410
+ * because no strategy hard-removed them, but likely penalized by one
411
+ * or more filters. Strategy-agnostic: the SessionController doesn't
412
+ * know or care which strategy assigned the score.
413
+ */
414
+ private static readonly WELL_INDICATED_SCORE;
415
+ /**
416
+ * Internal replan execution. Runs the pipeline, builds a new newQ,
417
+ * atomically swaps it in, and triggers hydration for the new contents.
418
+ *
419
+ * If the initial replan produces fewer than MIN_WELL_INDICATED cards that
420
+ * pass all hierarchy filters, one additive retry is attempted — merging
421
+ * any new high-quality candidates into the front of the queue.
422
+ */
423
+ private _executeReplan;
377
424
  addTime(seconds: number): void;
378
425
  get failedCount(): number;
379
426
  toString(): string;
@@ -418,6 +465,9 @@ declare class SessionController<TView = unknown> extends Loggable {
418
465
  count: number;
419
466
  cardIds: string[];
420
467
  };
468
+ replan: {
469
+ inProgress: boolean;
470
+ };
421
471
  };
422
472
  /**
423
473
  * Fetch content using the getWeightedCards API and mix across sources.
@@ -428,6 +478,17 @@ declare class SessionController<TView = unknown> extends Loggable {
428
478
  * 3. Uses SourceMixer to balance content across sources
429
479
  * 4. Populates review and new card queues with mixed results
430
480
  */
481
+ /**
482
+ * Fetch weighted content from all sources and populate session queues.
483
+ *
484
+ * @param options.replan - If true, this is a mid-session replan rather than
485
+ * initial session setup. Skips review queue population (avoiding duplicates),
486
+ * atomically replaces newQ contents, and treats empty results as non-fatal.
487
+ * @param options.additive - If true (replan only), merge new high-quality
488
+ * candidates into the front of the existing newQ instead of replacing it.
489
+ * @returns Number of "well-indicated" cards (passed all hierarchy filters)
490
+ * in the new content. Returns -1 if no content was loaded.
491
+ */
431
492
  private getWeightedContent;
432
493
  /**
433
494
  * Returns items that should be pre-hydrated.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource, C as CourseDBInterface } from './contentSource-ygoFw9oV.js';
2
- export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, a8 as DocumentUpdater, a2 as LearnableWeight, N as NavigatorConstructor, _ as NavigatorRole, $ as NavigatorRoles, Z as Navigators, a3 as OrchestrationContext, j as ScheduledCard, H as SessionTrackingData, X as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, L as UserOutcomeRecord, B as UsrCrsDataInterface, a4 as computeDeviation, a6 as computeEffectiveWeight, a5 as computeSpread, a7 as createOrchestrationContext, Y as getCardOrigin, O as getRegisteredNavigator, R as getRegisteredNavigatorNames, Q as getRegisteredNavigatorRole, r as getStudySource, P as hasRegisteredNavigator, V as initializeNavigatorRegistry, a1 as isFilter, a0 as isGenerator, p as isReview, a9 as newInterval, M as registerNavigator } from './contentSource-ygoFw9oV.js';
3
- import { D as DataLayerProvider } from './dataLayerProvider-BfXUVDuG.js';
1
+ import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource, C as CourseDBInterface } from './contentSource-Bdwkvqa8.js';
2
+ export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, a8 as DocumentUpdater, a2 as LearnableWeight, N as NavigatorConstructor, _ as NavigatorRole, $ as NavigatorRoles, Z as Navigators, a3 as OrchestrationContext, j as ScheduledCard, H as SessionTrackingData, X as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, L as UserOutcomeRecord, B as UsrCrsDataInterface, a4 as computeDeviation, a6 as computeEffectiveWeight, a5 as computeSpread, a7 as createOrchestrationContext, Y as getCardOrigin, O as getRegisteredNavigator, R as getRegisteredNavigatorNames, Q as getRegisteredNavigatorRole, r as getStudySource, P as hasRegisteredNavigator, V as initializeNavigatorRegistry, a1 as isFilter, a0 as isGenerator, p as isReview, a9 as newInterval, M as registerNavigator } from './contentSource-Bdwkvqa8.js';
3
+ import { D as DataLayerProvider } from './dataLayerProvider-BKmVoyJR.js';
4
4
  import { C as CardHistory, c as CardRecord } from './types-legacy-JXDxinpU.js';
5
5
  export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, i as QuestionRecord, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-JXDxinpU.js';
6
6
  import { Loggable } from './core/index.js';
@@ -344,6 +344,18 @@ declare class SessionController<TView = unknown> extends Loggable {
344
344
  private reviewQ;
345
345
  private newQ;
346
346
  private failedQ;
347
+ /**
348
+ * Promise tracking a currently in-progress replan, or null if idle.
349
+ * Used by nextCard() to await completion before drawing from queues.
350
+ */
351
+ private _replanPromise;
352
+ /**
353
+ * Number of well-indicated new cards remaining before the queue
354
+ * degrades to poorly-indicated content. Decremented on each newQ
355
+ * draw; when it hits 0, a replan is triggered automatically
356
+ * (user state has changed from completing good cards).
357
+ */
358
+ private _wellIndicatedRemaining;
347
359
  private startTime;
348
360
  private endTime;
349
361
  private _secondsRemaining;
@@ -374,6 +386,41 @@ declare class SessionController<TView = unknown> extends Loggable {
374
386
  */
375
387
  private estimateReviewTime;
376
388
  prepareSession(): Promise<void>;
389
+ /**
390
+ * Request a mid-session replan. Re-runs the pipeline with current user state
391
+ * and atomically replaces the newQ contents. Safe to call at any time during
392
+ * a session — if called while a replan is already in progress, returns the
393
+ * existing replan promise (no duplicate work).
394
+ *
395
+ * Does NOT affect reviewQ or failedQ.
396
+ *
397
+ * If nextCard() is called while a replan is in flight, it will automatically
398
+ * await the replan before drawing from queues, ensuring the user always sees
399
+ * cards scored against their latest state.
400
+ *
401
+ * Typical trigger: application-level code (e.g. after a GPC intro completion)
402
+ * calls this to ensure newly-unlocked content appears in the session.
403
+ */
404
+ requestReplan(hints?: Record<string, unknown>): Promise<void>;
405
+ /** Minimum well-indicated cards before an additive retry is attempted */
406
+ private static readonly MIN_WELL_INDICATED;
407
+ /**
408
+ * Score threshold for considering a card "well-indicated."
409
+ * Cards below this score are treated as fallback filler — present only
410
+ * because no strategy hard-removed them, but likely penalized by one
411
+ * or more filters. Strategy-agnostic: the SessionController doesn't
412
+ * know or care which strategy assigned the score.
413
+ */
414
+ private static readonly WELL_INDICATED_SCORE;
415
+ /**
416
+ * Internal replan execution. Runs the pipeline, builds a new newQ,
417
+ * atomically swaps it in, and triggers hydration for the new contents.
418
+ *
419
+ * If the initial replan produces fewer than MIN_WELL_INDICATED cards that
420
+ * pass all hierarchy filters, one additive retry is attempted — merging
421
+ * any new high-quality candidates into the front of the queue.
422
+ */
423
+ private _executeReplan;
377
424
  addTime(seconds: number): void;
378
425
  get failedCount(): number;
379
426
  toString(): string;
@@ -418,6 +465,9 @@ declare class SessionController<TView = unknown> extends Loggable {
418
465
  count: number;
419
466
  cardIds: string[];
420
467
  };
468
+ replan: {
469
+ inProgress: boolean;
470
+ };
421
471
  };
422
472
  /**
423
473
  * Fetch content using the getWeightedCards API and mix across sources.
@@ -428,6 +478,17 @@ declare class SessionController<TView = unknown> extends Loggable {
428
478
  * 3. Uses SourceMixer to balance content across sources
429
479
  * 4. Populates review and new card queues with mixed results
430
480
  */
481
+ /**
482
+ * Fetch weighted content from all sources and populate session queues.
483
+ *
484
+ * @param options.replan - If true, this is a mid-session replan rather than
485
+ * initial session setup. Skips review queue population (avoiding duplicates),
486
+ * atomically replaces newQ contents, and treats empty results as non-fatal.
487
+ * @param options.additive - If true (replan only), merge new high-quality
488
+ * candidates into the front of the existing newQ instead of replacing it.
489
+ * @returns Number of "well-indicated" cards (passed all hierarchy filters)
490
+ * in the new content. Returns -1 if no content was loaded.
491
+ */
431
492
  private getWeightedContent;
432
493
  /**
433
494
  * Returns items that should be pre-hydrated.