@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/index.cjs CHANGED
@@ -22,11 +22,13 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ACCORDION_FORBIDDEN_CHILD_TYPES: () => ACCORDION_FORBIDDEN_CHILD_TYPES,
24
24
  ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: () => ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES,
25
+ BLOCKS_14_PAGE_SLIDE: () => BLOCKS_14_PAGE_SLIDE,
25
26
  COMPOUND_MAX_NESTING_DEPTH: () => COMPOUND_MAX_NESTING_DEPTH,
26
27
  COMPOUND_RESUME_SCHEMA_VERSION: () => COMPOUND_RESUME_SCHEMA_VERSION,
27
28
  ID_MAX_LENGTH: () => ID_MAX_LENGTH,
28
29
  ID_PATTERN: () => ID_PATTERN,
29
30
  INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES: () => INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES,
31
+ INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES: () => INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES,
30
32
  PAGE_ALLOWED_CHILD_TYPES: () => PAGE_ALLOWED_CHILD_TYPES,
31
33
  SESSION_STORAGE_KEY: () => SESSION_STORAGE_KEY,
32
34
  SLIDE_ALLOWED_CHILD_TYPES: () => SLIDE_ALLOWED_CHILD_TYPES,
@@ -34,6 +36,7 @@ __export(index_exports, {
34
36
  TELEMETRY_EVENT_CATALOG: () => TELEMETRY_EVENT_CATALOG,
35
37
  TELEMETRY_EVENT_CATALOG_V2: () => TELEMETRY_EVENT_CATALOG_V2,
36
38
  TELEMETRY_EVENT_CATALOG_V3: () => TELEMETRY_EVENT_CATALOG_V3,
39
+ TIMED_CUE_ALLOWED_CHILD_TYPES: () => TIMED_CUE_ALLOWED_CHILD_TYPES,
37
40
  assertNever: () => assertNever,
38
41
  assertValidId: () => assertValidId,
39
42
  buildCourseStartedTelemetryEvent: () => buildCourseStartedTelemetryEvent,
@@ -322,10 +325,23 @@ function clearCompoundState(storage, courseId, compoundId) {
322
325
  }
323
326
 
324
327
  // src/compoundAllowlists.ts
328
+ var PAGE_AND_SLIDE_14_BLOCKS = [
329
+ "Video",
330
+ "Summary",
331
+ "ImagePairing",
332
+ "ImageSequencing",
333
+ "MemoryGame",
334
+ "InformationWall",
335
+ "ParallaxSlideshow",
336
+ "Questionnaire",
337
+ "Essay",
338
+ "ArithmeticQuiz"
339
+ ];
325
340
  var PAGE_ALLOWED_CHILD_TYPES = [
326
341
  "Text",
327
342
  "Heading",
328
343
  "Image",
344
+ "Video",
329
345
  "Scenario",
330
346
  "Reflection",
331
347
  "Quiz",
@@ -335,6 +351,15 @@ var PAGE_ALLOWED_CHILD_TYPES = [
335
351
  "DragAndDrop",
336
352
  "DragTheWords",
337
353
  "MarkTheWords",
354
+ "Summary",
355
+ "ImagePairing",
356
+ "ImageSequencing",
357
+ "MemoryGame",
358
+ "InformationWall",
359
+ "ParallaxSlideshow",
360
+ "Questionnaire",
361
+ "Essay",
362
+ "ArithmeticQuiz",
338
363
  "Accordion",
339
364
  "DialogCards",
340
365
  "Flashcards",
@@ -349,6 +374,7 @@ var SLIDE_ALLOWED_CHILD_TYPES = [
349
374
  "Text",
350
375
  "Heading",
351
376
  "Image",
377
+ "Video",
352
378
  "Scenario",
353
379
  "Reflection",
354
380
  "Quiz",
@@ -358,6 +384,15 @@ var SLIDE_ALLOWED_CHILD_TYPES = [
358
384
  "DragAndDrop",
359
385
  "DragTheWords",
360
386
  "MarkTheWords",
387
+ "Summary",
388
+ "ImagePairing",
389
+ "ImageSequencing",
390
+ "MemoryGame",
391
+ "InformationWall",
392
+ "ParallaxSlideshow",
393
+ "Questionnaire",
394
+ "Essay",
395
+ "ArithmeticQuiz",
361
396
  "Accordion",
362
397
  "DialogCards",
363
398
  "Flashcards",
@@ -367,6 +402,22 @@ var SLIDE_ALLOWED_CHILD_TYPES = [
367
402
  "ImageSlider"
368
403
  ];
369
404
  var SLIDE_DECK_ALLOWED_CHILD_TYPES = ["Slide"];
405
+ var TIMED_CUE_ALLOWED_CHILD_TYPES = [
406
+ "Text",
407
+ "Heading",
408
+ "Image",
409
+ "Quiz",
410
+ "TrueFalse",
411
+ "FillInTheBlanks",
412
+ "Summary",
413
+ "ImagePairing",
414
+ "ImageSequencing",
415
+ "MemoryGame",
416
+ "Questionnaire",
417
+ "Essay",
418
+ "ArithmeticQuiz"
419
+ ];
420
+ var INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES = ["TimedCue"];
370
421
  var ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES = [
371
422
  "TrueFalse",
372
423
  "FillInTheBlanks",
@@ -376,13 +427,20 @@ var ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES = [
376
427
  "Quiz",
377
428
  "KnowledgeCheck",
378
429
  "FindHotspot",
379
- "FindMultipleHotspots"
430
+ "FindMultipleHotspots",
431
+ "Summary",
432
+ "ImagePairing",
433
+ "ImageSequencing",
434
+ "ArithmeticQuiz",
435
+ "Essay"
380
436
  ];
381
437
  var ALLOWLISTS = {
382
438
  Page: PAGE_ALLOWED_CHILD_TYPES,
383
439
  InteractiveBook: INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES,
384
440
  Slide: SLIDE_ALLOWED_CHILD_TYPES,
385
441
  SlideDeck: SLIDE_DECK_ALLOWED_CHILD_TYPES,
442
+ TimedCue: TIMED_CUE_ALLOWED_CHILD_TYPES,
443
+ InteractiveVideo: INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES,
386
444
  AssessmentSequence: ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES
387
445
  };
388
446
  var COMPOUND_MAX_NESTING_DEPTH = {
@@ -390,6 +448,8 @@ var COMPOUND_MAX_NESTING_DEPTH = {
390
448
  InteractiveBook: 2,
391
449
  Slide: 1,
392
450
  SlideDeck: 2,
451
+ TimedCue: 1,
452
+ InteractiveVideo: 2,
393
453
  AssessmentSequence: 1
394
454
  };
395
455
  function getAllowedChildTypes(parent) {
@@ -399,6 +459,7 @@ function isChildTypeAllowed(parent, childType) {
399
459
  return ALLOWLISTS[parent].includes(childType);
400
460
  }
401
461
  var ACCORDION_FORBIDDEN_CHILD_TYPES = ["Accordion"];
462
+ var BLOCKS_14_PAGE_SLIDE = PAGE_AND_SLIDE_14_BLOCKS;
402
463
 
403
464
  // src/telemetryCatalog.ts
404
465
  var telemetryCatalogVersion = 1;
@@ -554,6 +615,54 @@ var TELEMETRY_EVENT_CATALOG_V3 = [
554
615
  dataFields: ["blockId", "slideIndex"],
555
616
  xapiVerb: "http://adlnet.gov/expapi/verbs/experienced",
556
617
  urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
618
+ },
619
+ {
620
+ name: "video_cue_reached",
621
+ description: "Learner reached a timed cue in an Interactive Video",
622
+ requiredFields: ["courseId", "lessonId", "sessionId", "timestamp"],
623
+ dataFields: ["blockId", "cueIndex", "atSeconds", "cueLabel"],
624
+ xapiVerb: "http://adlnet.gov/expapi/verbs/experienced",
625
+ urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
626
+ },
627
+ {
628
+ name: "video_segment_completed",
629
+ description: "Learner completed a timed segment in an Interactive Video",
630
+ requiredFields: ["courseId", "lessonId", "sessionId", "timestamp"],
631
+ dataFields: ["blockId", "segmentIndex", "atSeconds", "segmentLabel"],
632
+ xapiVerb: "http://adlnet.gov/expapi/verbs/completed",
633
+ urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
634
+ },
635
+ {
636
+ name: "memory_card_flipped",
637
+ description: "Learner flipped a memory game card",
638
+ requiredFields: ["courseId", "sessionId", "timestamp"],
639
+ dataFields: ["blockId", "cardIndex", "face"],
640
+ xapiVerb: "http://adlnet.gov/expapi/verbs/experienced",
641
+ urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
642
+ },
643
+ {
644
+ name: "information_wall_search",
645
+ description: "Learner searched an information wall",
646
+ requiredFields: ["courseId", "sessionId", "timestamp"],
647
+ dataFields: ["blockId", "query", "resultCount"],
648
+ xapiVerb: "http://adlnet.gov/expapi/verbs/experienced",
649
+ urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
650
+ },
651
+ {
652
+ name: "parallax_slide_viewed",
653
+ description: "Learner viewed a slide in a parallax slideshow",
654
+ requiredFields: ["courseId", "sessionId", "timestamp"],
655
+ dataFields: ["blockId", "slideIndex"],
656
+ xapiVerb: "http://adlnet.gov/expapi/verbs/experienced",
657
+ urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
658
+ },
659
+ {
660
+ name: "questionnaire_submitted",
661
+ description: "Learner submitted an unscored questionnaire",
662
+ requiredFields: ["courseId", "lessonId", "sessionId", "timestamp"],
663
+ dataFields: ["blockId", "fieldCount"],
664
+ xapiVerb: "http://adlnet.gov/expapi/verbs/completed",
665
+ urnPattern: "urn:lessonkit:course:{courseId}:lesson:{lessonId}:block:{blockId}"
557
666
  }
558
667
  ];
559
668
  function buildTelemetryCatalogV3() {
@@ -561,6 +670,18 @@ function buildTelemetryCatalogV3() {
561
670
  }
562
671
 
563
672
  // src/internal/sinkInvoke.ts
673
+ async function invokeTrackingSinkWithResult(sink, event) {
674
+ try {
675
+ const result = sink(event);
676
+ if (result != null && typeof result.then === "function") {
677
+ await result;
678
+ }
679
+ return true;
680
+ } catch (err) {
681
+ warnDev("[lessonkit] tracking sink failed:", err);
682
+ return false;
683
+ }
684
+ }
564
685
  function invokeTrackingSink(sink, event) {
565
686
  let result;
566
687
  try {
@@ -607,7 +728,17 @@ function createTrackingClient(opts) {
607
728
  return {
608
729
  track: (event) => {
609
730
  if (disposed2) return;
610
- if (sink) invokeTrackingSink(sink, event);
731
+ if (sink) {
732
+ try {
733
+ invokeTrackingSink(sink, event);
734
+ } catch {
735
+ }
736
+ }
737
+ },
738
+ deliver: async (event) => {
739
+ if (disposed2) return false;
740
+ if (!sink) return true;
741
+ return invokeTrackingSinkWithResult(sink, event);
611
742
  },
612
743
  dispose: () => {
613
744
  disposed2 = true;
@@ -620,12 +751,14 @@ function createTrackingClient(opts) {
620
751
  }
621
752
  const buffer = [];
622
753
  let flushInFlight = null;
754
+ let inflightExitBatch = null;
623
755
  let disposed = false;
624
756
  let disposing = false;
625
757
  let intervalId;
626
758
  const runFlush = () => {
627
759
  if (!buffer.length) return Promise.resolve(true);
628
760
  const events = buffer.splice(0, buffer.length);
761
+ inflightExitBatch = events;
629
762
  let succeeded = false;
630
763
  return Promise.resolve().then(async () => {
631
764
  if (batchSink) {
@@ -650,6 +783,8 @@ function createTrackingClient(opts) {
650
783
  return runFlush();
651
784
  }
652
785
  return succeeded;
786
+ }).finally(() => {
787
+ inflightExitBatch = null;
653
788
  });
654
789
  };
655
790
  const flush = () => {
@@ -680,23 +815,44 @@ function createTrackingClient(opts) {
680
815
  };
681
816
  intervalId = flushIntervalMs > 0 ? globalThis.setInterval(() => void flush(), flushIntervalMs) : void 0;
682
817
  intervalId?.unref?.();
683
- return {
684
- track: (event) => {
685
- if (disposed || disposing) return;
686
- if (buffer.length >= maxBufferSize) {
687
- opts?.onBufferDrop?.();
688
- if (!warnedBufferCap && isDevEnvironment()) {
689
- warnedBufferCap = true;
690
- console.warn(
691
- `[lessonkit] telemetry batch buffer capped at ${maxBufferSize} events; new events are dropped until the buffer drains.`
692
- );
693
- }
694
- return;
818
+ const track = (event) => {
819
+ if (disposed || disposing) return;
820
+ if (buffer.length >= maxBufferSize) {
821
+ opts?.onBufferDrop?.();
822
+ if (!warnedBufferCap && isDevEnvironment()) {
823
+ warnedBufferCap = true;
824
+ console.warn(
825
+ `[lessonkit] telemetry batch buffer capped at ${maxBufferSize} events; new events are dropped until the buffer drains.`
826
+ );
695
827
  }
696
- buffer.push(event);
697
- if (buffer.length >= maxBatchSize) void flush();
828
+ return;
829
+ }
830
+ buffer.push(event);
831
+ if (buffer.length >= maxBatchSize) void flush();
832
+ };
833
+ return {
834
+ track,
835
+ deliver: async (event) => {
836
+ track(event);
837
+ return flush();
698
838
  },
699
839
  flush,
840
+ flushOnExit: opts?.exitBatchSink ? () => {
841
+ const fromBuffer = buffer.splice(0, buffer.length);
842
+ const fromInflight = inflightExitBatch ? [...inflightExitBatch] : [];
843
+ const events = [...fromInflight, ...fromBuffer];
844
+ if (!events.length) return;
845
+ try {
846
+ const result = opts.exitBatchSink(events);
847
+ if (result != null && typeof result.catch === "function") {
848
+ void result.catch(() => {
849
+ buffer.unshift(...events);
850
+ });
851
+ }
852
+ } catch {
853
+ buffer.unshift(...events);
854
+ }
855
+ } : void 0,
700
856
  dispose: () => {
701
857
  if (disposed || disposing) return Promise.resolve();
702
858
  disposing = true;
@@ -920,6 +1076,81 @@ var TELEMETRY_EVENT_REGISTRY = {
920
1076
  data: opts.data
921
1077
  };
922
1078
  }
1079
+ },
1080
+ video_cue_reached: {
1081
+ requiresLessonId: true,
1082
+ build: (opts, base) => {
1083
+ if (opts.name !== "video_cue_reached") throw new Error("unexpected event");
1084
+ const lessonId = opts.lessonId;
1085
+ if (!lessonId) throw new Error("video_cue_reached requires active lessonId");
1086
+ return {
1087
+ name: "video_cue_reached",
1088
+ ...base,
1089
+ lessonId,
1090
+ data: opts.data
1091
+ };
1092
+ }
1093
+ },
1094
+ video_segment_completed: {
1095
+ requiresLessonId: true,
1096
+ build: (opts, base) => {
1097
+ if (opts.name !== "video_segment_completed") throw new Error("unexpected event");
1098
+ const lessonId = opts.lessonId;
1099
+ if (!lessonId) throw new Error("video_segment_completed requires active lessonId");
1100
+ return {
1101
+ name: "video_segment_completed",
1102
+ ...base,
1103
+ lessonId,
1104
+ data: opts.data
1105
+ };
1106
+ }
1107
+ },
1108
+ memory_card_flipped: {
1109
+ build: (opts, base) => {
1110
+ if (opts.name !== "memory_card_flipped") throw new Error("unexpected event");
1111
+ return {
1112
+ name: "memory_card_flipped",
1113
+ ...base,
1114
+ lessonId: opts.lessonId,
1115
+ data: opts.data
1116
+ };
1117
+ }
1118
+ },
1119
+ information_wall_search: {
1120
+ build: (opts, base) => {
1121
+ if (opts.name !== "information_wall_search") throw new Error("unexpected event");
1122
+ return {
1123
+ name: "information_wall_search",
1124
+ ...base,
1125
+ lessonId: opts.lessonId,
1126
+ data: opts.data
1127
+ };
1128
+ }
1129
+ },
1130
+ parallax_slide_viewed: {
1131
+ build: (opts, base) => {
1132
+ if (opts.name !== "parallax_slide_viewed") throw new Error("unexpected event");
1133
+ return {
1134
+ name: "parallax_slide_viewed",
1135
+ ...base,
1136
+ lessonId: opts.lessonId,
1137
+ data: opts.data
1138
+ };
1139
+ }
1140
+ },
1141
+ questionnaire_submitted: {
1142
+ requiresLessonId: true,
1143
+ build: (opts, base) => {
1144
+ if (opts.name !== "questionnaire_submitted") throw new Error("unexpected event");
1145
+ const lessonId = opts.lessonId;
1146
+ if (!lessonId) throw new Error("questionnaire_submitted requires active lessonId");
1147
+ return {
1148
+ name: "questionnaire_submitted",
1149
+ ...base,
1150
+ lessonId,
1151
+ data: opts.data
1152
+ };
1153
+ }
923
1154
  }
924
1155
  };
925
1156
  function buildTelemetryEventFromRegistry(opts) {
@@ -1207,16 +1438,16 @@ function hasCourseStartedEmittedToTracking(storage, sessionId, courseId) {
1207
1438
  return storage.getItem(courseStartedTrackingStorageKey(sessionId, courseId)) === "1";
1208
1439
  }
1209
1440
  function markCourseStartedEmittedToTracking(storage, sessionId, courseId) {
1210
- if (!courseId) return;
1211
- storage.setItem(courseStartedTrackingStorageKey(sessionId, courseId), "1");
1441
+ if (!courseId) return false;
1442
+ return storage.setItem(courseStartedTrackingStorageKey(sessionId, courseId), "1");
1212
1443
  }
1213
1444
  function hasCourseStartedPipelineDelivered(storage, sessionId, courseId) {
1214
1445
  if (!courseId) return false;
1215
1446
  return storage.getItem(courseStartedPipelineStorageKey(sessionId, courseId)) === "1";
1216
1447
  }
1217
1448
  function markCourseStartedPipelineDelivered(storage, sessionId, courseId) {
1218
- if (!courseId) return;
1219
- storage.setItem(courseStartedPipelineStorageKey(sessionId, courseId), "1");
1449
+ if (!courseId) return false;
1450
+ return storage.setItem(courseStartedPipelineStorageKey(sessionId, courseId), "1");
1220
1451
  }
1221
1452
  function resetSharedVolatileSessionIdForTests() {
1222
1453
  sharedVolatileSessionId = null;
@@ -1238,19 +1469,29 @@ function migrateCourseStartedMark(storage, fromSessionId, toSessionId, courseId)
1238
1469
  }
1239
1470
 
1240
1471
  // src/runtime/courseLifecycle.ts
1472
+ var courseStartedEmitFlights = /* @__PURE__ */ new Set();
1241
1473
  function tryEmitCourseStarted(ctx, deps, alreadyEmittedToSink) {
1474
+ const flightKey = `${ctx.sessionId}:${ctx.courseId}`;
1242
1475
  const marked = hasCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId);
1243
1476
  if (alreadyEmittedToSink) {
1244
1477
  return { emitted: true, marked };
1245
1478
  }
1246
- const emitted = deps.emitCourseStartedEvent(ctx);
1247
- if (emitted && !marked) {
1248
- markCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId);
1479
+ if (courseStartedEmitFlights.has(flightKey)) {
1480
+ return { emitted: false, marked };
1481
+ }
1482
+ courseStartedEmitFlights.add(flightKey);
1483
+ try {
1484
+ const emitted = deps.emitCourseStartedEvent(ctx);
1485
+ if (emitted && !marked) {
1486
+ markCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId);
1487
+ }
1488
+ return {
1489
+ emitted,
1490
+ marked: hasCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId)
1491
+ };
1492
+ } finally {
1493
+ courseStartedEmitFlights.delete(flightKey);
1249
1494
  }
1250
- return {
1251
- emitted,
1252
- marked: hasCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId)
1253
- };
1254
1495
  }
1255
1496
  function buildCourseStartedTelemetryEvent(ctx) {
1256
1497
  return buildTelemetryEvent({
@@ -1488,11 +1729,13 @@ function createLessonkitRuntime(config, ports = {}) {
1488
1729
  if (next.courseId !== void 0 && next.courseId !== previousCourseId) {
1489
1730
  progress = createProgressController();
1490
1731
  }
1491
- if (next.plugins !== void 0 && next.plugins !== pluginHost) {
1732
+ if (next.plugins !== void 0 && next.plugins !== configSnapshot.plugins) {
1492
1733
  pluginHost?.disposeAll();
1493
1734
  configSnapshot.plugins = next.plugins;
1494
1735
  pluginHost = resolvePluginHost(configSnapshot.plugins);
1495
- pluginHost?.setupAll(getPluginCtx());
1736
+ if (!configSnapshot.deferPluginSetup) {
1737
+ pluginHost?.setupAll(getPluginCtx());
1738
+ }
1496
1739
  } else if (next.session !== void 0 && sessionKeyBefore !== sessionKeyAfter && pluginHost && !configSnapshot.deferPluginSetup) {
1497
1740
  pluginHost.disposeAll();
1498
1741
  pluginHost.setupAll(getPluginCtx());
@@ -1502,17 +1745,17 @@ function createLessonkitRuntime(config, ports = {}) {
1502
1745
  const wrapped = wrapEmitFn(emitFn);
1503
1746
  const current = progress.getState();
1504
1747
  if (current.activeLessonId === lessonId) return;
1505
- if (current.completedLessonIds.has(lessonId)) {
1506
- progress.setActiveLesson(lessonId, clock.nowMs());
1507
- return;
1508
- }
1509
1748
  const previous = current.activeLessonId;
1510
- if (previous && previous !== lessonId) {
1749
+ if (previous && previous !== lessonId && !current.completedLessonIds.has(previous)) {
1511
1750
  const completed = progress.completeLesson(previous, clock.nowMs());
1512
1751
  if (completed.didComplete) {
1513
1752
  emitLessonCompletedEvents(previous, completed.durationMs, wrapped);
1514
1753
  }
1515
1754
  }
1755
+ if (current.completedLessonIds.has(lessonId)) {
1756
+ progress.setActiveLesson(lessonId, clock.nowMs());
1757
+ return;
1758
+ }
1516
1759
  progress.setActiveLesson(lessonId, clock.nowMs());
1517
1760
  wrapped("lesson_started", { lessonId }, lessonId);
1518
1761
  },
@@ -1533,9 +1776,12 @@ function createLessonkitRuntime(config, ports = {}) {
1533
1776
  });
1534
1777
  },
1535
1778
  track,
1536
- scoreAssessment(input, _lessonId) {
1779
+ scoreAssessment(input, lessonId) {
1537
1780
  if (!pluginHost) return null;
1538
- return pluginHost.scoreAssessment(input, getPluginCtx());
1781
+ return pluginHost.scoreAssessment(
1782
+ { ...input, lessonId: input.lessonId ?? lessonId },
1783
+ getPluginCtx()
1784
+ );
1539
1785
  },
1540
1786
  resetForCourseChange(nextCourseId) {
1541
1787
  configSnapshot.courseId = nextCourseId;
@@ -1562,11 +1808,13 @@ function defineLifecyclePlugin(plugin) {
1562
1808
  0 && (module.exports = {
1563
1809
  ACCORDION_FORBIDDEN_CHILD_TYPES,
1564
1810
  ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES,
1811
+ BLOCKS_14_PAGE_SLIDE,
1565
1812
  COMPOUND_MAX_NESTING_DEPTH,
1566
1813
  COMPOUND_RESUME_SCHEMA_VERSION,
1567
1814
  ID_MAX_LENGTH,
1568
1815
  ID_PATTERN,
1569
1816
  INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES,
1817
+ INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES,
1570
1818
  PAGE_ALLOWED_CHILD_TYPES,
1571
1819
  SESSION_STORAGE_KEY,
1572
1820
  SLIDE_ALLOWED_CHILD_TYPES,
@@ -1574,6 +1822,7 @@ function defineLifecyclePlugin(plugin) {
1574
1822
  TELEMETRY_EVENT_CATALOG,
1575
1823
  TELEMETRY_EVENT_CATALOG_V2,
1576
1824
  TELEMETRY_EVENT_CATALOG_V3,
1825
+ TIMED_CUE_ALLOWED_CHILD_TYPES,
1577
1826
  assertNever,
1578
1827
  assertValidId,
1579
1828
  buildCourseStartedTelemetryEvent,