import { ColorPaletteName } from "../colorPaletteName" ; import { EntityBase , EntityType } from "../entity" ; import { AttachmentID } from "./attachmentReference" ; export { parseSingleCurlyBraceClozePromptMarkup } from "./util/parseClozeMarkup" ; export interface Task < TC extends TaskContent = TaskContent > extends EntityBase < EntityType . Task , TaskID > { id : TaskID ; spec : TaskSpec < TC > ; provenance : TaskProvenance | null ; /**
     * Tasks may have several "components", each of which has its scheduling state separately tracked. For instance, cloze tasks have one component for each deletion. QA prompts just have one "main" component for now, but if we ever support double-sided flashcards, they'd have two, and so on.
     */ componentStates : TaskComponentStates < TC > ; isDeleted : boolean ; metadata : { [ key ] : string ; } ; } additionalProperties export type TaskComponentStates < TC extends TaskContent > = { [ ComponentID in ComponentIDsOf < TC > ] : TaskComponentState ; } ; export interface TaskComponentState { createdAtTimestampMillis : number ; lastRepetitionTimestampMillis : number | null ; intervalMillis : number ; dueTimestampMillis : number ; } TJS-type TJS-pattern export type TaskID = string & { __taskIDOpaqueType : never ; } ; export type TaskSpec < TC extends TaskContent = TaskContent > = MemoryTaskSpec < TC > ; export type MemoryTaskSpec < TC extends TaskContent > = TaskSpecBase < TaskSpecType . Memory , TC > ; interface TaskSpecBase < TST extends TaskSpecType , TC extends TaskContent > { type : TST ; content : TC ; } export enum TaskSpecType { Memory = "memory" } export type TaskContent = QATaskContent | ClozeTaskContent | PlainTaskContent ; export const mainTaskComponentID = "main" ; export type MainTaskComponentID = typeof mainTaskComponentID ; export interface QATaskContent extends TaskContentBase < TaskContentType . QA , MainTaskComponentID , undefined > { body : TaskContentField ; answer : TaskContentField ; } export interface ClozeTaskContent extends TaskContentBase < TaskContentType . Cloze , string , { [ ClozeID ] : ClozeTaskContentComponent ; } > { body : TaskContentField ; } export interface ClozeTaskContentComponent extends TaskContentComponent { ranges : { startIndex : number ; length : number ; hint : string | null ; } [ ] ; } export interface PlainTaskContent extends TaskContentBase < TaskContentType . Plain , MainTaskComponentID , undefined > { type : TaskContentType . Plain ; body : TaskContentField ; } type TaskContentBase < TCT extends TaskContentType , ComponentIDs extends string , ComponentData extends { [ ComponentID in ComponentIDs ] : TaskContentComponent ; } | undefined > = { type : TCT ; } & ( ComponentData extends undefined ? unknown : { components : ComponentData ; } ) ; export enum TaskContentType { QA = "qa" , Cloze = "cloze" , Plain = "plain" } export interface TaskContentComponent { order : number ; } export type ComponentIDsOf < TC extends TaskContent > = TC extends TaskContentBase < any , infer ComponentIDs , any > ? ComponentIDs : never ; export interface TaskContentField { text : string ; attachments : AttachmentID [ ] ; } export interface TaskProvenance { identifier : string ; url ? : string ; title ? : string ; containerTitle ? : string ; colorPaletteName ? : ColorPaletteName ; }