@vue-skuilder/db 0.1.18 → 0.1.20
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/{classroomDB-BgfrVb8d.d.ts → classroomDB-CZdMBiTU.d.ts} +71 -2
- package/dist/{classroomDB-CTOenngH.d.cts → classroomDB-PxDZTky3.d.cts} +71 -2
- package/dist/core/index.d.cts +80 -6
- package/dist/core/index.d.ts +80 -6
- package/dist/core/index.js +370 -52
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +369 -52
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-D6PoCwS6.d.cts → dataLayerProvider-D0MoZMjH.d.cts} +1 -1
- package/dist/{dataLayerProvider-CZxC9GtB.d.ts → dataLayerProvider-D8o6ZnKW.d.ts} +1 -1
- package/dist/impl/couch/index.d.cts +4 -3
- package/dist/impl/couch/index.d.ts +4 -3
- package/dist/impl/couch/index.js +371 -55
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +371 -55
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +5 -4
- package/dist/impl/static/index.d.ts +5 -4
- package/dist/impl/static/index.js +356 -44
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +356 -44
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/{index-D-Fa4Smt.d.cts → index-B_j6u5E4.d.cts} +1 -1
- package/dist/{index-CD8BZz2k.d.ts → index-Dj0SEgk3.d.ts} +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +382 -55
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +381 -55
- package/dist/index.mjs.map +1 -1
- package/dist/{types-CzPDLAK6.d.cts → types-Bn0itutr.d.cts} +1 -1
- package/dist/{types-CewsN87z.d.ts → types-DQaXnuoc.d.ts} +1 -1
- package/dist/{types-legacy-6ettoclI.d.cts → types-legacy-DDY4N-Uq.d.cts} +3 -1
- package/dist/{types-legacy-6ettoclI.d.ts → types-legacy-DDY4N-Uq.d.ts} +3 -1
- package/dist/util/packer/index.d.cts +3 -3
- package/dist/util/packer/index.d.ts +3 -3
- package/docs/navigators-architecture.md +115 -10
- package/package.json +4 -4
- package/src/core/index.ts +1 -0
- package/src/core/interfaces/courseDB.ts +13 -0
- package/src/core/interfaces/userDB.ts +32 -0
- package/src/core/navigators/Pipeline.ts +127 -14
- package/src/core/navigators/filters/index.ts +3 -0
- package/src/core/navigators/filters/userTagPreference.ts +232 -0
- package/src/core/navigators/hierarchyDefinition.ts +4 -4
- package/src/core/navigators/index.ts +59 -0
- package/src/core/navigators/inferredPreference.ts +107 -0
- package/src/core/navigators/interferenceMitigator.ts +1 -13
- package/src/core/navigators/relativePriority.ts +2 -14
- package/src/core/navigators/userGoal.ts +136 -0
- package/src/core/types/strategyState.ts +84 -0
- package/src/core/types/types-legacy.ts +2 -0
- package/src/impl/common/BaseUserDB.ts +74 -7
- package/src/impl/couch/adminDB.ts +1 -2
- package/src/impl/couch/courseDB.ts +30 -10
- package/src/impl/static/courseDB.ts +11 -0
- package/tests/core/navigators/Pipeline.test.ts +1 -0
- package/docs/todo-pipeline-optimization.md +0 -117
- package/docs/todo-strategy-state-storage.md +0 -278
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CourseConfig, ClassroomConfig, CourseElo, Status, SkuilderCourseData as SkuilderCourseData$1, DataShape, TagFilter } from '@vue-skuilder/common';
|
|
2
2
|
import { Moment } from 'moment';
|
|
3
|
-
import { S as SkuilderCourseData, b as DocTypePrefixes, D as DocType, Q as QualifiedCardID, T as TagStub, a as Tag, C as CardHistory, c as CardRecord } from './types-legacy-
|
|
3
|
+
import { S as SkuilderCourseData, b as DocTypePrefixes, D as DocType, Q as QualifiedCardID, T as TagStub, a as Tag, C as CardHistory, c as CardRecord } from './types-legacy-DDY4N-Uq.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Admin functionality
|
|
@@ -222,6 +222,18 @@ interface CourseDBInterface extends NavigationStrategyManager {
|
|
|
222
222
|
* Get tags for a card
|
|
223
223
|
*/
|
|
224
224
|
getAppliedTags(cardId: string): Promise<PouchDB.Query.Response<TagStub>>;
|
|
225
|
+
/**
|
|
226
|
+
* Get tags for multiple cards in a single batch query.
|
|
227
|
+
* More efficient than calling getAppliedTags() for each card.
|
|
228
|
+
*
|
|
229
|
+
* This method reduces redundant database operations when multiple filters
|
|
230
|
+
* need tag data for the same cards. The Pipeline uses this to pre-hydrate
|
|
231
|
+
* tags on WeightedCard objects before filters run.
|
|
232
|
+
*
|
|
233
|
+
* @param cardIds - Array of card IDs to fetch tags for
|
|
234
|
+
* @returns Map from cardId to array of tag names
|
|
235
|
+
*/
|
|
236
|
+
getAppliedTagsBatch(cardIds: string[]): Promise<Map<string, string[]>>;
|
|
225
237
|
/**
|
|
226
238
|
* Add a tag to a card
|
|
227
239
|
*/
|
|
@@ -323,6 +335,17 @@ interface UserDBReader {
|
|
|
323
335
|
*/
|
|
324
336
|
getPendingReviews(courseId?: string): Promise<ScheduledCard[]>;
|
|
325
337
|
getActivityRecords(): Promise<ActivityRecord[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Get strategy-specific state for a course.
|
|
340
|
+
*
|
|
341
|
+
* Strategies use this to persist preferences, learned patterns, or temporal
|
|
342
|
+
* tracking data across sessions. Each strategy owns its own namespace.
|
|
343
|
+
*
|
|
344
|
+
* @param courseId - The course this state applies to
|
|
345
|
+
* @param strategyKey - Unique key identifying the strategy (typically class name)
|
|
346
|
+
* @returns The strategy's data payload, or null if no state exists
|
|
347
|
+
*/
|
|
348
|
+
getStrategyState<T>(courseId: string, strategyKey: string): Promise<T | null>;
|
|
326
349
|
/**
|
|
327
350
|
* Get user's classroom registrations
|
|
328
351
|
*/
|
|
@@ -387,6 +410,24 @@ interface UserDBWriter extends DocumentUpdater {
|
|
|
387
410
|
status: Status;
|
|
388
411
|
error?: string;
|
|
389
412
|
}>;
|
|
413
|
+
/**
|
|
414
|
+
* Store strategy-specific state for a course.
|
|
415
|
+
*
|
|
416
|
+
* Strategies use this to persist preferences, learned patterns, or temporal
|
|
417
|
+
* tracking data across sessions. Each strategy owns its own namespace.
|
|
418
|
+
*
|
|
419
|
+
* @param courseId - The course this state applies to
|
|
420
|
+
* @param strategyKey - Unique key identifying the strategy (typically class name)
|
|
421
|
+
* @param data - The strategy's data payload to store
|
|
422
|
+
*/
|
|
423
|
+
putStrategyState<T>(courseId: string, strategyKey: string, data: T): Promise<void>;
|
|
424
|
+
/**
|
|
425
|
+
* Delete strategy-specific state for a course.
|
|
426
|
+
*
|
|
427
|
+
* @param courseId - The course this state applies to
|
|
428
|
+
* @param strategyKey - Unique key identifying the strategy (typically class name)
|
|
429
|
+
*/
|
|
430
|
+
deleteStrategyState(courseId: string, strategyKey: string): Promise<void>;
|
|
390
431
|
}
|
|
391
432
|
/**
|
|
392
433
|
* Authentication and account management operations
|
|
@@ -524,6 +565,11 @@ interface WeightedCard {
|
|
|
524
565
|
* First entry is from the generator, subsequent entries from filters.
|
|
525
566
|
*/
|
|
526
567
|
provenance: StrategyContribution[];
|
|
568
|
+
/**
|
|
569
|
+
* Pre-fetched tags. Populated by Pipeline before filters run.
|
|
570
|
+
* Filters should use this instead of querying getAppliedTags() individually.
|
|
571
|
+
*/
|
|
572
|
+
tags?: string[];
|
|
527
573
|
}
|
|
528
574
|
/**
|
|
529
575
|
* Extract card origin from provenance trail.
|
|
@@ -542,7 +588,8 @@ declare enum Navigators {
|
|
|
542
588
|
HARDCODED = "hardcodedOrder",
|
|
543
589
|
HIERARCHY = "hierarchyDefinition",
|
|
544
590
|
INTERFERENCE = "interferenceMitigator",
|
|
545
|
-
RELATIVE_PRIORITY = "relativePriority"
|
|
591
|
+
RELATIVE_PRIORITY = "relativePriority",
|
|
592
|
+
USER_TAG_PREFERENCE = "userTagPreference"
|
|
546
593
|
}
|
|
547
594
|
/**
|
|
548
595
|
* Role classification for navigation strategies.
|
|
@@ -598,6 +645,28 @@ declare abstract class ContentNavigator implements StudyContentSource {
|
|
|
598
645
|
* Note: CompositeGenerator doesn't use this pattern and should call super() without args.
|
|
599
646
|
*/
|
|
600
647
|
constructor(user?: UserDBInterface, course?: CourseDBInterface, strategyData?: ContentNavigationStrategyData);
|
|
648
|
+
/**
|
|
649
|
+
* Unique key identifying this strategy for state storage.
|
|
650
|
+
*
|
|
651
|
+
* Defaults to the constructor name (e.g., "UserTagPreferenceFilter").
|
|
652
|
+
* Override in subclasses if multiple instances of the same strategy type
|
|
653
|
+
* need separate state storage.
|
|
654
|
+
*/
|
|
655
|
+
protected get strategyKey(): string;
|
|
656
|
+
/**
|
|
657
|
+
* Get this strategy's persisted state for the current course.
|
|
658
|
+
*
|
|
659
|
+
* @returns The strategy's data payload, or null if no state exists
|
|
660
|
+
* @throws Error if user or course is not initialized
|
|
661
|
+
*/
|
|
662
|
+
protected getStrategyState<T>(): Promise<T | null>;
|
|
663
|
+
/**
|
|
664
|
+
* Persist this strategy's state for the current course.
|
|
665
|
+
*
|
|
666
|
+
* @param data - The strategy's data payload to store
|
|
667
|
+
* @throws Error if user or course is not initialized
|
|
668
|
+
*/
|
|
669
|
+
protected putStrategyState<T>(data: T): Promise<void>;
|
|
601
670
|
/**
|
|
602
671
|
* Factory method to create navigator instances dynamically.
|
|
603
672
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CourseConfig, ClassroomConfig, CourseElo, Status, SkuilderCourseData as SkuilderCourseData$1, DataShape, TagFilter } from '@vue-skuilder/common';
|
|
2
2
|
import { Moment } from 'moment';
|
|
3
|
-
import { S as SkuilderCourseData, b as DocTypePrefixes, D as DocType, Q as QualifiedCardID, T as TagStub, a as Tag, C as CardHistory, c as CardRecord } from './types-legacy-
|
|
3
|
+
import { S as SkuilderCourseData, b as DocTypePrefixes, D as DocType, Q as QualifiedCardID, T as TagStub, a as Tag, C as CardHistory, c as CardRecord } from './types-legacy-DDY4N-Uq.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Admin functionality
|
|
@@ -222,6 +222,18 @@ interface CourseDBInterface extends NavigationStrategyManager {
|
|
|
222
222
|
* Get tags for a card
|
|
223
223
|
*/
|
|
224
224
|
getAppliedTags(cardId: string): Promise<PouchDB.Query.Response<TagStub>>;
|
|
225
|
+
/**
|
|
226
|
+
* Get tags for multiple cards in a single batch query.
|
|
227
|
+
* More efficient than calling getAppliedTags() for each card.
|
|
228
|
+
*
|
|
229
|
+
* This method reduces redundant database operations when multiple filters
|
|
230
|
+
* need tag data for the same cards. The Pipeline uses this to pre-hydrate
|
|
231
|
+
* tags on WeightedCard objects before filters run.
|
|
232
|
+
*
|
|
233
|
+
* @param cardIds - Array of card IDs to fetch tags for
|
|
234
|
+
* @returns Map from cardId to array of tag names
|
|
235
|
+
*/
|
|
236
|
+
getAppliedTagsBatch(cardIds: string[]): Promise<Map<string, string[]>>;
|
|
225
237
|
/**
|
|
226
238
|
* Add a tag to a card
|
|
227
239
|
*/
|
|
@@ -323,6 +335,17 @@ interface UserDBReader {
|
|
|
323
335
|
*/
|
|
324
336
|
getPendingReviews(courseId?: string): Promise<ScheduledCard[]>;
|
|
325
337
|
getActivityRecords(): Promise<ActivityRecord[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Get strategy-specific state for a course.
|
|
340
|
+
*
|
|
341
|
+
* Strategies use this to persist preferences, learned patterns, or temporal
|
|
342
|
+
* tracking data across sessions. Each strategy owns its own namespace.
|
|
343
|
+
*
|
|
344
|
+
* @param courseId - The course this state applies to
|
|
345
|
+
* @param strategyKey - Unique key identifying the strategy (typically class name)
|
|
346
|
+
* @returns The strategy's data payload, or null if no state exists
|
|
347
|
+
*/
|
|
348
|
+
getStrategyState<T>(courseId: string, strategyKey: string): Promise<T | null>;
|
|
326
349
|
/**
|
|
327
350
|
* Get user's classroom registrations
|
|
328
351
|
*/
|
|
@@ -387,6 +410,24 @@ interface UserDBWriter extends DocumentUpdater {
|
|
|
387
410
|
status: Status;
|
|
388
411
|
error?: string;
|
|
389
412
|
}>;
|
|
413
|
+
/**
|
|
414
|
+
* Store strategy-specific state for a course.
|
|
415
|
+
*
|
|
416
|
+
* Strategies use this to persist preferences, learned patterns, or temporal
|
|
417
|
+
* tracking data across sessions. Each strategy owns its own namespace.
|
|
418
|
+
*
|
|
419
|
+
* @param courseId - The course this state applies to
|
|
420
|
+
* @param strategyKey - Unique key identifying the strategy (typically class name)
|
|
421
|
+
* @param data - The strategy's data payload to store
|
|
422
|
+
*/
|
|
423
|
+
putStrategyState<T>(courseId: string, strategyKey: string, data: T): Promise<void>;
|
|
424
|
+
/**
|
|
425
|
+
* Delete strategy-specific state for a course.
|
|
426
|
+
*
|
|
427
|
+
* @param courseId - The course this state applies to
|
|
428
|
+
* @param strategyKey - Unique key identifying the strategy (typically class name)
|
|
429
|
+
*/
|
|
430
|
+
deleteStrategyState(courseId: string, strategyKey: string): Promise<void>;
|
|
390
431
|
}
|
|
391
432
|
/**
|
|
392
433
|
* Authentication and account management operations
|
|
@@ -524,6 +565,11 @@ interface WeightedCard {
|
|
|
524
565
|
* First entry is from the generator, subsequent entries from filters.
|
|
525
566
|
*/
|
|
526
567
|
provenance: StrategyContribution[];
|
|
568
|
+
/**
|
|
569
|
+
* Pre-fetched tags. Populated by Pipeline before filters run.
|
|
570
|
+
* Filters should use this instead of querying getAppliedTags() individually.
|
|
571
|
+
*/
|
|
572
|
+
tags?: string[];
|
|
527
573
|
}
|
|
528
574
|
/**
|
|
529
575
|
* Extract card origin from provenance trail.
|
|
@@ -542,7 +588,8 @@ declare enum Navigators {
|
|
|
542
588
|
HARDCODED = "hardcodedOrder",
|
|
543
589
|
HIERARCHY = "hierarchyDefinition",
|
|
544
590
|
INTERFERENCE = "interferenceMitigator",
|
|
545
|
-
RELATIVE_PRIORITY = "relativePriority"
|
|
591
|
+
RELATIVE_PRIORITY = "relativePriority",
|
|
592
|
+
USER_TAG_PREFERENCE = "userTagPreference"
|
|
546
593
|
}
|
|
547
594
|
/**
|
|
548
595
|
* Role classification for navigation strategies.
|
|
@@ -598,6 +645,28 @@ declare abstract class ContentNavigator implements StudyContentSource {
|
|
|
598
645
|
* Note: CompositeGenerator doesn't use this pattern and should call super() without args.
|
|
599
646
|
*/
|
|
600
647
|
constructor(user?: UserDBInterface, course?: CourseDBInterface, strategyData?: ContentNavigationStrategyData);
|
|
648
|
+
/**
|
|
649
|
+
* Unique key identifying this strategy for state storage.
|
|
650
|
+
*
|
|
651
|
+
* Defaults to the constructor name (e.g., "UserTagPreferenceFilter").
|
|
652
|
+
* Override in subclasses if multiple instances of the same strategy type
|
|
653
|
+
* need separate state storage.
|
|
654
|
+
*/
|
|
655
|
+
protected get strategyKey(): string;
|
|
656
|
+
/**
|
|
657
|
+
* Get this strategy's persisted state for the current course.
|
|
658
|
+
*
|
|
659
|
+
* @returns The strategy's data payload, or null if no state exists
|
|
660
|
+
* @throws Error if user or course is not initialized
|
|
661
|
+
*/
|
|
662
|
+
protected getStrategyState<T>(): Promise<T | null>;
|
|
663
|
+
/**
|
|
664
|
+
* Persist this strategy's state for the current course.
|
|
665
|
+
*
|
|
666
|
+
* @param data - The strategy's data payload to store
|
|
667
|
+
* @throws Error if user or course is not initialized
|
|
668
|
+
*/
|
|
669
|
+
protected putStrategyState<T>(data: T): Promise<void>;
|
|
601
670
|
/**
|
|
602
671
|
* Factory method to create navigator instances dynamically.
|
|
603
672
|
*
|
package/dist/core/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../classroomDB-
|
|
2
|
-
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, h as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, k as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, O as NavigatorRole, P as NavigatorRoles, N as Navigators, g as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, j as StudentClassroomDBInterface, i as StudyContentSource, m as StudySessionFailedItem, n as StudySessionFailedNewItem, o as StudySessionFailedReviewItem, l as StudySessionItem, S as StudySessionNewItem, f as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview } from '../classroomDB-
|
|
3
|
-
export { D as DataLayerProvider } from '../dataLayerProvider-
|
|
4
|
-
import { C as CardHistory, c as CardRecord, i as QuestionRecord } from '../types-legacy-
|
|
5
|
-
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData,
|
|
1
|
+
import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../classroomDB-PxDZTky3.cjs';
|
|
2
|
+
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, h as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, k as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, O as NavigatorRole, P as NavigatorRoles, N as Navigators, g as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, j as StudentClassroomDBInterface, i as StudyContentSource, m as StudySessionFailedItem, n as StudySessionFailedNewItem, o as StudySessionFailedReviewItem, l as StudySessionItem, S as StudySessionNewItem, f as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview } from '../classroomDB-PxDZTky3.cjs';
|
|
3
|
+
export { D as DataLayerProvider } from '../dataLayerProvider-D0MoZMjH.cjs';
|
|
4
|
+
import { b as DocTypePrefixes, D as DocType, C as CardHistory, c as CardRecord, i as QuestionRecord } from '../types-legacy-DDY4N-Uq.cjs';
|
|
5
|
+
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-DDY4N-Uq.cjs';
|
|
6
6
|
import { DataShape, ParsedCard } from '@vue-skuilder/common';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
@@ -169,6 +169,80 @@ interface CardGenerator {
|
|
|
169
169
|
*/
|
|
170
170
|
type CardGeneratorFactory<TConfig = unknown> = (config: TConfig) => CardGenerator;
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Template literal type for strategy state document IDs.
|
|
174
|
+
*
|
|
175
|
+
* Format: `STRATEGY_STATE-{courseId}-{strategyKey}`
|
|
176
|
+
*/
|
|
177
|
+
type StrategyStateId = `${(typeof DocTypePrefixes)[DocType.STRATEGY_STATE]}::${string}::${string}`;
|
|
178
|
+
/**
|
|
179
|
+
* Document storing strategy-specific state in the user database.
|
|
180
|
+
*
|
|
181
|
+
* Each strategy can persist its own state (user preferences, learned patterns,
|
|
182
|
+
* temporal tracking, etc.) using this document type. The state is scoped to
|
|
183
|
+
* a (user, course, strategy) tuple.
|
|
184
|
+
*
|
|
185
|
+
* ## Use Cases
|
|
186
|
+
*
|
|
187
|
+
* 1. **Explicit user preferences**: User configures tag filters, difficulty
|
|
188
|
+
* preferences, or learning goals. UI writes to strategy state.
|
|
189
|
+
*
|
|
190
|
+
* 2. **Learned/temporal state**: Strategy tracks patterns over time, e.g.,
|
|
191
|
+
* "when did I last introduce confusable concepts together?"
|
|
192
|
+
*
|
|
193
|
+
* 3. **Adaptive personalization**: Strategy infers user preferences from
|
|
194
|
+
* behavior and stores them for future sessions.
|
|
195
|
+
*
|
|
196
|
+
* ## Storage Location
|
|
197
|
+
*
|
|
198
|
+
* These documents live in the **user database**, not the course database.
|
|
199
|
+
* They sync with the user's data across devices.
|
|
200
|
+
*
|
|
201
|
+
* ## Document ID Format
|
|
202
|
+
*
|
|
203
|
+
* `STRATEGY_STATE::{courseId}::{strategyKey}`
|
|
204
|
+
*
|
|
205
|
+
* Example: `STRATEGY_STATE::piano-basics::UserTagPreferenceFilter`
|
|
206
|
+
*
|
|
207
|
+
* @template T - The shape of the strategy-specific data payload
|
|
208
|
+
*/
|
|
209
|
+
interface StrategyStateDoc<T = unknown> {
|
|
210
|
+
_id: StrategyStateId;
|
|
211
|
+
_rev?: string;
|
|
212
|
+
docType: DocType.STRATEGY_STATE;
|
|
213
|
+
/**
|
|
214
|
+
* The course this state applies to.
|
|
215
|
+
*/
|
|
216
|
+
courseId: string;
|
|
217
|
+
/**
|
|
218
|
+
* Unique key identifying the strategy instance.
|
|
219
|
+
* Typically the strategy class name (e.g., "UserTagPreferenceFilter",
|
|
220
|
+
* "InterferenceMitigatorNavigator").
|
|
221
|
+
*
|
|
222
|
+
* If a course has multiple instances of the same strategy type with
|
|
223
|
+
* different configurations, use a more specific key.
|
|
224
|
+
*/
|
|
225
|
+
strategyKey: string;
|
|
226
|
+
/**
|
|
227
|
+
* Strategy-specific data payload.
|
|
228
|
+
* Each strategy defines its own schema for this field.
|
|
229
|
+
*/
|
|
230
|
+
data: T;
|
|
231
|
+
/**
|
|
232
|
+
* ISO timestamp of last update.
|
|
233
|
+
* Use `moment.utc(updatedAt)` to parse into a Moment object.
|
|
234
|
+
*/
|
|
235
|
+
updatedAt: string;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Build the document ID for a strategy state document.
|
|
239
|
+
*
|
|
240
|
+
* @param courseId - The course ID
|
|
241
|
+
* @param strategyKey - The strategy key (typically class name)
|
|
242
|
+
* @returns The document ID in format `STRATEGY_STATE::{courseId}::{strategyKey}`
|
|
243
|
+
*/
|
|
244
|
+
declare function buildStrategyStateId(courseId: string, strategyKey: string): StrategyStateId;
|
|
245
|
+
|
|
172
246
|
declare function areQuestionRecords(h: CardHistory<CardRecord>): h is CardHistory<QuestionRecord>;
|
|
173
247
|
declare function isQuestionRecord(c: CardRecord): c is QuestionRecord;
|
|
174
248
|
declare function getCardHistoryID(courseID: string, cardID: string): PouchDB.Core.DocumentId;
|
|
@@ -227,4 +301,4 @@ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig
|
|
|
227
301
|
errorMessage?: string;
|
|
228
302
|
};
|
|
229
303
|
|
|
230
|
-
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, UserDBInterface, WeightedCard, areQuestionRecords, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
|
|
304
|
+
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, type StrategyStateDoc, type StrategyStateId, UserDBInterface, WeightedCard, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../classroomDB-
|
|
2
|
-
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, h as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, k as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, O as NavigatorRole, P as NavigatorRoles, N as Navigators, g as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, j as StudentClassroomDBInterface, i as StudyContentSource, m as StudySessionFailedItem, n as StudySessionFailedNewItem, o as StudySessionFailedReviewItem, l as StudySessionItem, S as StudySessionNewItem, f as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview } from '../classroomDB-
|
|
3
|
-
export { D as DataLayerProvider } from '../dataLayerProvider-
|
|
4
|
-
import { C as CardHistory, c as CardRecord, i as QuestionRecord } from '../types-legacy-
|
|
5
|
-
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData,
|
|
1
|
+
import { W as WeightedCard, U as UserDBInterface, C as CourseDBInterface } from '../classroomDB-CZdMBiTU.js';
|
|
2
|
+
export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, h as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, k as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, O as NavigatorRole, P as NavigatorRoles, N as Navigators, g as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, j as StudentClassroomDBInterface, i as StudyContentSource, m as StudySessionFailedItem, n as StudySessionFailedNewItem, o as StudySessionFailedReviewItem, l as StudySessionItem, S as StudySessionNewItem, f as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview } from '../classroomDB-CZdMBiTU.js';
|
|
3
|
+
export { D as DataLayerProvider } from '../dataLayerProvider-D8o6ZnKW.js';
|
|
4
|
+
import { b as DocTypePrefixes, D as DocType, C as CardHistory, c as CardRecord, i as QuestionRecord } from '../types-legacy-DDY4N-Uq.js';
|
|
5
|
+
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-DDY4N-Uq.js';
|
|
6
6
|
import { DataShape, ParsedCard } from '@vue-skuilder/common';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
@@ -169,6 +169,80 @@ interface CardGenerator {
|
|
|
169
169
|
*/
|
|
170
170
|
type CardGeneratorFactory<TConfig = unknown> = (config: TConfig) => CardGenerator;
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Template literal type for strategy state document IDs.
|
|
174
|
+
*
|
|
175
|
+
* Format: `STRATEGY_STATE-{courseId}-{strategyKey}`
|
|
176
|
+
*/
|
|
177
|
+
type StrategyStateId = `${(typeof DocTypePrefixes)[DocType.STRATEGY_STATE]}::${string}::${string}`;
|
|
178
|
+
/**
|
|
179
|
+
* Document storing strategy-specific state in the user database.
|
|
180
|
+
*
|
|
181
|
+
* Each strategy can persist its own state (user preferences, learned patterns,
|
|
182
|
+
* temporal tracking, etc.) using this document type. The state is scoped to
|
|
183
|
+
* a (user, course, strategy) tuple.
|
|
184
|
+
*
|
|
185
|
+
* ## Use Cases
|
|
186
|
+
*
|
|
187
|
+
* 1. **Explicit user preferences**: User configures tag filters, difficulty
|
|
188
|
+
* preferences, or learning goals. UI writes to strategy state.
|
|
189
|
+
*
|
|
190
|
+
* 2. **Learned/temporal state**: Strategy tracks patterns over time, e.g.,
|
|
191
|
+
* "when did I last introduce confusable concepts together?"
|
|
192
|
+
*
|
|
193
|
+
* 3. **Adaptive personalization**: Strategy infers user preferences from
|
|
194
|
+
* behavior and stores them for future sessions.
|
|
195
|
+
*
|
|
196
|
+
* ## Storage Location
|
|
197
|
+
*
|
|
198
|
+
* These documents live in the **user database**, not the course database.
|
|
199
|
+
* They sync with the user's data across devices.
|
|
200
|
+
*
|
|
201
|
+
* ## Document ID Format
|
|
202
|
+
*
|
|
203
|
+
* `STRATEGY_STATE::{courseId}::{strategyKey}`
|
|
204
|
+
*
|
|
205
|
+
* Example: `STRATEGY_STATE::piano-basics::UserTagPreferenceFilter`
|
|
206
|
+
*
|
|
207
|
+
* @template T - The shape of the strategy-specific data payload
|
|
208
|
+
*/
|
|
209
|
+
interface StrategyStateDoc<T = unknown> {
|
|
210
|
+
_id: StrategyStateId;
|
|
211
|
+
_rev?: string;
|
|
212
|
+
docType: DocType.STRATEGY_STATE;
|
|
213
|
+
/**
|
|
214
|
+
* The course this state applies to.
|
|
215
|
+
*/
|
|
216
|
+
courseId: string;
|
|
217
|
+
/**
|
|
218
|
+
* Unique key identifying the strategy instance.
|
|
219
|
+
* Typically the strategy class name (e.g., "UserTagPreferenceFilter",
|
|
220
|
+
* "InterferenceMitigatorNavigator").
|
|
221
|
+
*
|
|
222
|
+
* If a course has multiple instances of the same strategy type with
|
|
223
|
+
* different configurations, use a more specific key.
|
|
224
|
+
*/
|
|
225
|
+
strategyKey: string;
|
|
226
|
+
/**
|
|
227
|
+
* Strategy-specific data payload.
|
|
228
|
+
* Each strategy defines its own schema for this field.
|
|
229
|
+
*/
|
|
230
|
+
data: T;
|
|
231
|
+
/**
|
|
232
|
+
* ISO timestamp of last update.
|
|
233
|
+
* Use `moment.utc(updatedAt)` to parse into a Moment object.
|
|
234
|
+
*/
|
|
235
|
+
updatedAt: string;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Build the document ID for a strategy state document.
|
|
239
|
+
*
|
|
240
|
+
* @param courseId - The course ID
|
|
241
|
+
* @param strategyKey - The strategy key (typically class name)
|
|
242
|
+
* @returns The document ID in format `STRATEGY_STATE::{courseId}::{strategyKey}`
|
|
243
|
+
*/
|
|
244
|
+
declare function buildStrategyStateId(courseId: string, strategyKey: string): StrategyStateId;
|
|
245
|
+
|
|
172
246
|
declare function areQuestionRecords(h: CardHistory<CardRecord>): h is CardHistory<QuestionRecord>;
|
|
173
247
|
declare function isQuestionRecord(c: CardRecord): c is QuestionRecord;
|
|
174
248
|
declare function getCardHistoryID(courseID: string, cardID: string): PouchDB.Core.DocumentId;
|
|
@@ -227,4 +301,4 @@ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig
|
|
|
227
301
|
errorMessage?: string;
|
|
228
302
|
};
|
|
229
303
|
|
|
230
|
-
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, UserDBInterface, WeightedCard, areQuestionRecords, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
|
|
304
|
+
export { type BulkCardProcessorConfig, type CardFilter, type CardFilterFactory, type CardGenerator, type CardGeneratorFactory, CardHistory, CardRecord, CourseDBInterface, DocType, DocTypePrefixes, type FilterContext, type GeneratorContext, type ImportResult, Loggable, QuestionRecord, type StrategyStateDoc, type StrategyStateId, UserDBInterface, WeightedCard, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig };
|