@vue-skuilder/db 0.1.32-b → 0.1.32-e

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 (51) hide show
  1. package/dist/{contentSource-DF1nUbPQ.d.cts → contentSource-BMlMwSiG.d.cts} +124 -5
  2. package/dist/{contentSource-Bdwkvqa8.d.ts → contentSource-Ht3N2f-y.d.ts} +124 -5
  3. package/dist/core/index.d.cts +26 -83
  4. package/dist/core/index.d.ts +26 -83
  5. package/dist/core/index.js +767 -71
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +767 -71
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/{dataLayerProvider-BQdfJuBN.d.cts → dataLayerProvider-BEqB8VBR.d.cts} +1 -1
  10. package/dist/{dataLayerProvider-BKmVoyJR.d.ts → dataLayerProvider-DObSXjnf.d.ts} +1 -1
  11. package/dist/impl/couch/index.d.cts +18 -5
  12. package/dist/impl/couch/index.d.ts +18 -5
  13. package/dist/impl/couch/index.js +817 -74
  14. package/dist/impl/couch/index.js.map +1 -1
  15. package/dist/impl/couch/index.mjs +817 -74
  16. package/dist/impl/couch/index.mjs.map +1 -1
  17. package/dist/impl/static/index.d.cts +4 -4
  18. package/dist/impl/static/index.d.ts +4 -4
  19. package/dist/impl/static/index.js +763 -67
  20. package/dist/impl/static/index.js.map +1 -1
  21. package/dist/impl/static/index.mjs +763 -67
  22. package/dist/impl/static/index.mjs.map +1 -1
  23. package/dist/index.d.cts +23 -8
  24. package/dist/index.d.ts +23 -8
  25. package/dist/index.js +872 -86
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +872 -86
  28. package/dist/index.mjs.map +1 -1
  29. package/docs/navigators-architecture.md +2 -2
  30. package/package.json +2 -2
  31. package/src/core/interfaces/contentSource.ts +3 -3
  32. package/src/core/navigators/Pipeline.ts +104 -32
  33. package/src/core/navigators/PipelineDebugger.ts +152 -1
  34. package/src/core/navigators/filters/hierarchyDefinition.ts +90 -6
  35. package/src/core/navigators/filters/interferenceMitigator.ts +2 -1
  36. package/src/core/navigators/filters/relativePriority.ts +2 -1
  37. package/src/core/navigators/filters/userTagPreference.ts +2 -1
  38. package/src/core/navigators/generators/CompositeGenerator.ts +58 -5
  39. package/src/core/navigators/generators/elo.ts +7 -7
  40. package/src/core/navigators/generators/prescribed.ts +710 -46
  41. package/src/core/navigators/generators/srs.ts +3 -4
  42. package/src/core/navigators/generators/types.ts +48 -2
  43. package/src/core/navigators/index.ts +4 -3
  44. package/src/impl/couch/CourseSyncService.ts +72 -4
  45. package/src/impl/couch/classroomDB.ts +4 -3
  46. package/src/impl/couch/courseDB.ts +5 -4
  47. package/src/impl/static/courseDB.ts +5 -4
  48. package/src/study/SessionController.ts +58 -10
  49. package/src/study/TagFilteredContentSource.ts +4 -3
  50. package/src/study/services/EloService.ts +22 -3
  51. package/src/study/services/ResponseProcessor.ts +7 -3
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
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';
1
+ import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, R as ReplanHints, h as StudyContentSource, G as GeneratorResult, C as CourseDBInterface } from './contentSource-BMlMwSiG.cjs';
2
+ export { K as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, a4 as CardGenerator, a6 as CardGeneratorFactory, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, H as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, L as CourseRegistration, b as CoursesDBInterface, ad as DocumentUpdater, a5 as GeneratorContext, a7 as LearnableWeight, N as NavigatorConstructor, a0 as NavigatorRole, a1 as NavigatorRoles, $ as Navigators, a8 as OrchestrationContext, j as ScheduledCard, I as SessionTrackingData, Z as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, J as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, M as UserOutcomeRecord, B as UsrCrsDataInterface, a9 as computeDeviation, ab as computeEffectiveWeight, aa as computeSpread, ac as createOrchestrationContext, _ as getCardOrigin, P as getRegisteredNavigator, X as getRegisteredNavigatorNames, V as getRegisteredNavigatorRole, r as getStudySource, Q as hasRegisteredNavigator, Y as initializeNavigatorRegistry, a3 as isFilter, a2 as isGenerator, p as isReview, ae as newInterval, O as registerNavigator } from './contentSource-BMlMwSiG.cjs';
3
+ import { D as DataLayerProvider } from './dataLayerProvider-BEqB8VBR.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';
7
- export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, FilterImpact, GeneratorContext, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, mountUserDBDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, userDBDebugAPI, validateProcessorConfig } from './core/index.cjs';
7
+ export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, FilterContext, FilterImpact, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, mountUserDBDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, userDBDebugAPI, validateProcessorConfig } from './core/index.cjs';
8
8
  import { TaggedPerformance, TagFilter, DataShape, CourseConfig } from '@vue-skuilder/common';
9
9
  import { S as StaticCourseManifest } from './types-W8n-B6HG.cjs';
10
10
  export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-W8n-B6HG.cjs';
@@ -316,7 +316,7 @@ declare class QuotaRoundRobinMixer implements SourceMixer {
316
316
  */
317
317
  interface ReplanOptions {
318
318
  /** Scoring hints forwarded to the pipeline (boost/exclude/require). */
319
- hints?: Record<string, unknown>;
319
+ hints?: ReplanHints;
320
320
  /**
321
321
  * Maximum number of new cards to return from the pipeline.
322
322
  * Default: 20 (the standard session batch size).
@@ -328,6 +328,13 @@ interface ReplanOptions {
328
328
  * - `'merge'`: insert new cards at the front, keeping existing cards.
329
329
  */
330
330
  mode?: 'replace' | 'merge';
331
+ /**
332
+ * Guarantee that at least this many cards will be served after the
333
+ * replan, even if the session timer has expired. Prevents intro cards
334
+ * from surfacing at the end of a session with zero follow-up exercise.
335
+ * Decremented on each card draw while active.
336
+ */
337
+ minFollowUpCards?: number;
331
338
  /**
332
339
  * Human-readable label for debugging / provenance.
333
340
  * Appears in console logs and in card provenance entries created
@@ -411,10 +418,17 @@ declare class SessionController<TView = unknown> extends Loggable {
411
418
  * (non-auto) replan is requested.
412
419
  */
413
420
  private _depletionReplanAttempted;
421
+ /**
422
+ * When > 0, the session timer cannot end the session. Decremented on
423
+ * each nextCard() draw. Set by replans that include `minFollowUpCards`.
424
+ */
425
+ private _minCardsGuarantee;
414
426
  private startTime;
415
427
  private endTime;
416
428
  private _secondsRemaining;
417
429
  get secondsRemaining(): number;
430
+ /** True when a card guarantee is active, preventing timer-based session end. */
431
+ get hasCardGuarantee(): boolean;
418
432
  get report(): string;
419
433
  get detailedReport(): string;
420
434
  private _intervalHandle;
@@ -462,7 +476,7 @@ declare class SessionController<TView = unknown> extends Loggable {
462
476
  * Typical trigger: application-level code (e.g. after a GPC intro completion)
463
477
  * calls this to ensure newly-unlocked content appears in the session.
464
478
  */
465
- requestReplan(options?: ReplanOptions | Record<string, unknown>): Promise<void>;
479
+ requestReplan(options?: ReplanOptions | ReplanHints): Promise<void>;
466
480
  /**
467
481
  * Normalise the requestReplan argument. Accepts either a ReplanOptions
468
482
  * object (new API) or a plain Record<string, unknown> (legacy callers
@@ -537,6 +551,7 @@ declare class SessionController<TView = unknown> extends Loggable {
537
551
  inProgress: boolean;
538
552
  suppressQualityReplan: boolean;
539
553
  defaultBatchLimit: number;
554
+ minCardsGuarantee: number;
540
555
  };
541
556
  };
542
557
  /**
@@ -634,7 +649,7 @@ declare class TagFilteredContentSource implements StudyContentSource {
634
649
  * @param limit - Maximum number of cards to return
635
650
  * @returns Cards sorted by score descending (all scores = 1.0)
636
651
  */
637
- getWeightedCards(limit: number): Promise<WeightedCard[]>;
652
+ getWeightedCards(limit: number): Promise<GeneratorResult>;
638
653
  /**
639
654
  * Clears the cached resolved card IDs.
640
655
  * Call this if the underlying tag data may have changed during a session.
@@ -1087,4 +1102,4 @@ interface CouchDbUserDoc extends PouchDB.Authentication.User {
1087
1102
  entitlements: UserEntitlements;
1088
1103
  }
1089
1104
 
1090
- export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, type CardPresentation, CardRecord, type CouchDbUserDoc, CourseDBInterface, CourseLookup, CourseRegistrationDoc, type CustomQuestionsData, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, Loggable, type MigrationOptions, type MigrationResult, type MixerCardInfo, type MixerRunReport, NOT_SET, type ProcessedDataShape, type ProcessedQuestionData, type QueueSnapshot, QuotaRoundRobinMixer, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, endSessionTracking, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, mixerDebugAPI, mountMixerDebugger, mountSessionDebugger, processCustomQuestionsData, recordCardPresentation, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, removeCustomQuestionTypes, removeDataShape, removeQuestionType, sessionDebugAPI, snapshotQueues, startSessionTracking, validateMigration, validateStaticCourse };
1105
+ export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, type CardPresentation, CardRecord, type CouchDbUserDoc, CourseDBInterface, CourseLookup, CourseRegistrationDoc, type CustomQuestionsData, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, GeneratorResult, Loggable, type MigrationOptions, type MigrationResult, type MixerCardInfo, type MixerRunReport, NOT_SET, type ProcessedDataShape, type ProcessedQuestionData, type QueueSnapshot, QuotaRoundRobinMixer, ReplanHints, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, endSessionTracking, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, mixerDebugAPI, mountMixerDebugger, mountSessionDebugger, processCustomQuestionsData, recordCardPresentation, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, removeCustomQuestionTypes, removeDataShape, removeQuestionType, sessionDebugAPI, snapshotQueues, startSessionTracking, validateMigration, validateStaticCourse };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
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';
1
+ import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, R as ReplanHints, h as StudyContentSource, G as GeneratorResult, C as CourseDBInterface } from './contentSource-Ht3N2f-y.js';
2
+ export { K as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, a4 as CardGenerator, a6 as CardGeneratorFactory, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, H as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, L as CourseRegistration, b as CoursesDBInterface, ad as DocumentUpdater, a5 as GeneratorContext, a7 as LearnableWeight, N as NavigatorConstructor, a0 as NavigatorRole, a1 as NavigatorRoles, $ as Navigators, a8 as OrchestrationContext, j as ScheduledCard, I as SessionTrackingData, Z as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, J as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, M as UserOutcomeRecord, B as UsrCrsDataInterface, a9 as computeDeviation, ab as computeEffectiveWeight, aa as computeSpread, ac as createOrchestrationContext, _ as getCardOrigin, P as getRegisteredNavigator, X as getRegisteredNavigatorNames, V as getRegisteredNavigatorRole, r as getStudySource, Q as hasRegisteredNavigator, Y as initializeNavigatorRegistry, a3 as isFilter, a2 as isGenerator, p as isReview, ae as newInterval, O as registerNavigator } from './contentSource-Ht3N2f-y.js';
3
+ import { D as DataLayerProvider } from './dataLayerProvider-DObSXjnf.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';
7
- export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, FilterImpact, GeneratorContext, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, mountUserDBDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, userDBDebugAPI, validateProcessorConfig } from './core/index.js';
7
+ export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, FilterContext, FilterImpact, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, mountUserDBDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, userDBDebugAPI, validateProcessorConfig } from './core/index.js';
8
8
  import { TaggedPerformance, TagFilter, DataShape, CourseConfig } from '@vue-skuilder/common';
9
9
  import { S as StaticCourseManifest } from './types-CJrLM1Ew.js';
10
10
  export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-CJrLM1Ew.js';
@@ -316,7 +316,7 @@ declare class QuotaRoundRobinMixer implements SourceMixer {
316
316
  */
317
317
  interface ReplanOptions {
318
318
  /** Scoring hints forwarded to the pipeline (boost/exclude/require). */
319
- hints?: Record<string, unknown>;
319
+ hints?: ReplanHints;
320
320
  /**
321
321
  * Maximum number of new cards to return from the pipeline.
322
322
  * Default: 20 (the standard session batch size).
@@ -328,6 +328,13 @@ interface ReplanOptions {
328
328
  * - `'merge'`: insert new cards at the front, keeping existing cards.
329
329
  */
330
330
  mode?: 'replace' | 'merge';
331
+ /**
332
+ * Guarantee that at least this many cards will be served after the
333
+ * replan, even if the session timer has expired. Prevents intro cards
334
+ * from surfacing at the end of a session with zero follow-up exercise.
335
+ * Decremented on each card draw while active.
336
+ */
337
+ minFollowUpCards?: number;
331
338
  /**
332
339
  * Human-readable label for debugging / provenance.
333
340
  * Appears in console logs and in card provenance entries created
@@ -411,10 +418,17 @@ declare class SessionController<TView = unknown> extends Loggable {
411
418
  * (non-auto) replan is requested.
412
419
  */
413
420
  private _depletionReplanAttempted;
421
+ /**
422
+ * When > 0, the session timer cannot end the session. Decremented on
423
+ * each nextCard() draw. Set by replans that include `minFollowUpCards`.
424
+ */
425
+ private _minCardsGuarantee;
414
426
  private startTime;
415
427
  private endTime;
416
428
  private _secondsRemaining;
417
429
  get secondsRemaining(): number;
430
+ /** True when a card guarantee is active, preventing timer-based session end. */
431
+ get hasCardGuarantee(): boolean;
418
432
  get report(): string;
419
433
  get detailedReport(): string;
420
434
  private _intervalHandle;
@@ -462,7 +476,7 @@ declare class SessionController<TView = unknown> extends Loggable {
462
476
  * Typical trigger: application-level code (e.g. after a GPC intro completion)
463
477
  * calls this to ensure newly-unlocked content appears in the session.
464
478
  */
465
- requestReplan(options?: ReplanOptions | Record<string, unknown>): Promise<void>;
479
+ requestReplan(options?: ReplanOptions | ReplanHints): Promise<void>;
466
480
  /**
467
481
  * Normalise the requestReplan argument. Accepts either a ReplanOptions
468
482
  * object (new API) or a plain Record<string, unknown> (legacy callers
@@ -537,6 +551,7 @@ declare class SessionController<TView = unknown> extends Loggable {
537
551
  inProgress: boolean;
538
552
  suppressQualityReplan: boolean;
539
553
  defaultBatchLimit: number;
554
+ minCardsGuarantee: number;
540
555
  };
541
556
  };
542
557
  /**
@@ -634,7 +649,7 @@ declare class TagFilteredContentSource implements StudyContentSource {
634
649
  * @param limit - Maximum number of cards to return
635
650
  * @returns Cards sorted by score descending (all scores = 1.0)
636
651
  */
637
- getWeightedCards(limit: number): Promise<WeightedCard[]>;
652
+ getWeightedCards(limit: number): Promise<GeneratorResult>;
638
653
  /**
639
654
  * Clears the cached resolved card IDs.
640
655
  * Call this if the underlying tag data may have changed during a session.
@@ -1087,4 +1102,4 @@ interface CouchDbUserDoc extends PouchDB.Authentication.User {
1087
1102
  entitlements: UserEntitlements;
1088
1103
  }
1089
1104
 
1090
- export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, type CardPresentation, CardRecord, type CouchDbUserDoc, CourseDBInterface, CourseLookup, CourseRegistrationDoc, type CustomQuestionsData, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, Loggable, type MigrationOptions, type MigrationResult, type MixerCardInfo, type MixerRunReport, NOT_SET, type ProcessedDataShape, type ProcessedQuestionData, type QueueSnapshot, QuotaRoundRobinMixer, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, endSessionTracking, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, mixerDebugAPI, mountMixerDebugger, mountSessionDebugger, processCustomQuestionsData, recordCardPresentation, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, removeCustomQuestionTypes, removeDataShape, removeQuestionType, sessionDebugAPI, snapshotQueues, startSessionTracking, validateMigration, validateStaticCourse };
1105
+ export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, type CardPresentation, CardRecord, type CouchDbUserDoc, CourseDBInterface, CourseLookup, CourseRegistrationDoc, type CustomQuestionsData, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, GeneratorResult, Loggable, type MigrationOptions, type MigrationResult, type MixerCardInfo, type MixerRunReport, NOT_SET, type ProcessedDataShape, type ProcessedQuestionData, type QueueSnapshot, QuotaRoundRobinMixer, ReplanHints, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, endSessionTracking, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, mixerDebugAPI, mountMixerDebugger, mountSessionDebugger, processCustomQuestionsData, recordCardPresentation, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, removeCustomQuestionTypes, removeDataShape, removeQuestionType, sessionDebugAPI, snapshotQueues, startSessionTracking, validateMigration, validateStaticCourse };