@lessonkit/core 1.0.2 → 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.d.cts CHANGED
@@ -54,7 +54,45 @@ type LessonkitUrnParts = {
54
54
  */
55
55
  declare function buildLessonkitUrn(parts: LessonkitUrnParts): LessonkitUrn;
56
56
 
57
- type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "interaction";
57
+ /** H5P-aligned interaction kinds for assessment telemetry and xAPI. */
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>;
61
+ /** Behaviour flags aligned with H5P question types. */
62
+ type AssessmentBehaviour = {
63
+ enableRetry?: boolean;
64
+ enableSolutionsButton?: boolean;
65
+ autoCheck?: boolean;
66
+ };
67
+ /** Payload for xAPI mapping from assessment components. */
68
+ type AssessmentXAPIData = {
69
+ checkId: CheckId;
70
+ interactionType: AssessmentInteractionType;
71
+ response?: string | string[] | boolean | Record<string, unknown>;
72
+ correct?: boolean;
73
+ score?: number;
74
+ maxScore?: number;
75
+ };
76
+ /**
77
+ * Imperative handle for scored blocks (H5P question-type contract analogue).
78
+ * Parent containers (`AssessmentSequence`, future compounds) may call these methods.
79
+ */
80
+ type AssessmentHandle = {
81
+ getScore: () => number;
82
+ getMaxScore: () => number;
83
+ getAnswerGiven: () => boolean;
84
+ resetTask: () => void;
85
+ showSolutions: () => void;
86
+ getXAPIData: () => AssessmentXAPIData;
87
+ getCurrentState?: () => AssessmentResumeState;
88
+ resume?: (state: AssessmentResumeState) => void;
89
+ };
90
+ type AssessmentBaseProps = AssessmentBehaviour & {
91
+ checkId: CheckId;
92
+ passingScore?: number;
93
+ };
94
+
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";
58
96
  type TelemetryUser = {
59
97
  id?: string;
60
98
  email?: string;
@@ -87,12 +125,54 @@ type QuizCompletedData = {
87
125
  maxScore?: number;
88
126
  passingScore?: number;
89
127
  };
128
+ type AssessmentAnsweredData = {
129
+ checkId: CheckId;
130
+ interactionType: AssessmentInteractionType;
131
+ question?: string;
132
+ response?: string | string[] | boolean | Record<string, unknown>;
133
+ correct?: boolean;
134
+ };
135
+ type AssessmentCompletedData = {
136
+ checkId: CheckId;
137
+ interactionType: AssessmentInteractionType;
138
+ score?: number;
139
+ maxScore?: number;
140
+ passingScore?: number;
141
+ };
90
142
  type InteractionData = {
91
143
  kind?: string;
92
144
  blockId?: BlockId;
93
145
  payload?: Record<string, unknown>;
94
146
  [key: string]: unknown;
95
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
+ };
96
176
  type TelemetryEvent = (TelemetryEventBase & {
97
177
  name: "course_started";
98
178
  lessonId?: LessonId;
@@ -121,10 +201,42 @@ type TelemetryEvent = (TelemetryEventBase & {
121
201
  name: "quiz_completed";
122
202
  lessonId: LessonId;
123
203
  data: QuizCompletedData;
204
+ }) | (TelemetryEventBase & {
205
+ name: "assessment_answered";
206
+ lessonId: LessonId;
207
+ data: AssessmentAnsweredData;
208
+ }) | (TelemetryEventBase & {
209
+ name: "assessment_completed";
210
+ lessonId: LessonId;
211
+ data: AssessmentCompletedData;
124
212
  }) | (TelemetryEventBase & {
125
213
  name: "interaction";
126
214
  lessonId?: LessonId;
127
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;
128
240
  });
129
241
  /** Payload shape for a telemetry event name. */
130
242
  type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
@@ -140,6 +252,78 @@ type TrackingClient = {
140
252
  dispose?: () => void | Promise<void>;
141
253
  };
142
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
+
143
327
  declare const telemetryCatalogVersion: 1;
144
328
  type TelemetryCatalogEntry = {
145
329
  name: TelemetryEventName;
@@ -152,6 +336,31 @@ type TelemetryCatalogEntry = {
152
336
  declare const TELEMETRY_EVENT_CATALOG: TelemetryCatalogEntry[];
153
337
  declare function buildTelemetryCatalog(): TelemetryCatalogEntry[];
154
338
 
339
+ declare const telemetryCatalogV2Version: 2;
340
+ type TelemetryCatalogV2Entry = {
341
+ name: Extract<TelemetryEventName, "assessment_answered" | "assessment_completed">;
342
+ description: string;
343
+ requiredFields: string[];
344
+ dataFields: string[];
345
+ xapiVerb: string;
346
+ urnPattern: string;
347
+ };
348
+ declare const TELEMETRY_EVENT_CATALOG_V2: TelemetryCatalogV2Entry[];
349
+ declare function buildTelemetryCatalogV2(): TelemetryCatalogV2Entry[];
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
+
155
364
  declare function createTrackingClient(opts?: {
156
365
  sink?: TelemetrySink;
157
366
  batch?: {
@@ -201,11 +410,44 @@ type BuildTelemetryEventInput = (BuildTelemetryEventContext & {
201
410
  name: "quiz_completed";
202
411
  lessonId?: LessonId;
203
412
  data: QuizCompletedData;
413
+ }) | (BuildTelemetryEventContext & {
414
+ name: "assessment_answered";
415
+ lessonId?: LessonId;
416
+ data: AssessmentAnsweredData;
417
+ }) | (BuildTelemetryEventContext & {
418
+ name: "assessment_completed";
419
+ lessonId?: LessonId;
420
+ data: AssessmentCompletedData;
204
421
  }) | (BuildTelemetryEventContext & {
205
422
  name: "interaction";
206
423
  lessonId?: LessonId;
207
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;
208
449
  });
450
+
209
451
  /** Reset dev-warning state (tests only). */
210
452
  declare function resetTelemetryBuilderWarningsForTests(): void;
211
453
  /**
@@ -235,27 +477,6 @@ type TelemetryPipeline = {
235
477
  declare function createTelemetryPipeline(sinks: TelemetryPipelineSink[]): TelemetryPipeline;
236
478
  declare function createTrackingPipelineSink(id: string, track: (event: TelemetryEvent) => void): TelemetryPipelineSink;
237
479
 
238
- type StoragePort = {
239
- getItem: (key: string) => string | null;
240
- setItem: (key: string, value: string) => void;
241
- removeItem?: (key: string) => void;
242
- /** @internal Test helper to clear in-memory fallback state. */
243
- resetForTests?: () => void;
244
- };
245
- type ClockPort = {
246
- nowMs: () => number;
247
- nowIso: () => string;
248
- };
249
- type TimerPort = {
250
- setInterval: (fn: () => void, ms: number) => ReturnType<typeof globalThis.setInterval>;
251
- clearInterval: (id: ReturnType<typeof globalThis.setInterval>) => void;
252
- };
253
- declare function createDefaultClock(): ClockPort;
254
- declare function createNoopStorage(): StoragePort;
255
- declare function resetStoragePortForTests(storage: StoragePort): void;
256
- declare function createSessionStoragePort(): StoragePort;
257
- declare function createGlobalTimer(): TimerPort;
258
-
259
480
  type ProgressState = {
260
481
  activeLessonId?: LessonId;
261
482
  completedLessonIds: ReadonlySet<LessonId>;
@@ -334,7 +555,10 @@ type AssessmentPlugin = PluginIdentity & {
334
555
  kind: "assessment";
335
556
  scoreAssessment?: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
336
557
  };
337
- /** Narrow interaction metadata plugin (ISP). */
558
+ /**
559
+ * Narrow interaction metadata plugin (ISP).
560
+ * @experimental Not wired into PluginHost; reserved for a future release.
561
+ */
338
562
  type InteractionPlugin = PluginIdentity & {
339
563
  interactionBlocks?: InteractionBlockRegistration[];
340
564
  };
@@ -388,6 +612,7 @@ declare function completeCourseWithTelemetry(opts: {
388
612
  }): boolean;
389
613
 
390
614
  type LessonkitRuntimeVersion = "v1" | "v2";
615
+ type HeadlessLessonkitPlugins = readonly LessonkitPlugin[] | PluginRegistry | null | undefined;
391
616
  type HeadlessLessonkitConfig = {
392
617
  courseId: CourseId;
393
618
  runtimeVersion?: LessonkitRuntimeVersion;
@@ -396,7 +621,8 @@ type HeadlessLessonkitConfig = {
396
621
  attemptId?: string;
397
622
  user?: TelemetryUser;
398
623
  };
399
- plugins?: PluginRegistry | null;
624
+ /** Plugin list or registry; hooks run on {@link HeadlessLessonkitRuntime.track} and lifecycle emits. */
625
+ plugins?: HeadlessLessonkitPlugins;
400
626
  };
401
627
  type HeadlessRuntimePorts = {
402
628
  storage?: StoragePort;
@@ -408,6 +634,7 @@ type TelemetryEmitFn = {
408
634
  type HeadlessLessonkitRuntime = {
409
635
  readonly config: HeadlessLessonkitConfig;
410
636
  readonly progress: ProgressController;
637
+ readonly pluginHost: PluginHost | null;
411
638
  getProgressState: () => ProgressState;
412
639
  getSession: () => {
413
640
  sessionId: string;
@@ -419,14 +646,26 @@ type HeadlessLessonkitRuntime = {
419
646
  completeLesson: (lessonId: LessonId, emit: TelemetryEmitFn) => void;
420
647
  completeCourse: (emit: TelemetryEmitFn) => void;
421
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;
422
650
  resetForCourseChange: (courseId: CourseId) => void;
651
+ dispose: () => void;
423
652
  };
424
653
  declare function createLessonkitRuntime(config: HeadlessLessonkitConfig, ports?: HeadlessRuntimePorts): HeadlessLessonkitRuntime;
425
654
 
426
655
  declare function createPluginRegistry(plugins?: readonly LessonkitPlugin[]): PluginRegistry;
427
656
 
657
+ /** Identity helper for telemetry plugins; does not validate or register at import time. */
428
658
  declare function defineTelemetryPlugin(plugin: TelemetryPlugin): LessonkitPlugin;
659
+ /** Identity helper for assessment plugins; does not validate or register at import time. */
429
660
  declare function defineAssessmentPlugin(plugin: AssessmentPlugin): LessonkitPlugin;
661
+ /** Identity helper for lifecycle plugins; does not validate or register at import time. */
430
662
  declare function defineLifecyclePlugin(plugin: LifecyclePlugin): LessonkitPlugin;
431
663
 
432
- export { type AssessmentPlugin, type AssessmentScoreInput, type AssessmentScoreResult, type BlockId, type BuildTelemetryEventInput, type CheckId, type ClockPort, type CourseId, type CourseLifecycleContext, type CourseLifecycleDeps, type EmitContext, type HeadlessLessonkitConfig, type HeadlessLessonkitRuntime, type HeadlessRuntimePorts, ID_MAX_LENGTH, ID_PATTERN, type IdentityIdPath, type IdentityValidationIssue, type IdentityValidationResult, 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, type PluginHost, type PluginIdentity, type PluginRegistry, type ProgressController, type ProgressState, type QuizAnsweredData, type QuizCompletedData, SESSION_STORAGE_KEY, type StoragePort, TELEMETRY_EVENT_CATALOG, type TelemetryBatchSink, type TelemetryCatalogEntry, 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, buildTelemetryCatalog, buildTelemetryEvent, completeCourseWithTelemetry, completeLessonWithTelemetry, createDefaultClock, createGlobalTimer, createLessonkitRuntime, createNoopStorage, createPluginRegistry, createProgressController, createSessionId, createSessionStoragePort, createTelemetryPipeline, createTrackingClient, createTrackingPipelineSink, defineAssessmentPlugin, defineLifecyclePlugin, defineTelemetryPlugin, deriveId, getTabSessionId, hasCourseStarted, hasCourseStartedEmittedToTracking, hasCourseStartedPipelineDelivered, markCourseStarted, markCourseStartedEmittedToTracking, markCourseStartedPipelineDelivered, migrateCourseStartedMark, nowIso, parseBlockId, parseCheckId, parseCourseId, parseLessonId, resetStoragePortForTests, resetTelemetryBuilderWarningsForTests, resolveSessionId, slugifyId, telemetryCatalogVersion, tryBuildTelemetryEvent, tryEmitCourseStarted, validateId };
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 };