@lessonkit/core 1.3.0 → 1.4.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/chunk-PEWFPVQ6.js +628 -0
- package/dist/index.cjs +285 -36
- package/dist/index.d.cts +16 -481
- package/dist/index.d.ts +16 -481
- package/dist/index.js +216 -535
- package/dist/testing-BhVGckZ5.d.cts +569 -0
- package/dist/testing-BhVGckZ5.d.ts +569 -0
- package/dist/testing.cjs +60 -0
- package/dist/testing.d.cts +1 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.js +12 -0
- package/package.json +9 -4
- package/telemetry-catalog.v3.json +170 -14
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type CheckId = string;
|
|
4
|
-
type BlockId = string;
|
|
5
|
-
/** Stable URN string returned by {@link buildLessonkitUrn}. */
|
|
6
|
-
type LessonkitUrn = string;
|
|
7
|
-
type IdentityValidationIssue = {
|
|
8
|
-
path: string;
|
|
9
|
-
message: string;
|
|
10
|
-
};
|
|
11
|
-
type IdentityValidationResult = {
|
|
12
|
-
ok: true;
|
|
13
|
-
id: string;
|
|
14
|
-
} | {
|
|
15
|
-
ok: false;
|
|
16
|
-
issues: IdentityValidationIssue[];
|
|
17
|
-
};
|
|
18
|
-
type IdentityIdPath = "courseId" | "lessonId" | "checkId" | "blockId" | "id";
|
|
19
|
-
/** LessonKit id format: letter first, then alphanumeric, `_`, `-`; length 1–64. */
|
|
20
|
-
declare const ID_PATTERN: RegExp;
|
|
21
|
-
declare const ID_MAX_LENGTH = 64;
|
|
1
|
+
import { p as CourseId, E as LessonId, C as CheckId, B as BlockId, t as IdentityIdPath, v as IdentityValidationResult, N as LessonkitUrn, h as AssessmentResumeState, a0 as StoragePort, a5 as TelemetryEventName, a7 as TelemetrySink, a1 as TelemetryBatchSink, aa as TrackingClient, a3 as TelemetryEvent, a8 as TelemetryUser, J as LessonkitPlugin, U as PluginRegistry, V as ProgressController, S as PluginHost, W as ProgressState, a2 as TelemetryDataFor, i as AssessmentScoreInput, j as AssessmentScoreResult, n as ClockPort, g as AssessmentPlugin, O as LifecyclePlugin, a6 as TelemetryPlugin, K as LessonkitPluginContext } from './testing-BhVGckZ5.js';
|
|
2
|
+
export { A as AccordionSectionToggledData, a as AssessmentAnsweredData, b as AssessmentBaseProps, c as AssessmentBehaviour, d as AssessmentCompletedData, e as AssessmentHandle, f as AssessmentInteractionType, k as AssessmentXAPIData, l as BookPageViewedData, m as BuildTelemetryEventInput, o as CompoundPageViewedData, q as CourseLifecycleContext, r as CourseLifecycleDeps, F as FlashcardFlippedData, H as HotspotOpenedData, I as ID_MAX_LENGTH, s as ID_PATTERN, u as IdentityValidationIssue, w as ImageSliderChangedData, x as InformationWallSearchData, y as InteractionBlockRegistration, z as InteractionData, D as InteractionPlugin, L as LessonCompletionEmitter, G as LessonLifecycleData, M as LessonkitPluginKind, P as McqAssessmentProps, Q as MemoryCardFlippedData, R as ParallaxSlideViewedData, T as PluginIdentity, X as QuestionnaireSubmittedData, Y as QuizAnsweredData, Z as QuizCompletedData, _ as SESSION_STORAGE_KEY, $ as SlideViewedData, a4 as TelemetryEventBase, a9 as TimerPort, ab as VideoCueReachedData, ac as VideoSegmentCompletedData, ad as buildCourseStartedTelemetryEvent, ae as buildTelemetryEvent, af as completeCourseWithTelemetry, ag as completeLessonWithTelemetry, ah as createDefaultClock, ai as createGlobalTimer, aj as createNoopStorage, ak as createProgressController, al as createSessionStoragePort, am as getTabSessionId, an as hasCourseStarted, ao as hasCourseStartedEmittedToTracking, ap as hasCourseStartedPipelineDelivered, aq as markCourseStarted, ar as markCourseStartedEmittedToTracking, as as markCourseStartedPipelineDelivered, at as migrateCourseStartedMark, av as resetSharedVolatileSessionIdForTests, aw as resetStoragePortForTests, ax as resetTelemetryBuilderWarningsForTests, ay as resolveSessionId, az as tryBuildTelemetryEvent, aA as tryEmitCourseStarted } from './testing-BhVGckZ5.js';
|
|
22
3
|
|
|
23
4
|
/**
|
|
24
5
|
* Exhaustiveness helper for switch/default branches.
|
|
@@ -54,213 +35,8 @@ type LessonkitUrnParts = {
|
|
|
54
35
|
*/
|
|
55
36
|
declare function buildLessonkitUrn(parts: LessonkitUrnParts): LessonkitUrn;
|
|
56
37
|
|
|
57
|
-
/**
|
|
58
|
-
type
|
|
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" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed";
|
|
96
|
-
type TelemetryUser = {
|
|
97
|
-
id?: string;
|
|
98
|
-
email?: string;
|
|
99
|
-
name?: string;
|
|
100
|
-
[key: string]: unknown;
|
|
101
|
-
};
|
|
102
|
-
type TelemetryEventBase = {
|
|
103
|
-
timestamp: string;
|
|
104
|
-
courseId: CourseId;
|
|
105
|
-
sessionId?: string;
|
|
106
|
-
attemptId?: string;
|
|
107
|
-
user?: TelemetryUser;
|
|
108
|
-
};
|
|
109
|
-
type LessonLifecycleData = {
|
|
110
|
-
lessonId: LessonId;
|
|
111
|
-
durationMs?: number;
|
|
112
|
-
success?: boolean;
|
|
113
|
-
score?: number;
|
|
114
|
-
maxScore?: number;
|
|
115
|
-
};
|
|
116
|
-
type QuizAnsweredData = {
|
|
117
|
-
checkId: CheckId;
|
|
118
|
-
question: string;
|
|
119
|
-
choice: string;
|
|
120
|
-
correct: boolean;
|
|
121
|
-
};
|
|
122
|
-
type QuizCompletedData = {
|
|
123
|
-
checkId: CheckId;
|
|
124
|
-
score?: number;
|
|
125
|
-
maxScore?: number;
|
|
126
|
-
passingScore?: number;
|
|
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
|
-
};
|
|
142
|
-
type InteractionData = {
|
|
143
|
-
kind?: string;
|
|
144
|
-
blockId?: BlockId;
|
|
145
|
-
payload?: Record<string, unknown>;
|
|
146
|
-
[key: string]: unknown;
|
|
147
|
-
};
|
|
148
|
-
type BookPageViewedData = {
|
|
149
|
-
blockId: BlockId;
|
|
150
|
-
pageIndex: number;
|
|
151
|
-
pageTitle?: string;
|
|
152
|
-
};
|
|
153
|
-
type SlideViewedData = {
|
|
154
|
-
blockId: BlockId;
|
|
155
|
-
slideIndex: number;
|
|
156
|
-
slideTitle?: string;
|
|
157
|
-
};
|
|
158
|
-
type CompoundPageViewedData = {
|
|
159
|
-
blockId: BlockId;
|
|
160
|
-
pageIndex: number;
|
|
161
|
-
parentType?: string;
|
|
162
|
-
};
|
|
163
|
-
type HotspotOpenedData = {
|
|
164
|
-
blockId: BlockId;
|
|
165
|
-
hotspotId: string;
|
|
166
|
-
};
|
|
167
|
-
type AccordionSectionToggledData = {
|
|
168
|
-
blockId: BlockId;
|
|
169
|
-
sectionId: string;
|
|
170
|
-
expanded: boolean;
|
|
171
|
-
};
|
|
172
|
-
type FlashcardFlippedData = {
|
|
173
|
-
blockId: BlockId;
|
|
174
|
-
cardIndex: number;
|
|
175
|
-
face: "front" | "back";
|
|
176
|
-
};
|
|
177
|
-
type ImageSliderChangedData = {
|
|
178
|
-
blockId: BlockId;
|
|
179
|
-
slideIndex: number;
|
|
180
|
-
};
|
|
181
|
-
type TelemetryEvent = (TelemetryEventBase & {
|
|
182
|
-
name: "course_started";
|
|
183
|
-
lessonId?: LessonId;
|
|
184
|
-
data?: undefined;
|
|
185
|
-
}) | (TelemetryEventBase & {
|
|
186
|
-
name: "course_completed";
|
|
187
|
-
lessonId?: LessonId;
|
|
188
|
-
data?: undefined;
|
|
189
|
-
}) | (TelemetryEventBase & {
|
|
190
|
-
name: "lesson_started";
|
|
191
|
-
lessonId: LessonId;
|
|
192
|
-
data: LessonLifecycleData;
|
|
193
|
-
}) | (TelemetryEventBase & {
|
|
194
|
-
name: "lesson_completed";
|
|
195
|
-
lessonId: LessonId;
|
|
196
|
-
data: LessonLifecycleData;
|
|
197
|
-
}) | (TelemetryEventBase & {
|
|
198
|
-
name: "lesson_time_on_task";
|
|
199
|
-
lessonId: LessonId;
|
|
200
|
-
data: LessonLifecycleData;
|
|
201
|
-
}) | (TelemetryEventBase & {
|
|
202
|
-
name: "quiz_answered";
|
|
203
|
-
lessonId: LessonId;
|
|
204
|
-
data: QuizAnsweredData;
|
|
205
|
-
}) | (TelemetryEventBase & {
|
|
206
|
-
name: "quiz_completed";
|
|
207
|
-
lessonId: LessonId;
|
|
208
|
-
data: QuizCompletedData;
|
|
209
|
-
}) | (TelemetryEventBase & {
|
|
210
|
-
name: "assessment_answered";
|
|
211
|
-
lessonId: LessonId;
|
|
212
|
-
data: AssessmentAnsweredData;
|
|
213
|
-
}) | (TelemetryEventBase & {
|
|
214
|
-
name: "assessment_completed";
|
|
215
|
-
lessonId: LessonId;
|
|
216
|
-
data: AssessmentCompletedData;
|
|
217
|
-
}) | (TelemetryEventBase & {
|
|
218
|
-
name: "interaction";
|
|
219
|
-
lessonId?: LessonId;
|
|
220
|
-
data?: InteractionData;
|
|
221
|
-
}) | (TelemetryEventBase & {
|
|
222
|
-
name: "book_page_viewed";
|
|
223
|
-
lessonId: LessonId;
|
|
224
|
-
data: BookPageViewedData;
|
|
225
|
-
}) | (TelemetryEventBase & {
|
|
226
|
-
name: "slide_viewed";
|
|
227
|
-
lessonId: LessonId;
|
|
228
|
-
data: SlideViewedData;
|
|
229
|
-
}) | (TelemetryEventBase & {
|
|
230
|
-
name: "compound_page_viewed";
|
|
231
|
-
lessonId: LessonId;
|
|
232
|
-
data: CompoundPageViewedData;
|
|
233
|
-
}) | (TelemetryEventBase & {
|
|
234
|
-
name: "hotspot_opened";
|
|
235
|
-
lessonId?: LessonId;
|
|
236
|
-
data: HotspotOpenedData;
|
|
237
|
-
}) | (TelemetryEventBase & {
|
|
238
|
-
name: "accordion_section_toggled";
|
|
239
|
-
lessonId?: LessonId;
|
|
240
|
-
data: AccordionSectionToggledData;
|
|
241
|
-
}) | (TelemetryEventBase & {
|
|
242
|
-
name: "flashcard_flipped";
|
|
243
|
-
lessonId?: LessonId;
|
|
244
|
-
data: FlashcardFlippedData;
|
|
245
|
-
}) | (TelemetryEventBase & {
|
|
246
|
-
name: "image_slider_changed";
|
|
247
|
-
lessonId?: LessonId;
|
|
248
|
-
data: ImageSliderChangedData;
|
|
249
|
-
});
|
|
250
|
-
/** Payload shape for a telemetry event name. */
|
|
251
|
-
type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
|
|
252
|
-
name: N;
|
|
253
|
-
}> extends {
|
|
254
|
-
data?: infer D;
|
|
255
|
-
} ? D : never;
|
|
256
|
-
type TelemetrySink = (event: TelemetryEvent) => void | Promise<void>;
|
|
257
|
-
type TelemetryBatchSink = (events: TelemetryEvent[]) => void | Promise<void>;
|
|
258
|
-
type TrackingClient = {
|
|
259
|
-
track: (event: TelemetryEvent) => void;
|
|
260
|
-
/** Resolves to true when all buffered events were delivered; false when a sink failure re-queued events. */
|
|
261
|
-
flush?: () => void | Promise<boolean>;
|
|
262
|
-
dispose?: () => void | Promise<void>;
|
|
263
|
-
};
|
|
38
|
+
/** LMS parent-bridge forwarding mode for packaged course runtimes. */
|
|
39
|
+
type LmsBridgeMode = "auto" | "off";
|
|
264
40
|
|
|
265
41
|
declare const COMPOUND_RESUME_SCHEMA_VERSION: 1;
|
|
266
42
|
/** Serializable resume blob for a compound container (InteractiveBook, AssessmentSequence, …). */
|
|
@@ -297,46 +73,28 @@ type CompoundBaseProps = {
|
|
|
297
73
|
blockId: BlockId;
|
|
298
74
|
};
|
|
299
75
|
|
|
300
|
-
type StoragePort = {
|
|
301
|
-
getItem: (key: string) => string | null;
|
|
302
|
-
/** Returns false when the value could not be durably persisted (e.g. sessionStorage quota). */
|
|
303
|
-
setItem: (key: string, value: string) => boolean;
|
|
304
|
-
removeItem?: (key: string) => void;
|
|
305
|
-
/** @internal Test helper to clear in-memory fallback state. */
|
|
306
|
-
resetForTests?: () => void;
|
|
307
|
-
};
|
|
308
|
-
type ClockPort = {
|
|
309
|
-
nowMs: () => number;
|
|
310
|
-
nowIso: () => string;
|
|
311
|
-
};
|
|
312
|
-
type TimerPort = {
|
|
313
|
-
setInterval: (fn: () => void, ms: number) => ReturnType<typeof globalThis.setInterval>;
|
|
314
|
-
clearInterval: (id: ReturnType<typeof globalThis.setInterval>) => void;
|
|
315
|
-
};
|
|
316
|
-
declare function createDefaultClock(): ClockPort;
|
|
317
|
-
declare function createNoopStorage(): StoragePort;
|
|
318
|
-
declare function resetStoragePortForTests(storage: StoragePort): void;
|
|
319
|
-
declare function createSessionStoragePort(): StoragePort;
|
|
320
|
-
declare function createGlobalTimer(): TimerPort;
|
|
321
|
-
|
|
322
76
|
declare function compoundStateStorageKey(courseId: CourseId, compoundId: BlockId): string;
|
|
323
77
|
declare function loadCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): CompoundResumeState | null;
|
|
324
78
|
declare function saveCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId, state: CompoundResumeState): boolean;
|
|
325
79
|
declare function clearCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): void;
|
|
326
80
|
|
|
327
81
|
/** Canonical compound child allowlists (H5P sub-content curation). */
|
|
328
|
-
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"];
|
|
82
|
+
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", "ProgressTracker"];
|
|
329
83
|
declare const INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES: readonly ["Page"];
|
|
330
84
|
/** Per-slide content (H5P Course Presentation slide row). Excludes ProgressTracker. */
|
|
331
|
-
declare const SLIDE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Scenario", "Reflection", "Quiz", "KnowledgeCheck", "TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Accordion", "DialogCards", "Flashcards", "ImageHotspots", "FindHotspot", "FindMultipleHotspots", "ImageSlider"];
|
|
85
|
+
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"];
|
|
332
86
|
declare const SLIDE_DECK_ALLOWED_CHILD_TYPES: readonly ["Slide"];
|
|
333
|
-
declare const
|
|
334
|
-
|
|
87
|
+
declare const TIMED_CUE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Quiz", "TrueFalse", "FillInTheBlanks", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "Questionnaire", "Essay", "ArithmeticQuiz"];
|
|
88
|
+
declare const INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES: readonly ["TimedCue"];
|
|
89
|
+
declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots", "Summary", "ImagePairing", "ImageSequencing", "ArithmeticQuiz", "Essay"];
|
|
90
|
+
type CompoundParentType = "Page" | "InteractiveBook" | "Slide" | "SlideDeck" | "TimedCue" | "InteractiveVideo" | "AssessmentSequence";
|
|
335
91
|
declare const COMPOUND_MAX_NESTING_DEPTH: Record<CompoundParentType, number>;
|
|
336
92
|
declare function getAllowedChildTypes(parent: CompoundParentType): readonly string[];
|
|
337
93
|
declare function isChildTypeAllowed(parent: CompoundParentType, childType: string): boolean;
|
|
338
94
|
/** Blocks that must not nest inside Accordion (policy: no accordion-in-accordion). */
|
|
339
95
|
declare const ACCORDION_FORBIDDEN_CHILD_TYPES: readonly ["Accordion"];
|
|
96
|
+
/** New 1.4 blocks added to Page and Slide allowlists (for docs/tests). */
|
|
97
|
+
declare const BLOCKS_14_PAGE_SLIDE: readonly ["Video", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "InformationWall", "ParallaxSlideshow", "Questionnaire", "Essay", "ArithmeticQuiz"];
|
|
340
98
|
|
|
341
99
|
declare const telemetryCatalogVersion: 1;
|
|
342
100
|
type TelemetryCatalogEntry = {
|
|
@@ -363,7 +121,7 @@ declare const TELEMETRY_EVENT_CATALOG_V2: TelemetryCatalogV2Entry[];
|
|
|
363
121
|
declare function buildTelemetryCatalogV2(): TelemetryCatalogV2Entry[];
|
|
364
122
|
|
|
365
123
|
declare const telemetryCatalogV3Version: 3;
|
|
366
|
-
type TelemetryCatalogV3EventName = Extract<TelemetryEventName, "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed">;
|
|
124
|
+
type TelemetryCatalogV3EventName = Extract<TelemetryEventName, "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">;
|
|
367
125
|
type TelemetryCatalogV3Entry = {
|
|
368
126
|
name: TelemetryCatalogV3EventName;
|
|
369
127
|
description: string;
|
|
@@ -385,101 +143,14 @@ declare function createTrackingClient(opts?: {
|
|
|
385
143
|
batchSink?: TelemetryBatchSink;
|
|
386
144
|
/** Called when an event is dropped because the batch buffer is at cap (including in production). */
|
|
387
145
|
onBufferDrop?: () => void;
|
|
146
|
+
/** Keepalive batch delivery for pagehide (e.g. from createFetchBatchSink). */
|
|
147
|
+
exitBatchSink?: TelemetryBatchSink;
|
|
388
148
|
}): TrackingClient;
|
|
389
149
|
|
|
390
150
|
declare function createSessionId(): string;
|
|
391
151
|
|
|
392
152
|
declare function nowIso(): string;
|
|
393
153
|
|
|
394
|
-
type BuildTelemetryEventContext = {
|
|
395
|
-
courseId: CourseId;
|
|
396
|
-
sessionId?: string;
|
|
397
|
-
attemptId?: string;
|
|
398
|
-
user?: TelemetryUser;
|
|
399
|
-
timestamp?: string;
|
|
400
|
-
};
|
|
401
|
-
type BuildTelemetryEventInput = (BuildTelemetryEventContext & {
|
|
402
|
-
name: "course_started";
|
|
403
|
-
lessonId?: LessonId;
|
|
404
|
-
data?: undefined;
|
|
405
|
-
}) | (BuildTelemetryEventContext & {
|
|
406
|
-
name: "course_completed";
|
|
407
|
-
lessonId?: LessonId;
|
|
408
|
-
data?: undefined;
|
|
409
|
-
}) | (BuildTelemetryEventContext & {
|
|
410
|
-
name: "lesson_started";
|
|
411
|
-
lessonId?: LessonId;
|
|
412
|
-
data?: LessonLifecycleData;
|
|
413
|
-
}) | (BuildTelemetryEventContext & {
|
|
414
|
-
name: "lesson_completed";
|
|
415
|
-
lessonId?: LessonId;
|
|
416
|
-
data?: LessonLifecycleData;
|
|
417
|
-
}) | (BuildTelemetryEventContext & {
|
|
418
|
-
name: "lesson_time_on_task";
|
|
419
|
-
lessonId?: LessonId;
|
|
420
|
-
data?: LessonLifecycleData;
|
|
421
|
-
}) | (BuildTelemetryEventContext & {
|
|
422
|
-
name: "quiz_answered";
|
|
423
|
-
lessonId?: LessonId;
|
|
424
|
-
data: QuizAnsweredData;
|
|
425
|
-
}) | (BuildTelemetryEventContext & {
|
|
426
|
-
name: "quiz_completed";
|
|
427
|
-
lessonId?: LessonId;
|
|
428
|
-
data: QuizCompletedData;
|
|
429
|
-
}) | (BuildTelemetryEventContext & {
|
|
430
|
-
name: "assessment_answered";
|
|
431
|
-
lessonId?: LessonId;
|
|
432
|
-
data: AssessmentAnsweredData;
|
|
433
|
-
}) | (BuildTelemetryEventContext & {
|
|
434
|
-
name: "assessment_completed";
|
|
435
|
-
lessonId?: LessonId;
|
|
436
|
-
data: AssessmentCompletedData;
|
|
437
|
-
}) | (BuildTelemetryEventContext & {
|
|
438
|
-
name: "interaction";
|
|
439
|
-
lessonId?: LessonId;
|
|
440
|
-
data?: InteractionData;
|
|
441
|
-
}) | (BuildTelemetryEventContext & {
|
|
442
|
-
name: "book_page_viewed";
|
|
443
|
-
lessonId?: LessonId;
|
|
444
|
-
data: BookPageViewedData;
|
|
445
|
-
}) | (BuildTelemetryEventContext & {
|
|
446
|
-
name: "slide_viewed";
|
|
447
|
-
lessonId?: LessonId;
|
|
448
|
-
data: SlideViewedData;
|
|
449
|
-
}) | (BuildTelemetryEventContext & {
|
|
450
|
-
name: "compound_page_viewed";
|
|
451
|
-
lessonId?: LessonId;
|
|
452
|
-
data: CompoundPageViewedData;
|
|
453
|
-
}) | (BuildTelemetryEventContext & {
|
|
454
|
-
name: "hotspot_opened";
|
|
455
|
-
lessonId?: LessonId;
|
|
456
|
-
data: HotspotOpenedData;
|
|
457
|
-
}) | (BuildTelemetryEventContext & {
|
|
458
|
-
name: "accordion_section_toggled";
|
|
459
|
-
lessonId?: LessonId;
|
|
460
|
-
data: AccordionSectionToggledData;
|
|
461
|
-
}) | (BuildTelemetryEventContext & {
|
|
462
|
-
name: "flashcard_flipped";
|
|
463
|
-
lessonId?: LessonId;
|
|
464
|
-
data: FlashcardFlippedData;
|
|
465
|
-
}) | (BuildTelemetryEventContext & {
|
|
466
|
-
name: "image_slider_changed";
|
|
467
|
-
lessonId?: LessonId;
|
|
468
|
-
data: ImageSliderChangedData;
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
/** Reset dev-warning state (tests only). */
|
|
472
|
-
declare function resetTelemetryBuilderWarningsForTests(): void;
|
|
473
|
-
/**
|
|
474
|
-
* Build a typed telemetry event from a catalog event name and context.
|
|
475
|
-
* Validates lesson-scoped events require `lessonId`.
|
|
476
|
-
*/
|
|
477
|
-
declare function buildTelemetryEvent(opts: BuildTelemetryEventInput): TelemetryEvent;
|
|
478
|
-
/**
|
|
479
|
-
* Like `buildTelemetryEvent`, but returns null (with a dev warning) when quiz events lack an active lesson.
|
|
480
|
-
*/
|
|
481
|
-
declare function tryBuildTelemetryEvent(opts: BuildTelemetryEventInput): TelemetryEvent | null;
|
|
482
|
-
|
|
483
154
|
type EmitContext = {
|
|
484
155
|
courseId: CourseId;
|
|
485
156
|
sessionId?: string;
|
|
@@ -497,142 +168,6 @@ type TelemetryPipeline = {
|
|
|
497
168
|
declare function createTelemetryPipeline(sinks: TelemetryPipelineSink[]): TelemetryPipeline;
|
|
498
169
|
declare function createTrackingPipelineSink(id: string, track: (event: TelemetryEvent) => void): TelemetryPipelineSink;
|
|
499
170
|
|
|
500
|
-
type ProgressState = {
|
|
501
|
-
activeLessonId?: LessonId;
|
|
502
|
-
completedLessonIds: ReadonlySet<LessonId>;
|
|
503
|
-
courseCompleted: boolean;
|
|
504
|
-
};
|
|
505
|
-
type ProgressController = {
|
|
506
|
-
getState: () => ProgressState;
|
|
507
|
-
setActiveLesson: (lessonId: LessonId, startedAtMs: number) => {
|
|
508
|
-
previousLessonId?: LessonId;
|
|
509
|
-
};
|
|
510
|
-
completeLesson: (lessonId: LessonId, completedAtMs: number) => {
|
|
511
|
-
durationMs?: number;
|
|
512
|
-
didComplete: boolean;
|
|
513
|
-
};
|
|
514
|
-
completeCourse: () => {
|
|
515
|
-
didComplete: boolean;
|
|
516
|
-
};
|
|
517
|
-
};
|
|
518
|
-
declare function createProgressController(): ProgressController;
|
|
519
|
-
|
|
520
|
-
declare const SESSION_STORAGE_KEY = "lessonkit:sessionId";
|
|
521
|
-
declare function getTabSessionId(storage: StoragePort): string | null;
|
|
522
|
-
declare function resolveSessionId(storage: StoragePort, provided?: string): string;
|
|
523
|
-
declare function hasCourseStarted(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
524
|
-
declare function markCourseStarted(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
525
|
-
declare function hasCourseStartedEmittedToTracking(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
526
|
-
declare function markCourseStartedEmittedToTracking(storage: StoragePort, sessionId: string, courseId?: CourseId): void;
|
|
527
|
-
declare function hasCourseStartedPipelineDelivered(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
|
|
528
|
-
declare function markCourseStartedPipelineDelivered(storage: StoragePort, sessionId: string, courseId?: CourseId): void;
|
|
529
|
-
/** @internal Reset shared volatile session id between tests. */
|
|
530
|
-
declare function resetSharedVolatileSessionIdForTests(): void;
|
|
531
|
-
declare function migrateCourseStartedMark(storage: StoragePort, fromSessionId: string, toSessionId: string, courseId?: CourseId): void;
|
|
532
|
-
|
|
533
|
-
/** Plugin category — aligns with roadmap extension areas. */
|
|
534
|
-
type LessonkitPluginKind = "analytics" | "lms" | "assessment" | "interaction" | "ai";
|
|
535
|
-
type LessonkitPluginContext = {
|
|
536
|
-
courseId: CourseId;
|
|
537
|
-
sessionId?: string;
|
|
538
|
-
attemptId?: string;
|
|
539
|
-
user?: TelemetryUser;
|
|
540
|
-
};
|
|
541
|
-
type AssessmentScoreInput = {
|
|
542
|
-
checkId: CheckId;
|
|
543
|
-
lessonId?: LessonId;
|
|
544
|
-
response: unknown;
|
|
545
|
-
};
|
|
546
|
-
type AssessmentScoreResult = {
|
|
547
|
-
score: number;
|
|
548
|
-
maxScore?: number;
|
|
549
|
-
passed?: boolean;
|
|
550
|
-
feedback?: string;
|
|
551
|
-
};
|
|
552
|
-
/** Metadata for custom interaction blocks (renderer wiring stays in app code until 1.0). */
|
|
553
|
-
type InteractionBlockRegistration = {
|
|
554
|
-
blockType: string;
|
|
555
|
-
catalogVersion?: string;
|
|
556
|
-
description?: string;
|
|
557
|
-
};
|
|
558
|
-
type PluginIdentity = {
|
|
559
|
-
id: string;
|
|
560
|
-
version: string;
|
|
561
|
-
kind: LessonkitPluginKind;
|
|
562
|
-
name?: string;
|
|
563
|
-
};
|
|
564
|
-
/** Narrow telemetry plugin contract (ISP). */
|
|
565
|
-
type TelemetryPlugin = PluginIdentity & {
|
|
566
|
-
onTelemetry?: (event: TelemetryEvent, ctx: LessonkitPluginContext) => TelemetryEvent | null;
|
|
567
|
-
onTelemetryBatch?: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => void;
|
|
568
|
-
wrapTrackingSink?: (sink: TelemetrySink, ctx: LessonkitPluginContext) => TelemetrySink;
|
|
569
|
-
};
|
|
570
|
-
/** Narrow lifecycle plugin contract (ISP). */
|
|
571
|
-
type LifecyclePlugin = PluginIdentity & {
|
|
572
|
-
setup?: (ctx: LessonkitPluginContext) => void;
|
|
573
|
-
dispose?: () => void;
|
|
574
|
-
};
|
|
575
|
-
/** Narrow assessment plugin contract (ISP). */
|
|
576
|
-
type AssessmentPlugin = PluginIdentity & {
|
|
577
|
-
kind: "assessment";
|
|
578
|
-
scoreAssessment?: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
|
|
579
|
-
};
|
|
580
|
-
/**
|
|
581
|
-
* Narrow interaction metadata plugin (ISP).
|
|
582
|
-
* @experimental Not wired into PluginHost; reserved for a future release.
|
|
583
|
-
*/
|
|
584
|
-
type InteractionPlugin = PluginIdentity & {
|
|
585
|
-
interactionBlocks?: InteractionBlockRegistration[];
|
|
586
|
-
};
|
|
587
|
-
/**
|
|
588
|
-
* Combined plugin contract (v1). Prefer segregated types for new plugins.
|
|
589
|
-
* @deprecated Prefer `TelemetryPlugin`, `AssessmentPlugin`, or `LifecyclePlugin` via `define*Plugin`.
|
|
590
|
-
*/
|
|
591
|
-
type LessonkitPlugin = PluginIdentity & Partial<Pick<TelemetryPlugin, "onTelemetry" | "onTelemetryBatch" | "wrapTrackingSink"> & Pick<LifecyclePlugin, "setup" | "dispose"> & Pick<AssessmentPlugin, "scoreAssessment"> & Pick<InteractionPlugin, "interactionBlocks">>;
|
|
592
|
-
type PluginHost = {
|
|
593
|
-
readonly plugins: readonly LessonkitPlugin[];
|
|
594
|
-
setupAll: (ctx: LessonkitPluginContext) => void;
|
|
595
|
-
disposeAll: () => void;
|
|
596
|
-
runTelemetry: (event: TelemetryEvent, ctx: LessonkitPluginContext) => TelemetryEvent | null;
|
|
597
|
-
runTelemetryBatch: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => TelemetryEvent[];
|
|
598
|
-
deliverTelemetryBatch: (events: TelemetryEvent[], ctx: LessonkitPluginContext) => TelemetryEvent[];
|
|
599
|
-
composeTrackingSink: (sink: TelemetrySink | undefined, ctx: LessonkitPluginContext | (() => LessonkitPluginContext)) => TelemetrySink | undefined;
|
|
600
|
-
scoreAssessment: (input: AssessmentScoreInput, ctx: LessonkitPluginContext) => AssessmentScoreResult | null;
|
|
601
|
-
};
|
|
602
|
-
/** Segregated plugin registry (ISP + SRP). */
|
|
603
|
-
type PluginRegistry = PluginHost;
|
|
604
|
-
|
|
605
|
-
type CourseLifecycleContext = {
|
|
606
|
-
courseId: CourseId;
|
|
607
|
-
sessionId: string;
|
|
608
|
-
attemptId?: string;
|
|
609
|
-
user?: TelemetryUser;
|
|
610
|
-
storage: StoragePort;
|
|
611
|
-
pluginHost: PluginRegistry | null;
|
|
612
|
-
lxpackBridge: "auto" | "off";
|
|
613
|
-
};
|
|
614
|
-
type CourseLifecycleDeps = {
|
|
615
|
-
emitCourseStartedEvent: (ctx: CourseLifecycleContext) => boolean;
|
|
616
|
-
};
|
|
617
|
-
declare function tryEmitCourseStarted(ctx: CourseLifecycleContext, deps: CourseLifecycleDeps, alreadyEmittedToSink: boolean): {
|
|
618
|
-
emitted: boolean;
|
|
619
|
-
marked: boolean;
|
|
620
|
-
};
|
|
621
|
-
declare function buildCourseStartedTelemetryEvent(ctx: CourseLifecycleContext): TelemetryEvent;
|
|
622
|
-
type LessonCompletionEmitter = (lessonId: LessonId, durationMs?: number) => void;
|
|
623
|
-
declare function completeLessonWithTelemetry(opts: {
|
|
624
|
-
progress: ProgressController;
|
|
625
|
-
lessonId: LessonId;
|
|
626
|
-
nowMs: number;
|
|
627
|
-
emitLessonCompleted: LessonCompletionEmitter;
|
|
628
|
-
}): boolean;
|
|
629
|
-
declare function completeCourseWithTelemetry(opts: {
|
|
630
|
-
progress: ProgressController;
|
|
631
|
-
nowMs: number;
|
|
632
|
-
emitLessonCompleted: LessonCompletionEmitter;
|
|
633
|
-
emitCourseCompleted: () => void;
|
|
634
|
-
}): boolean;
|
|
635
|
-
|
|
636
171
|
type LessonkitRuntimeVersion = "v1" | "v2";
|
|
637
172
|
type HeadlessLessonkitPlugins = readonly LessonkitPlugin[] | PluginRegistry | null | undefined;
|
|
638
173
|
type HeadlessLessonkitConfig = {
|
|
@@ -692,4 +227,4 @@ declare function buildPluginContext(opts: {
|
|
|
692
227
|
user?: TelemetryUser;
|
|
693
228
|
}): LessonkitPluginContext;
|
|
694
229
|
|
|
695
|
-
export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES,
|
|
230
|
+
export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, AssessmentPlugin, AssessmentResumeState, AssessmentScoreInput, AssessmentScoreResult, BLOCKS_14_PAGE_SLIDE, BlockId, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, CheckId, ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, CourseId, type EmitContext, 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, PAGE_ALLOWED_CHILD_TYPES, 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, loadCompoundState, nowIso, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, saveCompoundState, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, validateId };
|