@bdelab/roar-firekit
Version:
A library to facilitate Firebase authentication and Cloud Firestore interaction for ROAR apps
180 lines (179 loc) • 6.37 kB
TypeScript
import { DocumentReference } from 'firebase/firestore';
import { RoarTaskVariant } from './task';
import { RoarAppUser } from './user';
import { OrgLists } from '../../interfaces';
/**
* Convert a trial data to allow storage on Cloud Firestore.
*
* This function leaves all other trial data intact but converts
* any URL object to a string.
*
* @function
* @param {Object} trialData - Trial data to convert
* @returns {Object} Converted trial data
*/
export declare const convertTrialToFirestore: (trialData: object) => object;
interface SummaryScores {
thetaEstimate: number | null;
thetaSE: number | null;
numAttempted: number;
numCorrect: number;
numIncorrect: number;
}
export interface RawScores {
[key: string]: {
practice: SummaryScores;
test: SummaryScores;
};
}
export interface ComputedScores {
[key: string]: unknown;
}
interface RunScores {
raw: RawScores;
computed: ComputedScores;
}
export interface RunInput {
user: RoarAppUser;
task: RoarTaskVariant;
assigningOrgs?: OrgLists;
readOrgs?: OrgLists;
assignmentId?: string;
runId?: string;
testData?: boolean;
demoData?: boolean;
}
declare type Event = 'blur' | 'focus' | 'fullscreenenter' | 'fullscreenexit';
export interface TrialData {
assessment_stage: string;
correct: boolean;
subtask?: string;
thetaEstimate?: number | null;
thetaSE?: number | null;
thetas?: {
[key: string]: number | null;
};
thetaSEs?: {
[key: string]: number | null;
};
[key: string]: unknown;
}
export interface InteractionEvent {
event: Event;
trial: number;
time: number;
}
interface InteractionSummary<T> {
blur?: T;
focus?: T;
fullscreenenter?: T;
fullscreenexit?: T;
}
/**
* Class representing a ROAR run.
*
* A run is a globally unique collection of successive trials that constitute
* one user "running" through a single assessment one time.
*/
export declare class RoarRun {
user: RoarAppUser;
task: RoarTaskVariant;
runRef: DocumentReference;
assigningOrgs?: OrgLists;
readOrgs?: OrgLists;
assignmentId?: string;
started: boolean;
completed: boolean;
aborted: boolean;
testData: boolean;
demoData: boolean;
scores: RunScores;
runInteractionIncrements: InteractionSummary<boolean>;
trialInteractions: InteractionSummary<number[]>;
/** Create a ROAR run
* @param {RunInput} input
* @param {RoarAppUser} input.user - The user running the task
* @param {RoarTaskVariant} input.task - The task variant being run
* @param {OrgLists} input.assigningOrgs - The IDs of the orgs to which this run belongs
* @param {OrgLists} input.readOrgs - The IDs of the orgs which can read this run
* @param {string} input.assignmentId = The ID of the assignment
* @param {string} input.runId = The ID of the run. If undefined, a new run will be created.
* @param {string} input.testData = Boolean flag indicating test data
* @param {string} input.demoData = Boolean flag indicating demo data
*/
constructor({ user, task, assigningOrgs, readOrgs, assignmentId, runId, testData, demoData, }: RunInput);
/**
* Reset the interaction data for the current trial
*/
resetInteractions(): void;
/**
* Add interaction data for the current trial.
*
* This will keep a running log of interaction data for the current trial.
* The log will be reset after each `writeTrial` call.
*
* @param {InteractionEvent} interaction - Interaction event
*/
addInteraction(interaction: InteractionEvent): void;
/**
* Writes interaction data for the current trial and updates run-level counters.
*
* This method saves the interaction data collected during the current trial to Firestore.
* It performs two writes:
* 1. Updates the trial document with detailed interaction data (e.g., timestamps).
* 2. Increments counters on the run document to track how many times each interaction type occurred
* (e.g., blur, focus) during a specific assessment stage (e.g., practice, test).
*
* After writing, the interaction data is reset for the next trial.
*
* @param assessmentStage - The current stage of the assessment (e.g., "practice", "test")
* @param trialDocRef - Reference to the Firestore document representing the current trial
*/
writeInteractions(assessmentStage: string, trialDocRef: DocumentReference): Promise<void>;
/**
* Create a new run on Firestore
* @method
* @async
*/
startRun(additionalRunMetadata?: {
[key: string]: unknown;
}): Promise<void>;
/**
* Add engagement flags to a run.
* @method
* @async
* @param {string[]} engagementFlags - Engagement flags to add to the run
* @param {boolean} markAsReliable - Whether or not to mark the run as reliable, defaults to false
* @param {Object} reliableByBlock - Stores the reliability of the run by block
* This is an optional parameter that needs only to be passed in for block scoped tasks
* For Example: {DEL: false, FSM: true, LSM: false}
*
* Please note that calling this function with a new set of engagement flags will
* overwrite the previous set.
*/
addEngagementFlags(engagementFlags: string[], markAsReliable?: boolean, reliableByBlock?: undefined): Promise<void>;
/**
* Mark this run as complete on Firestore
* @method
* @async
* @param {Object} [finishingMetaData={}] - Optional metadata to include when marking the run as complete.
* @returns {Promise<boolean | undefined>} - Resolves when the run has been marked as complete.
* @throws {Error} - Throws an error if the run has not been started yet.
*/
finishRun(finishingMetaData?: {
[key: string]: unknown;
}): Promise<boolean | undefined>;
/**
* Abort this run, preventing it from completing
* @method
*/
abortRun(): void;
/**
* Add a new trial to this run on Firestore
* @method
* @async
* @param {*} trialData - An object containing trial data.
*/
writeTrial(trialData: TrialData, computedScoreCallback?: (rawScores: RawScores) => Promise<ComputedScores>): Promise<void>;
}
export {};