@lessonkit/core 1.1.0 → 1.2.0
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/dist/index.cjs +583 -184
- package/dist/index.d.cts +189 -26
- package/dist/index.d.ts +189 -26
- package/dist/index.js +564 -184
- package/package.json +6 -2
- package/telemetry-catalog.v2.json +21 -0
- package/telemetry-catalog.v3.json +53 -0
package/dist/index.d.cts
CHANGED
|
@@ -55,7 +55,9 @@ type LessonkitUrnParts = {
|
|
|
55
55
|
declare function buildLessonkitUrn(parts: LessonkitUrnParts): LessonkitUrn;
|
|
56
56
|
|
|
57
57
|
/** H5P-aligned interaction kinds for assessment telemetry and xAPI. */
|
|
58
|
-
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence";
|
|
58
|
+
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence" | "findHotspot" | "findMultipleHotspots";
|
|
59
|
+
/** Serializable resume blob for a single assessment block. */
|
|
60
|
+
type AssessmentResumeState = Record<string, unknown>;
|
|
59
61
|
/** Behaviour flags aligned with H5P question types. */
|
|
60
62
|
type AssessmentBehaviour = {
|
|
61
63
|
enableRetry?: boolean;
|
|
@@ -82,13 +84,15 @@ type AssessmentHandle = {
|
|
|
82
84
|
resetTask: () => void;
|
|
83
85
|
showSolutions: () => void;
|
|
84
86
|
getXAPIData: () => AssessmentXAPIData;
|
|
87
|
+
getCurrentState?: () => AssessmentResumeState;
|
|
88
|
+
resume?: (state: AssessmentResumeState) => void;
|
|
85
89
|
};
|
|
86
90
|
type AssessmentBaseProps = AssessmentBehaviour & {
|
|
87
91
|
checkId: CheckId;
|
|
88
92
|
passingScore?: number;
|
|
89
93
|
};
|
|
90
94
|
|
|
91
|
-
type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction";
|
|
95
|
+
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" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed";
|
|
92
96
|
type TelemetryUser = {
|
|
93
97
|
id?: string;
|
|
94
98
|
email?: string;
|
|
@@ -141,6 +145,34 @@ type InteractionData = {
|
|
|
141
145
|
payload?: Record<string, unknown>;
|
|
142
146
|
[key: string]: unknown;
|
|
143
147
|
};
|
|
148
|
+
type BookPageViewedData = {
|
|
149
|
+
blockId: BlockId;
|
|
150
|
+
pageIndex: number;
|
|
151
|
+
pageTitle?: string;
|
|
152
|
+
};
|
|
153
|
+
type CompoundPageViewedData = {
|
|
154
|
+
blockId: BlockId;
|
|
155
|
+
pageIndex: number;
|
|
156
|
+
parentType?: string;
|
|
157
|
+
};
|
|
158
|
+
type HotspotOpenedData = {
|
|
159
|
+
blockId: BlockId;
|
|
160
|
+
hotspotId: string;
|
|
161
|
+
};
|
|
162
|
+
type AccordionSectionToggledData = {
|
|
163
|
+
blockId: BlockId;
|
|
164
|
+
sectionId: string;
|
|
165
|
+
expanded: boolean;
|
|
166
|
+
};
|
|
167
|
+
type FlashcardFlippedData = {
|
|
168
|
+
blockId: BlockId;
|
|
169
|
+
cardIndex: number;
|
|
170
|
+
face: "front" | "back";
|
|
171
|
+
};
|
|
172
|
+
type ImageSliderChangedData = {
|
|
173
|
+
blockId: BlockId;
|
|
174
|
+
slideIndex: number;
|
|
175
|
+
};
|
|
144
176
|
type TelemetryEvent = (TelemetryEventBase & {
|
|
145
177
|
name: "course_started";
|
|
146
178
|
lessonId?: LessonId;
|
|
@@ -181,6 +213,30 @@ type TelemetryEvent = (TelemetryEventBase & {
|
|
|
181
213
|
name: "interaction";
|
|
182
214
|
lessonId?: LessonId;
|
|
183
215
|
data?: InteractionData;
|
|
216
|
+
}) | (TelemetryEventBase & {
|
|
217
|
+
name: "book_page_viewed";
|
|
218
|
+
lessonId: LessonId;
|
|
219
|
+
data: BookPageViewedData;
|
|
220
|
+
}) | (TelemetryEventBase & {
|
|
221
|
+
name: "compound_page_viewed";
|
|
222
|
+
lessonId: LessonId;
|
|
223
|
+
data: CompoundPageViewedData;
|
|
224
|
+
}) | (TelemetryEventBase & {
|
|
225
|
+
name: "hotspot_opened";
|
|
226
|
+
lessonId?: LessonId;
|
|
227
|
+
data: HotspotOpenedData;
|
|
228
|
+
}) | (TelemetryEventBase & {
|
|
229
|
+
name: "accordion_section_toggled";
|
|
230
|
+
lessonId?: LessonId;
|
|
231
|
+
data: AccordionSectionToggledData;
|
|
232
|
+
}) | (TelemetryEventBase & {
|
|
233
|
+
name: "flashcard_flipped";
|
|
234
|
+
lessonId?: LessonId;
|
|
235
|
+
data: FlashcardFlippedData;
|
|
236
|
+
}) | (TelemetryEventBase & {
|
|
237
|
+
name: "image_slider_changed";
|
|
238
|
+
lessonId?: LessonId;
|
|
239
|
+
data: ImageSliderChangedData;
|
|
184
240
|
});
|
|
185
241
|
/** Payload shape for a telemetry event name. */
|
|
186
242
|
type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
|
|
@@ -196,6 +252,78 @@ type TrackingClient = {
|
|
|
196
252
|
dispose?: () => void | Promise<void>;
|
|
197
253
|
};
|
|
198
254
|
|
|
255
|
+
declare const COMPOUND_RESUME_SCHEMA_VERSION: 1;
|
|
256
|
+
/** Serializable resume blob for a compound container (InteractiveBook, AssessmentSequence, …). */
|
|
257
|
+
type CompoundResumeState = {
|
|
258
|
+
schemaVersion: typeof COMPOUND_RESUME_SCHEMA_VERSION;
|
|
259
|
+
activePageIndex: number;
|
|
260
|
+
/** Optional chapter index when nested inside InteractiveBook. */
|
|
261
|
+
activeChapterIndex?: number;
|
|
262
|
+
childStates: Record<string, AssessmentResumeState>;
|
|
263
|
+
};
|
|
264
|
+
type CompoundResumeInput = {
|
|
265
|
+
activePageIndex?: number;
|
|
266
|
+
activeChapterIndex?: number;
|
|
267
|
+
childStates?: Record<CheckId, AssessmentResumeState>;
|
|
268
|
+
};
|
|
269
|
+
declare function createCompoundResumeState(input?: CompoundResumeInput): CompoundResumeState;
|
|
270
|
+
/** Clamp page index to valid range for a compound with `pageCount` pages. */
|
|
271
|
+
declare function clampCompoundPageIndex(index: number, pageCount: number): number;
|
|
272
|
+
declare function parseCompoundResumeState(raw: unknown): CompoundResumeState | null;
|
|
273
|
+
/**
|
|
274
|
+
* Imperative handle for compound containers (H5P compound analogue).
|
|
275
|
+
* Parents aggregate child AssessmentHandle scores and persist navigation state.
|
|
276
|
+
*/
|
|
277
|
+
type CompoundHandle = {
|
|
278
|
+
getScore: () => number;
|
|
279
|
+
getMaxScore: () => number;
|
|
280
|
+
getAnswerGiven: () => boolean;
|
|
281
|
+
resetTask: () => void;
|
|
282
|
+
showSolutions: () => void;
|
|
283
|
+
getCurrentState: () => CompoundResumeState;
|
|
284
|
+
resume: (state: CompoundResumeState) => void;
|
|
285
|
+
};
|
|
286
|
+
type CompoundBaseProps = {
|
|
287
|
+
blockId: BlockId;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
type StoragePort = {
|
|
291
|
+
getItem: (key: string) => string | null;
|
|
292
|
+
setItem: (key: string, value: string) => void;
|
|
293
|
+
removeItem?: (key: string) => void;
|
|
294
|
+
/** @internal Test helper to clear in-memory fallback state. */
|
|
295
|
+
resetForTests?: () => void;
|
|
296
|
+
};
|
|
297
|
+
type ClockPort = {
|
|
298
|
+
nowMs: () => number;
|
|
299
|
+
nowIso: () => string;
|
|
300
|
+
};
|
|
301
|
+
type TimerPort = {
|
|
302
|
+
setInterval: (fn: () => void, ms: number) => ReturnType<typeof globalThis.setInterval>;
|
|
303
|
+
clearInterval: (id: ReturnType<typeof globalThis.setInterval>) => void;
|
|
304
|
+
};
|
|
305
|
+
declare function createDefaultClock(): ClockPort;
|
|
306
|
+
declare function createNoopStorage(): StoragePort;
|
|
307
|
+
declare function resetStoragePortForTests(storage: StoragePort): void;
|
|
308
|
+
declare function createSessionStoragePort(): StoragePort;
|
|
309
|
+
declare function createGlobalTimer(): TimerPort;
|
|
310
|
+
|
|
311
|
+
declare function compoundStateStorageKey(courseId: CourseId, compoundId: BlockId): string;
|
|
312
|
+
declare function loadCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): CompoundResumeState | null;
|
|
313
|
+
declare function saveCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId, state: CompoundResumeState): void;
|
|
314
|
+
declare function clearCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): void;
|
|
315
|
+
|
|
316
|
+
/** Canonical compound child allowlists (H5P sub-content curation). */
|
|
317
|
+
declare const PAGE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "ProgressTracker"];
|
|
318
|
+
declare const INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES: readonly ["Page"];
|
|
319
|
+
declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots"];
|
|
320
|
+
type CompoundParentType = "Page" | "InteractiveBook" | "AssessmentSequence";
|
|
321
|
+
declare const COMPOUND_MAX_NESTING_DEPTH: Record<CompoundParentType, number>;
|
|
322
|
+
declare function getAllowedChildTypes(parent: CompoundParentType): readonly string[];
|
|
323
|
+
declare function isChildTypeAllowed(parent: CompoundParentType, childType: string): boolean;
|
|
324
|
+
/** Blocks that must not nest inside Accordion (policy: no accordion-in-accordion). */
|
|
325
|
+
declare const ACCORDION_FORBIDDEN_CHILD_TYPES: readonly ["Accordion"];
|
|
326
|
+
|
|
199
327
|
declare const telemetryCatalogVersion: 1;
|
|
200
328
|
type TelemetryCatalogEntry = {
|
|
201
329
|
name: TelemetryEventName;
|
|
@@ -220,6 +348,19 @@ type TelemetryCatalogV2Entry = {
|
|
|
220
348
|
declare const TELEMETRY_EVENT_CATALOG_V2: TelemetryCatalogV2Entry[];
|
|
221
349
|
declare function buildTelemetryCatalogV2(): TelemetryCatalogV2Entry[];
|
|
222
350
|
|
|
351
|
+
declare const telemetryCatalogV3Version: 3;
|
|
352
|
+
type TelemetryCatalogV3EventName = Extract<TelemetryEventName, "book_page_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed">;
|
|
353
|
+
type TelemetryCatalogV3Entry = {
|
|
354
|
+
name: TelemetryCatalogV3EventName;
|
|
355
|
+
description: string;
|
|
356
|
+
requiredFields: string[];
|
|
357
|
+
dataFields: string[];
|
|
358
|
+
xapiVerb: string;
|
|
359
|
+
urnPattern: string;
|
|
360
|
+
};
|
|
361
|
+
declare const TELEMETRY_EVENT_CATALOG_V3: TelemetryCatalogV3Entry[];
|
|
362
|
+
declare function buildTelemetryCatalogV3(): TelemetryCatalogV3Entry[];
|
|
363
|
+
|
|
223
364
|
declare function createTrackingClient(opts?: {
|
|
224
365
|
sink?: TelemetrySink;
|
|
225
366
|
batch?: {
|
|
@@ -281,7 +422,32 @@ type BuildTelemetryEventInput = (BuildTelemetryEventContext & {
|
|
|
281
422
|
name: "interaction";
|
|
282
423
|
lessonId?: LessonId;
|
|
283
424
|
data?: InteractionData;
|
|
425
|
+
}) | (BuildTelemetryEventContext & {
|
|
426
|
+
name: "book_page_viewed";
|
|
427
|
+
lessonId?: LessonId;
|
|
428
|
+
data: BookPageViewedData;
|
|
429
|
+
}) | (BuildTelemetryEventContext & {
|
|
430
|
+
name: "compound_page_viewed";
|
|
431
|
+
lessonId?: LessonId;
|
|
432
|
+
data: CompoundPageViewedData;
|
|
433
|
+
}) | (BuildTelemetryEventContext & {
|
|
434
|
+
name: "hotspot_opened";
|
|
435
|
+
lessonId?: LessonId;
|
|
436
|
+
data: HotspotOpenedData;
|
|
437
|
+
}) | (BuildTelemetryEventContext & {
|
|
438
|
+
name: "accordion_section_toggled";
|
|
439
|
+
lessonId?: LessonId;
|
|
440
|
+
data: AccordionSectionToggledData;
|
|
441
|
+
}) | (BuildTelemetryEventContext & {
|
|
442
|
+
name: "flashcard_flipped";
|
|
443
|
+
lessonId?: LessonId;
|
|
444
|
+
data: FlashcardFlippedData;
|
|
445
|
+
}) | (BuildTelemetryEventContext & {
|
|
446
|
+
name: "image_slider_changed";
|
|
447
|
+
lessonId?: LessonId;
|
|
448
|
+
data: ImageSliderChangedData;
|
|
284
449
|
});
|
|
450
|
+
|
|
285
451
|
/** Reset dev-warning state (tests only). */
|
|
286
452
|
declare function resetTelemetryBuilderWarningsForTests(): void;
|
|
287
453
|
/**
|
|
@@ -311,27 +477,6 @@ type TelemetryPipeline = {
|
|
|
311
477
|
declare function createTelemetryPipeline(sinks: TelemetryPipelineSink[]): TelemetryPipeline;
|
|
312
478
|
declare function createTrackingPipelineSink(id: string, track: (event: TelemetryEvent) => void): TelemetryPipelineSink;
|
|
313
479
|
|
|
314
|
-
type StoragePort = {
|
|
315
|
-
getItem: (key: string) => string | null;
|
|
316
|
-
setItem: (key: string, value: string) => void;
|
|
317
|
-
removeItem?: (key: string) => void;
|
|
318
|
-
/** @internal Test helper to clear in-memory fallback state. */
|
|
319
|
-
resetForTests?: () => void;
|
|
320
|
-
};
|
|
321
|
-
type ClockPort = {
|
|
322
|
-
nowMs: () => number;
|
|
323
|
-
nowIso: () => string;
|
|
324
|
-
};
|
|
325
|
-
type TimerPort = {
|
|
326
|
-
setInterval: (fn: () => void, ms: number) => ReturnType<typeof globalThis.setInterval>;
|
|
327
|
-
clearInterval: (id: ReturnType<typeof globalThis.setInterval>) => void;
|
|
328
|
-
};
|
|
329
|
-
declare function createDefaultClock(): ClockPort;
|
|
330
|
-
declare function createNoopStorage(): StoragePort;
|
|
331
|
-
declare function resetStoragePortForTests(storage: StoragePort): void;
|
|
332
|
-
declare function createSessionStoragePort(): StoragePort;
|
|
333
|
-
declare function createGlobalTimer(): TimerPort;
|
|
334
|
-
|
|
335
480
|
type ProgressState = {
|
|
336
481
|
activeLessonId?: LessonId;
|
|
337
482
|
completedLessonIds: ReadonlySet<LessonId>;
|
|
@@ -410,7 +555,10 @@ type AssessmentPlugin = PluginIdentity & {
|
|
|
410
555
|
kind: "assessment";
|
|
411
556
|
scoreAssessment?: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
|
|
412
557
|
};
|
|
413
|
-
/**
|
|
558
|
+
/**
|
|
559
|
+
* Narrow interaction metadata plugin (ISP).
|
|
560
|
+
* @experimental Not wired into PluginHost; reserved for a future release.
|
|
561
|
+
*/
|
|
414
562
|
type InteractionPlugin = PluginIdentity & {
|
|
415
563
|
interactionBlocks?: InteractionBlockRegistration[];
|
|
416
564
|
};
|
|
@@ -464,6 +612,7 @@ declare function completeCourseWithTelemetry(opts: {
|
|
|
464
612
|
}): boolean;
|
|
465
613
|
|
|
466
614
|
type LessonkitRuntimeVersion = "v1" | "v2";
|
|
615
|
+
type HeadlessLessonkitPlugins = readonly LessonkitPlugin[] | PluginRegistry | null | undefined;
|
|
467
616
|
type HeadlessLessonkitConfig = {
|
|
468
617
|
courseId: CourseId;
|
|
469
618
|
runtimeVersion?: LessonkitRuntimeVersion;
|
|
@@ -472,7 +621,8 @@ type HeadlessLessonkitConfig = {
|
|
|
472
621
|
attemptId?: string;
|
|
473
622
|
user?: TelemetryUser;
|
|
474
623
|
};
|
|
475
|
-
|
|
624
|
+
/** Plugin list or registry; hooks run on {@link HeadlessLessonkitRuntime.track} and lifecycle emits. */
|
|
625
|
+
plugins?: HeadlessLessonkitPlugins;
|
|
476
626
|
};
|
|
477
627
|
type HeadlessRuntimePorts = {
|
|
478
628
|
storage?: StoragePort;
|
|
@@ -484,6 +634,7 @@ type TelemetryEmitFn = {
|
|
|
484
634
|
type HeadlessLessonkitRuntime = {
|
|
485
635
|
readonly config: HeadlessLessonkitConfig;
|
|
486
636
|
readonly progress: ProgressController;
|
|
637
|
+
readonly pluginHost: PluginHost | null;
|
|
487
638
|
getProgressState: () => ProgressState;
|
|
488
639
|
getSession: () => {
|
|
489
640
|
sessionId: string;
|
|
@@ -495,14 +646,26 @@ type HeadlessLessonkitRuntime = {
|
|
|
495
646
|
completeLesson: (lessonId: LessonId, emit: TelemetryEmitFn) => void;
|
|
496
647
|
completeCourse: (emit: TelemetryEmitFn) => void;
|
|
497
648
|
track: <N extends TelemetryEventName>(name: N, data: TelemetryDataFor<N> | undefined, emit: (event: TelemetryEvent) => void, lessonId?: LessonId) => void;
|
|
649
|
+
scoreAssessment: (input: AssessmentScoreInput, lessonId?: LessonId) => AssessmentScoreResult | null;
|
|
498
650
|
resetForCourseChange: (courseId: CourseId) => void;
|
|
651
|
+
dispose: () => void;
|
|
499
652
|
};
|
|
500
653
|
declare function createLessonkitRuntime(config: HeadlessLessonkitConfig, ports?: HeadlessRuntimePorts): HeadlessLessonkitRuntime;
|
|
501
654
|
|
|
502
655
|
declare function createPluginRegistry(plugins?: readonly LessonkitPlugin[]): PluginRegistry;
|
|
503
656
|
|
|
657
|
+
/** Identity helper for telemetry plugins; does not validate or register at import time. */
|
|
504
658
|
declare function defineTelemetryPlugin(plugin: TelemetryPlugin): LessonkitPlugin;
|
|
659
|
+
/** Identity helper for assessment plugins; does not validate or register at import time. */
|
|
505
660
|
declare function defineAssessmentPlugin(plugin: AssessmentPlugin): LessonkitPlugin;
|
|
661
|
+
/** Identity helper for lifecycle plugins; does not validate or register at import time. */
|
|
506
662
|
declare function defineLifecyclePlugin(plugin: LifecyclePlugin): LessonkitPlugin;
|
|
507
663
|
|
|
508
|
-
|
|
664
|
+
declare function buildPluginContext(opts: {
|
|
665
|
+
courseId: CourseId;
|
|
666
|
+
sessionId?: string;
|
|
667
|
+
attemptId?: string;
|
|
668
|
+
user?: TelemetryUser;
|
|
669
|
+
}): LessonkitPluginContext;
|
|
670
|
+
|
|
671
|
+
export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, type AccordionSectionToggledData, type AssessmentAnsweredData, type AssessmentBaseProps, type AssessmentBehaviour, type AssessmentCompletedData, type AssessmentHandle, type AssessmentInteractionType, type AssessmentPlugin, type AssessmentResumeState, type AssessmentScoreInput, type AssessmentScoreResult, type AssessmentXAPIData, type BlockId, type BookPageViewedData, type BuildTelemetryEventInput, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, type CheckId, type ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundPageViewedData, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, type CourseId, type CourseLifecycleContext, type CourseLifecycleDeps, type EmitContext, type FlashcardFlippedData, type HeadlessLessonkitConfig, type HeadlessLessonkitRuntime, type HeadlessRuntimePorts, type HotspotOpenedData, ID_MAX_LENGTH, ID_PATTERN, INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES, type IdentityIdPath, type IdentityValidationIssue, type IdentityValidationResult, type ImageSliderChangedData, type InteractionBlockRegistration, type InteractionData, type InteractionPlugin, type LessonCompletionEmitter, type LessonId, type LessonLifecycleData, type LessonkitPlugin, type LessonkitPluginContext, type LessonkitPluginKind, type LessonkitRuntimeVersion, type LessonkitUrn, type LessonkitUrnParts, type LifecyclePlugin, PAGE_ALLOWED_CHILD_TYPES, type PluginHost, type PluginIdentity, type PluginRegistry, type ProgressController, type ProgressState, type QuizAnsweredData, type QuizCompletedData, SESSION_STORAGE_KEY, type StoragePort, TELEMETRY_EVENT_CATALOG, TELEMETRY_EVENT_CATALOG_V2, TELEMETRY_EVENT_CATALOG_V3, type TelemetryBatchSink, type TelemetryCatalogEntry, type TelemetryCatalogV2Entry, type TelemetryCatalogV3Entry, type TelemetryDataFor, type TelemetryEmitFn, type TelemetryEvent, type TelemetryEventBase, type TelemetryEventName, type TelemetryPipeline, type TelemetryPipelineSink, type TelemetryPlugin, type TelemetrySink, type TelemetryUser, type TimerPort, type TrackingClient, assertNever, assertValidId, buildCourseStartedTelemetryEvent, buildLessonkitUrn, buildPluginContext, buildTelemetryCatalog, buildTelemetryCatalogV2, buildTelemetryCatalogV3, buildTelemetryEvent, clampCompoundPageIndex, clearCompoundState, completeCourseWithTelemetry, completeLessonWithTelemetry, compoundStateStorageKey, createCompoundResumeState, createDefaultClock, createGlobalTimer, createLessonkitRuntime, createNoopStorage, createPluginRegistry, createProgressController, createSessionId, createSessionStoragePort, createTelemetryPipeline, createTrackingClient, createTrackingPipelineSink, defineAssessmentPlugin, defineLifecyclePlugin, defineTelemetryPlugin, deriveId, getAllowedChildTypes, getTabSessionId, hasCourseStarted, hasCourseStartedEmittedToTracking, hasCourseStartedPipelineDelivered, isChildTypeAllowed, loadCompoundState, markCourseStarted, markCourseStartedEmittedToTracking, markCourseStartedPipelineDelivered, migrateCourseStartedMark, nowIso, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, resetStoragePortForTests, resetTelemetryBuilderWarningsForTests, resolveSessionId, saveCompoundState, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, tryBuildTelemetryEvent, tryEmitCourseStarted, validateId };
|
package/dist/index.d.ts
CHANGED
|
@@ -55,7 +55,9 @@ type LessonkitUrnParts = {
|
|
|
55
55
|
declare function buildLessonkitUrn(parts: LessonkitUrnParts): LessonkitUrn;
|
|
56
56
|
|
|
57
57
|
/** H5P-aligned interaction kinds for assessment telemetry and xAPI. */
|
|
58
|
-
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence";
|
|
58
|
+
type AssessmentInteractionType = "mcq" | "trueFalse" | "fillInBlanks" | "markTheWords" | "dragTheWords" | "dragAndDrop" | "assessmentSequence" | "findHotspot" | "findMultipleHotspots";
|
|
59
|
+
/** Serializable resume blob for a single assessment block. */
|
|
60
|
+
type AssessmentResumeState = Record<string, unknown>;
|
|
59
61
|
/** Behaviour flags aligned with H5P question types. */
|
|
60
62
|
type AssessmentBehaviour = {
|
|
61
63
|
enableRetry?: boolean;
|
|
@@ -82,13 +84,15 @@ type AssessmentHandle = {
|
|
|
82
84
|
resetTask: () => void;
|
|
83
85
|
showSolutions: () => void;
|
|
84
86
|
getXAPIData: () => AssessmentXAPIData;
|
|
87
|
+
getCurrentState?: () => AssessmentResumeState;
|
|
88
|
+
resume?: (state: AssessmentResumeState) => void;
|
|
85
89
|
};
|
|
86
90
|
type AssessmentBaseProps = AssessmentBehaviour & {
|
|
87
91
|
checkId: CheckId;
|
|
88
92
|
passingScore?: number;
|
|
89
93
|
};
|
|
90
94
|
|
|
91
|
-
type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction";
|
|
95
|
+
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" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed";
|
|
92
96
|
type TelemetryUser = {
|
|
93
97
|
id?: string;
|
|
94
98
|
email?: string;
|
|
@@ -141,6 +145,34 @@ type InteractionData = {
|
|
|
141
145
|
payload?: Record<string, unknown>;
|
|
142
146
|
[key: string]: unknown;
|
|
143
147
|
};
|
|
148
|
+
type BookPageViewedData = {
|
|
149
|
+
blockId: BlockId;
|
|
150
|
+
pageIndex: number;
|
|
151
|
+
pageTitle?: string;
|
|
152
|
+
};
|
|
153
|
+
type CompoundPageViewedData = {
|
|
154
|
+
blockId: BlockId;
|
|
155
|
+
pageIndex: number;
|
|
156
|
+
parentType?: string;
|
|
157
|
+
};
|
|
158
|
+
type HotspotOpenedData = {
|
|
159
|
+
blockId: BlockId;
|
|
160
|
+
hotspotId: string;
|
|
161
|
+
};
|
|
162
|
+
type AccordionSectionToggledData = {
|
|
163
|
+
blockId: BlockId;
|
|
164
|
+
sectionId: string;
|
|
165
|
+
expanded: boolean;
|
|
166
|
+
};
|
|
167
|
+
type FlashcardFlippedData = {
|
|
168
|
+
blockId: BlockId;
|
|
169
|
+
cardIndex: number;
|
|
170
|
+
face: "front" | "back";
|
|
171
|
+
};
|
|
172
|
+
type ImageSliderChangedData = {
|
|
173
|
+
blockId: BlockId;
|
|
174
|
+
slideIndex: number;
|
|
175
|
+
};
|
|
144
176
|
type TelemetryEvent = (TelemetryEventBase & {
|
|
145
177
|
name: "course_started";
|
|
146
178
|
lessonId?: LessonId;
|
|
@@ -181,6 +213,30 @@ type TelemetryEvent = (TelemetryEventBase & {
|
|
|
181
213
|
name: "interaction";
|
|
182
214
|
lessonId?: LessonId;
|
|
183
215
|
data?: InteractionData;
|
|
216
|
+
}) | (TelemetryEventBase & {
|
|
217
|
+
name: "book_page_viewed";
|
|
218
|
+
lessonId: LessonId;
|
|
219
|
+
data: BookPageViewedData;
|
|
220
|
+
}) | (TelemetryEventBase & {
|
|
221
|
+
name: "compound_page_viewed";
|
|
222
|
+
lessonId: LessonId;
|
|
223
|
+
data: CompoundPageViewedData;
|
|
224
|
+
}) | (TelemetryEventBase & {
|
|
225
|
+
name: "hotspot_opened";
|
|
226
|
+
lessonId?: LessonId;
|
|
227
|
+
data: HotspotOpenedData;
|
|
228
|
+
}) | (TelemetryEventBase & {
|
|
229
|
+
name: "accordion_section_toggled";
|
|
230
|
+
lessonId?: LessonId;
|
|
231
|
+
data: AccordionSectionToggledData;
|
|
232
|
+
}) | (TelemetryEventBase & {
|
|
233
|
+
name: "flashcard_flipped";
|
|
234
|
+
lessonId?: LessonId;
|
|
235
|
+
data: FlashcardFlippedData;
|
|
236
|
+
}) | (TelemetryEventBase & {
|
|
237
|
+
name: "image_slider_changed";
|
|
238
|
+
lessonId?: LessonId;
|
|
239
|
+
data: ImageSliderChangedData;
|
|
184
240
|
});
|
|
185
241
|
/** Payload shape for a telemetry event name. */
|
|
186
242
|
type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
|
|
@@ -196,6 +252,78 @@ type TrackingClient = {
|
|
|
196
252
|
dispose?: () => void | Promise<void>;
|
|
197
253
|
};
|
|
198
254
|
|
|
255
|
+
declare const COMPOUND_RESUME_SCHEMA_VERSION: 1;
|
|
256
|
+
/** Serializable resume blob for a compound container (InteractiveBook, AssessmentSequence, …). */
|
|
257
|
+
type CompoundResumeState = {
|
|
258
|
+
schemaVersion: typeof COMPOUND_RESUME_SCHEMA_VERSION;
|
|
259
|
+
activePageIndex: number;
|
|
260
|
+
/** Optional chapter index when nested inside InteractiveBook. */
|
|
261
|
+
activeChapterIndex?: number;
|
|
262
|
+
childStates: Record<string, AssessmentResumeState>;
|
|
263
|
+
};
|
|
264
|
+
type CompoundResumeInput = {
|
|
265
|
+
activePageIndex?: number;
|
|
266
|
+
activeChapterIndex?: number;
|
|
267
|
+
childStates?: Record<CheckId, AssessmentResumeState>;
|
|
268
|
+
};
|
|
269
|
+
declare function createCompoundResumeState(input?: CompoundResumeInput): CompoundResumeState;
|
|
270
|
+
/** Clamp page index to valid range for a compound with `pageCount` pages. */
|
|
271
|
+
declare function clampCompoundPageIndex(index: number, pageCount: number): number;
|
|
272
|
+
declare function parseCompoundResumeState(raw: unknown): CompoundResumeState | null;
|
|
273
|
+
/**
|
|
274
|
+
* Imperative handle for compound containers (H5P compound analogue).
|
|
275
|
+
* Parents aggregate child AssessmentHandle scores and persist navigation state.
|
|
276
|
+
*/
|
|
277
|
+
type CompoundHandle = {
|
|
278
|
+
getScore: () => number;
|
|
279
|
+
getMaxScore: () => number;
|
|
280
|
+
getAnswerGiven: () => boolean;
|
|
281
|
+
resetTask: () => void;
|
|
282
|
+
showSolutions: () => void;
|
|
283
|
+
getCurrentState: () => CompoundResumeState;
|
|
284
|
+
resume: (state: CompoundResumeState) => void;
|
|
285
|
+
};
|
|
286
|
+
type CompoundBaseProps = {
|
|
287
|
+
blockId: BlockId;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
type StoragePort = {
|
|
291
|
+
getItem: (key: string) => string | null;
|
|
292
|
+
setItem: (key: string, value: string) => void;
|
|
293
|
+
removeItem?: (key: string) => void;
|
|
294
|
+
/** @internal Test helper to clear in-memory fallback state. */
|
|
295
|
+
resetForTests?: () => void;
|
|
296
|
+
};
|
|
297
|
+
type ClockPort = {
|
|
298
|
+
nowMs: () => number;
|
|
299
|
+
nowIso: () => string;
|
|
300
|
+
};
|
|
301
|
+
type TimerPort = {
|
|
302
|
+
setInterval: (fn: () => void, ms: number) => ReturnType<typeof globalThis.setInterval>;
|
|
303
|
+
clearInterval: (id: ReturnType<typeof globalThis.setInterval>) => void;
|
|
304
|
+
};
|
|
305
|
+
declare function createDefaultClock(): ClockPort;
|
|
306
|
+
declare function createNoopStorage(): StoragePort;
|
|
307
|
+
declare function resetStoragePortForTests(storage: StoragePort): void;
|
|
308
|
+
declare function createSessionStoragePort(): StoragePort;
|
|
309
|
+
declare function createGlobalTimer(): TimerPort;
|
|
310
|
+
|
|
311
|
+
declare function compoundStateStorageKey(courseId: CourseId, compoundId: BlockId): string;
|
|
312
|
+
declare function loadCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): CompoundResumeState | null;
|
|
313
|
+
declare function saveCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId, state: CompoundResumeState): void;
|
|
314
|
+
declare function clearCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): void;
|
|
315
|
+
|
|
316
|
+
/** Canonical compound child allowlists (H5P sub-content curation). */
|
|
317
|
+
declare const PAGE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider", "ProgressTracker"];
|
|
318
|
+
declare const INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES: readonly ["Page"];
|
|
319
|
+
declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots"];
|
|
320
|
+
type CompoundParentType = "Page" | "InteractiveBook" | "AssessmentSequence";
|
|
321
|
+
declare const COMPOUND_MAX_NESTING_DEPTH: Record<CompoundParentType, number>;
|
|
322
|
+
declare function getAllowedChildTypes(parent: CompoundParentType): readonly string[];
|
|
323
|
+
declare function isChildTypeAllowed(parent: CompoundParentType, childType: string): boolean;
|
|
324
|
+
/** Blocks that must not nest inside Accordion (policy: no accordion-in-accordion). */
|
|
325
|
+
declare const ACCORDION_FORBIDDEN_CHILD_TYPES: readonly ["Accordion"];
|
|
326
|
+
|
|
199
327
|
declare const telemetryCatalogVersion: 1;
|
|
200
328
|
type TelemetryCatalogEntry = {
|
|
201
329
|
name: TelemetryEventName;
|
|
@@ -220,6 +348,19 @@ type TelemetryCatalogV2Entry = {
|
|
|
220
348
|
declare const TELEMETRY_EVENT_CATALOG_V2: TelemetryCatalogV2Entry[];
|
|
221
349
|
declare function buildTelemetryCatalogV2(): TelemetryCatalogV2Entry[];
|
|
222
350
|
|
|
351
|
+
declare const telemetryCatalogV3Version: 3;
|
|
352
|
+
type TelemetryCatalogV3EventName = Extract<TelemetryEventName, "book_page_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed">;
|
|
353
|
+
type TelemetryCatalogV3Entry = {
|
|
354
|
+
name: TelemetryCatalogV3EventName;
|
|
355
|
+
description: string;
|
|
356
|
+
requiredFields: string[];
|
|
357
|
+
dataFields: string[];
|
|
358
|
+
xapiVerb: string;
|
|
359
|
+
urnPattern: string;
|
|
360
|
+
};
|
|
361
|
+
declare const TELEMETRY_EVENT_CATALOG_V3: TelemetryCatalogV3Entry[];
|
|
362
|
+
declare function buildTelemetryCatalogV3(): TelemetryCatalogV3Entry[];
|
|
363
|
+
|
|
223
364
|
declare function createTrackingClient(opts?: {
|
|
224
365
|
sink?: TelemetrySink;
|
|
225
366
|
batch?: {
|
|
@@ -281,7 +422,32 @@ type BuildTelemetryEventInput = (BuildTelemetryEventContext & {
|
|
|
281
422
|
name: "interaction";
|
|
282
423
|
lessonId?: LessonId;
|
|
283
424
|
data?: InteractionData;
|
|
425
|
+
}) | (BuildTelemetryEventContext & {
|
|
426
|
+
name: "book_page_viewed";
|
|
427
|
+
lessonId?: LessonId;
|
|
428
|
+
data: BookPageViewedData;
|
|
429
|
+
}) | (BuildTelemetryEventContext & {
|
|
430
|
+
name: "compound_page_viewed";
|
|
431
|
+
lessonId?: LessonId;
|
|
432
|
+
data: CompoundPageViewedData;
|
|
433
|
+
}) | (BuildTelemetryEventContext & {
|
|
434
|
+
name: "hotspot_opened";
|
|
435
|
+
lessonId?: LessonId;
|
|
436
|
+
data: HotspotOpenedData;
|
|
437
|
+
}) | (BuildTelemetryEventContext & {
|
|
438
|
+
name: "accordion_section_toggled";
|
|
439
|
+
lessonId?: LessonId;
|
|
440
|
+
data: AccordionSectionToggledData;
|
|
441
|
+
}) | (BuildTelemetryEventContext & {
|
|
442
|
+
name: "flashcard_flipped";
|
|
443
|
+
lessonId?: LessonId;
|
|
444
|
+
data: FlashcardFlippedData;
|
|
445
|
+
}) | (BuildTelemetryEventContext & {
|
|
446
|
+
name: "image_slider_changed";
|
|
447
|
+
lessonId?: LessonId;
|
|
448
|
+
data: ImageSliderChangedData;
|
|
284
449
|
});
|
|
450
|
+
|
|
285
451
|
/** Reset dev-warning state (tests only). */
|
|
286
452
|
declare function resetTelemetryBuilderWarningsForTests(): void;
|
|
287
453
|
/**
|
|
@@ -311,27 +477,6 @@ type TelemetryPipeline = {
|
|
|
311
477
|
declare function createTelemetryPipeline(sinks: TelemetryPipelineSink[]): TelemetryPipeline;
|
|
312
478
|
declare function createTrackingPipelineSink(id: string, track: (event: TelemetryEvent) => void): TelemetryPipelineSink;
|
|
313
479
|
|
|
314
|
-
type StoragePort = {
|
|
315
|
-
getItem: (key: string) => string | null;
|
|
316
|
-
setItem: (key: string, value: string) => void;
|
|
317
|
-
removeItem?: (key: string) => void;
|
|
318
|
-
/** @internal Test helper to clear in-memory fallback state. */
|
|
319
|
-
resetForTests?: () => void;
|
|
320
|
-
};
|
|
321
|
-
type ClockPort = {
|
|
322
|
-
nowMs: () => number;
|
|
323
|
-
nowIso: () => string;
|
|
324
|
-
};
|
|
325
|
-
type TimerPort = {
|
|
326
|
-
setInterval: (fn: () => void, ms: number) => ReturnType<typeof globalThis.setInterval>;
|
|
327
|
-
clearInterval: (id: ReturnType<typeof globalThis.setInterval>) => void;
|
|
328
|
-
};
|
|
329
|
-
declare function createDefaultClock(): ClockPort;
|
|
330
|
-
declare function createNoopStorage(): StoragePort;
|
|
331
|
-
declare function resetStoragePortForTests(storage: StoragePort): void;
|
|
332
|
-
declare function createSessionStoragePort(): StoragePort;
|
|
333
|
-
declare function createGlobalTimer(): TimerPort;
|
|
334
|
-
|
|
335
480
|
type ProgressState = {
|
|
336
481
|
activeLessonId?: LessonId;
|
|
337
482
|
completedLessonIds: ReadonlySet<LessonId>;
|
|
@@ -410,7 +555,10 @@ type AssessmentPlugin = PluginIdentity & {
|
|
|
410
555
|
kind: "assessment";
|
|
411
556
|
scoreAssessment?: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
|
|
412
557
|
};
|
|
413
|
-
/**
|
|
558
|
+
/**
|
|
559
|
+
* Narrow interaction metadata plugin (ISP).
|
|
560
|
+
* @experimental Not wired into PluginHost; reserved for a future release.
|
|
561
|
+
*/
|
|
414
562
|
type InteractionPlugin = PluginIdentity & {
|
|
415
563
|
interactionBlocks?: InteractionBlockRegistration[];
|
|
416
564
|
};
|
|
@@ -464,6 +612,7 @@ declare function completeCourseWithTelemetry(opts: {
|
|
|
464
612
|
}): boolean;
|
|
465
613
|
|
|
466
614
|
type LessonkitRuntimeVersion = "v1" | "v2";
|
|
615
|
+
type HeadlessLessonkitPlugins = readonly LessonkitPlugin[] | PluginRegistry | null | undefined;
|
|
467
616
|
type HeadlessLessonkitConfig = {
|
|
468
617
|
courseId: CourseId;
|
|
469
618
|
runtimeVersion?: LessonkitRuntimeVersion;
|
|
@@ -472,7 +621,8 @@ type HeadlessLessonkitConfig = {
|
|
|
472
621
|
attemptId?: string;
|
|
473
622
|
user?: TelemetryUser;
|
|
474
623
|
};
|
|
475
|
-
|
|
624
|
+
/** Plugin list or registry; hooks run on {@link HeadlessLessonkitRuntime.track} and lifecycle emits. */
|
|
625
|
+
plugins?: HeadlessLessonkitPlugins;
|
|
476
626
|
};
|
|
477
627
|
type HeadlessRuntimePorts = {
|
|
478
628
|
storage?: StoragePort;
|
|
@@ -484,6 +634,7 @@ type TelemetryEmitFn = {
|
|
|
484
634
|
type HeadlessLessonkitRuntime = {
|
|
485
635
|
readonly config: HeadlessLessonkitConfig;
|
|
486
636
|
readonly progress: ProgressController;
|
|
637
|
+
readonly pluginHost: PluginHost | null;
|
|
487
638
|
getProgressState: () => ProgressState;
|
|
488
639
|
getSession: () => {
|
|
489
640
|
sessionId: string;
|
|
@@ -495,14 +646,26 @@ type HeadlessLessonkitRuntime = {
|
|
|
495
646
|
completeLesson: (lessonId: LessonId, emit: TelemetryEmitFn) => void;
|
|
496
647
|
completeCourse: (emit: TelemetryEmitFn) => void;
|
|
497
648
|
track: <N extends TelemetryEventName>(name: N, data: TelemetryDataFor<N> | undefined, emit: (event: TelemetryEvent) => void, lessonId?: LessonId) => void;
|
|
649
|
+
scoreAssessment: (input: AssessmentScoreInput, lessonId?: LessonId) => AssessmentScoreResult | null;
|
|
498
650
|
resetForCourseChange: (courseId: CourseId) => void;
|
|
651
|
+
dispose: () => void;
|
|
499
652
|
};
|
|
500
653
|
declare function createLessonkitRuntime(config: HeadlessLessonkitConfig, ports?: HeadlessRuntimePorts): HeadlessLessonkitRuntime;
|
|
501
654
|
|
|
502
655
|
declare function createPluginRegistry(plugins?: readonly LessonkitPlugin[]): PluginRegistry;
|
|
503
656
|
|
|
657
|
+
/** Identity helper for telemetry plugins; does not validate or register at import time. */
|
|
504
658
|
declare function defineTelemetryPlugin(plugin: TelemetryPlugin): LessonkitPlugin;
|
|
659
|
+
/** Identity helper for assessment plugins; does not validate or register at import time. */
|
|
505
660
|
declare function defineAssessmentPlugin(plugin: AssessmentPlugin): LessonkitPlugin;
|
|
661
|
+
/** Identity helper for lifecycle plugins; does not validate or register at import time. */
|
|
506
662
|
declare function defineLifecyclePlugin(plugin: LifecyclePlugin): LessonkitPlugin;
|
|
507
663
|
|
|
508
|
-
|
|
664
|
+
declare function buildPluginContext(opts: {
|
|
665
|
+
courseId: CourseId;
|
|
666
|
+
sessionId?: string;
|
|
667
|
+
attemptId?: string;
|
|
668
|
+
user?: TelemetryUser;
|
|
669
|
+
}): LessonkitPluginContext;
|
|
670
|
+
|
|
671
|
+
export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, type AccordionSectionToggledData, type AssessmentAnsweredData, type AssessmentBaseProps, type AssessmentBehaviour, type AssessmentCompletedData, type AssessmentHandle, type AssessmentInteractionType, type AssessmentPlugin, type AssessmentResumeState, type AssessmentScoreInput, type AssessmentScoreResult, type AssessmentXAPIData, type BlockId, type BookPageViewedData, type BuildTelemetryEventInput, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, type CheckId, type ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundPageViewedData, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, type CourseId, type CourseLifecycleContext, type CourseLifecycleDeps, type EmitContext, type FlashcardFlippedData, type HeadlessLessonkitConfig, type HeadlessLessonkitRuntime, type HeadlessRuntimePorts, type HotspotOpenedData, ID_MAX_LENGTH, ID_PATTERN, INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES, type IdentityIdPath, type IdentityValidationIssue, type IdentityValidationResult, type ImageSliderChangedData, type InteractionBlockRegistration, type InteractionData, type InteractionPlugin, type LessonCompletionEmitter, type LessonId, type LessonLifecycleData, type LessonkitPlugin, type LessonkitPluginContext, type LessonkitPluginKind, type LessonkitRuntimeVersion, type LessonkitUrn, type LessonkitUrnParts, type LifecyclePlugin, PAGE_ALLOWED_CHILD_TYPES, type PluginHost, type PluginIdentity, type PluginRegistry, type ProgressController, type ProgressState, type QuizAnsweredData, type QuizCompletedData, SESSION_STORAGE_KEY, type StoragePort, TELEMETRY_EVENT_CATALOG, TELEMETRY_EVENT_CATALOG_V2, TELEMETRY_EVENT_CATALOG_V3, type TelemetryBatchSink, type TelemetryCatalogEntry, type TelemetryCatalogV2Entry, type TelemetryCatalogV3Entry, type TelemetryDataFor, type TelemetryEmitFn, type TelemetryEvent, type TelemetryEventBase, type TelemetryEventName, type TelemetryPipeline, type TelemetryPipelineSink, type TelemetryPlugin, type TelemetrySink, type TelemetryUser, type TimerPort, type TrackingClient, assertNever, assertValidId, buildCourseStartedTelemetryEvent, buildLessonkitUrn, buildPluginContext, buildTelemetryCatalog, buildTelemetryCatalogV2, buildTelemetryCatalogV3, buildTelemetryEvent, clampCompoundPageIndex, clearCompoundState, completeCourseWithTelemetry, completeLessonWithTelemetry, compoundStateStorageKey, createCompoundResumeState, createDefaultClock, createGlobalTimer, createLessonkitRuntime, createNoopStorage, createPluginRegistry, createProgressController, createSessionId, createSessionStoragePort, createTelemetryPipeline, createTrackingClient, createTrackingPipelineSink, defineAssessmentPlugin, defineLifecyclePlugin, defineTelemetryPlugin, deriveId, getAllowedChildTypes, getTabSessionId, hasCourseStarted, hasCourseStartedEmittedToTracking, hasCourseStartedPipelineDelivered, isChildTypeAllowed, loadCompoundState, markCourseStarted, markCourseStartedEmittedToTracking, markCourseStartedPipelineDelivered, migrateCourseStartedMark, nowIso, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, resetStoragePortForTests, resetTelemetryBuilderWarningsForTests, resolveSessionId, saveCompoundState, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, tryBuildTelemetryEvent, tryEmitCourseStarted, validateId };
|