import { SCORM12, SCORM2004 } from './data-model.js'; import { ScormWrapper } from './api-adapter.js'; import type { Scorm2004Mode, Scorm2004Credit, Scorm2004Entry, ScormVersion } from './types.js'; import { ScoreState } from './score-state.svelte.js'; import { CompletionState } from './completion-state.svelte.js'; import { PersistentStore } from './persistent-store.svelte.js'; import { StandardStorageEngine, ChunkedStorageEngine } from './storage/index.js'; import type { StorageMode } from './storage/index.js'; export interface InitializeOptions { courseId: string; minScore: number; maxScore: number; storageMode?: StorageMode; } class StudentState { #id = $state(''); #name = $state(''); get id(): string { return this.#id; } get name(): string { return this.#name; } load(wrapper: ScormWrapper): void { const isV2004 = wrapper.version === '2004'; this.#id = wrapper.getValue(isV2004 ? SCORM2004.LEARNER_ID : SCORM12.CORE_STUDENT_ID); this.#name = wrapper.getValue(isV2004 ? SCORM2004.LEARNER_NAME : SCORM12.CORE_STUDENT_NAME); } } class SessionState { #mode = $state('normal'); #credit = $state('credit'); #entry = $state('ab-initio'); get mode(): Scorm2004Mode { return this.#mode; } get credit(): Scorm2004Credit { return this.#credit; } get entry(): Scorm2004Entry | 'ab-initio' { return this.#entry; } load(wrapper: ScormWrapper): void { const isV2004 = wrapper.version === '2004'; this.#mode = wrapper.getValue( isV2004 ? SCORM2004.MODE : SCORM12.CORE_LESSON_MODE ) as Scorm2004Mode; this.#credit = wrapper.getValue( isV2004 ? SCORM2004.CREDIT : SCORM12.CORE_CREDIT ) as Scorm2004Credit; this.#entry = wrapper.getValue(isV2004 ? SCORM2004.ENTRY : SCORM12.CORE_ENTRY) as | Scorm2004Entry | 'ab-initio'; } } export class ScormState { #wrapper = new ScormWrapper(); #sessionStart = 0; #location = $state(''); readonly student: StudentState; readonly session: SessionState; readonly score: ScoreState; readonly completion: CompletionState; readonly store: PersistentStore; isConnected = $state(false); isInitialized = $state(false); version = $state(); mode = $state<'lms' | 'dev'>('dev'); constructor() { this.student = new StudentState(); this.session = new SessionState(); this.score = new ScoreState(this.#wrapper); this.completion = new CompletionState(this.#wrapper); this.store = new PersistentStore(); } get location(): string { return this.#location; } set location(value: string) { this.#location = value; const element = this.#wrapper.version === '2004' ? SCORM2004.LOCATION : SCORM12.CORE_LESSON_LOCATION; this.#wrapper.setValue(element, value); this.#wrapper.commit(); } initialize({ courseId, minScore, maxScore, storageMode = 'standard' }: InitializeOptions): boolean { this.mode = this.#wrapper.connect(courseId); this.isConnected = true; const result = this.#wrapper.initialize(); this.isInitialized = result; this.version = this.#wrapper.version; this.student.load(this.#wrapper); this.session.load(this.#wrapper); this.score.load(this.#wrapper); this.score._setRange(minScore, maxScore); this.completion.load(this.#wrapper); const isV2004 = this.#wrapper.version === '2004'; this.#location = this.#wrapper.getValue( isV2004 ? SCORM2004.LOCATION : SCORM12.CORE_LESSON_LOCATION ); this.#sessionStart = Date.now(); const engine = storageMode === 'chunked' ? new ChunkedStorageEngine() : new StandardStorageEngine(); this.store._setEngine(engine, this.#wrapper); this.store._load(this.#wrapper); return result; } get sessionStartTime(): number { return this.isInitialized ? this.#sessionStart : 0; } get sessionElapsedMs(): number { return this.isInitialized ? Date.now() - this.#sessionStart : 0; } commit(): void { this.#wrapper.commit(); } terminate(): void { if (!this.isInitialized) return; this.isInitialized = false; const elapsed = Date.now() - this.#sessionStart; const sessionTime = this.#wrapper.formatSessionTime(elapsed); const timeElement = this.#wrapper.version === '2004' ? SCORM2004.SESSION_TIME : SCORM12.CORE_SESSION_TIME; this.#wrapper.setValue(timeElement, sessionTime); this.#wrapper.commit(); this.#wrapper.terminate(); } } export const scormState = new ScormState();