@lessonkit/core 1.6.0 → 1.7.1

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
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ACCORDION_FORBIDDEN_CHILD_TYPES: () => ACCORDION_FORBIDDEN_CHILD_TYPES,
24
+ ASSESSMENT_17_CHILD_TYPES: () => ASSESSMENT_17_CHILD_TYPES,
24
25
  ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: () => ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES,
25
26
  BLOCKS_14_PAGE_SLIDE: () => BLOCKS_14_PAGE_SLIDE,
26
27
  BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES: () => BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES,
@@ -35,6 +36,7 @@ __export(index_exports, {
35
36
  MAP_STAGE_ALLOWED_CHILD_TYPES: () => MAP_STAGE_ALLOWED_CHILD_TYPES,
36
37
  PAGE_ALLOWED_CHILD_TYPES: () => PAGE_ALLOWED_CHILD_TYPES,
37
38
  SESSION_STORAGE_KEY: () => SESSION_STORAGE_KEY,
39
+ SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES: () => SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES,
38
40
  SLIDE_ALLOWED_CHILD_TYPES: () => SLIDE_ALLOWED_CHILD_TYPES,
39
41
  SLIDE_DECK_ALLOWED_CHILD_TYPES: () => SLIDE_DECK_ALLOWED_CHILD_TYPES,
40
42
  TELEMETRY_EVENT_CATALOG: () => TELEMETRY_EVENT_CATALOG,
@@ -79,6 +81,7 @@ __export(index_exports, {
79
81
  hasCourseStartedXapiSent: () => hasCourseStartedXapiSent,
80
82
  isChildTypeAllowed: () => isChildTypeAllowed,
81
83
  isLifecycleTelemetryEvent: () => isLifecycleTelemetryEvent,
84
+ isMultiSelectMcq: () => isMultiSelectMcq,
82
85
  loadCompoundState: () => loadCompoundState,
83
86
  markCourseStarted: () => markCourseStarted,
84
87
  markCourseStartedEmittedToTracking: () => markCourseStartedEmittedToTracking,
@@ -86,6 +89,7 @@ __export(index_exports, {
86
89
  markCourseStartedXapiSent: () => markCourseStartedXapiSent,
87
90
  migrateCourseStartedMark: () => migrateCourseStartedMark,
88
91
  nowIso: () => nowIso,
92
+ orderChoicesByIndices: () => orderChoicesByIndices,
89
93
  parseBlockId: () => parseBlockId,
90
94
  parseCheckId: () => parseCheckId,
91
95
  parseCompoundResumeState: () => parseCompoundResumeState,
@@ -94,8 +98,12 @@ __export(index_exports, {
94
98
  resetSharedVolatileSessionIdForTests: () => resetSharedVolatileSessionIdForTests,
95
99
  resetStoragePortForTests: () => resetStoragePortForTests,
96
100
  resetTelemetryBuilderWarningsForTests: () => resetTelemetryBuilderWarningsForTests,
101
+ resolveMcqCorrectAnswers: () => resolveMcqCorrectAnswers,
102
+ resolveMcqShuffleSeed: () => resolveMcqShuffleSeed,
97
103
  resolveSessionId: () => resolveSessionId,
98
104
  saveCompoundState: () => saveCompoundState,
105
+ scoreMcqSelection: () => scoreMcqSelection,
106
+ shuffleChoiceIndices: () => shuffleChoiceIndices,
99
107
  slugifyId: () => slugifyId,
100
108
  telemetryCatalogV2Version: () => telemetryCatalogV2Version,
101
109
  telemetryCatalogV3Version: () => telemetryCatalogV3Version,
@@ -251,6 +259,69 @@ function buildLessonkitUrn(parts) {
251
259
  return urn;
252
260
  }
253
261
 
262
+ // src/mcqAssessment.ts
263
+ function resolveMcqCorrectAnswers(props) {
264
+ if (props.answers && props.answers.length > 1) {
265
+ return new Set(props.answers.map((a) => a.trim()).filter(Boolean));
266
+ }
267
+ const single = props.answers?.[0]?.trim() ?? props.answer.trim();
268
+ return new Set(single ? [single] : []);
269
+ }
270
+ function isMultiSelectMcq(props) {
271
+ return (props.answers?.length ?? 0) > 1;
272
+ }
273
+ function scoreMcqSelection(selected, correct, multi, passingScore) {
274
+ const maxScore = multi ? Math.max(correct.size, 1) : 1;
275
+ if (!selected || Array.isArray(selected) && selected.length === 0) {
276
+ return {
277
+ score: 0,
278
+ maxScore,
279
+ exactMatch: false,
280
+ hasWrongSelection: false,
281
+ passedThreshold: false
282
+ };
283
+ }
284
+ const selectedSet = new Set(
285
+ (Array.isArray(selected) ? selected : [selected]).map((s) => s.trim()).filter(Boolean)
286
+ );
287
+ let score = 0;
288
+ for (const label of selectedSet) {
289
+ if (correct.has(label)) score += 1;
290
+ }
291
+ const hasWrongSelection = [...selectedSet].some((label) => !correct.has(label));
292
+ const exactMatch = !hasWrongSelection && selectedSet.size === correct.size && [...correct].every((label) => selectedSet.has(label));
293
+ const threshold = passingScore ?? maxScore;
294
+ const passedThreshold = score >= threshold && !hasWrongSelection;
295
+ return { score, maxScore, exactMatch, hasWrongSelection, passedThreshold };
296
+ }
297
+ function hashSeedToNumber(seed) {
298
+ if (typeof seed === "number" && Number.isFinite(seed)) return Math.abs(Math.trunc(seed)) || 1;
299
+ let hash = 2166136261;
300
+ const text = String(seed);
301
+ for (let i = 0; i < text.length; i += 1) {
302
+ hash ^= text.charCodeAt(i);
303
+ hash = Math.imul(hash, 16777619);
304
+ }
305
+ return hash >>> 0 || 1;
306
+ }
307
+ function shuffleChoiceIndices(length, seed) {
308
+ const indices = Array.from({ length }, (_, i) => i);
309
+ if (length <= 1) return indices;
310
+ let state = hashSeedToNumber(seed);
311
+ for (let i = length - 1; i > 0; i -= 1) {
312
+ state = Math.imul(state, 1664525) + 1013904223 >>> 0;
313
+ const j = state % (i + 1);
314
+ [indices[i], indices[j]] = [indices[j], indices[i]];
315
+ }
316
+ return indices;
317
+ }
318
+ function resolveMcqShuffleSeed(props) {
319
+ return props.shuffleSeed ?? props.checkId;
320
+ }
321
+ function orderChoicesByIndices(choices, orderIndices) {
322
+ return orderIndices.map((index) => choices[index] ?? "").filter((c) => c.length > 0);
323
+ }
324
+
254
325
  // src/compound.ts
255
326
  var COMPOUND_RESUME_SCHEMA_VERSION = 1;
256
327
  function createCompoundResumeState(input = {}) {
@@ -366,6 +437,11 @@ function clearCompoundState(storage, courseId, compoundId) {
366
437
  }
367
438
 
368
439
  // src/compoundAllowlists.ts
440
+ var ASSESSMENT_17_CHILD_TYPES = [
441
+ "SortParagraphs",
442
+ "GuessTheAnswer",
443
+ "MultimediaChoice"
444
+ ];
369
445
  var PAGE_AND_SLIDE_14_BLOCKS = [
370
446
  "Video",
371
447
  "Summary",
@@ -420,7 +496,8 @@ var PAGE_ALLOWED_CHILD_TYPES = [
420
496
  "QrContent",
421
497
  "Crossword",
422
498
  "AdventCalendar",
423
- "ProgressTracker"
499
+ "ProgressTracker",
500
+ ...ASSESSMENT_17_CHILD_TYPES
424
501
  ];
425
502
  var BRANCH_NODE_ALLOWED_CHILD_TYPES = [
426
503
  "Text",
@@ -464,7 +541,8 @@ var BRANCH_NODE_ALLOWED_CHILD_TYPES = [
464
541
  "QrContent",
465
542
  "Crossword",
466
543
  "AdventCalendar",
467
- "BranchChoice"
544
+ "BranchChoice",
545
+ ...ASSESSMENT_17_CHILD_TYPES
468
546
  ];
469
547
  var BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES = ["BranchNode"];
470
548
  var GAME_MAP_ALLOWED_CHILD_TYPES = ["MapStage"];
@@ -510,7 +588,8 @@ var MAP_STAGE_ALLOWED_CHILD_TYPES = [
510
588
  "QrContent",
511
589
  "Crossword",
512
590
  "AdventCalendar",
513
- "MapExit"
591
+ "MapExit",
592
+ ...ASSESSMENT_17_CHILD_TYPES
514
593
  ];
515
594
  var INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES = ["Page"];
516
595
  var SLIDE_ALLOWED_CHILD_TYPES = [
@@ -554,7 +633,8 @@ var SLIDE_ALLOWED_CHILD_TYPES = [
554
633
  "CombinationLock",
555
634
  "QrContent",
556
635
  "Crossword",
557
- "AdventCalendar"
636
+ "AdventCalendar",
637
+ ...ASSESSMENT_17_CHILD_TYPES
558
638
  ];
559
639
  var SLIDE_DECK_ALLOWED_CHILD_TYPES = ["Slide"];
560
640
  var TIMED_CUE_ALLOWED_CHILD_TYPES = [
@@ -570,7 +650,9 @@ var TIMED_CUE_ALLOWED_CHILD_TYPES = [
570
650
  "MemoryGame",
571
651
  "Questionnaire",
572
652
  "Essay",
573
- "ArithmeticQuiz"
653
+ "ArithmeticQuiz",
654
+ "MultimediaChoice",
655
+ "GuessTheAnswer"
574
656
  ];
575
657
  var INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES = ["TimedCue"];
576
658
  var ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES = [
@@ -587,8 +669,10 @@ var ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES = [
587
669
  "ImagePairing",
588
670
  "ImageSequencing",
589
671
  "ArithmeticQuiz",
590
- "Essay"
672
+ "Essay",
673
+ ...ASSESSMENT_17_CHILD_TYPES
591
674
  ];
675
+ var SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES = ["Quiz", "KnowledgeCheck"];
592
676
  var ALLOWLISTS = {
593
677
  Page: PAGE_ALLOWED_CHILD_TYPES,
594
678
  InteractiveBook: INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES,
@@ -600,7 +684,8 @@ var ALLOWLISTS = {
600
684
  BranchingScenario: BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES,
601
685
  BranchNode: BRANCH_NODE_ALLOWED_CHILD_TYPES,
602
686
  GameMap: GAME_MAP_ALLOWED_CHILD_TYPES,
603
- MapStage: MAP_STAGE_ALLOWED_CHILD_TYPES
687
+ MapStage: MAP_STAGE_ALLOWED_CHILD_TYPES,
688
+ SingleChoiceSet: SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES
604
689
  };
605
690
  var COMPOUND_MAX_NESTING_DEPTH = {
606
691
  Page: 1,
@@ -613,7 +698,8 @@ var COMPOUND_MAX_NESTING_DEPTH = {
613
698
  BranchingScenario: 2,
614
699
  BranchNode: 1,
615
700
  GameMap: 2,
616
- MapStage: 1
701
+ MapStage: 1,
702
+ SingleChoiceSet: 1
617
703
  };
618
704
  function getAllowedChildTypes(parent) {
619
705
  return ALLOWLISTS[parent];
@@ -1793,9 +1879,15 @@ function createMemoryBackedSessionStorage(session) {
1793
1879
  if (!bypassCacheForKey(key) && memory.has(key)) return memory.get(key);
1794
1880
  try {
1795
1881
  const value = session.getItem(key);
1796
- if (value !== null) memory.set(key, value);
1797
- else if (bypassCacheForKey(key)) memory.delete(key);
1798
- return value;
1882
+ if (value !== null) {
1883
+ memory.set(key, value);
1884
+ return value;
1885
+ }
1886
+ if (bypassCacheForKey(key) && memory.has(key)) {
1887
+ return memory.get(key);
1888
+ }
1889
+ if (bypassCacheForKey(key)) memory.delete(key);
1890
+ return null;
1799
1891
  } catch {
1800
1892
  return memory.get(key) ?? null;
1801
1893
  }
@@ -1808,9 +1900,7 @@ function createMemoryBackedSessionStorage(session) {
1808
1900
  return true;
1809
1901
  } catch {
1810
1902
  warnPersistFailure();
1811
- if (!bypassCacheForKey(key)) {
1812
- memory.set(key, value);
1813
- }
1903
+ memory.set(key, value);
1814
1904
  return false;
1815
1905
  }
1816
1906
  },
@@ -1923,6 +2013,29 @@ function createProgressController() {
1923
2013
  // src/session.ts
1924
2014
  var SESSION_STORAGE_KEY = "lessonkit:sessionId";
1925
2015
  var volatileSessionIds = /* @__PURE__ */ new WeakMap();
2016
+ var volatileStorageMarks = /* @__PURE__ */ new WeakMap();
2017
+ function rememberVolatileMark(storage, key) {
2018
+ let keys = volatileStorageMarks.get(storage);
2019
+ if (!keys) {
2020
+ keys = /* @__PURE__ */ new Set();
2021
+ volatileStorageMarks.set(storage, keys);
2022
+ }
2023
+ keys.add(key);
2024
+ }
2025
+ function hasVolatileMark(storage, key) {
2026
+ return volatileStorageMarks.get(storage)?.has(key) ?? false;
2027
+ }
2028
+ function clearVolatileMark(storage, key) {
2029
+ volatileStorageMarks.get(storage)?.delete(key);
2030
+ }
2031
+ function storageHasMark(storage, key) {
2032
+ return storage.getItem(key) === "1" || hasVolatileMark(storage, key);
2033
+ }
2034
+ function storageSetMark(storage, key) {
2035
+ const persisted = storage.setItem(key, "1");
2036
+ if (!persisted) rememberVolatileMark(storage, key);
2037
+ return persisted;
2038
+ }
1926
2039
  function isDevEnvironment2() {
1927
2040
  const g = globalThis;
1928
2041
  return typeof g.process !== "undefined" && g.process.env?.NODE_ENV !== "production";
@@ -1938,19 +2051,23 @@ function sessionKeySegment(sessionId) {
1938
2051
  const validated = validateId(sessionId);
1939
2052
  return validated.ok ? validated.id : encodeURIComponent(sessionId);
1940
2053
  }
1941
- function resolveSessionId(storage, provided) {
1942
- if (provided !== void 0) {
1943
- const trimmed = provided.trim();
1944
- if (trimmed.length > 0) {
1945
- const validated = validateId(trimmed);
1946
- if (validated.ok) return validated.id;
1947
- if (isDevEnvironment2()) {
1948
- console.warn(
1949
- `[lessonkit] Invalid sessionId "${trimmed}"; falling back to tab or generated id.`
1950
- );
1951
- }
2054
+ function resolveGeneratedSessionId(storage) {
2055
+ const volatile = volatileSessionIds.get(storage);
2056
+ if (volatile) return volatile;
2057
+ const id = createSessionId();
2058
+ const persisted = storage.setItem(SESSION_STORAGE_KEY, id);
2059
+ if (!persisted) {
2060
+ volatileSessionIds.set(storage, id);
2061
+ if (isDevEnvironment2()) {
2062
+ console.warn(
2063
+ "[lessonkit] session id could not be persisted; using in-memory id for this storage."
2064
+ );
1952
2065
  }
2066
+ return id;
1953
2067
  }
2068
+ return id;
2069
+ }
2070
+ function resolveFallbackSessionId(storage, options) {
1954
2071
  const existing = storage.getItem(SESSION_STORAGE_KEY);
1955
2072
  if (existing) {
1956
2073
  const trimmedExisting = existing.trim();
@@ -1962,21 +2079,37 @@ function resolveSessionId(storage, provided) {
1962
2079
  `[lessonkit] Invalid stored sessionId "${existing}"; generating a new id.`
1963
2080
  );
1964
2081
  }
2082
+ const fallback = resolveGeneratedSessionId(storage);
2083
+ options?.onInvalidSessionId?.({
2084
+ invalidId: existing,
2085
+ fallbackId: fallback,
2086
+ source: "stored"
2087
+ });
2088
+ return fallback;
1965
2089
  }
1966
- const volatile = volatileSessionIds.get(storage);
1967
- if (volatile) return volatile;
1968
- const id = createSessionId();
1969
- const persisted = storage.setItem(SESSION_STORAGE_KEY, id);
1970
- if (!persisted) {
1971
- volatileSessionIds.set(storage, id);
1972
- if (isDevEnvironment2()) {
1973
- console.warn(
1974
- "[lessonkit] session id could not be persisted; using in-memory id for this storage."
1975
- );
2090
+ return resolveGeneratedSessionId(storage);
2091
+ }
2092
+ function resolveSessionId(storage, provided, options) {
2093
+ if (provided !== void 0) {
2094
+ const trimmed = provided.trim();
2095
+ if (trimmed.length > 0) {
2096
+ const validated = validateId(trimmed);
2097
+ if (validated.ok) return validated.id;
2098
+ if (isDevEnvironment2()) {
2099
+ console.warn(
2100
+ `[lessonkit] Invalid sessionId "${trimmed}"; falling back to tab or generated id.`
2101
+ );
2102
+ }
2103
+ const fallback = resolveFallbackSessionId(storage, options);
2104
+ options?.onInvalidSessionId?.({
2105
+ invalidId: trimmed,
2106
+ fallbackId: fallback,
2107
+ source: "provided"
2108
+ });
2109
+ return fallback;
1976
2110
  }
1977
- return id;
1978
2111
  }
1979
- return id;
2112
+ return resolveFallbackSessionId(storage, options);
1980
2113
  }
1981
2114
  function courseStartedStorageKey(sessionId, courseId) {
1982
2115
  return `${COURSE_STARTED_PREFIX}${sessionKeySegment(sessionId)}:${courseId ?? ""}`;
@@ -1992,35 +2125,35 @@ function courseStartedXapiStorageKey(sessionId, courseId) {
1992
2125
  }
1993
2126
  function hasCourseStarted(storage, sessionId, courseId) {
1994
2127
  if (!courseId) return false;
1995
- return storage.getItem(courseStartedStorageKey(sessionId, courseId)) === "1";
2128
+ return storageHasMark(storage, courseStartedStorageKey(sessionId, courseId));
1996
2129
  }
1997
2130
  function markCourseStarted(storage, sessionId, courseId) {
1998
2131
  if (!courseId) return false;
1999
- return storage.setItem(courseStartedStorageKey(sessionId, courseId), "1");
2132
+ return storageSetMark(storage, courseStartedStorageKey(sessionId, courseId));
2000
2133
  }
2001
2134
  function hasCourseStartedEmittedToTracking(storage, sessionId, courseId) {
2002
2135
  if (!courseId) return false;
2003
- return storage.getItem(courseStartedTrackingStorageKey(sessionId, courseId)) === "1";
2136
+ return storageHasMark(storage, courseStartedTrackingStorageKey(sessionId, courseId));
2004
2137
  }
2005
2138
  function markCourseStartedEmittedToTracking(storage, sessionId, courseId) {
2006
2139
  if (!courseId) return false;
2007
- return storage.setItem(courseStartedTrackingStorageKey(sessionId, courseId), "1");
2140
+ return storageSetMark(storage, courseStartedTrackingStorageKey(sessionId, courseId));
2008
2141
  }
2009
2142
  function hasCourseStartedPipelineDelivered(storage, sessionId, courseId) {
2010
2143
  if (!courseId) return false;
2011
- return storage.getItem(courseStartedPipelineStorageKey(sessionId, courseId)) === "1";
2144
+ return storageHasMark(storage, courseStartedPipelineStorageKey(sessionId, courseId));
2012
2145
  }
2013
2146
  function markCourseStartedPipelineDelivered(storage, sessionId, courseId) {
2014
2147
  if (!courseId) return false;
2015
- return storage.setItem(courseStartedPipelineStorageKey(sessionId, courseId), "1");
2148
+ return storageSetMark(storage, courseStartedPipelineStorageKey(sessionId, courseId));
2016
2149
  }
2017
2150
  function hasCourseStartedXapiSent(storage, sessionId, courseId) {
2018
2151
  if (!courseId) return false;
2019
- return storage.getItem(courseStartedXapiStorageKey(sessionId, courseId)) === "1";
2152
+ return storageHasMark(storage, courseStartedXapiStorageKey(sessionId, courseId));
2020
2153
  }
2021
2154
  function markCourseStartedXapiSent(storage, sessionId, courseId) {
2022
2155
  if (!courseId) return false;
2023
- return storage.setItem(courseStartedXapiStorageKey(sessionId, courseId), "1");
2156
+ return storageSetMark(storage, courseStartedXapiStorageKey(sessionId, courseId));
2024
2157
  }
2025
2158
  function resetSharedVolatileSessionIdForTests() {
2026
2159
  }
@@ -2028,6 +2161,7 @@ function migrateStorageMark(storage, fromKey, toKey, hasMark) {
2028
2161
  if (!hasMark) return;
2029
2162
  if (storage.setItem(toKey, "1")) {
2030
2163
  storage.removeItem?.(fromKey);
2164
+ clearVolatileMark(storage, fromKey);
2031
2165
  }
2032
2166
  }
2033
2167
  function migrateCourseStartedMark(storage, fromSessionId, toSessionId, courseId) {
@@ -2060,9 +2194,16 @@ function migrateCourseStartedMark(storage, fromSessionId, toSessionId, courseId)
2060
2194
 
2061
2195
  // src/runtime/courseLifecycle.ts
2062
2196
  var courseStartedEmitFlights = /* @__PURE__ */ new Map();
2197
+ var courseStartedEmittedInTab = /* @__PURE__ */ new Set();
2063
2198
  function tryEmitCourseStarted(ctx, deps, alreadyEmittedToSink) {
2064
2199
  const flightKey = `${ctx.sessionId}:${ctx.courseId}`;
2065
2200
  const marked = hasCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId);
2201
+ if (courseStartedEmittedInTab.has(flightKey)) {
2202
+ return Promise.resolve({
2203
+ emitted: true,
2204
+ marked: marked || markCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId)
2205
+ });
2206
+ }
2066
2207
  if (alreadyEmittedToSink) {
2067
2208
  const markPersisted = marked ? true : markCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId);
2068
2209
  return Promise.resolve({
@@ -2083,6 +2224,9 @@ function tryEmitCourseStarted(ctx, deps, alreadyEmittedToSink) {
2083
2224
  const flight = Promise.resolve().then(() => {
2084
2225
  try {
2085
2226
  const emitted = deps.emitCourseStartedEvent(ctx);
2227
+ if (emitted) {
2228
+ courseStartedEmittedInTab.add(flightKey);
2229
+ }
2086
2230
  const markPersisted = emitted && !marked ? markCourseStarted(ctx.storage, ctx.sessionId, ctx.courseId) : marked;
2087
2231
  return {
2088
2232
  emitted,
@@ -2490,6 +2634,7 @@ function defineLifecyclePlugin(plugin) {
2490
2634
  // Annotate the CommonJS export names for ESM import in node:
2491
2635
  0 && (module.exports = {
2492
2636
  ACCORDION_FORBIDDEN_CHILD_TYPES,
2637
+ ASSESSMENT_17_CHILD_TYPES,
2493
2638
  ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES,
2494
2639
  BLOCKS_14_PAGE_SLIDE,
2495
2640
  BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES,
@@ -2504,6 +2649,7 @@ function defineLifecyclePlugin(plugin) {
2504
2649
  MAP_STAGE_ALLOWED_CHILD_TYPES,
2505
2650
  PAGE_ALLOWED_CHILD_TYPES,
2506
2651
  SESSION_STORAGE_KEY,
2652
+ SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES,
2507
2653
  SLIDE_ALLOWED_CHILD_TYPES,
2508
2654
  SLIDE_DECK_ALLOWED_CHILD_TYPES,
2509
2655
  TELEMETRY_EVENT_CATALOG,
@@ -2548,6 +2694,7 @@ function defineLifecyclePlugin(plugin) {
2548
2694
  hasCourseStartedXapiSent,
2549
2695
  isChildTypeAllowed,
2550
2696
  isLifecycleTelemetryEvent,
2697
+ isMultiSelectMcq,
2551
2698
  loadCompoundState,
2552
2699
  markCourseStarted,
2553
2700
  markCourseStartedEmittedToTracking,
@@ -2555,6 +2702,7 @@ function defineLifecyclePlugin(plugin) {
2555
2702
  markCourseStartedXapiSent,
2556
2703
  migrateCourseStartedMark,
2557
2704
  nowIso,
2705
+ orderChoicesByIndices,
2558
2706
  parseBlockId,
2559
2707
  parseCheckId,
2560
2708
  parseCompoundResumeState,
@@ -2563,8 +2711,12 @@ function defineLifecyclePlugin(plugin) {
2563
2711
  resetSharedVolatileSessionIdForTests,
2564
2712
  resetStoragePortForTests,
2565
2713
  resetTelemetryBuilderWarningsForTests,
2714
+ resolveMcqCorrectAnswers,
2715
+ resolveMcqShuffleSeed,
2566
2716
  resolveSessionId,
2567
2717
  saveCompoundState,
2718
+ scoreMcqSelection,
2719
+ shuffleChoiceIndices,
2568
2720
  slugifyId,
2569
2721
  telemetryCatalogV2Version,
2570
2722
  telemetryCatalogV3Version,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CourseId, L as LessonId, a as CheckId, B as BlockId, I as IdentityIdPath, b as IdentityValidationResult, c as LessonkitUrn, A as AssessmentResumeState, S as StoragePort, T as TelemetryEventName, d as TelemetrySink, e as TelemetryBatchSink, f as TrackingClient, g as TelemetryEvent, h as TelemetryUser, i as LessonkitPlugin, P as PluginRegistry, j as ProgressController, k as PluginHost, l as ProgressState, m as TelemetryDataFor, n as AssessmentScoreInput, o as AssessmentScoreResult, p as ClockPort, q as AssessmentPlugin, r as LifecyclePlugin, s as TelemetryPlugin, t as LessonkitPluginContext } from './testing-CzgxF1Ru.cjs';
2
- export { u as AccordionSectionToggledData, v as AssessmentAnsweredData, w as AssessmentBaseProps, x as AssessmentBehaviour, y as AssessmentCompletedData, z as AssessmentHandle, D as AssessmentInteractionType, E as AssessmentXAPIData, F as BookPageViewedData, G as BranchNodeViewedData, H as BranchSelectedData, J as BuildTelemetryEventInput, K as CompoundPageViewedData, M as CourseLifecycleContext, N as CourseLifecycleDeps, O as FlashcardFlippedData, Q as HotspotOpenedData, R as ID_MAX_LENGTH, U as ID_PATTERN, V as IdentityValidationIssue, W as ImageSliderChangedData, X as InformationWallSearchData, Y as InteractionBlockRegistration, Z as InteractionData, _ as InteractionPlugin, $ as LessonCompletionEmitter, a0 as LessonLifecycleData, a1 as LessonkitPluginKind, a2 as McqAssessmentProps, a3 as MemoryCardFlippedData, a4 as ParallaxSlideViewedData, a5 as PluginIdentity, a6 as QuestionnaireSubmittedData, a7 as QuizAnsweredData, a8 as QuizCompletedData, a9 as SESSION_STORAGE_KEY, aa as SlideViewedData, ab as TelemetryEventBase, ac as TimerPort, ad as VideoCueReachedData, ae as VideoSegmentCompletedData, af as buildCourseStartedTelemetryEvent, ag as buildTelemetryEvent, ah as completeCourseWithTelemetry, ai as completeLessonWithTelemetry, aj as createDefaultClock, ak as createGlobalTimer, al as createNoopStorage, am as createProgressController, an as createSessionStoragePort, ao as getTabSessionId, ap as hasCourseStarted, aq as hasCourseStartedEmittedToTracking, ar as hasCourseStartedPipelineDelivered, as as hasCourseStartedXapiSent, at as markCourseStarted, au as markCourseStartedEmittedToTracking, av as markCourseStartedPipelineDelivered, aw as markCourseStartedXapiSent, ax as migrateCourseStartedMark, ay as resetSharedVolatileSessionIdForTests, az as resetStoragePortForTests, aA as resetTelemetryBuilderWarningsForTests, aB as resolveSessionId, aC as tryBuildTelemetryEvent, aD as tryEmitCourseStarted } from './testing-CzgxF1Ru.cjs';
1
+ import { C as CourseId, L as LessonId, a as CheckId, B as BlockId, I as IdentityIdPath, b as IdentityValidationResult, c as LessonkitUrn, M as McqAssessmentProps, A as AssessmentResumeState, S as StoragePort, T as TelemetryEventName, d as TelemetrySink, e as TelemetryBatchSink, f as TrackingClient, g as TelemetryEvent, h as TelemetryUser, i as LessonkitPlugin, P as PluginRegistry, j as ProgressController, k as PluginHost, l as ProgressState, m as TelemetryDataFor, n as AssessmentScoreInput, o as AssessmentScoreResult, p as ClockPort, q as AssessmentPlugin, r as LifecyclePlugin, s as TelemetryPlugin, t as LessonkitPluginContext } from './testing-CQ-ZsT7D.cjs';
2
+ export { u as AccordionSectionToggledData, v as AssessmentAnsweredData, w as AssessmentBaseProps, x as AssessmentBehaviour, y as AssessmentCompletedData, z as AssessmentHandle, D as AssessmentInteractionType, E as AssessmentXAPIData, F as BookPageViewedData, G as BranchNodeViewedData, H as BranchSelectedData, J as BuildTelemetryEventInput, K as CompoundPageViewedData, N as CourseLifecycleContext, O as CourseLifecycleDeps, Q as FlashcardFlippedData, R as HotspotOpenedData, U as ID_MAX_LENGTH, V as ID_PATTERN, W as IdentityValidationIssue, X as ImageSliderChangedData, Y as InformationWallSearchData, Z as InteractionBlockRegistration, _ as InteractionData, $ as InteractionPlugin, a0 as InvalidSessionIdContext, a1 as LessonCompletionEmitter, a2 as LessonLifecycleData, a3 as LessonkitPluginKind, a4 as MemoryCardFlippedData, a5 as ParallaxSlideViewedData, a6 as PluginIdentity, a7 as QuestionnaireSubmittedData, a8 as QuizAnsweredData, a9 as QuizCompletedData, aa as ResolveSessionIdOptions, ab as SESSION_STORAGE_KEY, ac as SlideViewedData, ad as TelemetryEventBase, ae as TimerPort, af as VideoCueReachedData, ag as VideoSegmentCompletedData, ah as buildCourseStartedTelemetryEvent, ai as buildTelemetryEvent, aj as completeCourseWithTelemetry, ak as completeLessonWithTelemetry, al as createDefaultClock, am as createGlobalTimer, an as createNoopStorage, ao as createProgressController, ap as createSessionStoragePort, aq as getTabSessionId, ar as hasCourseStarted, as as hasCourseStartedEmittedToTracking, at as hasCourseStartedPipelineDelivered, au as hasCourseStartedXapiSent, av as markCourseStarted, aw as markCourseStartedEmittedToTracking, ax as markCourseStartedPipelineDelivered, ay as markCourseStartedXapiSent, az as migrateCourseStartedMark, aA as resetSharedVolatileSessionIdForTests, aB as resetStoragePortForTests, aC as resetTelemetryBuilderWarningsForTests, aD as resolveSessionId, aE as tryBuildTelemetryEvent, aF as tryEmitCourseStarted } from './testing-CQ-ZsT7D.cjs';
3
3
 
4
4
  /**
5
5
  * Exhaustiveness helper for switch/default branches.
@@ -36,6 +36,22 @@ type LessonkitUrnParts = {
36
36
  */
37
37
  declare function buildLessonkitUrn(parts: LessonkitUrnParts): LessonkitUrn;
38
38
 
39
+ type McqScoreResult = {
40
+ score: number;
41
+ maxScore: number;
42
+ exactMatch: boolean;
43
+ hasWrongSelection: boolean;
44
+ passedThreshold: boolean;
45
+ };
46
+ /** Correct answer labels for scoring (multi-select uses `answers` when length > 1). */
47
+ declare function resolveMcqCorrectAnswers(props: Pick<McqAssessmentProps, "answer" | "answers">): Set<string>;
48
+ declare function isMultiSelectMcq(props: Pick<McqAssessmentProps, "answers">): boolean;
49
+ declare function scoreMcqSelection(selected: string | string[] | null | undefined, correct: Set<string>, multi: boolean, passingScore?: number): McqScoreResult;
50
+ /** Deterministic Fisher–Yates shuffle; returns display order indices. */
51
+ declare function shuffleChoiceIndices(length: number, seed: string | number): number[];
52
+ declare function resolveMcqShuffleSeed(props: Pick<McqAssessmentProps, "checkId" | "shuffleSeed">): string | number;
53
+ declare function orderChoicesByIndices(choices: string[], orderIndices: number[]): string[];
54
+
39
55
  /** LMS parent-bridge forwarding mode for packaged course runtimes. */
40
56
  type LmsBridgeMode = "auto" | "off";
41
57
 
@@ -88,21 +104,24 @@ declare function saveCompoundState(storage: StoragePort, courseId: CourseId, com
88
104
  declare function clearCompoundState(storage: StoragePort, courseId: CourseId, compoundId: BlockId): void;
89
105
 
90
106
  /** Canonical compound child allowlists (H5P sub-content curation). */
91
- 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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "ProgressTracker"];
107
+ /** Tier B P1 assessments shipped in framework 1.7.0. */
108
+ declare const ASSESSMENT_17_CHILD_TYPES: readonly ["SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
109
+ 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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "ProgressTracker", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
92
110
  /** Branch node content (Page-like minus ProgressTracker). */
93
- declare const BRANCH_NODE_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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "BranchChoice"];
111
+ declare const BRANCH_NODE_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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "BranchChoice", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
94
112
  declare const BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES: readonly ["BranchNode"];
95
113
  declare const GAME_MAP_ALLOWED_CHILD_TYPES: readonly ["MapStage"];
96
114
  /** Map stage content (BranchNode parity; WordSearch excluded from compounds). */
97
- declare const MAP_STAGE_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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "MapExit"];
115
+ declare const MAP_STAGE_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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "MapExit", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
98
116
  declare const INTERACTIVE_BOOK_ALLOWED_CHILD_TYPES: readonly ["Page"];
99
117
  /** Per-slide content (H5P Course Presentation slide row). Excludes ProgressTracker. */
100
- 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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar"];
118
+ 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", "Embed", "Chart", "Table", "ImageJuxtaposition", "Timeline", "ImageSequence", "Collage", "AudioRecorder", "CombinationLock", "QrContent", "Crossword", "AdventCalendar", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
101
119
  declare const SLIDE_DECK_ALLOWED_CHILD_TYPES: readonly ["Slide"];
102
- declare const TIMED_CUE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Quiz", "TrueFalse", "FillInTheBlanks", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "Questionnaire", "Essay", "ArithmeticQuiz"];
120
+ declare const TIMED_CUE_ALLOWED_CHILD_TYPES: readonly ["Text", "Heading", "Image", "Quiz", "TrueFalse", "FillInTheBlanks", "Summary", "ImagePairing", "ImageSequencing", "MemoryGame", "Questionnaire", "Essay", "ArithmeticQuiz", "MultimediaChoice", "GuessTheAnswer"];
103
121
  declare const INTERACTIVE_VIDEO_ALLOWED_CHILD_TYPES: readonly ["TimedCue"];
104
- declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots", "Summary", "ImagePairing", "ImageSequencing", "ArithmeticQuiz", "Essay"];
105
- type CompoundParentType = "Page" | "InteractiveBook" | "Slide" | "SlideDeck" | "TimedCue" | "InteractiveVideo" | "AssessmentSequence" | "BranchingScenario" | "BranchNode" | "GameMap" | "MapStage";
122
+ declare const ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES: readonly ["TrueFalse", "FillInTheBlanks", "DragAndDrop", "DragTheWords", "MarkTheWords", "Quiz", "KnowledgeCheck", "FindHotspot", "FindMultipleHotspots", "Summary", "ImagePairing", "ImageSequencing", "ArithmeticQuiz", "Essay", "SortParagraphs", "GuessTheAnswer", "MultimediaChoice"];
123
+ declare const SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES: readonly ["Quiz", "KnowledgeCheck"];
124
+ type CompoundParentType = "Page" | "InteractiveBook" | "Slide" | "SlideDeck" | "TimedCue" | "InteractiveVideo" | "AssessmentSequence" | "BranchingScenario" | "BranchNode" | "GameMap" | "MapStage" | "SingleChoiceSet";
106
125
  declare const COMPOUND_MAX_NESTING_DEPTH: Record<CompoundParentType, number>;
107
126
  declare function getAllowedChildTypes(parent: CompoundParentType): readonly string[];
108
127
  declare function isChildTypeAllowed(parent: CompoundParentType, childType: string): boolean;
@@ -290,9 +309,23 @@ type HeadlessLessonkitRuntime = {
290
309
  * runtime.setActiveLesson("lesson-1");
291
310
  * runtime.track("interaction", { label: "opened" }, { lessonId: "lesson-1" });
292
311
  * ```
312
+ *
313
+ * @throws When plugin registry setup fails or tracking batch config is invalid (same rules as React provider).
293
314
  */
294
315
  declare function createLessonkitRuntime(config: HeadlessLessonkitConfig, ports?: HeadlessRuntimePorts): HeadlessLessonkitRuntime;
295
316
 
317
+ /**
318
+ * Register framework plugins (telemetry, assessment scoring, lifecycle hooks).
319
+ *
320
+ * @example
321
+ * ```ts
322
+ * import { createPluginRegistry, defineTelemetryPlugin } from "@lessonkit/core";
323
+ *
324
+ * const plugins = createPluginRegistry([
325
+ * defineTelemetryPlugin({ id: "analytics-bridge", setup: () => {} }),
326
+ * ]);
327
+ * ```
328
+ */
296
329
  declare function createPluginRegistry(plugins?: readonly LessonkitPlugin[]): PluginRegistry;
297
330
 
298
331
  /**
@@ -354,4 +387,4 @@ declare function buildPluginContext(opts: {
354
387
  user?: TelemetryUser;
355
388
  }): LessonkitPluginContext;
356
389
 
357
- export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, AssessmentPlugin, AssessmentResumeState, AssessmentScoreInput, AssessmentScoreResult, BLOCKS_14_PAGE_SLIDE, BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES, BRANCH_NODE_ALLOWED_CHILD_TYPES, BlockId, type BranchGraphNodeInput, type BranchGraphValidationIssue, type BranchGraphValidationResult, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, CheckId, ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, CourseId, type EmitContext, GAME_MAP_ALLOWED_CHILD_TYPES, 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, type LoadCompoundStateOptions, MAP_STAGE_ALLOWED_CHILD_TYPES, PAGE_ALLOWED_CHILD_TYPES, type ParseCompoundResumeStateOptions, 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, isLifecycleTelemetryEvent, loadCompoundState, nowIso, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, saveCompoundState, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, validateBranchGraph, validateId };
390
+ export { ACCORDION_FORBIDDEN_CHILD_TYPES, ASSESSMENT_17_CHILD_TYPES, ASSESSMENT_SEQUENCE_ALLOWED_CHILD_TYPES, AssessmentPlugin, AssessmentResumeState, AssessmentScoreInput, AssessmentScoreResult, BLOCKS_14_PAGE_SLIDE, BRANCHING_SCENARIO_ALLOWED_CHILD_TYPES, BRANCH_NODE_ALLOWED_CHILD_TYPES, BlockId, type BranchGraphNodeInput, type BranchGraphValidationIssue, type BranchGraphValidationResult, COMPOUND_MAX_NESTING_DEPTH, COMPOUND_RESUME_SCHEMA_VERSION, CheckId, ClockPort, type CompoundBaseProps, type CompoundHandle, type CompoundParentType, type CompoundResumeInput, type CompoundResumeState, CourseId, type EmitContext, GAME_MAP_ALLOWED_CHILD_TYPES, 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, type LoadCompoundStateOptions, MAP_STAGE_ALLOWED_CHILD_TYPES, McqAssessmentProps, type McqScoreResult, PAGE_ALLOWED_CHILD_TYPES, type ParseCompoundResumeStateOptions, PluginHost, PluginRegistry, ProgressController, ProgressState, SINGLE_CHOICE_SET_ALLOWED_CHILD_TYPES, 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, isLifecycleTelemetryEvent, isMultiSelectMcq, loadCompoundState, nowIso, orderChoicesByIndices, parseBlockId, parseCheckId, parseCompoundResumeState, parseCourseId, parseLessonId, resolveMcqCorrectAnswers, resolveMcqShuffleSeed, saveCompoundState, scoreMcqSelection, shuffleChoiceIndices, slugifyId, telemetryCatalogV2Version, telemetryCatalogV3Version, telemetryCatalogVersion, validateBranchGraph, validateId };