@lessonkit/core 1.6.0 → 1.7.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.
- package/README.md +1 -1
- package/dist/{chunk-NGCHHJSM.js → chunk-DTJGIMUU.js} +96 -37
- package/dist/index.cjs +197 -45
- package/dist/index.d.cts +43 -10
- package/dist/index.d.ts +43 -10
- package/dist/index.js +95 -9
- package/dist/{testing-CzgxF1Ru.d.cts → testing-CQ-ZsT7D.d.cts} +38 -4
- package/dist/{testing-CzgxF1Ru.d.ts → testing-CQ-ZsT7D.d.ts} +38 -4
- package/dist/testing.cjs +2 -0
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CourseId, L as LessonId, a as CheckId, B as BlockId, I as IdentityIdPath, b as IdentityValidationResult, c as LessonkitUrn, A as AssessmentResumeState, S as StoragePort, T as TelemetryEventName, d as TelemetrySink, e as TelemetryBatchSink, f as TrackingClient, g as TelemetryEvent, h as TelemetryUser, i as LessonkitPlugin, P as PluginRegistry, j as ProgressController, k as PluginHost, l as ProgressState, m as TelemetryDataFor, n as AssessmentScoreInput, o as AssessmentScoreResult, p as ClockPort, q as AssessmentPlugin, r as LifecyclePlugin, s as TelemetryPlugin, t as LessonkitPluginContext } from './testing-
|
|
2
|
-
export { u as AccordionSectionToggledData, v as AssessmentAnsweredData, w as AssessmentBaseProps, x as AssessmentBehaviour, y as AssessmentCompletedData, z as AssessmentHandle, D as AssessmentInteractionType, E as AssessmentXAPIData, F as BookPageViewedData, G as BranchNodeViewedData, H as BranchSelectedData, J as BuildTelemetryEventInput, K as CompoundPageViewedData,
|
|
1
|
+
import { C as CourseId, L as LessonId, a as CheckId, B as BlockId, I as IdentityIdPath, b as IdentityValidationResult, c as LessonkitUrn, M as McqAssessmentProps, A as AssessmentResumeState, S as StoragePort, T as TelemetryEventName, d as TelemetrySink, e as TelemetryBatchSink, f as TrackingClient, g as TelemetryEvent, h as TelemetryUser, i as LessonkitPlugin, P as PluginRegistry, j as ProgressController, k as PluginHost, l as ProgressState, m as TelemetryDataFor, n as AssessmentScoreInput, o as AssessmentScoreResult, p as ClockPort, q as AssessmentPlugin, r as LifecyclePlugin, s as TelemetryPlugin, t as LessonkitPluginContext } from './testing-CQ-ZsT7D.js';
|
|
2
|
+
export { u as AccordionSectionToggledData, v as AssessmentAnsweredData, w as AssessmentBaseProps, x as AssessmentBehaviour, y as AssessmentCompletedData, z as AssessmentHandle, D as AssessmentInteractionType, E as AssessmentXAPIData, F as BookPageViewedData, G as BranchNodeViewedData, H as BranchSelectedData, J as BuildTelemetryEventInput, K as CompoundPageViewedData, N as CourseLifecycleContext, O as CourseLifecycleDeps, Q as FlashcardFlippedData, R as HotspotOpenedData, U as ID_MAX_LENGTH, V as ID_PATTERN, W as IdentityValidationIssue, X as ImageSliderChangedData, Y as InformationWallSearchData, Z as InteractionBlockRegistration, _ as InteractionData, $ as InteractionPlugin, a0 as InvalidSessionIdContext, a1 as LessonCompletionEmitter, a2 as LessonLifecycleData, a3 as LessonkitPluginKind, a4 as MemoryCardFlippedData, a5 as ParallaxSlideViewedData, a6 as PluginIdentity, a7 as QuestionnaireSubmittedData, a8 as QuizAnsweredData, a9 as QuizCompletedData, aa as ResolveSessionIdOptions, ab as SESSION_STORAGE_KEY, ac as SlideViewedData, ad as TelemetryEventBase, ae as TimerPort, af as VideoCueReachedData, ag as VideoSegmentCompletedData, ah as buildCourseStartedTelemetryEvent, ai as buildTelemetryEvent, aj as completeCourseWithTelemetry, ak as completeLessonWithTelemetry, al as createDefaultClock, am as createGlobalTimer, an as createNoopStorage, ao as createProgressController, ap as createSessionStoragePort, aq as getTabSessionId, ar as hasCourseStarted, as as hasCourseStartedEmittedToTracking, at as hasCourseStartedPipelineDelivered, au as hasCourseStartedXapiSent, av as markCourseStarted, aw as markCourseStartedEmittedToTracking, ax as markCourseStartedPipelineDelivered, ay as markCourseStartedXapiSent, az as migrateCourseStartedMark, aA as resetSharedVolatileSessionIdForTests, aB as resetStoragePortForTests, aC as resetTelemetryBuilderWarningsForTests, aD as resolveSessionId, aE as tryBuildTelemetryEvent, aF as tryEmitCourseStarted } from './testing-CQ-ZsT7D.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Exhaustiveness helper for switch/default branches.
|
|
@@ -36,6 +36,22 @@ type LessonkitUrnParts = {
|
|
|
36
36
|
*/
|
|
37
37
|
declare function buildLessonkitUrn(parts: LessonkitUrnParts): LessonkitUrn;
|
|
38
38
|
|
|
39
|
+
type McqScoreResult = {
|
|
40
|
+
score: number;
|
|
41
|
+
maxScore: number;
|
|
42
|
+
exactMatch: boolean;
|
|
43
|
+
hasWrongSelection: boolean;
|
|
44
|
+
passedThreshold: boolean;
|
|
45
|
+
};
|
|
46
|
+
/** Correct answer labels for scoring (multi-select uses `answers` when length > 1). */
|
|
47
|
+
declare function resolveMcqCorrectAnswers(props: Pick<McqAssessmentProps, "answer" | "answers">): Set<string>;
|
|
48
|
+
declare function isMultiSelectMcq(props: Pick<McqAssessmentProps, "answers">): boolean;
|
|
49
|
+
declare function scoreMcqSelection(selected: string | string[] | null | undefined, correct: Set<string>, multi: boolean, passingScore?: number): McqScoreResult;
|
|
50
|
+
/** Deterministic Fisher–Yates shuffle; returns display order indices. */
|
|
51
|
+
declare function shuffleChoiceIndices(length: number, seed: string | number): number[];
|
|
52
|
+
declare function resolveMcqShuffleSeed(props: Pick<McqAssessmentProps, "checkId" | "shuffleSeed">): string | number;
|
|
53
|
+
declare function orderChoicesByIndices(choices: string[], orderIndices: number[]): string[];
|
|
54
|
+
|
|
39
55
|
/** LMS parent-bridge forwarding mode for packaged course runtimes. */
|
|
40
56
|
type LmsBridgeMode = "auto" | "off";
|
|
41
57
|
|
|
@@ -88,21 +104,24 @@ declare function saveCompoundState(storage: StoragePort, courseId: CourseId, com
|
|
|
88
104
|
declare function clearCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): void;
|
|
89
105
|
|
|
90
106
|
/** Canonical compound child allowlists (H5P sub-content curation). */
|
|
91
|
-
|
|
107
|
+
/** Tier B P1 assessments shipped in framework 1.7.0. */
|
|
108
|
+
declare const ASSESSMENT_17_CHILD_TYPES: readonly ["SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
|
|
109
|
+
declare const PAGE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "ProgressTracker", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
|
|
92
110
|
/** Branch node content (Page-like minus ProgressTracker). */
|
|
93
|
-
declare const BRANCH_NODE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "BranchChoice"];
|
|
111
|
+
declare const BRANCH_NODE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "BranchChoice", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
|
|
94
112
|
declare const BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES: readonly ["BranchNode"];
|
|
95
113
|
declare const GAME_MAP_ALLOWED_CHILD_TYPES: readonly ["MapStage"];
|
|
96
114
|
/** Map stage content (BranchNode parity; WordSearch excluded from compounds). */
|
|
97
|
-
declare const MAP_STAGE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "MapExit"];
|
|
115
|
+
declare const MAP_STAGE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "MapExit", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
|
|
98
116
|
declare const INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES: readonly ["Page"];
|
|
99
117
|
/** Per-slide content (H5P Course Presentation slide row). Excludes ProgressTracker. */
|
|
100
|
-
declare const SLIDE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar"];
|
|
118
|
+
declare const SLIDE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Video", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
|
|
101
119
|
declare const SLIDE_DECK_ALLOWED_CHILD_TYPES: readonly ["Slide"];
|
|
102
|
-
declare const TIMED_CUE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Quiz", "TrueFalse", "FillInTheBlanks", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "Questionnaire", "Essay", "ArithmeticQuiz"];
|
|
120
|
+
declare const TIMED_CUE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Quiz", "TrueFalse", "FillInTheBlanks", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "Questionnaire", "Essay", "ArithmeticQuiz", "MultimediaChoice", "GuessTheAnswer"];
|
|
103
121
|
declare const INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES: readonly ["TimedCue"];
|
|
104
|
-
declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots", "Summary", "ImagePairing", "ImageSequencing", "ArithmeticQuiz", "Essay"];
|
|
105
|
-
|
|
122
|
+
declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots", "Summary", "ImagePairing", "ImageSequencing", "ArithmeticQuiz", "Essay", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
|
|
123
|
+
declare const SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES: readonly ["Quiz", "KnowledgeCheck"];
|
|
124
|
+
type CompoundParentType = "Page" | "InteractiveBook" | "Slide" | "SlideDeck" | "TimedCue" | "InteractiveVideo" | "AssessmentSequence" | "BranchingScenario" | "BranchNode" | "GameMap" | "MapStage" | "SingleChoiceSet";
|
|
106
125
|
declare const COMPOUND_MAX_NESTING_DEPTH: Record<CompoundParentType, number>;
|
|
107
126
|
declare function getAllowedChildTypes(parent: CompoundParentType): readonly string[];
|
|
108
127
|
declare function isChildTypeAllowed(parent: CompoundParentType, childType: string): boolean;
|
|
@@ -290,9 +309,23 @@ type HeadlessLessonkitRuntime = {
|
|
|
290
309
|
* runtime.setActiveLesson("lesson-1");
|
|
291
310
|
* runtime.track("interaction", { label: "opened" }, { lessonId: "lesson-1" });
|
|
292
311
|
* ```
|
|
312
|
+
*
|
|
313
|
+
* @throws When plugin registry setup fails or tracking batch config is invalid (same rules as React provider).
|
|
293
314
|
*/
|
|
294
315
|
declare function createLessonkitRuntime(config: HeadlessLessonkitConfig, ports?: HeadlessRuntimePorts): HeadlessLessonkitRuntime;
|
|
295
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Register framework plugins (telemetry, assessment scoring, lifecycle hooks).
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```ts
|
|
322
|
+
* import { createPluginRegistry, defineTelemetryPlugin } from "@lessonkit/core";
|
|
323
|
+
*
|
|
324
|
+
* const plugins = createPluginRegistry([
|
|
325
|
+
* defineTelemetryPlugin({ id: "analytics-bridge", setup: () => {} }),
|
|
326
|
+
* ]);
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
296
329
|
declare function createPluginRegistry(plugins?: readonly LessonkitPlugin[]): PluginRegistry;
|
|
297
330
|
|
|
298
331
|
/**
|
|
@@ -354,4 +387,4 @@ declare function buildPluginContext(opts: {
|
|
|
354
387
|
user?: TelemetryUser;
|
|
355
388
|
}): LessonkitPluginContext;
|
|
356
389
|
|
|
357
|
-
export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, AssessmentPlugin, AssessmentResumeState, AssessmentScoreInput, AssessmentScoreResult, BLOCKS_14_PAGE_SLIDE, BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES, BRANCH_NODE_ALLOWED_CHILD_TYPES, BlockId, type BranchGraphNodeInput, type BranchGraphValidationIssue, type BranchGraphValidationResult, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, CheckId, ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, CourseId, type EmitContext, GAME_MAP_ALLOWED_CHILD_TYPES, type HeadlessLessonkitConfig, type HeadlessLessonkitRuntime, type HeadlessRuntimePorts, INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES, INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES, IdentityIdPath, IdentityValidationResult, LessonId, LessonkitPlugin, LessonkitPluginContext, type LessonkitRuntimeVersion, LessonkitUrn, type LessonkitUrnParts, LifecyclePlugin, type LmsBridgeMode, type LoadCompoundStateOptions, MAP_STAGE_ALLOWED_CHILD_TYPES, PAGE_ALLOWED_CHILD_TYPES, type ParseCompoundResumeStateOptions, PluginHost, PluginRegistry, ProgressController, ProgressState, SLIDE_ALLOWED_CHILD_TYPES, SLIDE_DECK_ALLOWED_CHILD_TYPES, StoragePort, TELEMETRY_EVENT_CATALOG, TELEMETRY_EVENT_CATALOG_V2, TELEMETRY_EVENT_CATALOG_V3, TIMED_CUE_ALLOWED_CHILD_TYPES, TelemetryBatchSink, type TelemetryCatalogEntry, type TelemetryCatalogV2Entry, type TelemetryCatalogV3Entry, TelemetryDataFor, type TelemetryEmitFn, TelemetryEvent, TelemetryEventName, type TelemetryPipeline, type TelemetryPipelineSink, TelemetryPlugin, TelemetrySink, TelemetryUser, TrackingClient, assertNever, assertValidId, buildLessonkitUrn, buildPluginContext, buildTelemetryCatalog, buildTelemetryCatalogV2, buildTelemetryCatalogV3, clampCompoundPageIndex, clearCompoundState, compoundStateStorageKey, createCompoundResumeState, createLessonkitRuntime, createPluginRegistry, createSessionId, createTelemetryPipeline, createTrackingClient, createTrackingPipelineSink, defineAssessmentPlugin, defineLifecyclePlugin, defineTelemetryPlugin, deriveId, getAllowedChildTypes, isChildTypeAllowed, isLifecycleTelemetryEvent, loadCompoundState, nowIso, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, saveCompoundState, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, validateBranchGraph, validateId };
|
|
390
|
+
export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_17_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, AssessmentPlugin, AssessmentResumeState, AssessmentScoreInput, AssessmentScoreResult, BLOCKS_14_PAGE_SLIDE, BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES, BRANCH_NODE_ALLOWED_CHILD_TYPES, BlockId, type BranchGraphNodeInput, type BranchGraphValidationIssue, type BranchGraphValidationResult, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, CheckId, ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, CourseId, type EmitContext, GAME_MAP_ALLOWED_CHILD_TYPES, type HeadlessLessonkitConfig, type HeadlessLessonkitRuntime, type HeadlessRuntimePorts, INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES, INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES, IdentityIdPath, IdentityValidationResult, LessonId, LessonkitPlugin, LessonkitPluginContext, type LessonkitRuntimeVersion, LessonkitUrn, type LessonkitUrnParts, LifecyclePlugin, type LmsBridgeMode, type LoadCompoundStateOptions, MAP_STAGE_ALLOWED_CHILD_TYPES, McqAssessmentProps, type McqScoreResult, PAGE_ALLOWED_CHILD_TYPES, type ParseCompoundResumeStateOptions, PluginHost, PluginRegistry, ProgressController, ProgressState, SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES, SLIDE_ALLOWED_CHILD_TYPES, SLIDE_DECK_ALLOWED_CHILD_TYPES, StoragePort, TELEMETRY_EVENT_CATALOG, TELEMETRY_EVENT_CATALOG_V2, TELEMETRY_EVENT_CATALOG_V3, TIMED_CUE_ALLOWED_CHILD_TYPES, TelemetryBatchSink, type TelemetryCatalogEntry, type TelemetryCatalogV2Entry, type TelemetryCatalogV3Entry, TelemetryDataFor, type TelemetryEmitFn, TelemetryEvent, TelemetryEventName, type TelemetryPipeline, type TelemetryPipelineSink, TelemetryPlugin, TelemetrySink, TelemetryUser, TrackingClient, assertNever, assertValidId, buildLessonkitUrn, buildPluginContext, buildTelemetryCatalog, buildTelemetryCatalogV2, buildTelemetryCatalogV3, clampCompoundPageIndex, clearCompoundState, compoundStateStorageKey, createCompoundResumeState, createLessonkitRuntime, createPluginRegistry, createSessionId, createTelemetryPipeline, createTrackingClient, createTrackingPipelineSink, defineAssessmentPlugin, defineLifecyclePlugin, defineTelemetryPlugin, deriveId, getAllowedChildTypes, isChildTypeAllowed, isLifecycleTelemetryEvent, isMultiSelectMcq, loadCompoundState, nowIso, orderChoicesByIndices, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, resolveMcqCorrectAnswers, resolveMcqShuffleSeed, saveCompoundState, scoreMcqSelection, shuffleChoiceIndices, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, validateBranchGraph, validateId };
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
tryEmitCourseStarted,
|
|
37
37
|
validateId,
|
|
38
38
|
warnDev
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-DTJGIMUU.js";
|
|
40
40
|
|
|
41
41
|
// src/assertNever.ts
|
|
42
42
|
function assertNever(value, message = "Unexpected value") {
|
|
@@ -126,6 +126,69 @@ function buildLessonkitUrn(parts) {
|
|
|
126
126
|
return urn;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
// src/mcqAssessment.ts
|
|
130
|
+
function resolveMcqCorrectAnswers(props) {
|
|
131
|
+
if (props.answers && props.answers.length > 1) {
|
|
132
|
+
return new Set(props.answers.map((a) => a.trim()).filter(Boolean));
|
|
133
|
+
}
|
|
134
|
+
const single = props.answers?.[0]?.trim() ?? props.answer.trim();
|
|
135
|
+
return new Set(single ? [single] : []);
|
|
136
|
+
}
|
|
137
|
+
function isMultiSelectMcq(props) {
|
|
138
|
+
return (props.answers?.length ?? 0) > 1;
|
|
139
|
+
}
|
|
140
|
+
function scoreMcqSelection(selected, correct, multi, passingScore) {
|
|
141
|
+
const maxScore = multi ? Math.max(correct.size, 1) : 1;
|
|
142
|
+
if (!selected || Array.isArray(selected) && selected.length === 0) {
|
|
143
|
+
return {
|
|
144
|
+
score: 0,
|
|
145
|
+
maxScore,
|
|
146
|
+
exactMatch: false,
|
|
147
|
+
hasWrongSelection: false,
|
|
148
|
+
passedThreshold: false
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const selectedSet = new Set(
|
|
152
|
+
(Array.isArray(selected) ? selected : [selected]).map((s) => s.trim()).filter(Boolean)
|
|
153
|
+
);
|
|
154
|
+
let score = 0;
|
|
155
|
+
for (const label of selectedSet) {
|
|
156
|
+
if (correct.has(label)) score += 1;
|
|
157
|
+
}
|
|
158
|
+
const hasWrongSelection = [...selectedSet].some((label) => !correct.has(label));
|
|
159
|
+
const exactMatch = !hasWrongSelection && selectedSet.size === correct.size && [...correct].every((label) => selectedSet.has(label));
|
|
160
|
+
const threshold = passingScore ?? maxScore;
|
|
161
|
+
const passedThreshold = score >= threshold && !hasWrongSelection;
|
|
162
|
+
return { score, maxScore, exactMatch, hasWrongSelection, passedThreshold };
|
|
163
|
+
}
|
|
164
|
+
function hashSeedToNumber(seed) {
|
|
165
|
+
if (typeof seed === "number" && Number.isFinite(seed)) return Math.abs(Math.trunc(seed)) || 1;
|
|
166
|
+
let hash = 2166136261;
|
|
167
|
+
const text = String(seed);
|
|
168
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
169
|
+
hash ^= text.charCodeAt(i);
|
|
170
|
+
hash = Math.imul(hash, 16777619);
|
|
171
|
+
}
|
|
172
|
+
return hash >>> 0 || 1;
|
|
173
|
+
}
|
|
174
|
+
function shuffleChoiceIndices(length, seed) {
|
|
175
|
+
const indices = Array.from({ length }, (_, i) => i);
|
|
176
|
+
if (length <= 1) return indices;
|
|
177
|
+
let state = hashSeedToNumber(seed);
|
|
178
|
+
for (let i = length - 1; i > 0; i -= 1) {
|
|
179
|
+
state = Math.imul(state, 1664525) + 1013904223 >>> 0;
|
|
180
|
+
const j = state % (i + 1);
|
|
181
|
+
[indices[i], indices[j]] = [indices[j], indices[i]];
|
|
182
|
+
}
|
|
183
|
+
return indices;
|
|
184
|
+
}
|
|
185
|
+
function resolveMcqShuffleSeed(props) {
|
|
186
|
+
return props.shuffleSeed ?? props.checkId;
|
|
187
|
+
}
|
|
188
|
+
function orderChoicesByIndices(choices, orderIndices) {
|
|
189
|
+
return orderIndices.map((index) => choices[index] ?? "").filter((c) => c.length > 0);
|
|
190
|
+
}
|
|
191
|
+
|
|
129
192
|
// src/compound.ts
|
|
130
193
|
var COMPOUND_RESUME_SCHEMA_VERSION = 1;
|
|
131
194
|
function createCompoundResumeState(input = {}) {
|
|
@@ -231,6 +294,11 @@ function clearCompoundState(storage, courseId, compoundId) {
|
|
|
231
294
|
}
|
|
232
295
|
|
|
233
296
|
// src/compoundAllowlists.ts
|
|
297
|
+
var ASSESSMENT_17_CHILD_TYPES = [
|
|
298
|
+
"SortParagraphs",
|
|
299
|
+
"GuessTheAnswer",
|
|
300
|
+
"MultimediaChoice"
|
|
301
|
+
];
|
|
234
302
|
var PAGE_AND_SLIDE_14_BLOCKS = [
|
|
235
303
|
"Video",
|
|
236
304
|
"Summary",
|
|
@@ -285,7 +353,8 @@ var PAGE_ALLOWED_CHILD_TYPES = [
|
|
|
285
353
|
"QrContent",
|
|
286
354
|
"Crossword",
|
|
287
355
|
"AdventCalendar",
|
|
288
|
-
"ProgressTracker"
|
|
356
|
+
"ProgressTracker",
|
|
357
|
+
...ASSESSMENT_17_CHILD_TYPES
|
|
289
358
|
];
|
|
290
359
|
var BRANCH_NODE_ALLOWED_CHILD_TYPES = [
|
|
291
360
|
"Text",
|
|
@@ -329,7 +398,8 @@ var BRANCH_NODE_ALLOWED_CHILD_TYPES = [
|
|
|
329
398
|
"QrContent",
|
|
330
399
|
"Crossword",
|
|
331
400
|
"AdventCalendar",
|
|
332
|
-
"BranchChoice"
|
|
401
|
+
"BranchChoice",
|
|
402
|
+
...ASSESSMENT_17_CHILD_TYPES
|
|
333
403
|
];
|
|
334
404
|
var BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES = ["BranchNode"];
|
|
335
405
|
var GAME_MAP_ALLOWED_CHILD_TYPES = ["MapStage"];
|
|
@@ -375,7 +445,8 @@ var MAP_STAGE_ALLOWED_CHILD_TYPES = [
|
|
|
375
445
|
"QrContent",
|
|
376
446
|
"Crossword",
|
|
377
447
|
"AdventCalendar",
|
|
378
|
-
"MapExit"
|
|
448
|
+
"MapExit",
|
|
449
|
+
...ASSESSMENT_17_CHILD_TYPES
|
|
379
450
|
];
|
|
380
451
|
var INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES = ["Page"];
|
|
381
452
|
var SLIDE_ALLOWED_CHILD_TYPES = [
|
|
@@ -419,7 +490,8 @@ var SLIDE_ALLOWED_CHILD_TYPES = [
|
|
|
419
490
|
"CombinationLock",
|
|
420
491
|
"QrContent",
|
|
421
492
|
"Crossword",
|
|
422
|
-
"AdventCalendar"
|
|
493
|
+
"AdventCalendar",
|
|
494
|
+
...ASSESSMENT_17_CHILD_TYPES
|
|
423
495
|
];
|
|
424
496
|
var SLIDE_DECK_ALLOWED_CHILD_TYPES = ["Slide"];
|
|
425
497
|
var TIMED_CUE_ALLOWED_CHILD_TYPES = [
|
|
@@ -435,7 +507,9 @@ var TIMED_CUE_ALLOWED_CHILD_TYPES = [
|
|
|
435
507
|
"MemoryGame",
|
|
436
508
|
"Questionnaire",
|
|
437
509
|
"Essay",
|
|
438
|
-
"ArithmeticQuiz"
|
|
510
|
+
"ArithmeticQuiz",
|
|
511
|
+
"MultimediaChoice",
|
|
512
|
+
"GuessTheAnswer"
|
|
439
513
|
];
|
|
440
514
|
var INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES = ["TimedCue"];
|
|
441
515
|
var ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES = [
|
|
@@ -452,8 +526,10 @@ var ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES = [
|
|
|
452
526
|
"ImagePairing",
|
|
453
527
|
"ImageSequencing",
|
|
454
528
|
"ArithmeticQuiz",
|
|
455
|
-
"Essay"
|
|
529
|
+
"Essay",
|
|
530
|
+
...ASSESSMENT_17_CHILD_TYPES
|
|
456
531
|
];
|
|
532
|
+
var SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES = ["Quiz", "KnowledgeCheck"];
|
|
457
533
|
var ALLOWLISTS = {
|
|
458
534
|
Page: PAGE_ALLOWED_CHILD_TYPES,
|
|
459
535
|
InteractiveBook: INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES,
|
|
@@ -465,7 +541,8 @@ var ALLOWLISTS = {
|
|
|
465
541
|
BranchingScenario: BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES,
|
|
466
542
|
BranchNode: BRANCH_NODE_ALLOWED_CHILD_TYPES,
|
|
467
543
|
GameMap: GAME_MAP_ALLOWED_CHILD_TYPES,
|
|
468
|
-
MapStage: MAP_STAGE_ALLOWED_CHILD_TYPES
|
|
544
|
+
MapStage: MAP_STAGE_ALLOWED_CHILD_TYPES,
|
|
545
|
+
SingleChoiceSet: SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES
|
|
469
546
|
};
|
|
470
547
|
var COMPOUND_MAX_NESTING_DEPTH = {
|
|
471
548
|
Page: 1,
|
|
@@ -478,7 +555,8 @@ var COMPOUND_MAX_NESTING_DEPTH = {
|
|
|
478
555
|
BranchingScenario: 2,
|
|
479
556
|
BranchNode: 1,
|
|
480
557
|
GameMap: 2,
|
|
481
|
-
MapStage: 1
|
|
558
|
+
MapStage: 1,
|
|
559
|
+
SingleChoiceSet: 1
|
|
482
560
|
};
|
|
483
561
|
function getAllowedChildTypes(parent) {
|
|
484
562
|
return ALLOWLISTS[parent];
|
|
@@ -1528,6 +1606,7 @@ function defineLifecyclePlugin(plugin) {
|
|
|
1528
1606
|
}
|
|
1529
1607
|
export {
|
|
1530
1608
|
ACCORDION_FORBIDDEN_CHILD_TYPES,
|
|
1609
|
+
ASSESSMENT_17_CHILD_TYPES,
|
|
1531
1610
|
ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES,
|
|
1532
1611
|
BLOCKS_14_PAGE_SLIDE,
|
|
1533
1612
|
BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES,
|
|
@@ -1542,6 +1621,7 @@ export {
|
|
|
1542
1621
|
MAP_STAGE_ALLOWED_CHILD_TYPES,
|
|
1543
1622
|
PAGE_ALLOWED_CHILD_TYPES,
|
|
1544
1623
|
SESSION_STORAGE_KEY,
|
|
1624
|
+
SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES,
|
|
1545
1625
|
SLIDE_ALLOWED_CHILD_TYPES,
|
|
1546
1626
|
SLIDE_DECK_ALLOWED_CHILD_TYPES,
|
|
1547
1627
|
TELEMETRY_EVENT_CATALOG,
|
|
@@ -1586,6 +1666,7 @@ export {
|
|
|
1586
1666
|
hasCourseStartedXapiSent,
|
|
1587
1667
|
isChildTypeAllowed,
|
|
1588
1668
|
isLifecycleTelemetryEvent,
|
|
1669
|
+
isMultiSelectMcq,
|
|
1589
1670
|
loadCompoundState,
|
|
1590
1671
|
markCourseStarted,
|
|
1591
1672
|
markCourseStartedEmittedToTracking,
|
|
@@ -1593,6 +1674,7 @@ export {
|
|
|
1593
1674
|
markCourseStartedXapiSent,
|
|
1594
1675
|
migrateCourseStartedMark,
|
|
1595
1676
|
nowIso,
|
|
1677
|
+
orderChoicesByIndices,
|
|
1596
1678
|
parseBlockId,
|
|
1597
1679
|
parseCheckId,
|
|
1598
1680
|
parseCompoundResumeState,
|
|
@@ -1601,8 +1683,12 @@ export {
|
|
|
1601
1683
|
resetSharedVolatileSessionIdForTests,
|
|
1602
1684
|
resetStoragePortForTests,
|
|
1603
1685
|
resetTelemetryBuilderWarningsForTests,
|
|
1686
|
+
resolveMcqCorrectAnswers,
|
|
1687
|
+
resolveMcqShuffleSeed,
|
|
1604
1688
|
resolveSessionId,
|
|
1605
1689
|
saveCompoundState,
|
|
1690
|
+
scoreMcqSelection,
|
|
1691
|
+
shuffleChoiceIndices,
|
|
1606
1692
|
slugifyId,
|
|
1607
1693
|
telemetryCatalogV2Version,
|
|
1608
1694
|
telemetryCatalogV3Version,
|
|
@@ -21,7 +21,7 @@ declare const ID_PATTERN: RegExp;
|
|
|
21
21
|
declare const ID_MAX_LENGTH = 64;
|
|
22
22
|
|
|
23
23
|
/** H5P-aligned interaction kinds for assessment telemetry and xAPI. */
|
|
24
|
-
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence" | "findHotspot" | "findMultipleHotspots" | "summary" | "imagePairing" | "imageSequencing" | "essay" | "arithmeticQuiz" | "memoryGame" | "combinationLock" | "crossword" | "wordSearch";
|
|
24
|
+
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence" | "findHotspot" | "findMultipleHotspots" | "summary" | "imagePairing" | "imageSequencing" | "essay" | "arithmeticQuiz" | "memoryGame" | "combinationLock" | "crossword" | "wordSearch" | "sortParagraphs" | "guessTheAnswer";
|
|
25
25
|
/** Serializable resume blob for a single assessment block. */
|
|
26
26
|
type AssessmentResumeState = Record<string, unknown>;
|
|
27
27
|
/** Behaviour flags aligned with H5P question types. */
|
|
@@ -57,12 +57,34 @@ type AssessmentBaseProps = AssessmentBehaviour & {
|
|
|
57
57
|
checkId: CheckId;
|
|
58
58
|
passingScore?: number;
|
|
59
59
|
};
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* MCQ assessment props shared by React components and LMS packaging descriptors.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const props: McqAssessmentProps = {
|
|
66
|
+
* checkId: "verify-sender",
|
|
67
|
+
* question: "First step for a suspicious email?",
|
|
68
|
+
* choices: ["Open attachment", "Verify sender"],
|
|
69
|
+
* answer: "Verify sender",
|
|
70
|
+
* passingScore: 1,
|
|
71
|
+
* };
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
61
74
|
type McqAssessmentProps = AssessmentBaseProps & {
|
|
62
75
|
kind?: "mcq";
|
|
63
76
|
question: string;
|
|
64
77
|
choices: string[];
|
|
78
|
+
/** Single correct choice (required for backward compatibility). */
|
|
65
79
|
answer: string;
|
|
80
|
+
/** When length > 1, enables multi-select checkbox mode. */
|
|
81
|
+
answers?: string[];
|
|
82
|
+
/** Randomize choice display order in the SPA (stable when `shuffleSeed` set). */
|
|
83
|
+
shuffleChoices?: boolean;
|
|
84
|
+
/** Seed for deterministic shuffle; defaults to `checkId`. */
|
|
85
|
+
shuffleSeed?: string | number;
|
|
86
|
+
/** Per-choice feedback announced on selection; keys match choice labels. */
|
|
87
|
+
choiceFeedback?: Record<string, string>;
|
|
66
88
|
};
|
|
67
89
|
|
|
68
90
|
type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction" | "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed" | "video_cue_reached" | "video_segment_completed" | "memory_card_flipped" | "information_wall_search" | "parallax_slide_viewed" | "questionnaire_submitted" | "branch_node_viewed" | "branch_selected" | "image_juxtaposition_changed" | "timeline_event_viewed" | "image_sequence_changed" | "audio_recording_started" | "audio_recording_completed" | "qr_content_revealed" | "advent_door_opened" | "map_stage_viewed" | "map_exit_selected";
|
|
@@ -602,8 +624,20 @@ type ProgressController = {
|
|
|
602
624
|
declare function createProgressController(): ProgressController;
|
|
603
625
|
|
|
604
626
|
declare const SESSION_STORAGE_KEY = "lessonkit:sessionId";
|
|
627
|
+
type InvalidSessionIdContext = {
|
|
628
|
+
/** The invalid id that was rejected. */
|
|
629
|
+
invalidId: string;
|
|
630
|
+
/** Id actually used after fallback. */
|
|
631
|
+
fallbackId: string;
|
|
632
|
+
/** Whether the invalid id came from config or from stored tab state. */
|
|
633
|
+
source: "provided" | "stored";
|
|
634
|
+
};
|
|
635
|
+
type ResolveSessionIdOptions = {
|
|
636
|
+
/** Invoked when an invalid session id is replaced by a tab or generated id. */
|
|
637
|
+
onInvalidSessionId?: (ctx: InvalidSessionIdContext) => void;
|
|
638
|
+
};
|
|
605
639
|
declare function getTabSessionId(storage: StoragePort): string | null;
|
|
606
|
-
declare function resolveSessionId(storage: StoragePort, provided?: string): string;
|
|
640
|
+
declare function resolveSessionId(storage: StoragePort, provided?: string, options?: ResolveSessionIdOptions): string;
|
|
607
641
|
declare function hasCourseStarted(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
608
642
|
declare function markCourseStarted(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
609
643
|
declare function hasCourseStartedEmittedToTracking(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
@@ -751,4 +785,4 @@ declare function completeCourseWithTelemetry(opts: {
|
|
|
751
785
|
emitCourseCompleted: () => void;
|
|
752
786
|
}): boolean;
|
|
753
787
|
|
|
754
|
-
export { type
|
|
788
|
+
export { type InteractionPlugin as $, type AssessmentResumeState as A, type BlockId as B, type CourseId as C, type AssessmentInteractionType as D, type AssessmentXAPIData as E, type BookPageViewedData as F, type BranchNodeViewedData as G, type BranchSelectedData as H, type IdentityIdPath as I, type BuildTelemetryEventInput as J, type CompoundPageViewedData as K, type LessonId as L, type McqAssessmentProps as M, type CourseLifecycleContext as N, type CourseLifecycleDeps as O, type PluginRegistry as P, type FlashcardFlippedData as Q, type HotspotOpenedData as R, type StoragePort as S, type TelemetryEventName as T, ID_MAX_LENGTH as U, ID_PATTERN as V, type IdentityValidationIssue as W, type ImageSliderChangedData as X, type InformationWallSearchData as Y, type InteractionBlockRegistration as Z, type InteractionData as _, type CheckId as a, type InvalidSessionIdContext as a0, type LessonCompletionEmitter as a1, type LessonLifecycleData as a2, type LessonkitPluginKind as a3, type MemoryCardFlippedData as a4, type ParallaxSlideViewedData as a5, type PluginIdentity as a6, type QuestionnaireSubmittedData as a7, type QuizAnsweredData as a8, type QuizCompletedData as a9, resetSharedVolatileSessionIdForTests as aA, resetStoragePortForTests as aB, resetTelemetryBuilderWarningsForTests as aC, resolveSessionId as aD, tryBuildTelemetryEvent as aE, tryEmitCourseStarted as aF, resetCourseStartedEmitFlightForTests as aG, type ResolveSessionIdOptions as aa, SESSION_STORAGE_KEY as ab, type SlideViewedData as ac, type TelemetryEventBase as ad, type TimerPort as ae, type VideoCueReachedData as af, type VideoSegmentCompletedData as ag, buildCourseStartedTelemetryEvent as ah, buildTelemetryEvent as ai, completeCourseWithTelemetry as aj, completeLessonWithTelemetry as ak, createDefaultClock as al, createGlobalTimer as am, createNoopStorage as an, createProgressController as ao, createSessionStoragePort as ap, getTabSessionId as aq, hasCourseStarted as ar, hasCourseStartedEmittedToTracking as as, hasCourseStartedPipelineDelivered as at, hasCourseStartedXapiSent as au, markCourseStarted as av, markCourseStartedEmittedToTracking as aw, markCourseStartedPipelineDelivered as ax, markCourseStartedXapiSent as ay, migrateCourseStartedMark as az, type IdentityValidationResult as b, type LessonkitUrn as c, type TelemetrySink as d, type TelemetryBatchSink as e, type TrackingClient as f, type TelemetryEvent as g, type TelemetryUser as h, type LessonkitPlugin as i, type ProgressController as j, type PluginHost as k, type ProgressState as l, type TelemetryDataFor as m, type AssessmentScoreInput as n, type AssessmentScoreResult as o, type ClockPort as p, type AssessmentPlugin as q, type LifecyclePlugin as r, type TelemetryPlugin as s, type LessonkitPluginContext as t, type AccordionSectionToggledData as u, type AssessmentAnsweredData as v, type AssessmentBaseProps as w, type AssessmentBehaviour as x, type AssessmentCompletedData as y, type AssessmentHandle as z };
|
|
@@ -21,7 +21,7 @@ declare const ID_PATTERN: RegExp;
|
|
|
21
21
|
declare const ID_MAX_LENGTH = 64;
|
|
22
22
|
|
|
23
23
|
/** H5P-aligned interaction kinds for assessment telemetry and xAPI. */
|
|
24
|
-
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence" | "findHotspot" | "findMultipleHotspots" | "summary" | "imagePairing" | "imageSequencing" | "essay" | "arithmeticQuiz" | "memoryGame" | "combinationLock" | "crossword" | "wordSearch";
|
|
24
|
+
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence" | "findHotspot" | "findMultipleHotspots" | "summary" | "imagePairing" | "imageSequencing" | "essay" | "arithmeticQuiz" | "memoryGame" | "combinationLock" | "crossword" | "wordSearch" | "sortParagraphs" | "guessTheAnswer";
|
|
25
25
|
/** Serializable resume blob for a single assessment block. */
|
|
26
26
|
type AssessmentResumeState = Record<string, unknown>;
|
|
27
27
|
/** Behaviour flags aligned with H5P question types. */
|
|
@@ -57,12 +57,34 @@ type AssessmentBaseProps = AssessmentBehaviour & {
|
|
|
57
57
|
checkId: CheckId;
|
|
58
58
|
passingScore?: number;
|
|
59
59
|
};
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* MCQ assessment props shared by React components and LMS packaging descriptors.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const props: McqAssessmentProps = {
|
|
66
|
+
* checkId: "verify-sender",
|
|
67
|
+
* question: "First step for a suspicious email?",
|
|
68
|
+
* choices: ["Open attachment", "Verify sender"],
|
|
69
|
+
* answer: "Verify sender",
|
|
70
|
+
* passingScore: 1,
|
|
71
|
+
* };
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
61
74
|
type McqAssessmentProps = AssessmentBaseProps & {
|
|
62
75
|
kind?: "mcq";
|
|
63
76
|
question: string;
|
|
64
77
|
choices: string[];
|
|
78
|
+
/** Single correct choice (required for backward compatibility). */
|
|
65
79
|
answer: string;
|
|
80
|
+
/** When length > 1, enables multi-select checkbox mode. */
|
|
81
|
+
answers?: string[];
|
|
82
|
+
/** Randomize choice display order in the SPA (stable when `shuffleSeed` set). */
|
|
83
|
+
shuffleChoices?: boolean;
|
|
84
|
+
/** Seed for deterministic shuffle; defaults to `checkId`. */
|
|
85
|
+
shuffleSeed?: string | number;
|
|
86
|
+
/** Per-choice feedback announced on selection; keys match choice labels. */
|
|
87
|
+
choiceFeedback?: Record<string, string>;
|
|
66
88
|
};
|
|
67
89
|
|
|
68
90
|
type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction" | "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed" | "video_cue_reached" | "video_segment_completed" | "memory_card_flipped" | "information_wall_search" | "parallax_slide_viewed" | "questionnaire_submitted" | "branch_node_viewed" | "branch_selected" | "image_juxtaposition_changed" | "timeline_event_viewed" | "image_sequence_changed" | "audio_recording_started" | "audio_recording_completed" | "qr_content_revealed" | "advent_door_opened" | "map_stage_viewed" | "map_exit_selected";
|
|
@@ -602,8 +624,20 @@ type ProgressController = {
|
|
|
602
624
|
declare function createProgressController(): ProgressController;
|
|
603
625
|
|
|
604
626
|
declare const SESSION_STORAGE_KEY = "lessonkit:sessionId";
|
|
627
|
+
type InvalidSessionIdContext = {
|
|
628
|
+
/** The invalid id that was rejected. */
|
|
629
|
+
invalidId: string;
|
|
630
|
+
/** Id actually used after fallback. */
|
|
631
|
+
fallbackId: string;
|
|
632
|
+
/** Whether the invalid id came from config or from stored tab state. */
|
|
633
|
+
source: "provided" | "stored";
|
|
634
|
+
};
|
|
635
|
+
type ResolveSessionIdOptions = {
|
|
636
|
+
/** Invoked when an invalid session id is replaced by a tab or generated id. */
|
|
637
|
+
onInvalidSessionId?: (ctx: InvalidSessionIdContext) => void;
|
|
638
|
+
};
|
|
605
639
|
declare function getTabSessionId(storage: StoragePort): string | null;
|
|
606
|
-
declare function resolveSessionId(storage: StoragePort, provided?: string): string;
|
|
640
|
+
declare function resolveSessionId(storage: StoragePort, provided?: string, options?: ResolveSessionIdOptions): string;
|
|
607
641
|
declare function hasCourseStarted(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
608
642
|
declare function markCourseStarted(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
609
643
|
declare function hasCourseStartedEmittedToTracking(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
@@ -751,4 +785,4 @@ declare function completeCourseWithTelemetry(opts: {
|
|
|
751
785
|
emitCourseCompleted: () => void;
|
|
752
786
|
}): boolean;
|
|
753
787
|
|
|
754
|
-
export { type
|
|
788
|
+
export { type InteractionPlugin as $, type AssessmentResumeState as A, type BlockId as B, type CourseId as C, type AssessmentInteractionType as D, type AssessmentXAPIData as E, type BookPageViewedData as F, type BranchNodeViewedData as G, type BranchSelectedData as H, type IdentityIdPath as I, type BuildTelemetryEventInput as J, type CompoundPageViewedData as K, type LessonId as L, type McqAssessmentProps as M, type CourseLifecycleContext as N, type CourseLifecycleDeps as O, type PluginRegistry as P, type FlashcardFlippedData as Q, type HotspotOpenedData as R, type StoragePort as S, type TelemetryEventName as T, ID_MAX_LENGTH as U, ID_PATTERN as V, type IdentityValidationIssue as W, type ImageSliderChangedData as X, type InformationWallSearchData as Y, type InteractionBlockRegistration as Z, type InteractionData as _, type CheckId as a, type InvalidSessionIdContext as a0, type LessonCompletionEmitter as a1, type LessonLifecycleData as a2, type LessonkitPluginKind as a3, type MemoryCardFlippedData as a4, type ParallaxSlideViewedData as a5, type PluginIdentity as a6, type QuestionnaireSubmittedData as a7, type QuizAnsweredData as a8, type QuizCompletedData as a9, resetSharedVolatileSessionIdForTests as aA, resetStoragePortForTests as aB, resetTelemetryBuilderWarningsForTests as aC, resolveSessionId as aD, tryBuildTelemetryEvent as aE, tryEmitCourseStarted as aF, resetCourseStartedEmitFlightForTests as aG, type ResolveSessionIdOptions as aa, SESSION_STORAGE_KEY as ab, type SlideViewedData as ac, type TelemetryEventBase as ad, type TimerPort as ae, type VideoCueReachedData as af, type VideoSegmentCompletedData as ag, buildCourseStartedTelemetryEvent as ah, buildTelemetryEvent as ai, completeCourseWithTelemetry as aj, completeLessonWithTelemetry as ak, createDefaultClock as al, createGlobalTimer as am, createNoopStorage as an, createProgressController as ao, createSessionStoragePort as ap, getTabSessionId as aq, hasCourseStarted as ar, hasCourseStartedEmittedToTracking as as, hasCourseStartedPipelineDelivered as at, hasCourseStartedXapiSent as au, markCourseStarted as av, markCourseStartedEmittedToTracking as aw, markCourseStartedPipelineDelivered as ax, markCourseStartedXapiSent as ay, migrateCourseStartedMark as az, type IdentityValidationResult as b, type LessonkitUrn as c, type TelemetrySink as d, type TelemetryBatchSink as e, type TrackingClient as f, type TelemetryEvent as g, type TelemetryUser as h, type LessonkitPlugin as i, type ProgressController as j, type PluginHost as k, type ProgressState as l, type TelemetryDataFor as m, type AssessmentScoreInput as n, type AssessmentScoreResult as o, type ClockPort as p, type AssessmentPlugin as q, type LifecyclePlugin as r, type TelemetryPlugin as s, type LessonkitPluginContext as t, type AccordionSectionToggledData as u, type AssessmentAnsweredData as v, type AssessmentBaseProps as w, type AssessmentBehaviour as x, type AssessmentCompletedData as y, type AssessmentHandle as z };
|
package/dist/testing.cjs
CHANGED
|
@@ -46,8 +46,10 @@ function resetSharedVolatileSessionIdForTests() {
|
|
|
46
46
|
|
|
47
47
|
// src/runtime/courseLifecycle.ts
|
|
48
48
|
var courseStartedEmitFlights = /* @__PURE__ */ new Map();
|
|
49
|
+
var courseStartedEmittedInTab = /* @__PURE__ */ new Set();
|
|
49
50
|
function resetCourseStartedEmitFlightForTests() {
|
|
50
51
|
courseStartedEmitFlights.clear();
|
|
52
|
+
courseStartedEmittedInTab.clear();
|
|
51
53
|
}
|
|
52
54
|
// Annotate the CommonJS export names for ESM import in node:
|
|
53
55
|
0 && (module.exports = {
|
package/dist/testing.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { aG as resetCourseStartedEmitFlightForTests, aA as resetSharedVolatileSessionIdForTests, aB as resetStoragePortForTests, aC as resetTelemetryBuilderWarningsForTests } from './testing-CQ-ZsT7D.cjs';
|
package/dist/testing.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { aG as resetCourseStartedEmitFlightForTests, aA as resetSharedVolatileSessionIdForTests, aB as resetStoragePortForTests, aC as resetTelemetryBuilderWarningsForTests } from './testing-CQ-ZsT7D.js';
|
package/dist/testing.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
resetSharedVolatileSessionIdForTests,
|
|
4
4
|
resetStoragePortForTests,
|
|
5
5
|
resetTelemetryBuilderWarningsForTests
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DTJGIMUU.js";
|
|
7
7
|
export {
|
|
8
8
|
resetCourseStartedEmitFlightForTests,
|
|
9
9
|
resetSharedVolatileSessionIdForTests,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lessonkit/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared types and telemetry primitives for LessonKit.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"identity-contract.v1.json"
|
|
49
49
|
],
|
|
50
50
|
"scripts": {
|
|
51
|
-
"build": "tsup src/index.ts src/testing.ts --format esm,cjs --dts",
|
|
52
|
-
"dev": "tsup src/index.ts src/testing.ts --format esm,cjs --dts --watch",
|
|
51
|
+
"build": "tsup src/index.ts src/testing.ts --format esm,cjs --dts --tsconfig tsconfig.build.json",
|
|
52
|
+
"dev": "tsup src/index.ts src/testing.ts --format esm,cjs --dts --watch --tsconfig tsconfig.build.json",
|
|
53
53
|
"prepublishOnly": "npm run build",
|
|
54
54
|
"typecheck": "tsc -p tsconfig.json",
|
|
55
55
|
"test": "vitest run --passWithNoTests",
|