@intellectif/lk-core 0.2.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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/dist/activity-D5tqgx8A.d.cts +330 -0
  3. package/dist/activity-D5tqgx8A.d.ts +330 -0
  4. package/dist/chunk-2T3IL7VL.js +147 -0
  5. package/dist/chunk-2T3IL7VL.js.map +1 -0
  6. package/dist/chunk-3JMLUUFS.cjs +124 -0
  7. package/dist/chunk-3JMLUUFS.cjs.map +1 -0
  8. package/dist/chunk-6VOCV4EX.js +25 -0
  9. package/dist/chunk-6VOCV4EX.js.map +1 -0
  10. package/dist/chunk-DCDOTQNH.cjs +147 -0
  11. package/dist/chunk-DCDOTQNH.cjs.map +1 -0
  12. package/dist/chunk-DV466SBJ.cjs +25 -0
  13. package/dist/chunk-DV466SBJ.cjs.map +1 -0
  14. package/dist/chunk-GZ73G2TS.js +124 -0
  15. package/dist/chunk-GZ73G2TS.js.map +1 -0
  16. package/dist/chunk-PJFDAP54.cjs +188 -0
  17. package/dist/chunk-PJFDAP54.cjs.map +1 -0
  18. package/dist/chunk-ZHOX6TO4.js +188 -0
  19. package/dist/chunk-ZHOX6TO4.js.map +1 -0
  20. package/dist/index.cjs +45 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +56 -0
  23. package/dist/index.d.ts +56 -0
  24. package/dist/index.js +45 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/schemas.cjs +23 -0
  27. package/dist/schemas.cjs.map +1 -0
  28. package/dist/schemas.d.cts +179 -0
  29. package/dist/schemas.d.ts +179 -0
  30. package/dist/schemas.js +23 -0
  31. package/dist/schemas.js.map +1 -0
  32. package/dist/scoring.cjs +10 -0
  33. package/dist/scoring.cjs.map +1 -0
  34. package/dist/scoring.d.cts +20 -0
  35. package/dist/scoring.d.ts +20 -0
  36. package/dist/scoring.js +10 -0
  37. package/dist/scoring.js.map +1 -0
  38. package/dist/xapi.cjs +14 -0
  39. package/dist/xapi.cjs.map +1 -0
  40. package/dist/xapi.d.cts +88 -0
  41. package/dist/xapi.d.ts +88 -0
  42. package/dist/xapi.js +14 -0
  43. package/dist/xapi.js.map +1 -0
  44. package/package.json +50 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scoring/strategies/all-or-nothing.ts","../src/scoring/strategies/partial.ts","../src/scoring/activity-scorers/fill-in-the-blanks.ts","../src/scoring/activity-scorers/multiple-choice.ts","../src/scoring/index.ts"],"sourcesContent":["/**\n * All-or-nothing scoring: full credit only when every item is correct.\n *\n * @param correctItems - per-item correctness flags for the relevant items\n * @returns `1` if every item is correct (or the list is empty), otherwise `0`\n */\nexport function allOrNothingStrategy(correctItems: boolean[]): number {\n return correctItems.every((isCorrect) => isCorrect) ? 1 : 0;\n}\n","/**\n * Partial-credit scoring for Multiple Choice — balanced/symmetric scheme.\n *\n * Reward and penalty are each normalised by their own pool: the fraction of\n * correct options found, minus the fraction of distractors wrongly chosen.\n * This is fairer than normalising the penalty by the correct-option count —\n * under that older form a single wrong pick could zero an otherwise-correct\n * response when there was only one correct answer.\n *\n * Result is always in [0, 1]: `reward ∈ [0,1]` and `penalty ∈ [0,1]`, so\n * `reward - penalty ∈ [-1,1]` and `max(0, …)` floors it at 0. Selecting every\n * option yields `1 - 1 = 0`; selecting exactly the correct set yields `1`.\n *\n * @param correctSelected - number of selected options that are correct\n * @param incorrectSelected - number of selected options that are incorrect\n * @param totalCorrect - total correct options; the `MultipleChoiceDataSchema`\n * \"≥1 correct\" guard guarantees this is ≥ 1, so the reward term cannot\n * divide by zero for schema-validated data\n * @param totalIncorrect - total incorrect options (distractors); when `0`\n * (every option is correct) the penalty term is defined as `0`\n */\nexport function partialStrategy(\n correctSelected: number,\n incorrectSelected: number,\n totalCorrect: number,\n totalIncorrect: number,\n): number {\n const reward = correctSelected / totalCorrect;\n const penalty = totalIncorrect === 0 ? 0 : incorrectSelected / totalIncorrect;\n return Math.max(0, reward - penalty);\n}\n\n/**\n * Partial-credit scoring for Fill-in-the-Blanks: fraction of blanks answered\n * correctly. Each blank is independently right or wrong, so a plain proportion\n * is already fair — no penalty term applies.\n *\n * @param correctBlanks - number of blanks answered correctly\n * @param totalBlanks - total number of blanks; the `FillInTheBlanksDataSchema`\n * `blanks.min(1)` constraint guarantees this is ≥ 1, so division by zero\n * cannot occur for schema-validated data\n */\nexport function partialBlankStrategy(correctBlanks: number, totalBlanks: number): number {\n return correctBlanks / totalBlanks;\n}\n","import type {\n BlankConfig,\n FillInTheBlanksData,\n FillInTheBlanksLearnerResponse,\n ScoringDetail,\n} from '../../types/activity.js';\nimport { allOrNothingStrategy } from '../strategies/all-or-nothing.js';\nimport { partialBlankStrategy } from '../strategies/partial.js';\nimport type { PartialScoringResult } from './multiple-choice.js';\n\n/**\n * Normalises a value for comparison per the blank's rules.\n * Defaults: `trimWhitespace` true, `caseSensitive` false (case-insensitive\n * unless the author explicitly opts in).\n */\nfunction normalize(value: string, blank: BlankConfig): string {\n let result = value;\n if (blank.trimWhitespace !== false) {\n result = result.trim();\n }\n if (blank.caseSensitive !== true) {\n result = result.toLowerCase();\n }\n return result;\n}\n\n/**\n * Scores a Fill-in-the-Blanks response. Each blank is evaluated independently;\n * a missing answer key is treated as empty input and scored incorrect.\n */\nexport function scoreFillInTheBlanks(\n data: FillInTheBlanksData,\n response: FillInTheBlanksLearnerResponse,\n): PartialScoringResult {\n const details: ScoringDetail[] = [];\n const perBlankCorrect: boolean[] = [];\n\n for (const blank of data.blanks) {\n const rawInput = response.answers[blank.id];\n const input = typeof rawInput === 'string' ? rawInput : '';\n const normalizedInput = normalize(input, blank);\n const matched = blank.acceptedAnswers.some(\n (accepted) => normalize(accepted, blank) === normalizedInput,\n );\n\n perBlankCorrect.push(matched);\n details.push({\n itemId: blank.id,\n correct: matched,\n learnerResponse: [input],\n correctResponse: [...blank.acceptedAnswers],\n });\n }\n\n const correctBlanks = perBlankCorrect.filter(Boolean).length;\n const scoreValue =\n data.scoringStrategy === 'all-or-nothing'\n ? allOrNothingStrategy(perBlankCorrect)\n : partialBlankStrategy(correctBlanks, data.blanks.length);\n\n return { score: scoreValue, maxScore: 1, feedback: null, details };\n}\n","import type {\n MultipleChoiceData,\n MultipleChoiceLearnerResponse,\n ScoringDetail,\n ScoringResult,\n} from '../../types/activity.js';\nimport { partialStrategy } from '../strategies/partial.js';\n\n/** ScoringResult without `passed` — the public `score()` fills that in. */\nexport type PartialScoringResult = Omit<ScoringResult, 'passed'>;\n\n/**\n * Scores a Multiple Choice response. Pure; trusts its typed inputs (validation\n * is the component boundary's job). Options are looked up by id; an unknown\n * selected id is treated as an incorrect selection.\n */\nexport function scoreMultipleChoice(\n data: MultipleChoiceData,\n response: MultipleChoiceLearnerResponse,\n): PartialScoringResult {\n const optionById = new Map(data.options.map((option) => [option.id, option]));\n const selected = new Set(response.selectedOptionIds);\n\n const totalCorrect = data.options.filter((option) => option.isCorrect).length;\n const totalIncorrect = data.options.length - totalCorrect;\n\n let scoreValue: number;\n\n if (data.scoringStrategy === 'all-or-nothing') {\n if (data.mode === 'single') {\n scoreValue =\n response.selectedOptionIds.length === 1 &&\n optionById.get(response.selectedOptionIds[0])?.isCorrect === true\n ? 1\n : 0;\n } else {\n const correctIds = data.options.filter((o) => o.isCorrect).map((o) => o.id);\n const allCorrectSelected = correctIds.every((id) => selected.has(id));\n scoreValue = selected.size === correctIds.length && allCorrectSelected ? 1 : 0;\n }\n } else {\n let correctSelected = 0;\n let incorrectSelected = 0;\n for (const id of selected) {\n const option = optionById.get(id);\n if (option?.isCorrect) {\n correctSelected += 1;\n } else {\n incorrectSelected += 1;\n }\n }\n scoreValue = partialStrategy(correctSelected, incorrectSelected, totalCorrect, totalIncorrect);\n }\n\n const details: ScoringDetail[] = data.options.map((option) => {\n const wasSelected = selected.has(option.id);\n return {\n itemId: option.id,\n correct: wasSelected === option.isCorrect,\n learnerResponse: [wasSelected ? 'selected' : 'not-selected'],\n correctResponse: [option.isCorrect ? 'selected' : 'not-selected'],\n };\n });\n\n return { score: scoreValue, maxScore: 1, feedback: null, details };\n}\n","import { UnknownActivityTypeError } from '../errors.js';\nimport type {\n ActivityData,\n ActivityType,\n FillInTheBlanksData,\n FillInTheBlanksLearnerResponse,\n LearnerResponse,\n MultipleChoiceData,\n MultipleChoiceLearnerResponse,\n ScoringResult,\n} from '../types/activity.js';\nimport { scoreFillInTheBlanks } from './activity-scorers/fill-in-the-blanks.js';\nimport { scoreMultipleChoice } from './activity-scorers/multiple-choice.js';\n\n/** Default minimum scaled score required to pass when `passThreshold` is absent. */\nconst DEFAULT_PASS_THRESHOLD = 0.7;\n\n/**\n * Returns `true` iff `score` meets or exceeds the activity's `passThreshold`,\n * defaulting to {@link DEFAULT_PASS_THRESHOLD} when the field is absent.\n */\nexport function computePassThreshold(activityData: ActivityData, score: number): boolean {\n return score >= (activityData.passThreshold ?? DEFAULT_PASS_THRESHOLD);\n}\n\n/**\n * Scores a learner response against activity data and returns a full\n * {@link ScoringResult}.\n *\n * Pure and deterministic with no side effects. It does **not** re-validate\n * `activityData` — schema validation is the component boundary's\n * responsibility; this is a low-level scoring primitive that trusts its typed\n * inputs. Dispatches on `activityType`; an unrecognised type throws\n * {@link UnknownActivityTypeError}.\n */\nexport function score(\n activityType: ActivityType,\n activityData: ActivityData,\n learnerResponse: LearnerResponse,\n): ScoringResult {\n let result: Omit<ScoringResult, 'passed'>;\n\n switch (activityType) {\n case 'multiple-choice':\n result = scoreMultipleChoice(\n activityData as MultipleChoiceData,\n learnerResponse as MultipleChoiceLearnerResponse,\n );\n break;\n case 'fill-in-the-blanks':\n result = scoreFillInTheBlanks(\n activityData as FillInTheBlanksData,\n learnerResponse as FillInTheBlanksLearnerResponse,\n );\n break;\n default:\n throw new UnknownActivityTypeError(String(activityType));\n }\n\n return { ...result, passed: computePassThreshold(activityData, result.score) };\n}\n"],"mappings":"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","names":["score"]}
@@ -0,0 +1,188 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkDV466SBJcjs = require('./chunk-DV466SBJ.cjs');
4
+
5
+ // src/xapi/validators.ts
6
+ var _v4 = require('zod/v4');
7
+ var UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
8
+ var IRI = /^[a-z][a-z0-9+.-]*:/i;
9
+ var langMap = _v4.z.record(_v4.z.string(), _v4.z.string());
10
+ var extensions = _v4.z.record(_v4.z.string(), _v4.z.unknown());
11
+ var actorSchema = _v4.z.object({
12
+ objectType: _v4.z.literal("Agent"),
13
+ name: _v4.z.string().optional(),
14
+ mbox: _v4.z.string().regex(/^mailto:/, "mbox must be a mailto IRI").optional(),
15
+ account: _v4.z.object({ homePage: _v4.z.string(), name: _v4.z.string() }).optional()
16
+ }).refine((actor) => actor.mbox !== void 0 || actor.account !== void 0, {
17
+ error: "actor must be identified by an mbox or an account"
18
+ });
19
+ var statementSchema = _v4.z.object({
20
+ id: _v4.z.string().regex(UUID_V4, "id must be a UUID v4"),
21
+ actor: actorSchema,
22
+ verb: _v4.z.object({
23
+ id: _v4.z.string().regex(IRI, "verb.id must be an IRI"),
24
+ display: langMap
25
+ }),
26
+ object: _v4.z.object({
27
+ objectType: _v4.z.literal("Activity"),
28
+ id: _v4.z.string().regex(IRI, "object.id must be an IRI"),
29
+ definition: _v4.z.object({
30
+ name: langMap.optional(),
31
+ description: langMap.optional(),
32
+ type: _v4.z.string().optional(),
33
+ extensions: extensions.optional()
34
+ }).optional()
35
+ }),
36
+ result: _v4.z.object({
37
+ // xAPI 1.0.3 permits scaled in [-1, 1]; the SDK only emits [0, 1].
38
+ score: _v4.z.object({
39
+ scaled: _v4.z.number().min(-1).max(1),
40
+ raw: _v4.z.number().optional(),
41
+ min: _v4.z.number().optional(),
42
+ max: _v4.z.number().optional()
43
+ }).optional(),
44
+ success: _v4.z.boolean().optional(),
45
+ completion: _v4.z.boolean().optional(),
46
+ duration: _v4.z.string().regex(/^P/, "duration must be an ISO 8601 duration").optional(),
47
+ response: _v4.z.string().optional(),
48
+ extensions: extensions.optional()
49
+ }).optional(),
50
+ context: _v4.z.object({
51
+ platform: _v4.z.string().optional(),
52
+ language: _v4.z.string().optional(),
53
+ extensions: extensions.optional()
54
+ }).optional(),
55
+ timestamp: _v4.z.string().refine((value) => !Number.isNaN(Date.parse(value)), "timestamp must be ISO 8601"),
56
+ version: _v4.z.literal("1.0.3")
57
+ });
58
+ function isProduction() {
59
+ const g = globalThis;
60
+ return _optionalChain([g, 'access', _ => _.process, 'optionalAccess', _2 => _2.env, 'optionalAccess', _3 => _3.NODE_ENV]) === "production";
61
+ }
62
+ function validateXAPIStatement(statement) {
63
+ const result = statementSchema.safeParse(statement);
64
+ if (result.success) {
65
+ return;
66
+ }
67
+ const errors = result.error.issues.map((issue) => ({
68
+ path: issue.path.map(String),
69
+ message: issue.message,
70
+ code: issue.code
71
+ }));
72
+ if (isProduction()) {
73
+ console.warn("[learning-kit] Invalid xAPI statement (sent anyway):", errors);
74
+ return;
75
+ }
76
+ throw new (0, _chunkDV466SBJcjs.ActivitySchemaError)("xAPIStatement", errors);
77
+ }
78
+
79
+ // src/xapi/verbs.ts
80
+ var XAPIVerb = {
81
+ ANSWERED: "http://adlnet.gov/expapi/verbs/answered",
82
+ COMPLETED: "http://adlnet.gov/expapi/verbs/completed",
83
+ EXPERIENCED: "http://adlnet.gov/expapi/verbs/experienced",
84
+ INTERACTED: "http://adlnet.gov/expapi/verbs/interacted",
85
+ ATTEMPTED: "http://adlnet.gov/expapi/verbs/attempted",
86
+ PASSED: "http://adlnet.gov/expapi/verbs/passed",
87
+ FAILED: "http://adlnet.gov/expapi/verbs/failed",
88
+ WATCHED: "https://w3id.org/xapi/video/verbs/watched"
89
+ };
90
+ var XAPI_VERB_DISPLAY = {
91
+ ANSWERED: { "en-US": "answered" },
92
+ COMPLETED: { "en-US": "completed" },
93
+ EXPERIENCED: { "en-US": "experienced" },
94
+ INTERACTED: { "en-US": "interacted" },
95
+ ATTEMPTED: { "en-US": "attempted" },
96
+ PASSED: { "en-US": "passed" },
97
+ FAILED: { "en-US": "failed" },
98
+ WATCHED: { "en-US": "watched" }
99
+ };
100
+
101
+ // src/xapi/builder.ts
102
+ function msToIsoDuration(ms) {
103
+ return `PT${Math.round(ms / 1e3)}S`;
104
+ }
105
+ function buildObject(params) {
106
+ const definition = {
107
+ ...params.name !== void 0 ? { name: params.name } : {},
108
+ ...params.description !== void 0 ? { description: params.description } : {},
109
+ ...params.type !== void 0 ? { type: params.type } : {}
110
+ };
111
+ return {
112
+ objectType: "Activity",
113
+ id: params.id,
114
+ ...Object.keys(definition).length > 0 ? { definition } : {}
115
+ };
116
+ }
117
+ function buildResult(timeSpentMs, scoringResult, resultExtensions, response) {
118
+ return {
119
+ completion: true,
120
+ duration: msToIsoDuration(timeSpentMs),
121
+ ...scoringResult !== void 0 ? {
122
+ score: {
123
+ scaled: scoringResult.score,
124
+ raw: scoringResult.score,
125
+ min: 0,
126
+ max: scoringResult.maxScore
127
+ },
128
+ success: scoringResult.passed
129
+ } : {},
130
+ ...response !== void 0 ? { response } : {},
131
+ ...resultExtensions !== void 0 ? { extensions: resultExtensions } : {}
132
+ };
133
+ }
134
+ var xAPIBuilder = {
135
+ buildStatement(params) {
136
+ const statement = {
137
+ id: crypto.randomUUID(),
138
+ actor: params.actor,
139
+ verb: {
140
+ id: XAPIVerb[params.verb],
141
+ display: XAPI_VERB_DISPLAY[params.verb]
142
+ },
143
+ object: buildObject(params.object),
144
+ ...params.result !== void 0 ? { result: params.result } : {},
145
+ ...params.context !== void 0 ? { context: params.context } : {},
146
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
147
+ version: "1.0.3"
148
+ };
149
+ validateXAPIStatement(statement);
150
+ return statement;
151
+ },
152
+ buildAnsweredStatement(params) {
153
+ return this.buildStatement({
154
+ actor: params.actor,
155
+ verb: "ANSWERED",
156
+ object: params.object,
157
+ result: buildResult(
158
+ params.timeSpentMs,
159
+ params.scoringResult,
160
+ params.resultExtensions,
161
+ params.response
162
+ ),
163
+ ...params.context !== void 0 ? { context: params.context } : {}
164
+ });
165
+ },
166
+ buildCompletedStatement(params) {
167
+ return this.buildStatement({
168
+ actor: params.actor,
169
+ verb: "COMPLETED",
170
+ object: params.object,
171
+ result: buildResult(
172
+ params.timeSpentMs,
173
+ params.scoringResult,
174
+ params.resultExtensions,
175
+ void 0
176
+ ),
177
+ ...params.context !== void 0 ? { context: params.context } : {}
178
+ });
179
+ }
180
+ };
181
+
182
+
183
+
184
+
185
+
186
+
187
+ exports.validateXAPIStatement = validateXAPIStatement; exports.XAPIVerb = XAPIVerb; exports.XAPI_VERB_DISPLAY = XAPI_VERB_DISPLAY; exports.xAPIBuilder = xAPIBuilder;
188
+ //# sourceMappingURL=chunk-PJFDAP54.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["c:\\Users\\onecu\\Documents\\Intellectif\\IT-for-Intellectif\\learning-kit\\packages\\lk-core\\dist\\chunk-PJFDAP54.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACA;AACA,4BAA0B;AAC1B,IAAI,QAAQ,EAAE,wEAAwE;AACtF,IAAI,IAAI,EAAE,sBAAsB;AAChC,IAAI,QAAQ,EAAE,KAAC,CAAC,MAAM,CAAC,KAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9C,IAAI,WAAW,EAAE,KAAC,CAAC,MAAM,CAAC,KAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAClD,IAAI,YAAY,EAAE,KAAC,CAAC,MAAM,CAAC;AAC3B,EAAE,UAAU,EAAE,KAAC,CAAC,OAAO,CAAC,OAAO,CAAC;AAChC,EAAE,IAAI,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC7B,EAAE,IAAI,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC5E,EAAE,OAAO,EAAE,KAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AACzE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE;AACxE,EAAE,KAAK,EAAE;AACT,CAAC,CAAC;AACF,IAAI,gBAAgB,EAAE,KAAC,CAAC,MAAM,CAAC;AAC/B,EAAE,EAAE,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,sBAAsB,CAAC;AACvD,EAAE,KAAK,EAAE,WAAW;AACpB,EAAE,IAAI,EAAE,KAAC,CAAC,MAAM,CAAC;AACjB,IAAI,EAAE,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,wBAAwB,CAAC;AACvD,IAAI,OAAO,EAAE;AACb,EAAE,CAAC,CAAC;AACJ,EAAE,MAAM,EAAE,KAAC,CAAC,MAAM,CAAC;AACnB,IAAI,UAAU,EAAE,KAAC,CAAC,OAAO,CAAC,UAAU,CAAC;AACrC,IAAI,EAAE,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,0BAA0B,CAAC;AACzD,IAAI,UAAU,EAAE,KAAC,CAAC,MAAM,CAAC;AACzB,MAAM,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC9B,MAAM,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;AACrC,MAAM,IAAI,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACjC,MAAM,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC;AACtC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChB,EAAE,CAAC,CAAC;AACJ,EAAE,MAAM,EAAE,KAAC,CAAC,MAAM,CAAC;AACnB;AACA,IAAI,KAAK,EAAE,KAAC,CAAC,MAAM,CAAC;AACpB,MAAM,MAAM,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACvC,MAAM,GAAG,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAChC,MAAM,GAAG,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAChC,MAAM,GAAG,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/B,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACjB,IAAI,OAAO,EAAE,KAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACnC,IAAI,UAAU,EAAE,KAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACtC,IAAI,QAAQ,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,uCAAuC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACxF,IAAI,QAAQ,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACnC,IAAI,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC;AACpC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACf,EAAE,OAAO,EAAE,KAAC,CAAC,MAAM,CAAC;AACpB,IAAI,QAAQ,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACnC,IAAI,QAAQ,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACnC,IAAI,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC;AACpC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACf,EAAE,SAAS,EAAE,KAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,4BAA4B,CAAC;AACzG,EAAE,OAAO,EAAE,KAAC,CAAC,OAAO,CAAC,OAAO;AAC5B,CAAC,CAAC;AACF,SAAS,YAAY,CAAC,EAAE;AACxB,EAAE,MAAM,EAAE,EAAE,UAAU;AACtB,EAAE,uBAAO,CAAC,mBAAC,OAAO,6BAAE,GAAG,6BAAE,WAAS,IAAI,YAAY;AAClD;AACA,SAAS,qBAAqB,CAAC,SAAS,EAAE;AAC1C,EAAE,MAAM,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC;AACrD,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE;AACtB,IAAI,MAAM;AACV,EAAE;AACF,EAAE,MAAM,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC;AACrD,IAAI,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;AAChC,IAAI,OAAO,EAAE,KAAK,CAAC,OAAO;AAC1B,IAAI,IAAI,EAAE,KAAK,CAAC;AAChB,EAAE,CAAC,CAAC,CAAC;AACL,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE;AACtB,IAAI,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,MAAM,CAAC;AAChF,IAAI,MAAM;AACV,EAAE;AACF,EAAE,MAAM,IAAI,0CAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;AACxD;AACA;AACA;AACA,IAAI,SAAS,EAAE;AACf,EAAE,QAAQ,EAAE,yCAAyC;AACrD,EAAE,SAAS,EAAE,0CAA0C;AACvD,EAAE,WAAW,EAAE,4CAA4C;AAC3D,EAAE,UAAU,EAAE,2CAA2C;AACzD,EAAE,SAAS,EAAE,0CAA0C;AACvD,EAAE,MAAM,EAAE,uCAAuC;AACjD,EAAE,MAAM,EAAE,uCAAuC;AACjD,EAAE,OAAO,EAAE;AACX,CAAC;AACD,IAAI,kBAAkB,EAAE;AACxB,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC;AACnC,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC;AACrC,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC;AACzC,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC;AACvC,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC;AACrC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC;AAC/B,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC;AAC/B,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU;AAChC,CAAC;AACD;AACA;AACA,SAAS,eAAe,CAAC,EAAE,EAAE;AAC7B,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACrC;AACA,SAAS,WAAW,CAAC,MAAM,EAAE;AAC7B,EAAE,MAAM,WAAW,EAAE;AACrB,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC1D,IAAI,GAAG,MAAM,CAAC,YAAY,IAAI,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC/E,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;AACzD,EAAE,CAAC;AACH,EAAE,OAAO;AACT,IAAI,UAAU,EAAE,UAAU;AAC1B,IAAI,EAAE,EAAE,MAAM,CAAC,EAAE;AACjB,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,CAAC;AAC9D,EAAE,CAAC;AACH;AACA,SAAS,WAAW,CAAC,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE;AAC7E,EAAE,OAAO;AACT,IAAI,UAAU,EAAE,IAAI;AACpB,IAAI,QAAQ,EAAE,eAAe,CAAC,WAAW,CAAC;AAC1C,IAAI,GAAG,cAAc,IAAI,KAAK,EAAE,EAAE;AAClC,MAAM,KAAK,EAAE;AACb,QAAQ,MAAM,EAAE,aAAa,CAAC,KAAK;AACnC,QAAQ,GAAG,EAAE,aAAa,CAAC,KAAK;AAChC,QAAQ,GAAG,EAAE,CAAC;AACd,QAAQ,GAAG,EAAE,aAAa,CAAC;AAC3B,MAAM,CAAC;AACP,MAAM,OAAO,EAAE,aAAa,CAAC;AAC7B,IAAI,EAAE,EAAE,CAAC,CAAC;AACV,IAAI,GAAG,SAAS,IAAI,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AAC9C,IAAI,GAAG,iBAAiB,IAAI,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,CAAC;AACzE,EAAE,CAAC;AACH;AACA,IAAI,YAAY,EAAE;AAClB,EAAE,cAAc,CAAC,MAAM,EAAE;AACzB,IAAI,MAAM,UAAU,EAAE;AACtB,MAAM,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;AAC7B,MAAM,KAAK,EAAE,MAAM,CAAC,KAAK;AACzB,MAAM,IAAI,EAAE;AACZ,QAAQ,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AACjC,QAAQ,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,IAAI;AAC9C,MAAM,CAAC;AACP,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;AACxC,MAAM,GAAG,MAAM,CAAC,OAAO,IAAI,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClE,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACrE,MAAM,SAAS,EAAE,iBAAiB,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAC3D,MAAM,OAAO,EAAE;AACf,IAAI,CAAC;AACL,IAAI,qBAAqB,CAAC,SAAS,CAAC;AACpC,IAAI,OAAO,SAAS;AACpB,EAAE,CAAC;AACH,EAAE,sBAAsB,CAAC,MAAM,EAAE;AACjC,IAAI,OAAO,IAAI,CAAC,cAAc,CAAC;AAC/B,MAAM,KAAK,EAAE,MAAM,CAAC,KAAK;AACzB,MAAM,IAAI,EAAE,UAAU;AACtB,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM;AAC3B,MAAM,MAAM,EAAE,WAAW;AACzB,QAAQ,MAAM,CAAC,WAAW;AAC1B,QAAQ,MAAM,CAAC,aAAa;AAC5B,QAAQ,MAAM,CAAC,gBAAgB;AAC/B,QAAQ,MAAM,CAAC;AACf,MAAM,CAAC;AACP,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AACpE,IAAI,CAAC,CAAC;AACN,EAAE,CAAC;AACH,EAAE,uBAAuB,CAAC,MAAM,EAAE;AAClC,IAAI,OAAO,IAAI,CAAC,cAAc,CAAC;AAC/B,MAAM,KAAK,EAAE,MAAM,CAAC,KAAK;AACzB,MAAM,IAAI,EAAE,WAAW;AACvB,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM;AAC3B,MAAM,MAAM,EAAE,WAAW;AACzB,QAAQ,MAAM,CAAC,WAAW;AAC1B,QAAQ,MAAM,CAAC,aAAa;AAC5B,QAAQ,MAAM,CAAC,gBAAgB;AAC/B,QAAQ,KAAK;AACb,MAAM,CAAC;AACP,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AACpE,IAAI,CAAC,CAAC;AACN,EAAE;AACF,CAAC;AACD;AACA;AACE;AACA;AACA;AACA;AACF,qKAAC","file":"C:\\Users\\onecu\\Documents\\Intellectif\\IT-for-Intellectif\\learning-kit\\packages\\lk-core\\dist\\chunk-PJFDAP54.cjs","sourcesContent":[null]}
@@ -0,0 +1,188 @@
1
+ import {
2
+ ActivitySchemaError
3
+ } from "./chunk-6VOCV4EX.js";
4
+
5
+ // src/xapi/validators.ts
6
+ import { z } from "zod/v4";
7
+ var UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
8
+ var IRI = /^[a-z][a-z0-9+.-]*:/i;
9
+ var langMap = z.record(z.string(), z.string());
10
+ var extensions = z.record(z.string(), z.unknown());
11
+ var actorSchema = z.object({
12
+ objectType: z.literal("Agent"),
13
+ name: z.string().optional(),
14
+ mbox: z.string().regex(/^mailto:/, "mbox must be a mailto IRI").optional(),
15
+ account: z.object({ homePage: z.string(), name: z.string() }).optional()
16
+ }).refine((actor) => actor.mbox !== void 0 || actor.account !== void 0, {
17
+ error: "actor must be identified by an mbox or an account"
18
+ });
19
+ var statementSchema = z.object({
20
+ id: z.string().regex(UUID_V4, "id must be a UUID v4"),
21
+ actor: actorSchema,
22
+ verb: z.object({
23
+ id: z.string().regex(IRI, "verb.id must be an IRI"),
24
+ display: langMap
25
+ }),
26
+ object: z.object({
27
+ objectType: z.literal("Activity"),
28
+ id: z.string().regex(IRI, "object.id must be an IRI"),
29
+ definition: z.object({
30
+ name: langMap.optional(),
31
+ description: langMap.optional(),
32
+ type: z.string().optional(),
33
+ extensions: extensions.optional()
34
+ }).optional()
35
+ }),
36
+ result: z.object({
37
+ // xAPI 1.0.3 permits scaled in [-1, 1]; the SDK only emits [0, 1].
38
+ score: z.object({
39
+ scaled: z.number().min(-1).max(1),
40
+ raw: z.number().optional(),
41
+ min: z.number().optional(),
42
+ max: z.number().optional()
43
+ }).optional(),
44
+ success: z.boolean().optional(),
45
+ completion: z.boolean().optional(),
46
+ duration: z.string().regex(/^P/, "duration must be an ISO 8601 duration").optional(),
47
+ response: z.string().optional(),
48
+ extensions: extensions.optional()
49
+ }).optional(),
50
+ context: z.object({
51
+ platform: z.string().optional(),
52
+ language: z.string().optional(),
53
+ extensions: extensions.optional()
54
+ }).optional(),
55
+ timestamp: z.string().refine((value) => !Number.isNaN(Date.parse(value)), "timestamp must be ISO 8601"),
56
+ version: z.literal("1.0.3")
57
+ });
58
+ function isProduction() {
59
+ const g = globalThis;
60
+ return g.process?.env?.NODE_ENV === "production";
61
+ }
62
+ function validateXAPIStatement(statement) {
63
+ const result = statementSchema.safeParse(statement);
64
+ if (result.success) {
65
+ return;
66
+ }
67
+ const errors = result.error.issues.map((issue) => ({
68
+ path: issue.path.map(String),
69
+ message: issue.message,
70
+ code: issue.code
71
+ }));
72
+ if (isProduction()) {
73
+ console.warn("[learning-kit] Invalid xAPI statement (sent anyway):", errors);
74
+ return;
75
+ }
76
+ throw new ActivitySchemaError("xAPIStatement", errors);
77
+ }
78
+
79
+ // src/xapi/verbs.ts
80
+ var XAPIVerb = {
81
+ ANSWERED: "http://adlnet.gov/expapi/verbs/answered",
82
+ COMPLETED: "http://adlnet.gov/expapi/verbs/completed",
83
+ EXPERIENCED: "http://adlnet.gov/expapi/verbs/experienced",
84
+ INTERACTED: "http://adlnet.gov/expapi/verbs/interacted",
85
+ ATTEMPTED: "http://adlnet.gov/expapi/verbs/attempted",
86
+ PASSED: "http://adlnet.gov/expapi/verbs/passed",
87
+ FAILED: "http://adlnet.gov/expapi/verbs/failed",
88
+ WATCHED: "https://w3id.org/xapi/video/verbs/watched"
89
+ };
90
+ var XAPI_VERB_DISPLAY = {
91
+ ANSWERED: { "en-US": "answered" },
92
+ COMPLETED: { "en-US": "completed" },
93
+ EXPERIENCED: { "en-US": "experienced" },
94
+ INTERACTED: { "en-US": "interacted" },
95
+ ATTEMPTED: { "en-US": "attempted" },
96
+ PASSED: { "en-US": "passed" },
97
+ FAILED: { "en-US": "failed" },
98
+ WATCHED: { "en-US": "watched" }
99
+ };
100
+
101
+ // src/xapi/builder.ts
102
+ function msToIsoDuration(ms) {
103
+ return `PT${Math.round(ms / 1e3)}S`;
104
+ }
105
+ function buildObject(params) {
106
+ const definition = {
107
+ ...params.name !== void 0 ? { name: params.name } : {},
108
+ ...params.description !== void 0 ? { description: params.description } : {},
109
+ ...params.type !== void 0 ? { type: params.type } : {}
110
+ };
111
+ return {
112
+ objectType: "Activity",
113
+ id: params.id,
114
+ ...Object.keys(definition).length > 0 ? { definition } : {}
115
+ };
116
+ }
117
+ function buildResult(timeSpentMs, scoringResult, resultExtensions, response) {
118
+ return {
119
+ completion: true,
120
+ duration: msToIsoDuration(timeSpentMs),
121
+ ...scoringResult !== void 0 ? {
122
+ score: {
123
+ scaled: scoringResult.score,
124
+ raw: scoringResult.score,
125
+ min: 0,
126
+ max: scoringResult.maxScore
127
+ },
128
+ success: scoringResult.passed
129
+ } : {},
130
+ ...response !== void 0 ? { response } : {},
131
+ ...resultExtensions !== void 0 ? { extensions: resultExtensions } : {}
132
+ };
133
+ }
134
+ var xAPIBuilder = {
135
+ buildStatement(params) {
136
+ const statement = {
137
+ id: crypto.randomUUID(),
138
+ actor: params.actor,
139
+ verb: {
140
+ id: XAPIVerb[params.verb],
141
+ display: XAPI_VERB_DISPLAY[params.verb]
142
+ },
143
+ object: buildObject(params.object),
144
+ ...params.result !== void 0 ? { result: params.result } : {},
145
+ ...params.context !== void 0 ? { context: params.context } : {},
146
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
147
+ version: "1.0.3"
148
+ };
149
+ validateXAPIStatement(statement);
150
+ return statement;
151
+ },
152
+ buildAnsweredStatement(params) {
153
+ return this.buildStatement({
154
+ actor: params.actor,
155
+ verb: "ANSWERED",
156
+ object: params.object,
157
+ result: buildResult(
158
+ params.timeSpentMs,
159
+ params.scoringResult,
160
+ params.resultExtensions,
161
+ params.response
162
+ ),
163
+ ...params.context !== void 0 ? { context: params.context } : {}
164
+ });
165
+ },
166
+ buildCompletedStatement(params) {
167
+ return this.buildStatement({
168
+ actor: params.actor,
169
+ verb: "COMPLETED",
170
+ object: params.object,
171
+ result: buildResult(
172
+ params.timeSpentMs,
173
+ params.scoringResult,
174
+ params.resultExtensions,
175
+ void 0
176
+ ),
177
+ ...params.context !== void 0 ? { context: params.context } : {}
178
+ });
179
+ }
180
+ };
181
+
182
+ export {
183
+ validateXAPIStatement,
184
+ XAPIVerb,
185
+ XAPI_VERB_DISPLAY,
186
+ xAPIBuilder
187
+ };
188
+ //# sourceMappingURL=chunk-ZHOX6TO4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/xapi/validators.ts","../src/xapi/verbs.ts","../src/xapi/builder.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { ActivitySchemaError } from '../errors.js';\nimport type { ValidationError } from '../types/activity.js';\nimport type { XAPIStatement } from '../types/xapi.js';\n\nconst UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n// Minimal IRI/URI check: a scheme followed by ':'.\nconst IRI = /^[a-z][a-z0-9+.-]*:/i;\n\nconst langMap = z.record(z.string(), z.string());\nconst extensions = z.record(z.string(), z.unknown());\n\nconst actorSchema = z\n .object({\n objectType: z.literal('Agent'),\n name: z.string().optional(),\n mbox: z\n .string()\n .regex(/^mailto:/, 'mbox must be a mailto IRI')\n .optional(),\n account: z.object({ homePage: z.string(), name: z.string() }).optional(),\n })\n .refine((actor) => actor.mbox !== undefined || actor.account !== undefined, {\n error: 'actor must be identified by an mbox or an account',\n });\n\nconst statementSchema = z.object({\n id: z.string().regex(UUID_V4, 'id must be a UUID v4'),\n actor: actorSchema,\n verb: z.object({\n id: z.string().regex(IRI, 'verb.id must be an IRI'),\n display: langMap,\n }),\n object: z.object({\n objectType: z.literal('Activity'),\n id: z.string().regex(IRI, 'object.id must be an IRI'),\n definition: z\n .object({\n name: langMap.optional(),\n description: langMap.optional(),\n type: z.string().optional(),\n extensions: extensions.optional(),\n })\n .optional(),\n }),\n result: z\n .object({\n // xAPI 1.0.3 permits scaled in [-1, 1]; the SDK only emits [0, 1].\n score: z\n .object({\n scaled: z.number().min(-1).max(1),\n raw: z.number().optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n })\n .optional(),\n success: z.boolean().optional(),\n completion: z.boolean().optional(),\n duration: z.string().regex(/^P/, 'duration must be an ISO 8601 duration').optional(),\n response: z.string().optional(),\n extensions: extensions.optional(),\n })\n .optional(),\n context: z\n .object({\n platform: z.string().optional(),\n language: z.string().optional(),\n extensions: extensions.optional(),\n })\n .optional(),\n timestamp: z\n .string()\n .refine((value) => !Number.isNaN(Date.parse(value)), 'timestamp must be ISO 8601'),\n version: z.literal('1.0.3'),\n});\n\n/** True when running under `NODE_ENV=production`, safe in any environment. */\nfunction isProduction(): boolean {\n const g = globalThis as { process?: { env?: Record<string, string | undefined> } };\n return g.process?.env?.NODE_ENV === 'production';\n}\n\n/**\n * Validates a constructed {@link XAPIStatement} against the xAPI 1.0.3\n * structural contract.\n *\n * In development a structural failure throws (caught early); in production it\n * logs a warning and returns (the statement is still sent — see the design's\n * Error Handling table). Uses a `zod/v4` schema rather than `ajv` + an\n * external JSON Schema to keep `lk-core` dependency-free.\n *\n * NOTE: `ActivitySchemaError` is reused here per the task spec; its\n * `activityType` field carries the sentinel `'xAPIStatement'`. A dedicated\n * `XAPIValidationError` would be semantically cleaner — flagged for review.\n */\nexport function validateXAPIStatement(statement: XAPIStatement): void {\n const result = statementSchema.safeParse(statement);\n if (result.success) {\n return;\n }\n\n const errors: ValidationError[] = result.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n }));\n\n if (isProduction()) {\n console.warn('[learning-kit] Invalid xAPI statement (sent anyway):', errors);\n return;\n }\n\n throw new ActivitySchemaError('xAPIStatement', errors);\n}\n","/**\n * The set of xAPI verbs emitted by SDK activities, keyed by a stable\n * identifier mapped to its canonical xAPI verb IRI (xAPI 1.0.3 / ADL registry).\n */\nexport const XAPIVerb = {\n ANSWERED: 'http://adlnet.gov/expapi/verbs/answered',\n COMPLETED: 'http://adlnet.gov/expapi/verbs/completed',\n EXPERIENCED: 'http://adlnet.gov/expapi/verbs/experienced',\n INTERACTED: 'http://adlnet.gov/expapi/verbs/interacted',\n ATTEMPTED: 'http://adlnet.gov/expapi/verbs/attempted',\n PASSED: 'http://adlnet.gov/expapi/verbs/passed',\n FAILED: 'http://adlnet.gov/expapi/verbs/failed',\n WATCHED: 'https://w3id.org/xapi/video/verbs/watched',\n} as const;\n\n/** Union of the valid `XAPIVerb` keys. */\nexport type XAPIVerbKey = keyof typeof XAPIVerb;\n\n/**\n * Default `en-US` display label for each verb, used to populate\n * `XAPIVerbObject.display` when the builder resolves a verb key.\n */\nexport const XAPI_VERB_DISPLAY: Record<XAPIVerbKey, Record<string, string>> = {\n ANSWERED: { 'en-US': 'answered' },\n COMPLETED: { 'en-US': 'completed' },\n EXPERIENCED: { 'en-US': 'experienced' },\n INTERACTED: { 'en-US': 'interacted' },\n ATTEMPTED: { 'en-US': 'attempted' },\n PASSED: { 'en-US': 'passed' },\n FAILED: { 'en-US': 'failed' },\n WATCHED: { 'en-US': 'watched' },\n};\n","import type { ScoringResult } from '../types/activity.js';\nimport type {\n XAPIActor,\n XAPIContext,\n XAPIObject,\n XAPIResult,\n XAPIStatement,\n} from '../types/xapi.js';\nimport { validateXAPIStatement } from './validators.js';\nimport { XAPI_VERB_DISPLAY, XAPIVerb, type XAPIVerbKey } from './verbs.js';\n\n/** Caller-supplied activity object descriptor (mapped to an xAPI Activity). */\nexport interface XAPIObjectParams {\n /** Activity IRI. */\n id: string;\n name?: Record<string, string>;\n description?: Record<string, string>;\n /** Activity type IRI. */\n type?: string;\n}\n\n/** Parameters for the generic {@link xAPIBuilder.buildStatement}. */\nexport interface XAPIStatementParams {\n actor: XAPIActor;\n verb: XAPIVerbKey;\n object: XAPIObjectParams;\n result?: XAPIResult;\n context?: XAPIContext;\n}\n\n/** Parameters for {@link xAPIBuilder.buildAnsweredStatement} (verb = ANSWERED). */\nexport interface AnsweredStatementParams {\n actor: XAPIActor;\n object: XAPIObjectParams;\n scoringResult: ScoringResult;\n timeSpentMs: number;\n /** Serialized learner response string. */\n response?: string;\n context?: XAPIContext;\n resultExtensions?: Record<string, unknown>;\n}\n\n/** Parameters for {@link xAPIBuilder.buildCompletedStatement} (verb = COMPLETED). */\nexport interface CompletedStatementParams {\n actor: XAPIActor;\n object: XAPIObjectParams;\n scoringResult?: ScoringResult;\n timeSpentMs: number;\n context?: XAPIContext;\n resultExtensions?: Record<string, unknown>;\n}\n\n/** Converts a millisecond duration to an ISO 8601 `PT<seconds>S` string. */\nfunction msToIsoDuration(ms: number): string {\n return `PT${Math.round(ms / 1000)}S`;\n}\n\n/** Builds the xAPI Activity object, including `definition` only when populated. */\nfunction buildObject(params: XAPIObjectParams): XAPIObject {\n const definition: NonNullable<XAPIObject['definition']> = {\n ...(params.name !== undefined ? { name: params.name } : {}),\n ...(params.description !== undefined ? { description: params.description } : {}),\n ...(params.type !== undefined ? { type: params.type } : {}),\n };\n return {\n objectType: 'Activity',\n id: params.id,\n ...(Object.keys(definition).length > 0 ? { definition } : {}),\n };\n}\n\n/**\n * Maps a {@link ScoringResult} + timing to an {@link XAPIResult} per the\n * normative mapping in the design document.\n */\nfunction buildResult(\n timeSpentMs: number,\n scoringResult: ScoringResult | undefined,\n resultExtensions: Record<string, unknown> | undefined,\n response: string | undefined,\n): XAPIResult {\n return {\n completion: true,\n duration: msToIsoDuration(timeSpentMs),\n ...(scoringResult !== undefined\n ? {\n score: {\n scaled: scoringResult.score,\n raw: scoringResult.score,\n min: 0,\n max: scoringResult.maxScore,\n },\n success: scoringResult.passed,\n }\n : {}),\n ...(response !== undefined ? { response } : {}),\n ...(resultExtensions !== undefined ? { extensions: resultExtensions } : {}),\n };\n}\n\n/**\n * Constructs xAPI 1.0.3 Statements. Every call stamps a fresh UUID v4 `id`,\n * an ISO 8601 `timestamp`, and `version: '1.0.3'`. Not pure by design —\n * statements are unique events.\n */\nexport const xAPIBuilder = {\n buildStatement(params: XAPIStatementParams): XAPIStatement {\n const statement: XAPIStatement = {\n id: crypto.randomUUID(),\n actor: params.actor,\n verb: {\n id: XAPIVerb[params.verb],\n display: XAPI_VERB_DISPLAY[params.verb],\n },\n object: buildObject(params.object),\n ...(params.result !== undefined ? { result: params.result } : {}),\n ...(params.context !== undefined ? { context: params.context } : {}),\n timestamp: new Date().toISOString(),\n version: '1.0.3',\n };\n // Design xAPIBuilder step 4: validate every statement (throws in dev,\n // warns in prod). All build*Statement helpers route through here.\n validateXAPIStatement(statement);\n return statement;\n },\n\n buildAnsweredStatement(params: AnsweredStatementParams): XAPIStatement {\n return this.buildStatement({\n actor: params.actor,\n verb: 'ANSWERED',\n object: params.object,\n result: buildResult(\n params.timeSpentMs,\n params.scoringResult,\n params.resultExtensions,\n params.response,\n ),\n ...(params.context !== undefined ? { context: params.context } : {}),\n });\n },\n\n buildCompletedStatement(params: CompletedStatementParams): XAPIStatement {\n return this.buildStatement({\n actor: params.actor,\n verb: 'COMPLETED',\n object: params.object,\n result: buildResult(\n params.timeSpentMs,\n params.scoringResult,\n params.resultExtensions,\n undefined,\n ),\n ...(params.context !== undefined ? { context: params.context } : {}),\n });\n },\n};\n"],"mappings":"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","names":[]}
package/dist/index.cjs ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunk3JMLUUFScjs = require('./chunk-3JMLUUFS.cjs');
5
+
6
+
7
+
8
+
9
+
10
+ var _chunkPJFDAP54cjs = require('./chunk-PJFDAP54.cjs');
11
+
12
+
13
+
14
+ var _chunkDV466SBJcjs = require('./chunk-DV466SBJ.cjs');
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+ var _chunkDCDOTQNHcjs = require('./chunk-DCDOTQNH.cjs');
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+ exports.ActivitySchemaError = _chunkDV466SBJcjs.ActivitySchemaError; exports.BlankConfigSchema = _chunkDCDOTQNHcjs.BlankConfigSchema; exports.FeedbackSchema = _chunkDCDOTQNHcjs.FeedbackSchema; exports.FillInTheBlanksDataSchema = _chunkDCDOTQNHcjs.FillInTheBlanksDataSchema; exports.MediaSchema = _chunkDCDOTQNHcjs.MediaSchema; exports.MultipleChoiceDataSchema = _chunkDCDOTQNHcjs.MultipleChoiceDataSchema; exports.MultipleChoiceOptionSchema = _chunkDCDOTQNHcjs.MultipleChoiceOptionSchema; exports.UnknownActivityTypeError = _chunkDV466SBJcjs.UnknownActivityTypeError; exports.XAPIVerb = _chunkPJFDAP54cjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunkPJFDAP54cjs.XAPI_VERB_DISPLAY; exports.computePassThreshold = _chunk3JMLUUFScjs.computePassThreshold; exports.fillInTheBlanksJsonSchema = _chunkDCDOTQNHcjs.fillInTheBlanksJsonSchema; exports.multipleChoiceJsonSchema = _chunkDCDOTQNHcjs.multipleChoiceJsonSchema; exports.score = _chunk3JMLUUFScjs.score; exports.validateActivity = _chunkDCDOTQNHcjs.validateActivity; exports.validateXAPIStatement = _chunkPJFDAP54cjs.validateXAPIStatement; exports.xAPIBuilder = _chunkPJFDAP54cjs.xAPIBuilder;
45
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["c:\\Users\\onecu\\Documents\\Intellectif\\IT-for-Intellectif\\learning-kit\\packages\\lk-core\\dist\\index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,onCAAC","file":"C:\\Users\\onecu\\Documents\\Intellectif\\IT-for-Intellectif\\learning-kit\\packages\\lk-core\\dist\\index.cjs"}
@@ -0,0 +1,56 @@
1
+ import { V as ValidationError } from './activity-D5tqgx8A.cjs';
2
+ export { A as ActivityData, a as ActivityDataMap, b as ActivityFeedback, c as ActivityMedia, d as ActivityResult, e as ActivityType, B as BlankConfig, F as FillInTheBlanksData, f as FillInTheBlanksLearnerResponse, I as InteractionEvent, L as LearnerResponse, M as MultipleChoiceData, g as MultipleChoiceLearnerResponse, h as MultipleChoiceOption, S as ScoringDetail, i as ScoringResult, j as ValidationResult, X as XAPIActor, k as XAPIConfig, l as XAPIContext, m as XAPIError, n as XAPIObject, o as XAPIResult, p as XAPIScore, q as XAPIStatement, r as XAPIVerbObject } from './activity-D5tqgx8A.cjs';
3
+ export { BlankConfigSchema, FeedbackSchema, FillInTheBlanksDataSchema, MediaSchema, MultipleChoiceDataSchema, MultipleChoiceOptionSchema, fillInTheBlanksJsonSchema, multipleChoiceJsonSchema, validateActivity } from './schemas.cjs';
4
+ export { computePassThreshold, score } from './scoring.cjs';
5
+ export { AnsweredStatementParams, CompletedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder } from './xapi.cjs';
6
+ import 'zod/v4';
7
+
8
+ /** Thrown when activity data fails schema validation at a component boundary. */
9
+ declare class ActivitySchemaError extends Error {
10
+ readonly activityType: string;
11
+ readonly errors: ValidationError[];
12
+ constructor(activityType: string, errors: ValidationError[]);
13
+ }
14
+ /** Thrown when an unrecognised activity type is passed to the scoring engine. */
15
+ declare class UnknownActivityTypeError extends Error {
16
+ readonly activityType: string;
17
+ constructor(activityType: string);
18
+ }
19
+
20
+ /**
21
+ * All CSS custom property tokens consumed by learning-kit components.
22
+ * Every key maps to a `--lk-*` CSS variable name; every value is a CSS value string.
23
+ * Pass a `Partial<ThemeTokens>` to `ThemeProvider` to override individual tokens.
24
+ */
25
+ interface ThemeTokens {
26
+ '--lk-color-primary': string;
27
+ '--lk-color-primary-hover': string;
28
+ '--lk-color-surface': string;
29
+ '--lk-color-surface-raised': string;
30
+ '--lk-color-border': string;
31
+ '--lk-color-text': string;
32
+ '--lk-color-text-muted': string;
33
+ '--lk-color-success': string;
34
+ '--lk-color-error': string;
35
+ '--lk-color-warning': string;
36
+ '--lk-color-focus-ring': string;
37
+ '--lk-spacing-xs': string;
38
+ '--lk-spacing-sm': string;
39
+ '--lk-spacing-md': string;
40
+ '--lk-spacing-lg': string;
41
+ '--lk-spacing-xl': string;
42
+ '--lk-font-family-base': string;
43
+ '--lk-font-size-sm': string;
44
+ '--lk-font-size-base': string;
45
+ '--lk-font-size-lg': string;
46
+ '--lk-font-weight-normal': string;
47
+ '--lk-font-weight-bold': string;
48
+ '--lk-line-height-base': string;
49
+ '--lk-radius-sm': string;
50
+ '--lk-radius-base': string;
51
+ '--lk-radius-lg': string;
52
+ '--lk-transition-fast': string;
53
+ '--lk-transition-base': string;
54
+ }
55
+
56
+ export { ActivitySchemaError, type ThemeTokens, UnknownActivityTypeError, ValidationError };
@@ -0,0 +1,56 @@
1
+ import { V as ValidationError } from './activity-D5tqgx8A.js';
2
+ export { A as ActivityData, a as ActivityDataMap, b as ActivityFeedback, c as ActivityMedia, d as ActivityResult, e as ActivityType, B as BlankConfig, F as FillInTheBlanksData, f as FillInTheBlanksLearnerResponse, I as InteractionEvent, L as LearnerResponse, M as MultipleChoiceData, g as MultipleChoiceLearnerResponse, h as MultipleChoiceOption, S as ScoringDetail, i as ScoringResult, j as ValidationResult, X as XAPIActor, k as XAPIConfig, l as XAPIContext, m as XAPIError, n as XAPIObject, o as XAPIResult, p as XAPIScore, q as XAPIStatement, r as XAPIVerbObject } from './activity-D5tqgx8A.js';
3
+ export { BlankConfigSchema, FeedbackSchema, FillInTheBlanksDataSchema, MediaSchema, MultipleChoiceDataSchema, MultipleChoiceOptionSchema, fillInTheBlanksJsonSchema, multipleChoiceJsonSchema, validateActivity } from './schemas.js';
4
+ export { computePassThreshold, score } from './scoring.js';
5
+ export { AnsweredStatementParams, CompletedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder } from './xapi.js';
6
+ import 'zod/v4';
7
+
8
+ /** Thrown when activity data fails schema validation at a component boundary. */
9
+ declare class ActivitySchemaError extends Error {
10
+ readonly activityType: string;
11
+ readonly errors: ValidationError[];
12
+ constructor(activityType: string, errors: ValidationError[]);
13
+ }
14
+ /** Thrown when an unrecognised activity type is passed to the scoring engine. */
15
+ declare class UnknownActivityTypeError extends Error {
16
+ readonly activityType: string;
17
+ constructor(activityType: string);
18
+ }
19
+
20
+ /**
21
+ * All CSS custom property tokens consumed by learning-kit components.
22
+ * Every key maps to a `--lk-*` CSS variable name; every value is a CSS value string.
23
+ * Pass a `Partial<ThemeTokens>` to `ThemeProvider` to override individual tokens.
24
+ */
25
+ interface ThemeTokens {
26
+ '--lk-color-primary': string;
27
+ '--lk-color-primary-hover': string;
28
+ '--lk-color-surface': string;
29
+ '--lk-color-surface-raised': string;
30
+ '--lk-color-border': string;
31
+ '--lk-color-text': string;
32
+ '--lk-color-text-muted': string;
33
+ '--lk-color-success': string;
34
+ '--lk-color-error': string;
35
+ '--lk-color-warning': string;
36
+ '--lk-color-focus-ring': string;
37
+ '--lk-spacing-xs': string;
38
+ '--lk-spacing-sm': string;
39
+ '--lk-spacing-md': string;
40
+ '--lk-spacing-lg': string;
41
+ '--lk-spacing-xl': string;
42
+ '--lk-font-family-base': string;
43
+ '--lk-font-size-sm': string;
44
+ '--lk-font-size-base': string;
45
+ '--lk-font-size-lg': string;
46
+ '--lk-font-weight-normal': string;
47
+ '--lk-font-weight-bold': string;
48
+ '--lk-line-height-base': string;
49
+ '--lk-radius-sm': string;
50
+ '--lk-radius-base': string;
51
+ '--lk-radius-lg': string;
52
+ '--lk-transition-fast': string;
53
+ '--lk-transition-base': string;
54
+ }
55
+
56
+ export { ActivitySchemaError, type ThemeTokens, UnknownActivityTypeError, ValidationError };