@intellectif/lk-core 0.5.0 → 0.7.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 (46) hide show
  1. package/README.md +12 -4
  2. package/dist/{activity-wkzRemHx.d.cts → activity-gelWNZ6V.d.cts} +49 -10
  3. package/dist/{activity-wkzRemHx.d.ts → activity-gelWNZ6V.d.ts} +49 -10
  4. package/dist/{chunk-WV5WQ3SZ.js → chunk-2SQ75JTE.js} +2 -2
  5. package/dist/{chunk-4JR3UXX6.cjs → chunk-5RE3ZRSA.cjs} +8 -1
  6. package/dist/chunk-5RE3ZRSA.cjs.map +1 -0
  7. package/dist/{chunk-FCM5VJBS.cjs → chunk-7NIH5IL3.cjs} +16 -13
  8. package/dist/chunk-7NIH5IL3.cjs.map +1 -0
  9. package/dist/{chunk-R7PDJBRX.cjs → chunk-AFIQQADJ.cjs} +4 -4
  10. package/dist/{chunk-R7PDJBRX.cjs.map → chunk-AFIQQADJ.cjs.map} +1 -1
  11. package/dist/{chunk-SM5HUGYU.cjs → chunk-MVZKEWZN.cjs} +21 -11
  12. package/dist/chunk-MVZKEWZN.cjs.map +1 -0
  13. package/dist/{chunk-DUQVGLQ3.js → chunk-NOBJYDOB.js} +15 -5
  14. package/dist/chunk-NOBJYDOB.js.map +1 -0
  15. package/dist/{chunk-LSHDNA2T.js → chunk-XL75ZZVM.js} +6 -3
  16. package/dist/chunk-XL75ZZVM.js.map +1 -0
  17. package/dist/{chunk-NUCEUU4P.js → chunk-YCXIHFLG.js} +8 -1
  18. package/dist/chunk-YCXIHFLG.js.map +1 -0
  19. package/dist/{index-BKyZrd94.d.cts → index-B_RLyeEj.d.ts} +101 -14
  20. package/dist/{index-CLmXzBhB.d.ts → index-CDWH2WIg.d.cts} +101 -14
  21. package/dist/index.cjs +336 -25
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +360 -6
  24. package/dist/index.d.ts +360 -6
  25. package/dist/index.js +317 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/schemas.cjs +3 -3
  28. package/dist/schemas.d.cts +2 -2
  29. package/dist/schemas.d.ts +2 -2
  30. package/dist/schemas.js +2 -2
  31. package/dist/scoring.cjs +3 -3
  32. package/dist/scoring.d.cts +2 -2
  33. package/dist/scoring.d.ts +2 -2
  34. package/dist/scoring.js +2 -2
  35. package/dist/xapi.cjs +3 -3
  36. package/dist/xapi.d.cts +1 -1
  37. package/dist/xapi.d.ts +1 -1
  38. package/dist/xapi.js +2 -2
  39. package/package.json +1 -1
  40. package/dist/chunk-4JR3UXX6.cjs.map +0 -1
  41. package/dist/chunk-DUQVGLQ3.js.map +0 -1
  42. package/dist/chunk-FCM5VJBS.cjs.map +0 -1
  43. package/dist/chunk-LSHDNA2T.js.map +0 -1
  44. package/dist/chunk-NUCEUU4P.js.map +0 -1
  45. package/dist/chunk-SM5HUGYU.cjs.map +0 -1
  46. /package/dist/{chunk-WV5WQ3SZ.js.map → chunk-2SQ75JTE.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { A as ActivityData, c as ActivityMedia, t as ValidationResult, e as ActivityType, a as ActivityDataMap } from './activity-wkzRemHx.js';
1
+ import { A as ActivityData, c as ActivityMedia, t as ValidationResult, e as ActivityType, a as ActivityDataMap } from './activity-gelWNZ6V.cjs';
2
2
  import { z } from 'zod/v4';
3
3
 
4
4
  /** What a stimulus primarily is. Drives validation and layout, never scoring. */
@@ -56,9 +56,26 @@ interface ItemGroup<TItem = ActivityData> {
56
56
  type: 'item-group';
57
57
  id: string;
58
58
  title?: string;
59
+ /**
60
+ * Stable identity for this entry's slots, independent of where it sits in
61
+ * the array. See {@link SequenceSlot.slotId}: without one, inserting a
62
+ * question above this group re-maps every slot id beneath it, and stored
63
+ * grades quietly start naming different questions.
64
+ */
65
+ slotKey?: string;
59
66
  stimulus: Stimulus;
60
- /** The items, in authored order. Non-empty; ids unique within the group; no nested groups. */
61
- items: TItem[];
67
+ /**
68
+ * The items, in authored order. Non-empty; ids unique within the group; no
69
+ * nested groups.
70
+ *
71
+ * An item may declare its own `slotKey`, for the same reason an entry can:
72
+ * it pins the item's identity within the group (`"reading.q1"` rather than
73
+ * `"reading.0"`), so inserting a question into a published group does not
74
+ * re-map the ones after it.
75
+ */
76
+ items: (TItem & {
77
+ slotKey?: string;
78
+ })[];
62
79
  /**
63
80
  * `none` (default) keeps authored order; `within-group` shuffles the items
64
81
  * among themselves under the sequence seed. Either way the group stays one
@@ -66,8 +83,20 @@ interface ItemGroup<TItem = ActivityData> {
66
83
  */
67
84
  shuffle?: 'none' | 'within-group';
68
85
  }
69
- /** What a sequence is made of: loose activities and item groups, in authored order. */
70
- type SequenceEntry<TItem = ActivityData> = TItem | ItemGroup<TItem>;
86
+ /**
87
+ * What a sequence is made of: loose activities and item groups, in authored
88
+ * order.
89
+ *
90
+ * A plain activity may carry `slotKey` here even though no activity SCHEMA
91
+ * declares one, because a slot key describes an item's PLACE in a paper, not
92
+ * its content — the same question keeps its own id in every paper it appears
93
+ * in. Putting it on the entry rather than on the activity is what lets it be
94
+ * authored without every activity type having to know about assessment
95
+ * assembly. See {@link SequenceSlot.slotId}.
96
+ */
97
+ type SequenceEntry<TItem = ActivityData> = (TItem & {
98
+ slotKey?: string;
99
+ }) | ItemGroup<TItem>;
71
100
  /** The group a presented slot belongs to. */
72
101
  interface SequenceSlotGroup {
73
102
  id: string;
@@ -82,10 +111,20 @@ interface SequenceSlotGroup {
82
111
  interface SequenceSlot<TItem = ActivityData> {
83
112
  /**
84
113
  * Identity of the slot within the sequence definition — unique, and stable
85
- * under shuffling. Derived from the AUTHORED position (`"2"` for the third
114
+ * under shuffling. Feed it to `composeAssessmentScore` as `slotId`.
115
+ *
116
+ * By default it is derived from the AUTHORED position (`"2"` for the third
86
117
  * top-level entry; `"2.1"` for the second item of that entry when it is a
87
118
  * group), so the same activity can appear in two entries and still be two
88
- * slots. Feed it to `composeAssessmentScore` as `slotId`.
119
+ * slots.
120
+ *
121
+ * **A positional id is only valid against one version of the entries
122
+ * array.** Insert a question at the top of a published paper and every id
123
+ * below it shifts: rows stored as `"3"` now name what used to be entry 2,
124
+ * and a re-grade or a review render pairs each response with the wrong
125
+ * question — silently, because the ids still look valid. For any content
126
+ * whose slot ids you persist, give the entries an explicit `slotKey`; it is
127
+ * used verbatim here and survives insertion, deletion and re-ordering.
89
128
  */
90
129
  slotId: string;
91
130
  /** 0-based PRESENTED position, after shuffling. */
@@ -212,7 +251,7 @@ declare const FillInTheBlanksDataSchema: z.ZodObject<{
212
251
  passThreshold: z.ZodOptional<z.ZodNumber>;
213
252
  locale: z.ZodOptional<z.ZodString>;
214
253
  learningObjectives: z.ZodOptional<z.ZodArray<z.ZodString>>;
215
- difficultyLevel: z.ZodOptional<z.ZodLiteral<1 | 2 | 3 | 4 | 5>>;
254
+ difficultyLevel: z.ZodOptional<z.ZodLiteral<2 | 1 | 3 | 4 | 5>>;
216
255
  }, z.core.$loose>;
217
256
 
218
257
  /**
@@ -262,6 +301,7 @@ declare const ItemGroupSchema: z.ZodObject<{
262
301
  type: z.ZodLiteral<"item-group">;
263
302
  id: z.ZodString;
264
303
  title: z.ZodOptional<z.ZodString>;
304
+ slotKey: z.ZodOptional<z.ZodString>;
265
305
  stimulus: z.ZodObject<{
266
306
  id: z.ZodString;
267
307
  kind: z.ZodEnum<{
@@ -292,12 +332,15 @@ declare const ItemGroupSchema: z.ZodObject<{
292
332
  items: z.ZodArray<z.ZodObject<{
293
333
  type: z.ZodString;
294
334
  id: z.ZodString;
335
+ slotKey: z.ZodOptional<z.ZodString>;
295
336
  }, z.core.$loose>>;
296
337
  shuffle: z.ZodOptional<z.ZodEnum<{
297
338
  none: "none";
298
339
  "within-group": "within-group";
299
340
  }>>;
300
341
  }, z.core.$loose>;
342
+ /** The learner-safe shape of a stimulus, derived from the strict schema below. */
343
+ type RedactedStimulus = z.infer<typeof RedactedStimulusSchema>;
301
344
  /** Strict learner-safe stimulus: everything but the author-only `transcript`. */
302
345
  declare const RedactedStimulusSchema: z.ZodObject<{
303
346
  id: z.ZodString;
@@ -336,6 +379,7 @@ declare const RedactedItemGroupSchema: z.ZodObject<{
336
379
  type: z.ZodLiteral<"item-group">;
337
380
  id: z.ZodString;
338
381
  title: z.ZodOptional<z.ZodString>;
382
+ slotKey: z.ZodOptional<z.ZodString>;
339
383
  stimulus: z.ZodObject<{
340
384
  id: z.ZodString;
341
385
  kind: z.ZodEnum<{
@@ -527,7 +571,7 @@ declare const MultipleChoiceDataSchema: z.ZodObject<{
527
571
  shuffle: z.ZodOptional<z.ZodBoolean>;
528
572
  locale: z.ZodOptional<z.ZodString>;
529
573
  learningObjectives: z.ZodOptional<z.ZodArray<z.ZodString>>;
530
- difficultyLevel: z.ZodOptional<z.ZodLiteral<1 | 2 | 3 | 4 | 5>>;
574
+ difficultyLevel: z.ZodOptional<z.ZodLiteral<2 | 1 | 3 | 4 | 5>>;
531
575
  }, z.core.$loose>;
532
576
 
533
577
  /** A redacted Multiple Choice option: id and display text only — no `isCorrect`, no feedback. */
@@ -557,6 +601,8 @@ declare const RedactedMultipleChoiceDataSchema: z.ZodObject<{
557
601
  shuffle: z.ZodOptional<z.ZodBoolean>;
558
602
  /** Marker distinguishing a redacted projection from full activity data. */
559
603
  redacted: z.ZodLiteral<true>;
604
+ /** Slot identity, carried through redaction so the client and the plan agree. */
605
+ slotKey: z.ZodOptional<z.ZodString>;
560
606
  schemaVersion: z.ZodLiteral<"1.0">;
561
607
  id: z.ZodString;
562
608
  title: z.ZodString;
@@ -574,7 +620,7 @@ declare const RedactedMultipleChoiceDataSchema: z.ZodObject<{
574
620
  passThreshold: z.ZodOptional<z.ZodNumber>;
575
621
  locale: z.ZodOptional<z.ZodString>;
576
622
  learningObjectives: z.ZodOptional<z.ZodArray<z.ZodString>>;
577
- difficultyLevel: z.ZodOptional<z.ZodLiteral<1 | 2 | 3 | 4 | 5>>;
623
+ difficultyLevel: z.ZodOptional<z.ZodLiteral<2 | 1 | 3 | 4 | 5>>;
578
624
  }, z.core.$strict>;
579
625
  /** A redacted blank: id and hint only — no accepted answers, no matching rules, no feedback. */
580
626
  declare const RedactedBlankConfigSchema: z.ZodObject<{
@@ -592,6 +638,8 @@ declare const RedactedFillInTheBlanksDataSchema: z.ZodObject<{
592
638
  }, z.core.$strict>>;
593
639
  /** Marker distinguishing a redacted projection from full activity data. */
594
640
  redacted: z.ZodLiteral<true>;
641
+ /** Slot identity, carried through redaction so the client and the plan agree. */
642
+ slotKey: z.ZodOptional<z.ZodString>;
595
643
  schemaVersion: z.ZodLiteral<"1.0">;
596
644
  id: z.ZodString;
597
645
  title: z.ZodString;
@@ -609,7 +657,7 @@ declare const RedactedFillInTheBlanksDataSchema: z.ZodObject<{
609
657
  passThreshold: z.ZodOptional<z.ZodNumber>;
610
658
  locale: z.ZodOptional<z.ZodString>;
611
659
  learningObjectives: z.ZodOptional<z.ZodArray<z.ZodString>>;
612
- difficultyLevel: z.ZodOptional<z.ZodLiteral<1 | 2 | 3 | 4 | 5>>;
660
+ difficultyLevel: z.ZodOptional<z.ZodLiteral<2 | 1 | 3 | 4 | 5>>;
613
661
  }, z.core.$strict>;
614
662
  /**
615
663
  * Redacted Written Response data: the prompt, word bounds and rubric are
@@ -633,6 +681,8 @@ declare const RedactedWrittenResponseDataSchema: z.ZodObject<{
633
681
  languageTarget: z.ZodOptional<z.ZodString>;
634
682
  /** Marker distinguishing a redacted projection from full activity data. */
635
683
  redacted: z.ZodLiteral<true>;
684
+ /** Slot identity, carried through redaction so the client and the plan agree. */
685
+ slotKey: z.ZodOptional<z.ZodString>;
636
686
  schemaVersion: z.ZodLiteral<"1.0">;
637
687
  id: z.ZodString;
638
688
  title: z.ZodString;
@@ -650,8 +700,45 @@ declare const RedactedWrittenResponseDataSchema: z.ZodObject<{
650
700
  passThreshold: z.ZodOptional<z.ZodNumber>;
651
701
  locale: z.ZodOptional<z.ZodString>;
652
702
  learningObjectives: z.ZodOptional<z.ZodArray<z.ZodString>>;
653
- difficultyLevel: z.ZodOptional<z.ZodLiteral<1 | 2 | 3 | 4 | 5>>;
703
+ difficultyLevel: z.ZodOptional<z.ZodLiteral<2 | 1 | 3 | 4 | 5>>;
654
704
  }, z.core.$strict>;
705
+ /**
706
+ * The learner-safe SHAPE of each built-in type, derived from the strict schema
707
+ * above rather than hand-written beside it.
708
+ *
709
+ * `redact()` returns {@link RedactedActivityData}, which proves a payload is
710
+ * learner-safe but is index-signature typed — it deliberately says nothing
711
+ * about what the payload still CONTAINS. That is right for the assertion and
712
+ * useless for anything that has to render or transport the result, so every
713
+ * integrator ends up re-declaring these interfaces by hand and they drift the
714
+ * moment a schema changes. Deriving them with `z.infer` means the type and the
715
+ * validator can never disagree.
716
+ *
717
+ * Use them for the payload a server sends an exam client, and for the props of
718
+ * a renderer that must never see an answer key.
719
+ */
720
+ type RedactedMultipleChoiceOption = z.infer<typeof RedactedMultipleChoiceOptionSchema>;
721
+ /** A Multiple Choice item with the answer key, feedback and strategy removed. */
722
+ type RedactedMultipleChoiceData = z.infer<typeof RedactedMultipleChoiceDataSchema>;
723
+ /** A blank with its accepted answers and matching rules removed; the hint survives. */
724
+ type RedactedBlankConfig = z.infer<typeof RedactedBlankConfigSchema>;
725
+ /** A Fill-in-the-Blanks item with every accepted answer removed. */
726
+ type RedactedFillInTheBlanksData = z.infer<typeof RedactedFillInTheBlanksDataSchema>;
727
+ /** A Written Response item; the rubric survives, because it tells the learner what is assessed. */
728
+ type RedactedWrittenResponseData = z.infer<typeof RedactedWrittenResponseDataSchema>;
729
+ /**
730
+ * Discriminated union of every built-in redacted activity. Narrow it on
731
+ * `type`, exactly as you would {@link ActivityData}:
732
+ *
733
+ * ```ts
734
+ * function render(item: RedactedActivity) {
735
+ * if (item.type === 'multiple-choice') {
736
+ * return item.options.map((option) => option.text); // no `isCorrect` to leak
737
+ * }
738
+ * }
739
+ * ```
740
+ */
741
+ type RedactedActivity = RedactedMultipleChoiceData | RedactedFillInTheBlanksData | RedactedWrittenResponseData;
655
742
 
656
743
  /** Zod schema for a single rubric criterion. Loose: unknown keys preserved. */
657
744
  declare const WrittenResponseRubricCriterionSchema: z.ZodObject<{
@@ -712,7 +799,7 @@ declare const WrittenResponseDataSchema: z.ZodObject<{
712
799
  passThreshold: z.ZodOptional<z.ZodNumber>;
713
800
  locale: z.ZodOptional<z.ZodString>;
714
801
  learningObjectives: z.ZodOptional<z.ZodArray<z.ZodString>>;
715
- difficultyLevel: z.ZodOptional<z.ZodLiteral<1 | 2 | 3 | 4 | 5>>;
802
+ difficultyLevel: z.ZodOptional<z.ZodLiteral<2 | 1 | 3 | 4 | 5>>;
716
803
  }, z.core.$loose>;
717
804
 
718
805
  /**
@@ -729,4 +816,4 @@ declare const WrittenResponseDataSchema: z.ZodObject<{
729
816
  */
730
817
  declare function validateActivity<T extends ActivityType>(type: T, data: unknown): ValidationResult<ActivityDataMap[T]>;
731
818
 
732
- export { BlankConfigSchema as B, FeedbackSchema as F, type ItemGroup as I, MediaSchema as M, RedactedBlankConfigSchema as R, type SequenceEntry as S, TextMatchPolicySchema as T, WrittenResponseDataSchema as W, FillInTheBlanksDataSchema as a, ItemGroupSchema as b, MediaUrlSchema as c, MultipleChoiceDataSchema as d, MultipleChoiceOptionSchema as e, RedactedFillInTheBlanksDataSchema as f, RedactedItemGroupSchema as g, RedactedMultipleChoiceDataSchema as h, RedactedMultipleChoiceOptionSchema as i, RedactedStimulusSchema as j, RedactedWrittenResponseDataSchema as k, type SequenceSlot as l, type SequenceSlotGroup as m, type Stimulus as n, type StimulusKind as o, StimulusSchema as p, WrittenResponseRubricCriterionSchema as q, WrittenResponseRubricSchema as r, fillInTheBlanksJsonSchema as s, itemGroupJsonSchema as t, jsonSchemaFor as u, multipleChoiceJsonSchema as v, stimulusJsonSchema as w, validateActivity as x, validateItemGroup as y, writtenResponseJsonSchema as z };
819
+ export { itemGroupJsonSchema as A, BlankConfigSchema as B, jsonSchemaFor as C, multipleChoiceJsonSchema as D, stimulusJsonSchema as E, FeedbackSchema as F, validateActivity as G, validateItemGroup as H, type ItemGroup as I, writtenResponseJsonSchema as J, MediaSchema as M, type RedactedActivity as R, type SequenceEntry as S, TextMatchPolicySchema as T, WrittenResponseDataSchema as W, FillInTheBlanksDataSchema as a, ItemGroupSchema as b, MediaUrlSchema as c, MultipleChoiceDataSchema as d, MultipleChoiceOptionSchema as e, type RedactedBlankConfig as f, RedactedBlankConfigSchema as g, type RedactedFillInTheBlanksData as h, RedactedFillInTheBlanksDataSchema as i, RedactedItemGroupSchema as j, type RedactedMultipleChoiceData as k, RedactedMultipleChoiceDataSchema as l, type RedactedMultipleChoiceOption as m, RedactedMultipleChoiceOptionSchema as n, type RedactedStimulus as o, RedactedStimulusSchema as p, type RedactedWrittenResponseData as q, RedactedWrittenResponseDataSchema as r, type SequenceSlot as s, type SequenceSlotGroup as t, type Stimulus as u, type StimulusKind as v, StimulusSchema as w, WrittenResponseRubricCriterionSchema as x, WrittenResponseRubricSchema as y, fillInTheBlanksJsonSchema as z };