@lessonkit/core 1.4.0 → 1.5.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.
@@ -65,7 +65,7 @@ type McqAssessmentProps = AssessmentBaseProps & {
65
65
  answer: string;
66
66
  };
67
67
 
68
- type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction" | "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed" | "video_cue_reached" | "video_segment_completed" | "memory_card_flipped" | "information_wall_search" | "parallax_slide_viewed" | "questionnaire_submitted";
68
+ type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction" | "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed" | "video_cue_reached" | "video_segment_completed" | "memory_card_flipped" | "information_wall_search" | "parallax_slide_viewed" | "questionnaire_submitted" | "branch_node_viewed" | "branch_selected";
69
69
  type TelemetryUser = {
70
70
  id?: string;
71
71
  email?: string;
@@ -75,6 +75,8 @@ type TelemetryUser = {
75
75
  type TelemetryEventBase = {
76
76
  timestamp: string;
77
77
  courseId: CourseId;
78
+ /** Optional stable id for sink deduplication (e.g. deliver retry). */
79
+ id?: string;
78
80
  sessionId?: string;
79
81
  attemptId?: string;
80
82
  user?: TelemetryUser;
@@ -181,6 +183,19 @@ type QuestionnaireSubmittedData = {
181
183
  blockId: BlockId;
182
184
  fieldCount: number;
183
185
  };
186
+ type BranchNodeViewedData = {
187
+ blockId: BlockId;
188
+ nodeId: string;
189
+ nodeIndex: number;
190
+ nodeTitle?: string;
191
+ };
192
+ type BranchSelectedData = {
193
+ blockId: BlockId;
194
+ fromNodeId: string;
195
+ toNodeId: string;
196
+ label: string;
197
+ scoreWeight?: number;
198
+ };
184
199
  type TelemetryEvent = (TelemetryEventBase & {
185
200
  name: "course_started";
186
201
  lessonId?: LessonId;
@@ -273,6 +288,14 @@ type TelemetryEvent = (TelemetryEventBase & {
273
288
  name: "questionnaire_submitted";
274
289
  lessonId: LessonId;
275
290
  data: QuestionnaireSubmittedData;
291
+ }) | (TelemetryEventBase & {
292
+ name: "branch_node_viewed";
293
+ lessonId: LessonId;
294
+ data: BranchNodeViewedData;
295
+ }) | (TelemetryEventBase & {
296
+ name: "branch_selected";
297
+ lessonId: LessonId;
298
+ data: BranchSelectedData;
276
299
  });
277
300
  /** Payload shape for a telemetry event name. */
278
301
  type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
@@ -283,7 +306,8 @@ type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
283
306
  type TelemetrySink = (event: TelemetryEvent) => void | Promise<void>;
284
307
  type TelemetryBatchSink = (events: TelemetryEvent[]) => void | Promise<void>;
285
308
  type TrackingClient = {
286
- track: (event: TelemetryEvent) => void;
309
+ /** Returns false when the event was dropped (e.g. buffer cap or after dispose). */
310
+ track: (event: TelemetryEvent) => boolean;
287
311
  /** Delivers one event and resolves to true only when the sink accepted it (batch: includes flush). */
288
312
  deliver?: (event: TelemetryEvent) => Promise<boolean>;
289
313
  /** Resolves to true when all buffered events were delivered; false when a sink failure re-queued events. */
@@ -414,6 +438,14 @@ type BuildTelemetryEventInput = (BuildTelemetryEventContext & {
414
438
  name: "questionnaire_submitted";
415
439
  lessonId?: LessonId;
416
440
  data: QuestionnaireSubmittedData;
441
+ }) | (BuildTelemetryEventContext & {
442
+ name: "branch_node_viewed";
443
+ lessonId?: LessonId;
444
+ data: BranchNodeViewedData;
445
+ }) | (BuildTelemetryEventContext & {
446
+ name: "branch_selected";
447
+ lessonId?: LessonId;
448
+ data: BranchSelectedData;
417
449
  });
418
450
 
419
451
  /** Reset dev-warning state (tests only). */
@@ -424,7 +456,8 @@ declare function resetTelemetryBuilderWarningsForTests(): void;
424
456
  */
425
457
  declare function buildTelemetryEvent(opts: BuildTelemetryEventInput): TelemetryEvent;
426
458
  /**
427
- * Like `buildTelemetryEvent`, but returns null (with a dev warning) when quiz events lack an active lesson.
459
+ * Like `buildTelemetryEvent`, but returns null when lesson-scoped events lack `lessonId`
460
+ * (with dev warnings for quiz/assessment events).
428
461
  */
429
462
  declare function tryBuildTelemetryEvent(opts: BuildTelemetryEventInput): TelemetryEvent | null;
430
463
 
@@ -457,7 +490,9 @@ declare function hasCourseStartedEmittedToTracking(storage: StoragePort, session
457
490
  declare function markCourseStartedEmittedToTracking(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
458
491
  declare function hasCourseStartedPipelineDelivered(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
459
492
  declare function markCourseStartedPipelineDelivered(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
460
- /** @internal Reset shared volatile session id between tests. */
493
+ declare function hasCourseStartedXapiSent(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
494
+ declare function markCourseStartedXapiSent(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
495
+ /** @internal Reset volatile session ids between tests. */
461
496
  declare function resetSharedVolatileSessionIdForTests(): void;
462
497
  declare function migrateCourseStartedMark(storage: StoragePort, fromSessionId: string, toSessionId: string, courseId?: CourseId): void;
463
498
 
@@ -547,10 +582,14 @@ type CourseLifecycleContext = {
547
582
  type CourseLifecycleDeps = {
548
583
  emitCourseStartedEvent: (ctx: CourseLifecycleContext) => boolean;
549
584
  };
550
- declare function tryEmitCourseStarted(ctx: CourseLifecycleContext, deps: CourseLifecycleDeps, alreadyEmittedToSink: boolean): {
585
+ /**
586
+ * Emit `course_started` once per tab session when tracking/xAPI are active.
587
+ * Coalesces concurrent calls via an in-flight guard.
588
+ */
589
+ declare function tryEmitCourseStarted(ctx: CourseLifecycleContext, deps: CourseLifecycleDeps, alreadyEmittedToSink: boolean): Promise<{
551
590
  emitted: boolean;
552
591
  marked: boolean;
553
- };
592
+ }>;
554
593
  declare function buildCourseStartedTelemetryEvent(ctx: CourseLifecycleContext): TelemetryEvent;
555
594
  type LessonCompletionEmitter = (lessonId: LessonId, durationMs?: number) => void;
556
595
  declare function completeLessonWithTelemetry(opts: {
@@ -566,4 +605,4 @@ declare function completeCourseWithTelemetry(opts: {
566
605
  emitCourseCompleted: () => void;
567
606
  }): boolean;
568
607
 
569
- export { type SlideViewedData as $, type AccordionSectionToggledData as A, type BlockId as B, type CheckId as C, type InteractionPlugin as D, type LessonId as E, type FlashcardFlippedData as F, type LessonLifecycleData as G, type HotspotOpenedData as H, ID_MAX_LENGTH as I, type LessonkitPlugin as J, type LessonkitPluginContext as K, type LessonCompletionEmitter as L, type LessonkitPluginKind as M, type LessonkitUrn as N, type LifecyclePlugin as O, type McqAssessmentProps as P, type MemoryCardFlippedData as Q, type ParallaxSlideViewedData as R, type PluginHost as S, type PluginIdentity as T, type PluginRegistry as U, type ProgressController as V, type ProgressState as W, type QuestionnaireSubmittedData as X, type QuizAnsweredData as Y, type QuizCompletedData as Z, SESSION_STORAGE_KEY as _, type AssessmentAnsweredData as a, type StoragePort as a0, type TelemetryBatchSink as a1, type TelemetryDataFor as a2, type TelemetryEvent as a3, type TelemetryEventBase as a4, type TelemetryEventName as a5, type TelemetryPlugin as a6, type TelemetrySink as a7, type TelemetryUser as a8, type TimerPort as a9, tryEmitCourseStarted as aA, type TrackingClient as aa, type VideoCueReachedData as ab, type VideoSegmentCompletedData as ac, buildCourseStartedTelemetryEvent as ad, buildTelemetryEvent as ae, completeCourseWithTelemetry as af, completeLessonWithTelemetry as ag, createDefaultClock as ah, createGlobalTimer as ai, createNoopStorage as aj, createProgressController as ak, createSessionStoragePort as al, getTabSessionId as am, hasCourseStarted as an, hasCourseStartedEmittedToTracking as ao, hasCourseStartedPipelineDelivered as ap, markCourseStarted as aq, markCourseStartedEmittedToTracking as ar, markCourseStartedPipelineDelivered as as, migrateCourseStartedMark as at, resetCourseStartedEmitFlightForTests as au, resetSharedVolatileSessionIdForTests as av, resetStoragePortForTests as aw, resetTelemetryBuilderWarningsForTests as ax, resolveSessionId as ay, tryBuildTelemetryEvent as az, type AssessmentBaseProps as b, type AssessmentBehaviour as c, type AssessmentCompletedData as d, type AssessmentHandle as e, type AssessmentInteractionType as f, type AssessmentPlugin as g, type AssessmentResumeState as h, type AssessmentScoreInput as i, type AssessmentScoreResult as j, type AssessmentXAPIData as k, type BookPageViewedData as l, type BuildTelemetryEventInput as m, type ClockPort as n, type CompoundPageViewedData as o, type CourseId as p, type CourseLifecycleContext as q, type CourseLifecycleDeps as r, ID_PATTERN as s, type IdentityIdPath as t, type IdentityValidationIssue as u, type IdentityValidationResult as v, type ImageSliderChangedData as w, type InformationWallSearchData as x, type InteractionBlockRegistration as y, type InteractionData as z };
608
+ export { type LessonCompletionEmitter as $, type AssessmentResumeState as A, type BlockId as B, type CourseId as C, type AssessmentInteractionType as D, type AssessmentXAPIData as E, type BookPageViewedData as F, type BranchNodeViewedData as G, type BranchSelectedData as H, type IdentityIdPath as I, type BuildTelemetryEventInput as J, type CompoundPageViewedData as K, type LessonId as L, type CourseLifecycleContext as M, type CourseLifecycleDeps as N, type FlashcardFlippedData as O, type PluginRegistry as P, type HotspotOpenedData as Q, ID_MAX_LENGTH as R, type StoragePort as S, type TelemetryEventName as T, ID_PATTERN as U, type IdentityValidationIssue as V, type ImageSliderChangedData as W, type InformationWallSearchData as X, type InteractionBlockRegistration as Y, type InteractionData as Z, type InteractionPlugin as _, type CheckId as a, type LessonLifecycleData as a0, type LessonkitPluginKind as a1, type McqAssessmentProps as a2, type MemoryCardFlippedData as a3, type ParallaxSlideViewedData as a4, type PluginIdentity as a5, type QuestionnaireSubmittedData as a6, type QuizAnsweredData as a7, type QuizCompletedData as a8, SESSION_STORAGE_KEY as a9, resetTelemetryBuilderWarningsForTests as aA, resolveSessionId as aB, tryBuildTelemetryEvent as aC, tryEmitCourseStarted as aD, resetCourseStartedEmitFlightForTests as aE, type SlideViewedData as aa, type TelemetryEventBase as ab, type TimerPort as ac, type VideoCueReachedData as ad, type VideoSegmentCompletedData as ae, buildCourseStartedTelemetryEvent as af, buildTelemetryEvent as ag, completeCourseWithTelemetry as ah, completeLessonWithTelemetry as ai, createDefaultClock as aj, createGlobalTimer as ak, createNoopStorage as al, createProgressController as am, createSessionStoragePort as an, getTabSessionId as ao, hasCourseStarted as ap, hasCourseStartedEmittedToTracking as aq, hasCourseStartedPipelineDelivered as ar, hasCourseStartedXapiSent as as, markCourseStarted as at, markCourseStartedEmittedToTracking as au, markCourseStartedPipelineDelivered as av, markCourseStartedXapiSent as aw, migrateCourseStartedMark as ax, resetSharedVolatileSessionIdForTests as ay, resetStoragePortForTests as az, type IdentityValidationResult as b, type LessonkitUrn as c, type TelemetrySink as d, type TelemetryBatchSink as e, type TrackingClient as f, type TelemetryEvent as g, type TelemetryUser as h, type LessonkitPlugin as i, type ProgressController as j, type PluginHost as k, type ProgressState as l, type TelemetryDataFor as m, type AssessmentScoreInput as n, type AssessmentScoreResult as o, type ClockPort as p, type AssessmentPlugin as q, type LifecyclePlugin as r, type TelemetryPlugin as s, type LessonkitPluginContext as t, type AccordionSectionToggledData as u, type AssessmentAnsweredData as v, type AssessmentBaseProps as w, type AssessmentBehaviour as x, type AssessmentCompletedData as y, type AssessmentHandle as z };
@@ -65,7 +65,7 @@ type McqAssessmentProps = AssessmentBaseProps & {
65
65
  answer: string;
66
66
  };
67
67
 
68
- type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction" | "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed" | "video_cue_reached" | "video_segment_completed" | "memory_card_flipped" | "information_wall_search" | "parallax_slide_viewed" | "questionnaire_submitted";
68
+ type TelemetryEventName = "course_started" | "course_completed" | "lesson_started" | "lesson_completed" | "lesson_time_on_task" | "quiz_answered" | "quiz_completed" | "assessment_answered" | "assessment_completed" | "interaction" | "book_page_viewed" | "slide_viewed" | "compound_page_viewed" | "hotspot_opened" | "accordion_section_toggled" | "flashcard_flipped" | "image_slider_changed" | "video_cue_reached" | "video_segment_completed" | "memory_card_flipped" | "information_wall_search" | "parallax_slide_viewed" | "questionnaire_submitted" | "branch_node_viewed" | "branch_selected";
69
69
  type TelemetryUser = {
70
70
  id?: string;
71
71
  email?: string;
@@ -75,6 +75,8 @@ type TelemetryUser = {
75
75
  type TelemetryEventBase = {
76
76
  timestamp: string;
77
77
  courseId: CourseId;
78
+ /** Optional stable id for sink deduplication (e.g. deliver retry). */
79
+ id?: string;
78
80
  sessionId?: string;
79
81
  attemptId?: string;
80
82
  user?: TelemetryUser;
@@ -181,6 +183,19 @@ type QuestionnaireSubmittedData = {
181
183
  blockId: BlockId;
182
184
  fieldCount: number;
183
185
  };
186
+ type BranchNodeViewedData = {
187
+ blockId: BlockId;
188
+ nodeId: string;
189
+ nodeIndex: number;
190
+ nodeTitle?: string;
191
+ };
192
+ type BranchSelectedData = {
193
+ blockId: BlockId;
194
+ fromNodeId: string;
195
+ toNodeId: string;
196
+ label: string;
197
+ scoreWeight?: number;
198
+ };
184
199
  type TelemetryEvent = (TelemetryEventBase & {
185
200
  name: "course_started";
186
201
  lessonId?: LessonId;
@@ -273,6 +288,14 @@ type TelemetryEvent = (TelemetryEventBase & {
273
288
  name: "questionnaire_submitted";
274
289
  lessonId: LessonId;
275
290
  data: QuestionnaireSubmittedData;
291
+ }) | (TelemetryEventBase & {
292
+ name: "branch_node_viewed";
293
+ lessonId: LessonId;
294
+ data: BranchNodeViewedData;
295
+ }) | (TelemetryEventBase & {
296
+ name: "branch_selected";
297
+ lessonId: LessonId;
298
+ data: BranchSelectedData;
276
299
  });
277
300
  /** Payload shape for a telemetry event name. */
278
301
  type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
@@ -283,7 +306,8 @@ type TelemetryDataFor<N extends TelemetryEventName> = Extract<TelemetryEvent, {
283
306
  type TelemetrySink = (event: TelemetryEvent) => void | Promise<void>;
284
307
  type TelemetryBatchSink = (events: TelemetryEvent[]) => void | Promise<void>;
285
308
  type TrackingClient = {
286
- track: (event: TelemetryEvent) => void;
309
+ /** Returns false when the event was dropped (e.g. buffer cap or after dispose). */
310
+ track: (event: TelemetryEvent) => boolean;
287
311
  /** Delivers one event and resolves to true only when the sink accepted it (batch: includes flush). */
288
312
  deliver?: (event: TelemetryEvent) => Promise<boolean>;
289
313
  /** Resolves to true when all buffered events were delivered; false when a sink failure re-queued events. */
@@ -414,6 +438,14 @@ type BuildTelemetryEventInput = (BuildTelemetryEventContext & {
414
438
  name: "questionnaire_submitted";
415
439
  lessonId?: LessonId;
416
440
  data: QuestionnaireSubmittedData;
441
+ }) | (BuildTelemetryEventContext & {
442
+ name: "branch_node_viewed";
443
+ lessonId?: LessonId;
444
+ data: BranchNodeViewedData;
445
+ }) | (BuildTelemetryEventContext & {
446
+ name: "branch_selected";
447
+ lessonId?: LessonId;
448
+ data: BranchSelectedData;
417
449
  });
418
450
 
419
451
  /** Reset dev-warning state (tests only). */
@@ -424,7 +456,8 @@ declare function resetTelemetryBuilderWarningsForTests(): void;
424
456
  */
425
457
  declare function buildTelemetryEvent(opts: BuildTelemetryEventInput): TelemetryEvent;
426
458
  /**
427
- * Like `buildTelemetryEvent`, but returns null (with a dev warning) when quiz events lack an active lesson.
459
+ * Like `buildTelemetryEvent`, but returns null when lesson-scoped events lack `lessonId`
460
+ * (with dev warnings for quiz/assessment events).
428
461
  */
429
462
  declare function tryBuildTelemetryEvent(opts: BuildTelemetryEventInput): TelemetryEvent | null;
430
463
 
@@ -457,7 +490,9 @@ declare function hasCourseStartedEmittedToTracking(storage: StoragePort, session
457
490
  declare function markCourseStartedEmittedToTracking(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
458
491
  declare function hasCourseStartedPipelineDelivered(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
459
492
  declare function markCourseStartedPipelineDelivered(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
460
- /** @internal Reset shared volatile session id between tests. */
493
+ declare function hasCourseStartedXapiSent(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
494
+ declare function markCourseStartedXapiSent(storage: StoragePort, sessionId: string, courseId?: CourseId): boolean;
495
+ /** @internal Reset volatile session ids between tests. */
461
496
  declare function resetSharedVolatileSessionIdForTests(): void;
462
497
  declare function migrateCourseStartedMark(storage: StoragePort, fromSessionId: string, toSessionId: string, courseId?: CourseId): void;
463
498
 
@@ -547,10 +582,14 @@ type CourseLifecycleContext = {
547
582
  type CourseLifecycleDeps = {
548
583
  emitCourseStartedEvent: (ctx: CourseLifecycleContext) => boolean;
549
584
  };
550
- declare function tryEmitCourseStarted(ctx: CourseLifecycleContext, deps: CourseLifecycleDeps, alreadyEmittedToSink: boolean): {
585
+ /**
586
+ * Emit `course_started` once per tab session when tracking/xAPI are active.
587
+ * Coalesces concurrent calls via an in-flight guard.
588
+ */
589
+ declare function tryEmitCourseStarted(ctx: CourseLifecycleContext, deps: CourseLifecycleDeps, alreadyEmittedToSink: boolean): Promise<{
551
590
  emitted: boolean;
552
591
  marked: boolean;
553
- };
592
+ }>;
554
593
  declare function buildCourseStartedTelemetryEvent(ctx: CourseLifecycleContext): TelemetryEvent;
555
594
  type LessonCompletionEmitter = (lessonId: LessonId, durationMs?: number) => void;
556
595
  declare function completeLessonWithTelemetry(opts: {
@@ -566,4 +605,4 @@ declare function completeCourseWithTelemetry(opts: {
566
605
  emitCourseCompleted: () => void;
567
606
  }): boolean;
568
607
 
569
- export { type SlideViewedData as $, type AccordionSectionToggledData as A, type BlockId as B, type CheckId as C, type InteractionPlugin as D, type LessonId as E, type FlashcardFlippedData as F, type LessonLifecycleData as G, type HotspotOpenedData as H, ID_MAX_LENGTH as I, type LessonkitPlugin as J, type LessonkitPluginContext as K, type LessonCompletionEmitter as L, type LessonkitPluginKind as M, type LessonkitUrn as N, type LifecyclePlugin as O, type McqAssessmentProps as P, type MemoryCardFlippedData as Q, type ParallaxSlideViewedData as R, type PluginHost as S, type PluginIdentity as T, type PluginRegistry as U, type ProgressController as V, type ProgressState as W, type QuestionnaireSubmittedData as X, type QuizAnsweredData as Y, type QuizCompletedData as Z, SESSION_STORAGE_KEY as _, type AssessmentAnsweredData as a, type StoragePort as a0, type TelemetryBatchSink as a1, type TelemetryDataFor as a2, type TelemetryEvent as a3, type TelemetryEventBase as a4, type TelemetryEventName as a5, type TelemetryPlugin as a6, type TelemetrySink as a7, type TelemetryUser as a8, type TimerPort as a9, tryEmitCourseStarted as aA, type TrackingClient as aa, type VideoCueReachedData as ab, type VideoSegmentCompletedData as ac, buildCourseStartedTelemetryEvent as ad, buildTelemetryEvent as ae, completeCourseWithTelemetry as af, completeLessonWithTelemetry as ag, createDefaultClock as ah, createGlobalTimer as ai, createNoopStorage as aj, createProgressController as ak, createSessionStoragePort as al, getTabSessionId as am, hasCourseStarted as an, hasCourseStartedEmittedToTracking as ao, hasCourseStartedPipelineDelivered as ap, markCourseStarted as aq, markCourseStartedEmittedToTracking as ar, markCourseStartedPipelineDelivered as as, migrateCourseStartedMark as at, resetCourseStartedEmitFlightForTests as au, resetSharedVolatileSessionIdForTests as av, resetStoragePortForTests as aw, resetTelemetryBuilderWarningsForTests as ax, resolveSessionId as ay, tryBuildTelemetryEvent as az, type AssessmentBaseProps as b, type AssessmentBehaviour as c, type AssessmentCompletedData as d, type AssessmentHandle as e, type AssessmentInteractionType as f, type AssessmentPlugin as g, type AssessmentResumeState as h, type AssessmentScoreInput as i, type AssessmentScoreResult as j, type AssessmentXAPIData as k, type BookPageViewedData as l, type BuildTelemetryEventInput as m, type ClockPort as n, type CompoundPageViewedData as o, type CourseId as p, type CourseLifecycleContext as q, type CourseLifecycleDeps as r, ID_PATTERN as s, type IdentityIdPath as t, type IdentityValidationIssue as u, type IdentityValidationResult as v, type ImageSliderChangedData as w, type InformationWallSearchData as x, type InteractionBlockRegistration as y, type InteractionData as z };
608
+ export { type LessonCompletionEmitter as $, type AssessmentResumeState as A, type BlockId as B, type CourseId as C, type AssessmentInteractionType as D, type AssessmentXAPIData as E, type BookPageViewedData as F, type BranchNodeViewedData as G, type BranchSelectedData as H, type IdentityIdPath as I, type BuildTelemetryEventInput as J, type CompoundPageViewedData as K, type LessonId as L, type CourseLifecycleContext as M, type CourseLifecycleDeps as N, type FlashcardFlippedData as O, type PluginRegistry as P, type HotspotOpenedData as Q, ID_MAX_LENGTH as R, type StoragePort as S, type TelemetryEventName as T, ID_PATTERN as U, type IdentityValidationIssue as V, type ImageSliderChangedData as W, type InformationWallSearchData as X, type InteractionBlockRegistration as Y, type InteractionData as Z, type InteractionPlugin as _, type CheckId as a, type LessonLifecycleData as a0, type LessonkitPluginKind as a1, type McqAssessmentProps as a2, type MemoryCardFlippedData as a3, type ParallaxSlideViewedData as a4, type PluginIdentity as a5, type QuestionnaireSubmittedData as a6, type QuizAnsweredData as a7, type QuizCompletedData as a8, SESSION_STORAGE_KEY as a9, resetTelemetryBuilderWarningsForTests as aA, resolveSessionId as aB, tryBuildTelemetryEvent as aC, tryEmitCourseStarted as aD, resetCourseStartedEmitFlightForTests as aE, type SlideViewedData as aa, type TelemetryEventBase as ab, type TimerPort as ac, type VideoCueReachedData as ad, type VideoSegmentCompletedData as ae, buildCourseStartedTelemetryEvent as af, buildTelemetryEvent as ag, completeCourseWithTelemetry as ah, completeLessonWithTelemetry as ai, createDefaultClock as aj, createGlobalTimer as ak, createNoopStorage as al, createProgressController as am, createSessionStoragePort as an, getTabSessionId as ao, hasCourseStarted as ap, hasCourseStartedEmittedToTracking as aq, hasCourseStartedPipelineDelivered as ar, hasCourseStartedXapiSent as as, markCourseStarted as at, markCourseStartedEmittedToTracking as au, markCourseStartedPipelineDelivered as av, markCourseStartedXapiSent as aw, migrateCourseStartedMark as ax, resetSharedVolatileSessionIdForTests as ay, resetStoragePortForTests as az, type IdentityValidationResult as b, type LessonkitUrn as c, type TelemetrySink as d, type TelemetryBatchSink as e, type TrackingClient as f, type TelemetryEvent as g, type TelemetryUser as h, type LessonkitPlugin as i, type ProgressController as j, type PluginHost as k, type ProgressState as l, type TelemetryDataFor as m, type AssessmentScoreInput as n, type AssessmentScoreResult as o, type ClockPort as p, type AssessmentPlugin as q, type LifecyclePlugin as r, type TelemetryPlugin as s, type LessonkitPluginContext as t, type AccordionSectionToggledData as u, type AssessmentAnsweredData as v, type AssessmentBaseProps as w, type AssessmentBehaviour as x, type AssessmentCompletedData as y, type AssessmentHandle as z };
package/dist/testing.cjs CHANGED
@@ -41,13 +41,11 @@ function resetStoragePortForTests(storage) {
41
41
  }
42
42
 
43
43
  // src/session.ts
44
- var sharedVolatileSessionId = null;
45
44
  function resetSharedVolatileSessionIdForTests() {
46
- sharedVolatileSessionId = null;
47
45
  }
48
46
 
49
47
  // src/runtime/courseLifecycle.ts
50
- var courseStartedEmitFlights = /* @__PURE__ */ new Set();
48
+ var courseStartedEmitFlights = /* @__PURE__ */ new Map();
51
49
  function resetCourseStartedEmitFlightForTests() {
52
50
  courseStartedEmitFlights.clear();
53
51
  }
@@ -1 +1 @@
1
- export { au as resetCourseStartedEmitFlightForTests, av as resetSharedVolatileSessionIdForTests, aw as resetStoragePortForTests, ax as resetTelemetryBuilderWarningsForTests } from './testing-BhVGckZ5.cjs';
1
+ export { aE as resetCourseStartedEmitFlightForTests, ay as resetSharedVolatileSessionIdForTests, az as resetStoragePortForTests, aA as resetTelemetryBuilderWarningsForTests } from './testing-BFr8oEfw.cjs';
package/dist/testing.d.ts CHANGED
@@ -1 +1 @@
1
- export { au as resetCourseStartedEmitFlightForTests, av as resetSharedVolatileSessionIdForTests, aw as resetStoragePortForTests, ax as resetTelemetryBuilderWarningsForTests } from './testing-BhVGckZ5.js';
1
+ export { aE as resetCourseStartedEmitFlightForTests, ay as resetSharedVolatileSessionIdForTests, az as resetStoragePortForTests, aA as resetTelemetryBuilderWarningsForTests } from './testing-BFr8oEfw.js';
package/dist/testing.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  resetSharedVolatileSessionIdForTests,
4
4
  resetStoragePortForTests,
5
5
  resetTelemetryBuilderWarningsForTests
6
- } from "./chunk-PEWFPVQ6.js";
6
+ } from "./chunk-KFXFQ6B2.js";
7
7
  export {
8
8
  resetCourseStartedEmitFlightForTests,
9
9
  resetSharedVolatileSessionIdForTests,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessonkit/core",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "private": false,
5
5
  "description": "Shared types and telemetry primitives for LessonKit.",
6
6
  "license": "Apache-2.0",
@@ -54,12 +54,12 @@
54
54
  "typecheck": "tsc -p tsconfig.json",
55
55
  "test": "vitest run --passWithNoTests",
56
56
  "test:coverage": "vitest run --coverage --passWithNoTests=false",
57
- "lint": "echo \"(no lint configured yet)\""
57
+ "lint": "eslint --max-warnings 0 \"src/**/*.{ts,tsx}\" \"test/**/*.{ts,tsx}\""
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^25.9.2",
61
61
  "tsup": "^8.5.0",
62
- "typescript": "^5.8.3",
62
+ "typescript": "^6.0.3",
63
63
  "vitest": "^4.1.8"
64
64
  }
65
65
  }
@@ -212,6 +212,43 @@
212
212
  ],
213
213
  "xapiVerb": "http://adlnet.gov/expapi/verbs/completed",
214
214
  "urnPattern": "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
215
+ },
216
+ {
217
+ "name": "branch_node_viewed",
218
+ "description": "Learner viewed a node in a BranchingScenario",
219
+ "requiredFields": [
220
+ "courseId",
221
+ "lessonId",
222
+ "sessionId",
223
+ "timestamp"
224
+ ],
225
+ "dataFields": [
226
+ "blockId",
227
+ "nodeId",
228
+ "nodeIndex",
229
+ "nodeTitle"
230
+ ],
231
+ "xapiVerb": "http://adlnet.gov/expapi/verbs/experienced",
232
+ "urnPattern": "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}:node:{nodeId}"
233
+ },
234
+ {
235
+ "name": "branch_selected",
236
+ "description": "Learner selected a branch choice in a BranchingScenario",
237
+ "requiredFields": [
238
+ "courseId",
239
+ "lessonId",
240
+ "sessionId",
241
+ "timestamp"
242
+ ],
243
+ "dataFields": [
244
+ "blockId",
245
+ "fromNodeId",
246
+ "toNodeId",
247
+ "label",
248
+ "scoreWeight"
249
+ ],
250
+ "xapiVerb": "http://adlnet.gov/expapi/verbs/answered",
251
+ "urnPattern": "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}:node:{toNodeId}"
215
252
  }
216
253
  ]
217
254
  }