@vue-skuilder/db 0.1.1

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 (62) hide show
  1. package/README.md +26 -0
  2. package/dist/core/index.d.mts +3 -0
  3. package/dist/core/index.d.ts +3 -0
  4. package/dist/core/index.js +7906 -0
  5. package/dist/core/index.js.map +1 -0
  6. package/dist/core/index.mjs +7886 -0
  7. package/dist/core/index.mjs.map +1 -0
  8. package/dist/index-QMtzQI65.d.mts +734 -0
  9. package/dist/index-QMtzQI65.d.ts +734 -0
  10. package/dist/index.d.mts +133 -0
  11. package/dist/index.d.ts +133 -0
  12. package/dist/index.js +8726 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/index.mjs +8699 -0
  15. package/dist/index.mjs.map +1 -0
  16. package/eslint.config.mjs +20 -0
  17. package/package.json +47 -0
  18. package/src/core/bulkImport/cardProcessor.ts +165 -0
  19. package/src/core/bulkImport/index.ts +2 -0
  20. package/src/core/bulkImport/types.ts +27 -0
  21. package/src/core/index.ts +9 -0
  22. package/src/core/interfaces/adminDB.ts +27 -0
  23. package/src/core/interfaces/classroomDB.ts +75 -0
  24. package/src/core/interfaces/contentSource.ts +64 -0
  25. package/src/core/interfaces/courseDB.ts +139 -0
  26. package/src/core/interfaces/dataLayerProvider.ts +46 -0
  27. package/src/core/interfaces/index.ts +7 -0
  28. package/src/core/interfaces/navigationStrategyManager.ts +46 -0
  29. package/src/core/interfaces/userDB.ts +183 -0
  30. package/src/core/navigators/elo.ts +76 -0
  31. package/src/core/navigators/index.ts +57 -0
  32. package/src/core/readme.md +9 -0
  33. package/src/core/types/contentNavigationStrategy.ts +21 -0
  34. package/src/core/types/db.ts +7 -0
  35. package/src/core/types/types-legacy.ts +155 -0
  36. package/src/core/types/user.ts +70 -0
  37. package/src/core/util/index.ts +42 -0
  38. package/src/factory.ts +86 -0
  39. package/src/impl/pouch/PouchDataLayerProvider.ts +102 -0
  40. package/src/impl/pouch/adminDB.ts +91 -0
  41. package/src/impl/pouch/auth.ts +48 -0
  42. package/src/impl/pouch/classroomDB.ts +306 -0
  43. package/src/impl/pouch/clientCache.ts +19 -0
  44. package/src/impl/pouch/courseAPI.ts +245 -0
  45. package/src/impl/pouch/courseDB.ts +772 -0
  46. package/src/impl/pouch/courseLookupDB.ts +135 -0
  47. package/src/impl/pouch/index.ts +235 -0
  48. package/src/impl/pouch/pouchdb-setup.ts +16 -0
  49. package/src/impl/pouch/types.ts +7 -0
  50. package/src/impl/pouch/updateQueue.ts +89 -0
  51. package/src/impl/pouch/user-course-relDB.ts +73 -0
  52. package/src/impl/pouch/userDB.ts +1097 -0
  53. package/src/index.ts +8 -0
  54. package/src/study/SessionController.ts +401 -0
  55. package/src/study/SpacedRepetition.ts +128 -0
  56. package/src/study/getCardDataShape.ts +34 -0
  57. package/src/study/index.ts +2 -0
  58. package/src/util/Loggable.ts +11 -0
  59. package/src/util/index.ts +1 -0
  60. package/src/util/logger.ts +55 -0
  61. package/tsconfig.json +12 -0
  62. package/tsup.config.ts +17 -0
@@ -0,0 +1,734 @@
1
+ import { CourseConfig, ClassroomConfig, CourseElo, Evaluation, Answer, Status, SkuilderCourseData as SkuilderCourseData$1, DataShape, ParsedCard } from '@vue-skuilder/common';
2
+ import { Moment } from 'moment';
3
+
4
+ /**
5
+ * Admin functionality
6
+ */
7
+ interface AdminDBInterface {
8
+ /**
9
+ * Get all users
10
+ */
11
+ getUsers(): Promise<PouchDB.Core.Document<{}>[]>;
12
+ /**
13
+ * Get all courses
14
+ */
15
+ getCourses(): Promise<CourseConfig[]>;
16
+ /**
17
+ * Remove a course
18
+ */
19
+ removeCourse(id: string): Promise<PouchDB.Core.Response>;
20
+ /**
21
+ * Get all classrooms
22
+ */
23
+ getClassrooms(): Promise<(ClassroomConfig & {
24
+ _id: string;
25
+ })[]>;
26
+ }
27
+
28
+ interface UserConfig {
29
+ darkMode: boolean;
30
+ likesConfetti: boolean;
31
+ }
32
+ interface ActivityRecord {
33
+ timeStamp: number | string;
34
+ [key: string]: any;
35
+ }
36
+ interface CourseRegistration {
37
+ status?: 'active' | 'dropped' | 'maintenance-mode' | 'preview';
38
+ courseID: string;
39
+ admin: boolean;
40
+ moderator: boolean;
41
+ user: boolean;
42
+ settings?: {
43
+ [setting: string]: string | number | boolean;
44
+ };
45
+ elo: number | CourseElo;
46
+ }
47
+ interface StudyWeights {
48
+ [courseID: string]: number;
49
+ }
50
+ interface CourseRegistrationDoc {
51
+ courses: CourseRegistration[];
52
+ studyWeight: StudyWeights;
53
+ }
54
+ interface ScheduledCard {
55
+ _id: PouchDB.Core.DocumentId;
56
+ /**
57
+ * The docID of the card to be reviewed
58
+ */
59
+ cardId: PouchDB.Core.DocumentId;
60
+ /**
61
+ * The ID of the course
62
+ */
63
+ courseId: string;
64
+ /**
65
+ * The time at which the card becomes eligible for review.
66
+ *
67
+ * (Should probably be UTC adjusted so that performance is
68
+ * not wonky across time zones)
69
+ */
70
+ reviewTime: Moment;
71
+ /**
72
+ * The time at which this scheduled event was created.
73
+ */
74
+ scheduledAt: Moment;
75
+ /**
76
+ * Classifying whether this card is scheduled on behalf of a
77
+ * user-registered course or by as assigned content from a
78
+ * user-registered classroom
79
+ */
80
+ scheduledFor: 'course' | 'classroom';
81
+ /**
82
+ * The ID of the course or classroom that requested this card
83
+ */
84
+ schedulingAgentId: string;
85
+ }
86
+
87
+ type StudySessionFailedItem = StudySessionFailedNewItem | StudySessionFailedReviewItem;
88
+ interface StudySessionFailedNewItem extends StudySessionItem {
89
+ status: 'failed-new';
90
+ }
91
+ interface StudySessionFailedReviewItem extends StudySessionReviewItem {
92
+ status: 'failed-review';
93
+ }
94
+ interface StudySessionNewItem extends StudySessionItem {
95
+ status: 'new';
96
+ }
97
+ interface StudySessionReviewItem extends StudySessionItem {
98
+ reviewID: string;
99
+ status: 'review' | 'failed-review';
100
+ }
101
+ declare function isReview(item: StudySessionItem): item is StudySessionReviewItem;
102
+ interface StudySessionItem {
103
+ status: 'new' | 'review' | 'failed-new' | 'failed-review';
104
+ qualifiedID: `${string}-${string}` | `${string}-${string}-${number}`;
105
+ cardID: string;
106
+ contentSourceType: 'course' | 'classroom';
107
+ contentSourceID: string;
108
+ courseID: string;
109
+ }
110
+ interface ContentSourceID {
111
+ type: 'course' | 'classroom';
112
+ id: string;
113
+ }
114
+ interface StudyContentSource {
115
+ getPendingReviews(): Promise<(StudySessionReviewItem & ScheduledCard)[]>;
116
+ getNewCards(n?: number): Promise<StudySessionNewItem[]>;
117
+ }
118
+ declare function getStudySource(source: ContentSourceID, user: UserDBInterface): Promise<StudyContentSource>;
119
+
120
+ /**
121
+ * Classroom management
122
+ */
123
+ interface ClassroomDBInterface {
124
+ /**
125
+ * Get classroom config
126
+ */
127
+ getConfig(): ClassroomConfig;
128
+ /**
129
+ * Get assigned content
130
+ */
131
+ getAssignedContent(): Promise<AssignedContent[]>;
132
+ }
133
+ interface TeacherClassroomDBInterface extends ClassroomDBInterface {
134
+ /**
135
+ * For teacher interfaces: assign content
136
+ */
137
+ assignContent?(content: AssignedContent): Promise<boolean>;
138
+ /**
139
+ * For teacher interfaces: remove content
140
+ */
141
+ removeContent?(content: AssignedContent): Promise<void>;
142
+ }
143
+ interface StudentClassroomDBInterface extends ClassroomDBInterface {
144
+ /**
145
+ * For student interfaces: get pending reviews
146
+ */
147
+ getPendingReviews?(): Promise<(StudySessionReviewItem & ScheduledCard)[]>;
148
+ /**
149
+ * For student interfaces: get new cards
150
+ */
151
+ getNewCards?(limit?: number): Promise<StudySessionNewItem[]>;
152
+ }
153
+ type AssignedContent = AssignedCourse | AssignedTag | AssignedCard;
154
+ interface AssignedTag extends ContentBase {
155
+ type: 'tag';
156
+ tagID: string;
157
+ }
158
+ interface AssignedCourse extends ContentBase {
159
+ type: 'course';
160
+ }
161
+ interface AssignedCard extends ContentBase {
162
+ type: 'card';
163
+ cardID: string;
164
+ }
165
+ interface ContentBase {
166
+ type: 'course' | 'tag' | 'card';
167
+ /**
168
+ * Username of the assigning teacher.
169
+ */
170
+ assignedBy: string;
171
+ /**
172
+ * Date the content was assigned.
173
+ */
174
+ assignedOn: moment.Moment;
175
+ /**
176
+ * A 'due' date for this assigned content, for scheduling content
177
+ * in advance. Content will not be actively pushed to students until
178
+ * this date.
179
+ */
180
+ activeOn: moment.Moment;
181
+ courseID: string;
182
+ }
183
+
184
+ declare const GuestUsername: string;
185
+ declare const log: (message: string) => void;
186
+ declare enum DocType {
187
+ DISPLAYABLE_DATA = "DISPLAYABLE_DATA",
188
+ CARD = "CARD",
189
+ DATASHAPE = "DATASHAPE",
190
+ QUESTIONTYPE = "QUESTION",
191
+ VIEW = "VIEW",
192
+ PEDAGOGY = "PEDAGOGY",
193
+ CARDRECORD = "CARDRECORD",
194
+ SCHEDULED_CARD = "SCHEDULED_CARD",
195
+ TAG = "TAG",
196
+ NAVIGATION_STRATEGY = "NAVIGATION_STRATEGY"
197
+ }
198
+ /**
199
+ * Interface for all data on course content and pedagogy stored
200
+ * in the c/pouch database.
201
+ */
202
+ interface SkuilderCourseData {
203
+ course: string;
204
+ docType: DocType;
205
+ }
206
+ interface Tag extends SkuilderCourseData {
207
+ docType: DocType.TAG;
208
+ name: string;
209
+ snippet: string;
210
+ wiki: string;
211
+ taggedCards: PouchDB.Core.DocumentId[];
212
+ }
213
+ interface TagStub {
214
+ name: string;
215
+ snippet: string;
216
+ count: number;
217
+ }
218
+ interface CardData extends SkuilderCourseData {
219
+ docType: DocType.CARD;
220
+ id_displayable_data: PouchDB.Core.DocumentId[];
221
+ id_view: PouchDB.Core.DocumentId;
222
+ elo: CourseElo;
223
+ }
224
+ /** A list of populated courses in the DB */
225
+ interface CourseListData extends PouchDB.Core.Response {
226
+ courses: string[];
227
+ }
228
+ /**
229
+ * The data used to hydrate viewable components (questions, info, etc)
230
+ */
231
+ interface DisplayableData extends SkuilderCourseData {
232
+ docType: DocType.DISPLAYABLE_DATA;
233
+ author?: string;
234
+ id_datashape: PouchDB.Core.DocumentId;
235
+ data: Field[];
236
+ _attachments?: {
237
+ [index: string]: PouchDB.Core.FullAttachment;
238
+ };
239
+ }
240
+ interface Field {
241
+ data: unknown;
242
+ name: string;
243
+ }
244
+ interface DataShapeData extends SkuilderCourseData {
245
+ docType: DocType.DATASHAPE;
246
+ _id: PouchDB.Core.DocumentId;
247
+ questionTypes: PouchDB.Core.DocumentId[];
248
+ }
249
+ interface QuestionData extends SkuilderCourseData {
250
+ docType: DocType.QUESTIONTYPE;
251
+ _id: PouchDB.Core.DocumentId;
252
+ viewList: string[];
253
+ dataShapeList: PouchDB.Core.DocumentId[];
254
+ }
255
+ declare const cardHistoryPrefix = "cardH";
256
+ interface CardHistory<T extends CardRecord> {
257
+ _id: PouchDB.Core.DocumentId;
258
+ /**
259
+ * The CouchDB id of the card
260
+ */
261
+ cardID: PouchDB.Core.DocumentId;
262
+ /**
263
+ * The ID of the course
264
+ */
265
+ courseID: string;
266
+ /**
267
+ * The to-date largest interval between successful
268
+ * card reviews. `0` indicates no successful reviews.
269
+ */
270
+ bestInterval: number;
271
+ /**
272
+ * The number of times that a card has been
273
+ * failed in review
274
+ */
275
+ lapses: number;
276
+ /**
277
+ * The number of consecutive successful impressions
278
+ * on this card
279
+ */
280
+ streak: number;
281
+ records: T[];
282
+ }
283
+ interface CardRecord {
284
+ /**
285
+ * The CouchDB id of the card
286
+ */
287
+ cardID: string;
288
+ /**
289
+ * The ID of the course
290
+ */
291
+ courseID: string;
292
+ /**
293
+ * Number of milliseconds that the user spent before dismissing
294
+ * the card (ie, "I've read this" or "here is my answer")
295
+ *
296
+ * //TODO: this (sometimes?) wants to be replaced with a rich
297
+ * recording of user activity in working the question
298
+ */
299
+ timeSpent: number;
300
+ /**
301
+ * The date-time that the card was rendered. timeStamp + timeSpent will give the
302
+ * time of user submission.
303
+ */
304
+ timeStamp: Moment;
305
+ }
306
+ interface QuestionRecord extends CardRecord, Evaluation {
307
+ userAnswer: Answer;
308
+ /**
309
+ * The number of incorrect user submissions prededing this submisstion.
310
+ *
311
+ * eg, if a user is asked 7*6=__, submitting 46, 48, 42 will result in three
312
+ * records being created having 0, 1, and 2 as their recorded 'priorAttempts' values
313
+ */
314
+ priorAttemps: number;
315
+ }
316
+
317
+ interface DataLayerResult {
318
+ status: Status;
319
+ message: string;
320
+ id?: string;
321
+ }
322
+
323
+ /**
324
+ *
325
+ */
326
+ interface ContentNavigationStrategyData extends SkuilderCourseData {
327
+ id: string;
328
+ docType: DocType.NAVIGATION_STRATEGY;
329
+ name: string;
330
+ description: string;
331
+ /**
332
+ The name of the class that implements the navigation strategy at runtime.
333
+ */
334
+ implementingClass: string;
335
+ /**
336
+ A representation of the strategy's parameterization - to be deserialized
337
+ by the implementing class's constructor at runtime.
338
+ */
339
+ serializedData: string;
340
+ }
341
+
342
+ /**
343
+ * A NavigationStrategyManager is an entity which may contain multiple strategies.
344
+ *
345
+ * This interface defines strategy CRUD.
346
+ */
347
+ interface NavigationStrategyManager {
348
+ /**
349
+ * Get the navigation strategy for a given course
350
+ * @returns The navigation strategy for the course
351
+ */
352
+ getNavigationStrategy(id: string): Promise<ContentNavigationStrategyData>;
353
+ /**
354
+ * Get all available navigation strategies
355
+ * @returns An array of all available navigation strategies
356
+ */
357
+ getAllNavigationStrategies(): Promise<ContentNavigationStrategyData[]>;
358
+ /**
359
+ * Add a new navigation strategy
360
+ * @param data The data for the new navigation strategy
361
+ * @returns A promise that resolves when the strategy has been added
362
+ */
363
+ addNavigationStrategy(data: ContentNavigationStrategyData): Promise<void>;
364
+ /**
365
+ * Update an existing navigation strategy
366
+ * @param id The ID of the navigation strategy to update
367
+ * @param data The new data for the navigation strategy
368
+ * @returns A promise that resolves when the update is complete
369
+ */
370
+ updateNavigationStrategy(id: string, data: ContentNavigationStrategyData): Promise<void>;
371
+ /**
372
+ * @returns A content navigation strategy suitable to the current context.
373
+ */
374
+ surfaceNavigationStrategy(): Promise<ContentNavigationStrategyData>;
375
+ }
376
+
377
+ /**
378
+ * Course content and management
379
+ */
380
+ interface CoursesDBInterface {
381
+ /**
382
+ * Get course config
383
+ */
384
+ getCourseConfig(courseId: string): Promise<CourseConfig>;
385
+ /**
386
+ * Get a list of all courses
387
+ */
388
+ getCourseList(): Promise<CourseConfig[]>;
389
+ disambiguateCourse(courseId: string, disambiguator: string): Promise<void>;
390
+ }
391
+ interface CourseInfo {
392
+ cardCount: number;
393
+ registeredUsers: number;
394
+ }
395
+ interface CourseDBInterface extends NavigationStrategyManager {
396
+ /**
397
+ * Get course config
398
+ */
399
+ getCourseConfig(): Promise<CourseConfig>;
400
+ getCourseID(): string;
401
+ /**
402
+ * Set course config
403
+ */
404
+ updateCourseConfig(cfg: CourseConfig): Promise<PouchDB.Core.Response>;
405
+ getCourseInfo(): Promise<CourseInfo>;
406
+ getCourseDoc<T extends SkuilderCourseData$1>(id: string, options?: PouchDB.Core.GetOptions): Promise<T>;
407
+ getCourseDocs<T extends SkuilderCourseData$1>(ids: string[], options?: PouchDB.Core.AllDocsOptions): Promise<PouchDB.Core.AllDocsWithKeysResponse<{} & T>>;
408
+ /**
409
+ * Get cards sorted by ELO rating
410
+ */
411
+ getCardsByELO(elo: number, limit?: number): Promise<string[]>;
412
+ /**
413
+ * Get ELO data for specific cards
414
+ */
415
+ getCardEloData(cardIds: string[]): Promise<CourseElo[]>;
416
+ /**
417
+ * Update card ELO rating
418
+ */
419
+ updateCardElo(cardId: string, elo: CourseElo): Promise<PouchDB.Core.Response>;
420
+ /**
421
+ * Get new cards for study
422
+ */
423
+ getNewCards(limit?: number): Promise<StudySessionNewItem[]>;
424
+ /**
425
+ * Get cards centered at a particular ELO rating
426
+ */
427
+ getCardsCenteredAtELO(options: {
428
+ limit: number;
429
+ elo: 'user' | 'random' | number;
430
+ }, filter?: (id: string) => boolean): Promise<StudySessionItem[]>;
431
+ /**
432
+ * Get tags for a card
433
+ */
434
+ getAppliedTags(cardId: string): Promise<PouchDB.Query.Response<TagStub>>;
435
+ /**
436
+ * Add a tag to a card
437
+ */
438
+ addTagToCard(cardId: string, tagId: string, updateELO?: boolean): Promise<PouchDB.Core.Response>;
439
+ /**
440
+ * Remove a tag from a card
441
+ */
442
+ removeTagFromCard(cardId: string, tagId: string): Promise<PouchDB.Core.Response>;
443
+ /**
444
+ * Create a new tag
445
+ */
446
+ createTag(tagName: string): Promise<PouchDB.Core.Response>;
447
+ /**
448
+ * Get a tag by name
449
+ */
450
+ getTag(tagName: string): Promise<Tag>;
451
+ /**
452
+ * Update a tag
453
+ */
454
+ updateTag(tag: Tag): Promise<PouchDB.Core.Response>;
455
+ /**
456
+ * Get all tag stubs for a course
457
+ */
458
+ getCourseTagStubs(): Promise<PouchDB.Core.AllDocsResponse<Tag>>;
459
+ /**
460
+ * Add a note to the course
461
+ */
462
+ addNote(codeCourse: string, shape: DataShape, data: unknown, author: string, tags: string[], uploads?: {
463
+ [key: string]: PouchDB.Core.FullAttachment;
464
+ }, elo?: CourseElo): Promise<DataLayerResult>;
465
+ removeCard(cardId: string): Promise<PouchDB.Core.Response>;
466
+ getInexperiencedCards(): Promise<{
467
+ courseId: string;
468
+ cardId: string;
469
+ count: number;
470
+ elo: CourseElo;
471
+ }[]>;
472
+ }
473
+
474
+ declare abstract class Loggable {
475
+ protected abstract readonly _className: string;
476
+ protected log(...args: unknown[]): void;
477
+ protected error(...args: unknown[]): void;
478
+ }
479
+
480
+ type Update<T> = Partial<T> | ((x: T) => T);
481
+
482
+ interface DocumentUpdater {
483
+ update<T extends PouchDB.Core.Document<object>>(id: string, update: Update<T>): Promise<T>;
484
+ }
485
+ /**
486
+ * Returns the minimum number of seconds that should pass before a
487
+ * card is redisplayed for review / practice.
488
+ *
489
+ * @param cardHistory The user's history working with the given card
490
+ */
491
+ declare function newInterval(user: DocumentUpdater, cardHistory: CardHistory<CardRecord>): number;
492
+
493
+ /**
494
+ * User data and authentication
495
+ */
496
+ interface UserDBInterface extends DocumentUpdater {
497
+ /**
498
+ * Create a new user account
499
+ */
500
+ createAccount(username: string, password: string): Promise<{
501
+ status: Status;
502
+ error: string;
503
+ }>;
504
+ /**
505
+ * Log in as a user
506
+ */
507
+ login(username: string, password: string): Promise<{
508
+ ok: boolean;
509
+ name?: string;
510
+ roles?: string[];
511
+ }>;
512
+ /**
513
+ * Log out the current user
514
+ */
515
+ logout(): Promise<{
516
+ ok: boolean;
517
+ }>;
518
+ getUsername(): string;
519
+ isLoggedIn(): boolean;
520
+ /**
521
+ * Get user configuration
522
+ */
523
+ getConfig(): Promise<UserConfig>;
524
+ /**
525
+ * Update user configuration
526
+ */
527
+ setConfig(config: Partial<UserConfig>): Promise<void>;
528
+ /**
529
+ * Record a user's interaction with a card
530
+ */
531
+ putCardRecord<T extends CardRecord>(record: T): Promise<CardHistory<CardRecord>>;
532
+ /**
533
+ * Get cards that the user has seen
534
+ */
535
+ getSeenCards(courseId?: string): Promise<string[]>;
536
+ /**
537
+ * Get cards that are actively scheduled for review
538
+ */
539
+ getActiveCards(): Promise<string[]>;
540
+ /**
541
+ * Register user for a course
542
+ */
543
+ registerForCourse(courseId: string, previewMode?: boolean): Promise<PouchDB.Core.Response>;
544
+ /**
545
+ * Drop a course registration
546
+ */
547
+ dropCourse(courseId: string, dropStatus?: string): Promise<PouchDB.Core.Response>;
548
+ /**
549
+ * Get user's course registrations
550
+ */
551
+ getCourseRegistrationsDoc(): Promise<CourseRegistrationDoc>;
552
+ /**
553
+ * Get the registration doc for a specific course.
554
+ * @param courseId
555
+ */
556
+ getCourseRegDoc(courseId: string): Promise<CourseRegistration>;
557
+ /**
558
+ * Get user's active courses
559
+ */
560
+ getActiveCourses(): Promise<CourseRegistration[]>;
561
+ /**
562
+ * Get user's pending reviews
563
+ */
564
+ getPendingReviews(courseId?: string): Promise<ScheduledCard[]>;
565
+ getActivityRecords(): Promise<ActivityRecord[]>;
566
+ /**
567
+ * Schedule a card for review
568
+ */
569
+ scheduleCardReview(review: {
570
+ user: string;
571
+ course_id: string;
572
+ card_id: string;
573
+ time: Moment;
574
+ scheduledFor: 'course' | 'classroom';
575
+ schedulingAgentId: string;
576
+ }): Promise<void>;
577
+ /**
578
+ * Remove a scheduled card review
579
+ */
580
+ removeScheduledCardReview(reviewId: string): Promise<void>;
581
+ /**
582
+ * Register user for a classroom
583
+ */
584
+ registerForClassroom(classId: string, registerAs: 'student' | 'teacher' | 'aide' | 'admin'): Promise<PouchDB.Core.Response>;
585
+ /**
586
+ * Drop user from classroom
587
+ */
588
+ dropFromClassroom(classId: string): Promise<PouchDB.Core.Response>;
589
+ /**
590
+ * Get user's classroom registrations
591
+ */
592
+ getUserClassrooms(): Promise<ClassroomRegistrationDoc>;
593
+ /**
594
+ * Get user's active classes
595
+ */
596
+ getActiveClasses(): Promise<string[]>;
597
+ /**
598
+ * Update user's ELO rating for a course
599
+ */
600
+ updateUserElo(courseId: string, elo: CourseElo): Promise<PouchDB.Core.Response>;
601
+ getCourseInterface(courseId: string): Promise<UsrCrsDataInterface>;
602
+ }
603
+ interface UserCourseSettings {
604
+ [setting: string]: string | number | boolean;
605
+ }
606
+ interface UserCourseSetting {
607
+ key: string;
608
+ value: string | number | boolean;
609
+ }
610
+ interface UsrCrsDataInterface {
611
+ getScheduledReviewCount(): Promise<number>;
612
+ getCourseSettings(): Promise<UserCourseSettings>;
613
+ updateCourseSettings(updates: UserCourseSetting[]): void;
614
+ }
615
+ type ClassroomRegistrationDesignation = 'student' | 'teacher' | 'aide' | 'admin';
616
+ interface ClassroomRegistration {
617
+ classID: string;
618
+ registeredAs: ClassroomRegistrationDesignation;
619
+ }
620
+ interface ClassroomRegistrationDoc {
621
+ registrations: ClassroomRegistration[];
622
+ }
623
+
624
+ /**
625
+ * Main factory interface for data access
626
+ */
627
+ interface DataLayerProvider {
628
+ /**
629
+ * Get the user database interface
630
+ */
631
+ getUserDB(): UserDBInterface;
632
+ /**
633
+ * Get a course database interface
634
+ */
635
+ getCourseDB(courseId: string): CourseDBInterface;
636
+ /**
637
+ * Get the courses-lookup interface
638
+ */
639
+ getCoursesDB(): CoursesDBInterface;
640
+ /**
641
+ * Get a classroom database interface
642
+ */
643
+ getClassroomDB(classId: string, type: 'student' | 'teacher'): Promise<ClassroomDBInterface>;
644
+ /**
645
+ * Get the admin database interface
646
+ */
647
+ getAdminDB(): AdminDBInterface;
648
+ /**
649
+ * Initialize the data layer
650
+ */
651
+ initialize(): Promise<void>;
652
+ /**
653
+ * Teardown the data layer
654
+ */
655
+ teardown(): Promise<void>;
656
+ }
657
+
658
+ declare function areQuestionRecords(h: CardHistory<CardRecord>): h is CardHistory<QuestionRecord>;
659
+ declare function isQuestionRecord(c: CardRecord): c is QuestionRecord;
660
+ declare function getCardHistoryID(courseID: string, cardID: string): PouchDB.Core.DocumentId;
661
+ declare function parseCardHistoryID(id: string): {
662
+ courseID: string;
663
+ cardID: string;
664
+ };
665
+ interface PouchDBError extends Error {
666
+ error?: string;
667
+ reason?: string;
668
+ }
669
+ declare function docIsDeleted(e: PouchDBError): boolean;
670
+
671
+ declare enum Navigators {
672
+ ELO = "elo"
673
+ }
674
+ /**
675
+ * A content-navigator provides runtime steering of study sessions.
676
+ */
677
+ declare abstract class ContentNavigator implements StudyContentSource {
678
+ /**
679
+ *
680
+ * @param user
681
+ * @param strategyData
682
+ * @returns the runtime object used to steer a study session.
683
+ */
684
+ static create(user: UserDBInterface, course: CourseDBInterface, strategyData: ContentNavigationStrategyData): Promise<ContentNavigator>;
685
+ abstract getPendingReviews(): Promise<(StudySessionReviewItem & ScheduledCard)[]>;
686
+ abstract getNewCards(n?: number): Promise<StudySessionNewItem[]>;
687
+ }
688
+
689
+ /**
690
+ * Interface representing the result of a bulk import operation for a single card
691
+ */
692
+ interface ImportResult {
693
+ /** The original text input for the card */
694
+ originalText: string;
695
+ /** Status of the import operation */
696
+ status: 'success' | 'error';
697
+ /** Message describing the result or error */
698
+ message: string;
699
+ /** ID of the newly created card (only for success) */
700
+ cardId?: string;
701
+ }
702
+ /**
703
+ * Configuration for the bulk card processor
704
+ */
705
+ interface BulkCardProcessorConfig {
706
+ /** The data shape to use for the cards */
707
+ dataShape: DataShape;
708
+ /** The course code used for adding notes */
709
+ courseCode: string;
710
+ /** The username of the current user */
711
+ userName: string;
712
+ }
713
+
714
+ /**
715
+ * Processes multiple cards from bulk text input
716
+ *
717
+ * @param parsedCards - Array of parsed cards to import
718
+ * @param courseDB - Course database interface
719
+ * @param config - Configuration for the card processor
720
+ * @returns Array of import results
721
+ */
722
+ declare function importParsedCards(parsedCards: ParsedCard[], courseDB: CourseDBInterface, config: BulkCardProcessorConfig): Promise<ImportResult[]>;
723
+ /**
724
+ * Validates the configuration for bulk card processing
725
+ *
726
+ * @param config - Configuration to validate
727
+ * @returns Object with validation result and error message if any
728
+ */
729
+ declare function validateProcessorConfig(config: Partial<BulkCardProcessorConfig>): {
730
+ isValid: boolean;
731
+ errorMessage?: string;
732
+ };
733
+
734
+ export { getCardHistoryID as $, type AdminDBInterface as A, type SkuilderCourseData as B, type CardRecord as C, type DataLayerProvider as D, type Tag as E, type TagStub as F, GuestUsername as G, type CardData as H, type CourseListData as I, type DisplayableData as J, type Field as K, Loggable as L, type DataShapeData as M, cardHistoryPrefix as N, type CardHistory as O, type QuestionRecord as P, type QuestionData as Q, type UserConfig as R, type StudySessionItem as S, type TeacherClassroomDBInterface as T, type UserDBInterface as U, type ActivityRecord as V, type CourseRegistration as W, type CourseRegistrationDoc as X, type ScheduledCard as Y, areQuestionRecords as Z, isQuestionRecord as _, type StudyContentSource as a, parseCardHistoryID as a0, docIsDeleted as a1, Navigators as a2, ContentNavigator as a3, importParsedCards as a4, validateProcessorConfig as a5, type ImportResult as a6, type BulkCardProcessorConfig as a7, type DocumentUpdater as a8, newInterval as a9, type ClassroomDBInterface as b, type StudentClassroomDBInterface as c, type AssignedContent as d, type AssignedTag as e, type AssignedCourse as f, type AssignedCard as g, type StudySessionFailedItem as h, type StudySessionFailedNewItem as i, type StudySessionFailedReviewItem as j, type StudySessionNewItem as k, type StudySessionReviewItem as l, isReview as m, type ContentSourceID as n, getStudySource as o, type CoursesDBInterface as p, type CourseInfo as q, type CourseDBInterface as r, type UserCourseSettings as s, type UserCourseSetting as t, type UsrCrsDataInterface as u, type ClassroomRegistrationDesignation as v, type ClassroomRegistration as w, type ClassroomRegistrationDoc as x, log as y, DocType as z };