@vue-skuilder/db 0.2.13 → 0.2.15
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.
- package/dist/{contentSource-C-0t0y0V.d.ts → contentSource-B1p-vdz7.d.ts} +7 -0
- package/dist/{contentSource-jSkcOt2s.d.cts → contentSource-Brz42x7n.d.cts} +7 -0
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +6 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +6 -3
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-BB0oi9T0.d.ts → dataLayerProvider-BWayUIoK.d.ts} +1 -1
- package/dist/{dataLayerProvider-BDClIrFC.d.cts → dataLayerProvider-CpwpT1rM.d.cts} +1 -1
- package/dist/impl/couch/index.d.cts +2 -2
- package/dist/impl/couch/index.d.ts +2 -2
- package/dist/impl/couch/index.js +6 -3
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +6 -3
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +2 -2
- package/dist/impl/static/index.d.ts +2 -2
- package/dist/impl/static/index.js +6 -3
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +6 -3
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.d.cts +47 -5
- package/dist/index.d.ts +47 -5
- package/dist/index.js +50 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/core/interfaces/userDB.ts +8 -0
- package/src/impl/common/BaseUserDB.ts +2 -2
- package/src/impl/common/userDBHelpers.ts +14 -1
- package/src/index.ts +6 -0
- package/src/study/SessionOverlay.ts +16 -3
- package/src/study/index.ts +4 -0
- package/src/study/services/EloService.ts +20 -8
- package/src/study/services/ResponseProcessor.ts +62 -50
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-
|
|
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-
|
|
3
|
-
import { D as DataLayerProvider } from './dataLayerProvider-
|
|
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-Brz42x7n.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-Brz42x7n.cjs';
|
|
3
|
+
import { D as DataLayerProvider } from './dataLayerProvider-CpwpT1rM.cjs';
|
|
4
4
|
import { C as CardHistory, c as CardRecord, d as QuestionRecord } from './types-legacy-4tlwHnXo.cjs';
|
|
5
5
|
export { e as CardData, f as CourseListData, h as DataShapeData, g as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, i as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-4tlwHnXo.cjs';
|
|
6
6
|
import { SrsBacklogDebug, Loggable } from './core/index.cjs';
|
|
@@ -10,7 +10,7 @@ import { S as StaticCourseManifest } from './types-BFUa1pa3.cjs';
|
|
|
10
10
|
export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-BFUa1pa3.cjs';
|
|
11
11
|
import { F as FileSystemAdapter } from './index-k9NFHpS1.cjs';
|
|
12
12
|
export { C as CouchDBToStaticPacker, a as FileStats, b as FileSystemError } from './index-k9NFHpS1.cjs';
|
|
13
|
-
import 'moment';
|
|
13
|
+
import moment from 'moment';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Service responsible for ELO rating calculations and updates.
|
|
@@ -70,6 +70,12 @@ declare class ResponseProcessor {
|
|
|
70
70
|
private srsService;
|
|
71
71
|
private eloService;
|
|
72
72
|
constructor(srsService: SrsService, eloService: EloService);
|
|
73
|
+
/**
|
|
74
|
+
* ELO updates are fired without awaiting so response handling isn't blocked
|
|
75
|
+
* on DB writes — but an unhandled rejection silently drops the update.
|
|
76
|
+
* This produces a catch handler that surfaces the failure in logs.
|
|
77
|
+
*/
|
|
78
|
+
private logEloFailure;
|
|
73
79
|
/**
|
|
74
80
|
* Parses performance data into global score and optional per-tag scores.
|
|
75
81
|
*
|
|
@@ -362,6 +368,30 @@ interface SessionDebugSnapshot {
|
|
|
362
368
|
/** Every card the learner has interacted with this session, draw order. */
|
|
363
369
|
drawnCards: SessionDrawnCardDebug[];
|
|
364
370
|
}
|
|
371
|
+
/** The narrow surface the overlay needs from a SessionController. */
|
|
372
|
+
interface SessionDebugTarget {
|
|
373
|
+
getDebugSnapshot(): SessionDebugSnapshot;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* The live-session surface available to out-of-tree callers through the
|
|
377
|
+
* active-controller registry: the debug snapshot, plus the small set of
|
|
378
|
+
* user-facing session controls a view may need without holding a ref into
|
|
379
|
+
* the `<StudySession>` component's internals (e.g. wiring a timer's
|
|
380
|
+
* add-time button from a composable). Keep this narrow — it is not a
|
|
381
|
+
* general escape hatch to `SessionController`.
|
|
382
|
+
*/
|
|
383
|
+
interface ActiveSessionHandle extends SessionDebugTarget {
|
|
384
|
+
/** Extend the session clock by `seconds`. */
|
|
385
|
+
addTime(seconds: number): void;
|
|
386
|
+
}
|
|
387
|
+
/** Called by SessionController's constructor. Pass `null` to deregister. */
|
|
388
|
+
declare function registerActiveController(controller: ActiveSessionHandle | null): void;
|
|
389
|
+
declare function getActiveController(): ActiveSessionHandle | null;
|
|
390
|
+
/**
|
|
391
|
+
* Toggle the pinned overlay on/off. No-ops (with a console hint) when there is
|
|
392
|
+
* no DOM, so it is safe to call from any host environment.
|
|
393
|
+
*/
|
|
394
|
+
declare function toggleSessionOverlay(): void;
|
|
365
395
|
|
|
366
396
|
/**
|
|
367
397
|
* Options for requesting a mid-session replan.
|
|
@@ -1460,6 +1490,18 @@ declare function getDataLayer(): DataLayerProvider;
|
|
|
1460
1490
|
*/
|
|
1461
1491
|
declare function _resetDataLayer(): Promise<void>;
|
|
1462
1492
|
|
|
1493
|
+
declare const REVIEW_TIME_FORMAT: string;
|
|
1494
|
+
/**
|
|
1495
|
+
* Build a ScheduledCard `_id` for the given review time.
|
|
1496
|
+
*
|
|
1497
|
+
* The id suffix is not a mere uniquifier: `getReviewstoDate` PARSES the id
|
|
1498
|
+
* (with {@link REVIEW_TIME_FORMAT}) to decide due-ness, so the id is the
|
|
1499
|
+
* datum. Anything that writes or rewrites scheduled-card docs (scheduling,
|
|
1500
|
+
* user-state snapshot rebasing) must construct ids through this helper —
|
|
1501
|
+
* a hand-rolled formatter will get moment's `kk` token (01-24 hours) wrong.
|
|
1502
|
+
*/
|
|
1503
|
+
declare function makeScheduledCardId(reviewTime: string | Date | moment.Moment): string;
|
|
1504
|
+
|
|
1463
1505
|
type UserAccountStatus = 'pending_verification' | 'verified' | 'suspended';
|
|
1464
1506
|
interface Entitlement {
|
|
1465
1507
|
status: 'trial' | 'paid';
|
|
@@ -1479,4 +1521,4 @@ interface CouchDbUserDoc extends PouchDB.Authentication.User {
|
|
|
1479
1521
|
entitlements: UserEntitlements;
|
|
1480
1522
|
}
|
|
1481
1523
|
|
|
1482
|
-
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 OutcomeObserver, type ProcessedDataShape, type ProcessedQuestionData, QuestionRecord, type QueueSnapshot, QuotaRoundRobinMixer, ReplanHints, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionControls, type SessionOutcome, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, SrsBacklogDebug, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, clearStaleSessionDebugState, 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 };
|
|
1524
|
+
export { type ActiveSessionHandle, 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 OutcomeObserver, type ProcessedDataShape, type ProcessedQuestionData, QuestionRecord, type QueueSnapshot, QuotaRoundRobinMixer, REVIEW_TIME_FORMAT, ReplanHints, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionControls, type SessionDebugSnapshot, type SessionDebugTarget, type SessionDrawnCardDebug, type SessionOutcome, type SessionQueueDebug, type SessionQueueItemDebug, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, SrsBacklogDebug, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, clearStaleSessionDebugState, endSessionTracking, ensureAppDataDirectory, getActiveController, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, makeScheduledCardId, mixerDebugAPI, mountMixerDebugger, mountSessionDebugger, processCustomQuestionsData, recordCardPresentation, registerActiveController, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, removeCustomQuestionTypes, removeDataShape, removeQuestionType, sessionDebugAPI, snapshotQueues, startSessionTracking, toggleSessionOverlay, validateMigration, validateStaticCourse };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-
|
|
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-
|
|
3
|
-
import { D as DataLayerProvider } from './dataLayerProvider-
|
|
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-B1p-vdz7.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-B1p-vdz7.js';
|
|
3
|
+
import { D as DataLayerProvider } from './dataLayerProvider-BWayUIoK.js';
|
|
4
4
|
import { C as CardHistory, c as CardRecord, d as QuestionRecord } from './types-legacy-4tlwHnXo.js';
|
|
5
5
|
export { e as CardData, f as CourseListData, h as DataShapeData, g as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, i as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-4tlwHnXo.js';
|
|
6
6
|
import { SrsBacklogDebug, Loggable } from './core/index.js';
|
|
@@ -10,7 +10,7 @@ import { S as StaticCourseManifest } from './types-CHgpWQAY.js';
|
|
|
10
10
|
export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-CHgpWQAY.js';
|
|
11
11
|
import { F as FileSystemAdapter } from './index-BLLT5BYE.js';
|
|
12
12
|
export { C as CouchDBToStaticPacker, a as FileStats, b as FileSystemError } from './index-BLLT5BYE.js';
|
|
13
|
-
import 'moment';
|
|
13
|
+
import moment from 'moment';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Service responsible for ELO rating calculations and updates.
|
|
@@ -70,6 +70,12 @@ declare class ResponseProcessor {
|
|
|
70
70
|
private srsService;
|
|
71
71
|
private eloService;
|
|
72
72
|
constructor(srsService: SrsService, eloService: EloService);
|
|
73
|
+
/**
|
|
74
|
+
* ELO updates are fired without awaiting so response handling isn't blocked
|
|
75
|
+
* on DB writes — but an unhandled rejection silently drops the update.
|
|
76
|
+
* This produces a catch handler that surfaces the failure in logs.
|
|
77
|
+
*/
|
|
78
|
+
private logEloFailure;
|
|
73
79
|
/**
|
|
74
80
|
* Parses performance data into global score and optional per-tag scores.
|
|
75
81
|
*
|
|
@@ -362,6 +368,30 @@ interface SessionDebugSnapshot {
|
|
|
362
368
|
/** Every card the learner has interacted with this session, draw order. */
|
|
363
369
|
drawnCards: SessionDrawnCardDebug[];
|
|
364
370
|
}
|
|
371
|
+
/** The narrow surface the overlay needs from a SessionController. */
|
|
372
|
+
interface SessionDebugTarget {
|
|
373
|
+
getDebugSnapshot(): SessionDebugSnapshot;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* The live-session surface available to out-of-tree callers through the
|
|
377
|
+
* active-controller registry: the debug snapshot, plus the small set of
|
|
378
|
+
* user-facing session controls a view may need without holding a ref into
|
|
379
|
+
* the `<StudySession>` component's internals (e.g. wiring a timer's
|
|
380
|
+
* add-time button from a composable). Keep this narrow — it is not a
|
|
381
|
+
* general escape hatch to `SessionController`.
|
|
382
|
+
*/
|
|
383
|
+
interface ActiveSessionHandle extends SessionDebugTarget {
|
|
384
|
+
/** Extend the session clock by `seconds`. */
|
|
385
|
+
addTime(seconds: number): void;
|
|
386
|
+
}
|
|
387
|
+
/** Called by SessionController's constructor. Pass `null` to deregister. */
|
|
388
|
+
declare function registerActiveController(controller: ActiveSessionHandle | null): void;
|
|
389
|
+
declare function getActiveController(): ActiveSessionHandle | null;
|
|
390
|
+
/**
|
|
391
|
+
* Toggle the pinned overlay on/off. No-ops (with a console hint) when there is
|
|
392
|
+
* no DOM, so it is safe to call from any host environment.
|
|
393
|
+
*/
|
|
394
|
+
declare function toggleSessionOverlay(): void;
|
|
365
395
|
|
|
366
396
|
/**
|
|
367
397
|
* Options for requesting a mid-session replan.
|
|
@@ -1460,6 +1490,18 @@ declare function getDataLayer(): DataLayerProvider;
|
|
|
1460
1490
|
*/
|
|
1461
1491
|
declare function _resetDataLayer(): Promise<void>;
|
|
1462
1492
|
|
|
1493
|
+
declare const REVIEW_TIME_FORMAT: string;
|
|
1494
|
+
/**
|
|
1495
|
+
* Build a ScheduledCard `_id` for the given review time.
|
|
1496
|
+
*
|
|
1497
|
+
* The id suffix is not a mere uniquifier: `getReviewstoDate` PARSES the id
|
|
1498
|
+
* (with {@link REVIEW_TIME_FORMAT}) to decide due-ness, so the id is the
|
|
1499
|
+
* datum. Anything that writes or rewrites scheduled-card docs (scheduling,
|
|
1500
|
+
* user-state snapshot rebasing) must construct ids through this helper —
|
|
1501
|
+
* a hand-rolled formatter will get moment's `kk` token (01-24 hours) wrong.
|
|
1502
|
+
*/
|
|
1503
|
+
declare function makeScheduledCardId(reviewTime: string | Date | moment.Moment): string;
|
|
1504
|
+
|
|
1463
1505
|
type UserAccountStatus = 'pending_verification' | 'verified' | 'suspended';
|
|
1464
1506
|
interface Entitlement {
|
|
1465
1507
|
status: 'trial' | 'paid';
|
|
@@ -1479,4 +1521,4 @@ interface CouchDbUserDoc extends PouchDB.Authentication.User {
|
|
|
1479
1521
|
entitlements: UserEntitlements;
|
|
1480
1522
|
}
|
|
1481
1523
|
|
|
1482
|
-
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 OutcomeObserver, type ProcessedDataShape, type ProcessedQuestionData, QuestionRecord, type QueueSnapshot, QuotaRoundRobinMixer, ReplanHints, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionControls, type SessionOutcome, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, SrsBacklogDebug, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, clearStaleSessionDebugState, 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 };
|
|
1524
|
+
export { type ActiveSessionHandle, 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 OutcomeObserver, type ProcessedDataShape, type ProcessedQuestionData, QuestionRecord, type QueueSnapshot, QuotaRoundRobinMixer, REVIEW_TIME_FORMAT, ReplanHints, type ReplanOptions, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SessionControls, type SessionDebugSnapshot, type SessionDebugTarget, type SessionDrawnCardDebug, type SessionOutcome, type SessionQueueDebug, type SessionQueueItemDebug, type SessionRunReport, type SourceBatch, type SourceMixer, type SourceSelectionBreakdown, type SourceSummary, SrsBacklogDebug, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, captureMixerRun, clearStaleSessionDebugState, endSessionTracking, ensureAppDataDirectory, getActiveController, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, makeScheduledCardId, mixerDebugAPI, mountMixerDebugger, mountSessionDebugger, processCustomQuestionsData, recordCardPresentation, registerActiveController, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, removeCustomQuestionTypes, removeDataShape, removeQuestionType, sessionDebugAPI, snapshotQueues, startSessionTracking, toggleSessionOverlay, validateMigration, validateStaticCourse };
|
package/dist/index.js
CHANGED
|
@@ -243,6 +243,9 @@ var init_dataDirectory = __esm({
|
|
|
243
243
|
});
|
|
244
244
|
|
|
245
245
|
// src/impl/common/userDBHelpers.ts
|
|
246
|
+
function makeScheduledCardId(reviewTime) {
|
|
247
|
+
return DocTypePrefixes["SCHEDULED_CARD" /* SCHEDULED_CARD */] + import_moment.default.utc(reviewTime).format(REVIEW_TIME_FORMAT);
|
|
248
|
+
}
|
|
246
249
|
function hexEncode(str) {
|
|
247
250
|
let hex;
|
|
248
251
|
let returnStr = "";
|
|
@@ -298,7 +301,7 @@ function scheduleCardReviewLocal(userDB, review) {
|
|
|
298
301
|
const now = import_moment.default.utc();
|
|
299
302
|
logger.info(`Scheduling for review in: ${review.time.diff(now, "h") / 24} days`);
|
|
300
303
|
void userDB.put({
|
|
301
|
-
_id:
|
|
304
|
+
_id: makeScheduledCardId(review.time),
|
|
302
305
|
cardId: review.card_id,
|
|
303
306
|
reviewTime: review.time.toISOString(),
|
|
304
307
|
courseId: review.course_id,
|
|
@@ -8008,9 +8011,9 @@ Currently logged-in as ${this._username}.`
|
|
|
8008
8011
|
}
|
|
8009
8012
|
}).map((r) => r.doc);
|
|
8010
8013
|
}
|
|
8011
|
-
async getReviewsForcast(daysCount) {
|
|
8014
|
+
async getReviewsForcast(daysCount, course_id) {
|
|
8012
8015
|
const time = import_moment6.default.utc().add(daysCount, "days");
|
|
8013
|
-
return this.getReviewstoDate(time);
|
|
8016
|
+
return this.getReviewstoDate(time, course_id);
|
|
8014
8017
|
}
|
|
8015
8018
|
async getPendingReviews(course_id) {
|
|
8016
8019
|
const now = import_moment6.default.utc();
|
|
@@ -10577,6 +10580,7 @@ __export(index_exports, {
|
|
|
10577
10580
|
NavigatorRoles: () => NavigatorRoles,
|
|
10578
10581
|
Navigators: () => Navigators,
|
|
10579
10582
|
QuotaRoundRobinMixer: () => QuotaRoundRobinMixer,
|
|
10583
|
+
REVIEW_TIME_FORMAT: () => REVIEW_TIME_FORMAT,
|
|
10580
10584
|
SessionController: () => SessionController,
|
|
10581
10585
|
StaticToCouchDBMigrator: () => StaticToCouchDBMigrator,
|
|
10582
10586
|
TagFilteredContentSource: () => TagFilteredContentSource,
|
|
@@ -10597,6 +10601,7 @@ __export(index_exports, {
|
|
|
10597
10601
|
docIsDeleted: () => docIsDeleted,
|
|
10598
10602
|
endSessionTracking: () => endSessionTracking,
|
|
10599
10603
|
ensureAppDataDirectory: () => ensureAppDataDirectory,
|
|
10604
|
+
getActiveController: () => getActiveController,
|
|
10600
10605
|
getActivePipeline: () => getActivePipeline,
|
|
10601
10606
|
getAppDataDirectory: () => getAppDataDirectory,
|
|
10602
10607
|
getCardHistoryID: () => getCardHistoryID,
|
|
@@ -10622,6 +10627,7 @@ __export(index_exports, {
|
|
|
10622
10627
|
isQuestionTypeRegistered: () => isQuestionTypeRegistered,
|
|
10623
10628
|
isReview: () => isReview,
|
|
10624
10629
|
log: () => log,
|
|
10630
|
+
makeScheduledCardId: () => makeScheduledCardId,
|
|
10625
10631
|
mixerDebugAPI: () => mixerDebugAPI,
|
|
10626
10632
|
mountMixerDebugger: () => mountMixerDebugger,
|
|
10627
10633
|
mountPipelineDebugger: () => mountPipelineDebugger,
|
|
@@ -10633,6 +10639,7 @@ __export(index_exports, {
|
|
|
10633
10639
|
processCustomQuestionsData: () => processCustomQuestionsData,
|
|
10634
10640
|
recordCardPresentation: () => recordCardPresentation,
|
|
10635
10641
|
recordUserOutcome: () => recordUserOutcome,
|
|
10642
|
+
registerActiveController: () => registerActiveController,
|
|
10636
10643
|
registerBlanksCard: () => registerBlanksCard,
|
|
10637
10644
|
registerCustomQuestionTypes: () => registerCustomQuestionTypes,
|
|
10638
10645
|
registerDataShape: () => registerDataShape,
|
|
@@ -10647,6 +10654,7 @@ __export(index_exports, {
|
|
|
10647
10654
|
sessionDebugAPI: () => sessionDebugAPI,
|
|
10648
10655
|
snapshotQueues: () => snapshotQueues,
|
|
10649
10656
|
startSessionTracking: () => startSessionTracking,
|
|
10657
|
+
toggleSessionOverlay: () => toggleSessionOverlay,
|
|
10650
10658
|
updateLearningState: () => updateLearningState,
|
|
10651
10659
|
updateStrategyWeight: () => updateStrategyWeight,
|
|
10652
10660
|
userDBDebugAPI: () => userDBDebugAPI,
|
|
@@ -11109,13 +11117,18 @@ var EloService = class {
|
|
|
11109
11117
|
logger.warn(`k value interpretation not currently implemented`);
|
|
11110
11118
|
}
|
|
11111
11119
|
const courseDB = this.dataLayer.getCourseDB(currentCard.card.course_id);
|
|
11112
|
-
const
|
|
11113
|
-
|
|
11114
|
-
|
|
11120
|
+
const courseReg = userCourseRegDoc.courses.find((c) => c.courseID === course_id);
|
|
11121
|
+
if (!courseReg) {
|
|
11122
|
+
logger.error(
|
|
11123
|
+
`[EloService] No registration for course ${course_id} on user's registration doc \u2014 skipping ELO update for card ${card_id}. (Is the user registered for this course?)`
|
|
11124
|
+
);
|
|
11125
|
+
return;
|
|
11126
|
+
}
|
|
11127
|
+
const userElo = (0, import_common23.toCourseElo)(courseReg.elo);
|
|
11115
11128
|
const cardElo = (await courseDB.getCardEloData([currentCard.card.card_id]))[0];
|
|
11116
11129
|
if (cardElo && userElo) {
|
|
11117
11130
|
const eloUpdate = (0, import_common23.adjustCourseScores)(userElo, cardElo, userScore);
|
|
11118
|
-
|
|
11131
|
+
courseReg.elo = eloUpdate.userElo;
|
|
11119
11132
|
const results = await Promise.allSettled([
|
|
11120
11133
|
this.user.updateUserElo(course_id, eloUpdate.userElo),
|
|
11121
11134
|
courseDB.updateCardElo(card_id, eloUpdate.cardElo)
|
|
@@ -11160,9 +11173,14 @@ var EloService = class {
|
|
|
11160
11173
|
*/
|
|
11161
11174
|
async updateUserAndCardEloPerTag(taggedPerformance, course_id, card_id, userCourseRegDoc, currentCard) {
|
|
11162
11175
|
const courseDB = this.dataLayer.getCourseDB(currentCard.card.course_id);
|
|
11163
|
-
const
|
|
11164
|
-
|
|
11165
|
-
|
|
11176
|
+
const courseReg = userCourseRegDoc.courses.find((c) => c.courseID === course_id);
|
|
11177
|
+
if (!courseReg) {
|
|
11178
|
+
logger.error(
|
|
11179
|
+
`[EloService] No registration for course ${course_id} on user's registration doc \u2014 skipping per-tag ELO update for card ${card_id}. (Is the user registered for this course?)`
|
|
11180
|
+
);
|
|
11181
|
+
return;
|
|
11182
|
+
}
|
|
11183
|
+
const userElo = (0, import_common23.toCourseElo)(courseReg.elo);
|
|
11166
11184
|
const [cardEloResults, cardTagsMap] = await Promise.all([
|
|
11167
11185
|
courseDB.getCardEloData([currentCard.card.card_id]),
|
|
11168
11186
|
courseDB.getAppliedTagsBatch([card_id])
|
|
@@ -11178,7 +11196,7 @@ var EloService = class {
|
|
|
11178
11196
|
}
|
|
11179
11197
|
if (cardElo && userElo) {
|
|
11180
11198
|
const eloUpdate = (0, import_common23.adjustCourseScoresPerTag)(userElo, cardElo, enriched);
|
|
11181
|
-
|
|
11199
|
+
courseReg.elo = eloUpdate.userElo;
|
|
11182
11200
|
const results = await Promise.allSettled([
|
|
11183
11201
|
this.user.updateUserElo(course_id, eloUpdate.userElo),
|
|
11184
11202
|
courseDB.updateCardElo(card_id, eloUpdate.cardElo)
|
|
@@ -11225,6 +11243,14 @@ var ResponseProcessor = class {
|
|
|
11225
11243
|
this.srsService = srsService;
|
|
11226
11244
|
this.eloService = eloService;
|
|
11227
11245
|
}
|
|
11246
|
+
/**
|
|
11247
|
+
* ELO updates are fired without awaiting so response handling isn't blocked
|
|
11248
|
+
* on DB writes — but an unhandled rejection silently drops the update.
|
|
11249
|
+
* This produces a catch handler that surfaces the failure in logs.
|
|
11250
|
+
*/
|
|
11251
|
+
logEloFailure(context, cardId) {
|
|
11252
|
+
return (e) => logger.error(`[ResponseProcessor] ELO update failed (${context}) for ${cardId}:`, e);
|
|
11253
|
+
}
|
|
11228
11254
|
/**
|
|
11229
11255
|
* Parses performance data into global score and optional per-tag scores.
|
|
11230
11256
|
*
|
|
@@ -11342,17 +11368,11 @@ var ResponseProcessor = class {
|
|
|
11342
11368
|
cardId,
|
|
11343
11369
|
courseRegistrationDoc,
|
|
11344
11370
|
currentCard
|
|
11345
|
-
);
|
|
11371
|
+
).catch(this.logEloFailure("correct per-tag", cardId));
|
|
11346
11372
|
} else {
|
|
11347
11373
|
const userScore = 0.5 + globalScore / 2;
|
|
11348
11374
|
if (history.records.length === 1) {
|
|
11349
|
-
void this.eloService.updateUserAndCardElo(
|
|
11350
|
-
userScore,
|
|
11351
|
-
courseId,
|
|
11352
|
-
cardId,
|
|
11353
|
-
courseRegistrationDoc,
|
|
11354
|
-
currentCard
|
|
11355
|
-
);
|
|
11375
|
+
void this.eloService.updateUserAndCardElo(userScore, courseId, cardId, courseRegistrationDoc, currentCard).catch(this.logEloFailure("correct", cardId));
|
|
11356
11376
|
} else {
|
|
11357
11377
|
const k = Math.ceil(32 / history.records.length);
|
|
11358
11378
|
void this.eloService.updateUserAndCardElo(
|
|
@@ -11362,7 +11382,7 @@ var ResponseProcessor = class {
|
|
|
11362
11382
|
courseRegistrationDoc,
|
|
11363
11383
|
currentCard,
|
|
11364
11384
|
k
|
|
11365
|
-
);
|
|
11385
|
+
).catch(this.logEloFailure("correct repeat-view", cardId));
|
|
11366
11386
|
}
|
|
11367
11387
|
logger.info(
|
|
11368
11388
|
`[FirstContactElo] correct first-attempt ELO update (score=${userScore.toFixed(3)}) for ${cardId} (historyLen=${history.records.length}, priorAttemps=${cardRecord.priorAttemps})`
|
|
@@ -11403,7 +11423,7 @@ var ResponseProcessor = class {
|
|
|
11403
11423
|
cardId,
|
|
11404
11424
|
courseRegistrationDoc,
|
|
11405
11425
|
currentCard
|
|
11406
|
-
);
|
|
11426
|
+
).catch(this.logEloFailure("incorrect per-tag", cardId));
|
|
11407
11427
|
logger.info(
|
|
11408
11428
|
`[FirstContactElo] incorrect first-attempt per-tag ELO update for ${cardId} (historyLen=${history.records.length}, priorAttemps=${cardRecord.priorAttemps}, tags=${Object.keys(taggedPerformance).length - 1})`
|
|
11409
11429
|
);
|
|
@@ -11415,7 +11435,7 @@ var ResponseProcessor = class {
|
|
|
11415
11435
|
cardId,
|
|
11416
11436
|
courseRegistrationDoc,
|
|
11417
11437
|
currentCard
|
|
11418
|
-
);
|
|
11438
|
+
).catch(this.logEloFailure("incorrect", cardId));
|
|
11419
11439
|
logger.info(
|
|
11420
11440
|
`[FirstContactElo] incorrect first-attempt ELO update (score=0) for ${cardId} (historyLen=${history.records.length}, priorAttemps=${cardRecord.priorAttemps})`
|
|
11421
11441
|
);
|
|
@@ -11436,15 +11456,9 @@ var ResponseProcessor = class {
|
|
|
11436
11456
|
cardId,
|
|
11437
11457
|
courseRegistrationDoc,
|
|
11438
11458
|
currentCard
|
|
11439
|
-
);
|
|
11459
|
+
).catch(this.logEloFailure("dismiss-failed per-tag", cardId));
|
|
11440
11460
|
} else {
|
|
11441
|
-
void this.eloService.updateUserAndCardElo(
|
|
11442
|
-
0,
|
|
11443
|
-
courseId,
|
|
11444
|
-
cardId,
|
|
11445
|
-
courseRegistrationDoc,
|
|
11446
|
-
currentCard
|
|
11447
|
-
);
|
|
11461
|
+
void this.eloService.updateUserAndCardElo(0, courseId, cardId, courseRegistrationDoc, currentCard).catch(this.logEloFailure("dismiss-failed", cardId));
|
|
11448
11462
|
}
|
|
11449
11463
|
logger.info(
|
|
11450
11464
|
`[FirstContactElo] dismiss-failed final ELO penalty for ${cardId} (historyLen=${history.records.length}, sessionViews=${sessionViews})`
|
|
@@ -15263,6 +15277,7 @@ init_TagFilteredContentSource();
|
|
|
15263
15277
|
|
|
15264
15278
|
// src/index.ts
|
|
15265
15279
|
init_factory();
|
|
15280
|
+
init_userDBHelpers();
|
|
15266
15281
|
// Annotate the CommonJS export names for ESM import in node:
|
|
15267
15282
|
0 && (module.exports = {
|
|
15268
15283
|
ContentNavigator,
|
|
@@ -15281,6 +15296,7 @@ init_factory();
|
|
|
15281
15296
|
NavigatorRoles,
|
|
15282
15297
|
Navigators,
|
|
15283
15298
|
QuotaRoundRobinMixer,
|
|
15299
|
+
REVIEW_TIME_FORMAT,
|
|
15284
15300
|
SessionController,
|
|
15285
15301
|
StaticToCouchDBMigrator,
|
|
15286
15302
|
TagFilteredContentSource,
|
|
@@ -15301,6 +15317,7 @@ init_factory();
|
|
|
15301
15317
|
docIsDeleted,
|
|
15302
15318
|
endSessionTracking,
|
|
15303
15319
|
ensureAppDataDirectory,
|
|
15320
|
+
getActiveController,
|
|
15304
15321
|
getActivePipeline,
|
|
15305
15322
|
getAppDataDirectory,
|
|
15306
15323
|
getCardHistoryID,
|
|
@@ -15326,6 +15343,7 @@ init_factory();
|
|
|
15326
15343
|
isQuestionTypeRegistered,
|
|
15327
15344
|
isReview,
|
|
15328
15345
|
log,
|
|
15346
|
+
makeScheduledCardId,
|
|
15329
15347
|
mixerDebugAPI,
|
|
15330
15348
|
mountMixerDebugger,
|
|
15331
15349
|
mountPipelineDebugger,
|
|
@@ -15337,6 +15355,7 @@ init_factory();
|
|
|
15337
15355
|
processCustomQuestionsData,
|
|
15338
15356
|
recordCardPresentation,
|
|
15339
15357
|
recordUserOutcome,
|
|
15358
|
+
registerActiveController,
|
|
15340
15359
|
registerBlanksCard,
|
|
15341
15360
|
registerCustomQuestionTypes,
|
|
15342
15361
|
registerDataShape,
|
|
@@ -15351,6 +15370,7 @@ init_factory();
|
|
|
15351
15370
|
sessionDebugAPI,
|
|
15352
15371
|
snapshotQueues,
|
|
15353
15372
|
startSessionTracking,
|
|
15373
|
+
toggleSessionOverlay,
|
|
15354
15374
|
updateLearningState,
|
|
15355
15375
|
updateStrategyWeight,
|
|
15356
15376
|
userDBDebugAPI,
|