@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/README.md +1 -1
- package/dist/{chunk-NGCHHJSM.js → chunk-DTJGIMUU.js} +96 -37
- package/dist/index.cjs +197 -45
- package/dist/index.d.cts +43 -10
- package/dist/index.d.ts +43 -10
- package/dist/index.js +95 -9
- package/dist/{testing-CzgxF1Ru.d.cts → testing-CQ-ZsT7D.d.cts} +38 -4
- package/dist/{testing-CzgxF1Ru.d.ts → testing-CQ-ZsT7D.d.ts} +38 -4
- package/dist/testing.cjs +2 -0
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +3 -3
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)
|
|
1797
|
-
|
|
1798
|
-
|
|
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
|
-
|
|
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
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
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
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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 };
|