@conform-ed/qti-react 0.0.12 → 0.0.14

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 (134) hide show
  1. package/dist/capability.d.ts +17 -0
  2. package/dist/content-model.d.ts +42 -0
  3. package/dist/graphic.d.ts +23 -0
  4. package/dist/index.d.ts +14 -0
  5. package/dist/index.js +4556 -212
  6. package/dist/interactions/associate.d.ts +2 -0
  7. package/dist/interactions/choice.d.ts +2 -0
  8. package/dist/interactions/drawing.d.ts +2 -0
  9. package/dist/interactions/end-attempt.d.ts +2 -0
  10. package/dist/interactions/extended-text.d.ts +2 -0
  11. package/dist/interactions/gap-match.d.ts +2 -0
  12. package/dist/interactions/graphic.d.ts +13 -0
  13. package/dist/interactions/hottext.d.ts +2 -0
  14. package/dist/interactions/index.d.ts +18 -0
  15. package/dist/interactions/inline-choice.d.ts +2 -0
  16. package/dist/interactions/match.d.ts +2 -0
  17. package/dist/interactions/media.d.ts +2 -0
  18. package/dist/interactions/order.d.ts +2 -0
  19. package/dist/interactions/slider.d.ts +2 -0
  20. package/dist/interactions/text-entry.d.ts +2 -0
  21. package/dist/interactions/upload.d.ts +2 -0
  22. package/dist/normalized-item.d.ts +30 -0
  23. package/dist/pci/index.d.ts +6 -0
  24. package/dist/pci/interaction.d.ts +8 -0
  25. package/dist/pci/markup.d.ts +10 -0
  26. package/dist/pci/mount.d.ts +50 -0
  27. package/dist/pci/registry.d.ts +53 -0
  28. package/dist/pci/response.d.ts +11 -0
  29. package/dist/pci/skin.d.ts +12 -0
  30. package/dist/reference-skin/associate.d.ts +8 -0
  31. package/dist/reference-skin/choice.d.ts +8 -0
  32. package/dist/reference-skin/content.d.ts +6 -0
  33. package/dist/reference-skin/drawing.d.ts +9 -0
  34. package/dist/reference-skin/end-attempt.d.ts +7 -0
  35. package/dist/reference-skin/extended-text.d.ts +6 -0
  36. package/dist/reference-skin/gap-match.d.ts +8 -0
  37. package/dist/reference-skin/graphic-associate.d.ts +8 -0
  38. package/dist/reference-skin/graphic-base.d.ts +39 -0
  39. package/dist/reference-skin/graphic-gap-match.d.ts +8 -0
  40. package/dist/reference-skin/graphic-order.d.ts +8 -0
  41. package/dist/reference-skin/hotspot.d.ts +8 -0
  42. package/dist/reference-skin/hottext.d.ts +8 -0
  43. package/dist/reference-skin/index.d.ts +30 -0
  44. package/dist/reference-skin/inline-choice.d.ts +7 -0
  45. package/dist/reference-skin/match.d.ts +8 -0
  46. package/dist/reference-skin/media.d.ts +9 -0
  47. package/dist/reference-skin/order.d.ts +8 -0
  48. package/dist/reference-skin/position-object.d.ts +9 -0
  49. package/dist/reference-skin/select-point.d.ts +8 -0
  50. package/dist/reference-skin/slider.d.ts +8 -0
  51. package/dist/reference-skin/text-entry.d.ts +6 -0
  52. package/dist/reference-skin/upload.d.ts +8 -0
  53. package/dist/response-processing.d.ts +48 -0
  54. package/dist/rp/evaluate.d.ts +35 -0
  55. package/dist/rp/index.d.ts +4 -0
  56. package/dist/rp/interpreter.d.ts +15 -0
  57. package/dist/rp/template-processing.d.ts +49 -0
  58. package/dist/rp/templates.d.ts +8 -0
  59. package/dist/rp/types.d.ts +158 -0
  60. package/dist/rp/values.d.ts +27 -0
  61. package/dist/runtime.d.ts +164 -0
  62. package/dist/store.d.ts +61 -0
  63. package/dist/test/controller.d.ts +11 -0
  64. package/dist/test/index.d.ts +3 -0
  65. package/dist/test/session-store.d.ts +46 -0
  66. package/dist/test/types.d.ts +194 -0
  67. package/dist/types.d.ts +58 -0
  68. package/package.json +8 -6
  69. package/src/capability.ts +24 -0
  70. package/src/content-model.ts +104 -5
  71. package/src/graphic.ts +103 -0
  72. package/src/index.ts +139 -3
  73. package/src/interactions/associate.ts +22 -0
  74. package/src/interactions/choice.ts +2 -2
  75. package/src/interactions/drawing.ts +24 -0
  76. package/src/interactions/end-attempt.ts +19 -0
  77. package/src/interactions/extended-text.ts +21 -0
  78. package/src/interactions/gap-match.ts +22 -0
  79. package/src/interactions/graphic.ts +104 -0
  80. package/src/interactions/hottext.ts +21 -0
  81. package/src/interactions/index.ts +57 -3
  82. package/src/interactions/inline-choice.ts +2 -2
  83. package/src/interactions/match.ts +27 -0
  84. package/src/interactions/media.ts +24 -0
  85. package/src/interactions/order.ts +21 -0
  86. package/src/interactions/slider.ts +24 -0
  87. package/src/interactions/text-entry.ts +2 -2
  88. package/src/interactions/upload.ts +19 -0
  89. package/src/normalized-item.ts +563 -0
  90. package/src/pci/index.ts +22 -0
  91. package/src/pci/interaction.ts +42 -0
  92. package/src/pci/markup.ts +102 -0
  93. package/src/pci/mount.ts +134 -0
  94. package/src/pci/registry.ts +240 -0
  95. package/src/pci/response.ts +138 -0
  96. package/src/pci/skin.ts +86 -0
  97. package/src/reference-skin/associate.ts +98 -0
  98. package/src/reference-skin/choice.ts +44 -0
  99. package/src/reference-skin/content.ts +30 -0
  100. package/src/reference-skin/drawing.ts +160 -0
  101. package/src/reference-skin/end-attempt.ts +27 -0
  102. package/src/reference-skin/extended-text.ts +35 -0
  103. package/src/reference-skin/gap-match.ts +69 -0
  104. package/src/reference-skin/graphic-associate.ts +123 -0
  105. package/src/reference-skin/graphic-base.ts +142 -0
  106. package/src/reference-skin/graphic-gap-match.ts +143 -0
  107. package/src/reference-skin/graphic-order.ts +76 -0
  108. package/src/reference-skin/hotspot.ts +43 -0
  109. package/src/reference-skin/hottext.ts +42 -0
  110. package/src/reference-skin/index.ts +74 -0
  111. package/src/reference-skin/inline-choice.ts +42 -0
  112. package/src/reference-skin/match.ts +80 -0
  113. package/src/reference-skin/media.ts +74 -0
  114. package/src/reference-skin/order.ts +79 -0
  115. package/src/reference-skin/position-object.ts +84 -0
  116. package/src/reference-skin/select-point.ts +87 -0
  117. package/src/reference-skin/slider.ts +41 -0
  118. package/src/reference-skin/text-entry.ts +31 -0
  119. package/src/reference-skin/upload.ts +46 -0
  120. package/src/response-processing.ts +178 -29
  121. package/src/rp/evaluate.ts +827 -0
  122. package/src/rp/index.ts +30 -0
  123. package/src/rp/interpreter.ts +254 -0
  124. package/src/rp/template-processing.ts +290 -0
  125. package/src/rp/templates.ts +190 -0
  126. package/src/rp/types.ts +167 -0
  127. package/src/rp/values.ts +211 -0
  128. package/src/runtime.ts +476 -28
  129. package/src/store.ts +161 -5
  130. package/src/test/controller.ts +809 -0
  131. package/src/test/index.ts +25 -0
  132. package/src/test/session-store.ts +243 -0
  133. package/src/test/types.ts +203 -0
  134. package/src/types.ts +27 -1
package/src/index.ts CHANGED
@@ -12,9 +12,70 @@ export {
12
12
  type V0InteractionKind,
13
13
  } from "./content-model";
14
14
 
15
- export { foldString, mapResponse, matchCorrect, scoreResponse } from "./response-processing";
15
+ export { foldString, mapResponse, matchCorrect, mapResponsePoint, scoreResponse } from "./response-processing";
16
16
 
17
- export { createAttemptStore, type AttemptSnapshot, type AttemptStore } from "./store";
17
+ export { assessmentItemViewFromNormalized, assessmentTestViewFromNormalized } from "./normalized-item";
18
+
19
+ export { formatPoint, parseCoords, parsePoint, pointInShape, type Point, type QtiShape } from "./graphic";
20
+
21
+ export {
22
+ applyCorrectResponseOverrides,
23
+ collectRpIssues,
24
+ collectTemplateIssues,
25
+ executeResponseProcessing,
26
+ executeTemplateProcessing,
27
+ mulberry32,
28
+ resolveTemplate,
29
+ } from "./rp";
30
+
31
+ export type {
32
+ CustomOperatorImplementation,
33
+ MaybeRpValue,
34
+ OutcomeDeclarationView,
35
+ OutcomeValue,
36
+ ResponseNormalization,
37
+ ResponseProcessingContext,
38
+ ResponseProcessingResult,
39
+ ResponseProcessingView,
40
+ RpConditionBranch,
41
+ RpExpressionView,
42
+ RpRecordField,
43
+ RpRuleView,
44
+ RpScalar,
45
+ RpValue,
46
+ TemplateConditionBranch,
47
+ TemplateDeclarationView,
48
+ TemplateProcessingContext,
49
+ TemplateProcessingResult,
50
+ TemplateProcessingView,
51
+ TemplateRuleView,
52
+ } from "./rp";
53
+
54
+ export { createAttemptStore, type AttemptSnapshot, type AttemptStore, type AttemptStoreOptions } from "./store";
55
+
56
+ export {
57
+ createTestController,
58
+ createTestSessionStore,
59
+ type TestSessionSnapshot,
60
+ type TestSessionStore,
61
+ type TestSessionStoreOptions,
62
+ type AssessmentItemRefView,
63
+ type AssessmentSectionView,
64
+ type AssessmentTestView,
65
+ type BranchRuleView,
66
+ type ItemSessionControlView,
67
+ type OutcomeConditionBranch,
68
+ type OutcomeRuleView,
69
+ type TestController,
70
+ type TestFeedbackView,
71
+ type TestItemResult,
72
+ type TestPartView,
73
+ type TestPlan,
74
+ type TestPlanItem,
75
+ type TestPlanPart,
76
+ type TestSessionState,
77
+ type TimeLimitsView,
78
+ } from "./test";
18
79
 
19
80
  export {
20
81
  createQtiRuntime,
@@ -22,12 +83,18 @@ export {
22
83
  type AssessmentItemView,
23
84
  type AttemptController,
24
85
  type BodyNode,
86
+ type CapabilityIssue,
87
+ type CapabilityIssueType,
88
+ type CapabilityReport,
89
+ type ContentRendererProps,
90
+ type FeedbackView,
25
91
  type InteractionDescriptor,
26
92
  type InteractionNode,
27
93
  type InteractionRenderProps,
28
94
  type InteractionSkin,
29
95
  type InteractionStatus,
30
96
  type ItemRendererProps,
97
+ type NodeOverrides,
31
98
  type OptionProps,
32
99
  type OptionStatus,
33
100
  type QtiRuntime,
@@ -36,9 +103,78 @@ export {
36
103
  type XmlContentNode,
37
104
  } from "./runtime";
38
105
 
39
- export { choiceInteraction, inlineChoiceInteraction, qtiCoreInteractions, textEntryInteraction } from "./interactions";
106
+ export {
107
+ createPciModuleRegistry,
108
+ createPciSkin,
109
+ mountPci,
110
+ pciResponseToValue,
111
+ portableCustomInteraction,
112
+ serializePciMarkup,
113
+ valueToPciResponse,
114
+ type PciConfiguration,
115
+ type PciInstance,
116
+ type PciInteractionNode,
117
+ type PciModule,
118
+ type PciModuleRegistry,
119
+ type PciModuleRegistryOptions,
120
+ type PciMountHandle,
121
+ type PciMountOptions,
122
+ type PciSkinOptions,
123
+ } from "./pci";
124
+
125
+ export {
126
+ associateInteraction,
127
+ choiceInteraction,
128
+ drawingInteraction,
129
+ endAttemptInteraction,
130
+ extendedTextInteraction,
131
+ gapMatchInteraction,
132
+ graphicAssociateInteraction,
133
+ graphicGapMatchInteraction,
134
+ graphicOrderInteraction,
135
+ hotspotInteraction,
136
+ hottextInteraction,
137
+ inlineChoiceInteraction,
138
+ matchInteraction,
139
+ mediaInteraction,
140
+ orderInteraction,
141
+ positionObjectStage,
142
+ qtiCoreInteractions,
143
+ selectPointInteraction,
144
+ sliderInteraction,
145
+ textEntryInteraction,
146
+ uploadInteraction,
147
+ } from "./interactions";
148
+
149
+ export {
150
+ AssociateReferenceSkin,
151
+ ChoiceReferenceSkin,
152
+ DrawingReferenceSkin,
153
+ EndAttemptReferenceSkin,
154
+ ExtendedTextReferenceSkin,
155
+ GapMatchReferenceSkin,
156
+ GraphicAssociateReferenceSkin,
157
+ GraphicGapMatchReferenceSkin,
158
+ GraphicOrderReferenceSkin,
159
+ GraphicStage,
160
+ HotspotReferenceSkin,
161
+ HottextReferenceSkin,
162
+ InlineChoiceReferenceSkin,
163
+ MatchReferenceSkin,
164
+ MediaReferenceSkin,
165
+ OrderReferenceSkin,
166
+ PositionObjectReferenceSkin,
167
+ SelectPointReferenceSkin,
168
+ SliderReferenceSkin,
169
+ TextEntryReferenceSkin,
170
+ UploadReferenceSkin,
171
+ referenceSkin,
172
+ textOf,
173
+ } from "./reference-skin";
40
174
 
41
175
  export type {
176
+ AreaMapEntryView,
177
+ AreaMappingView,
42
178
  Cardinality,
43
179
  CorrectResponseView,
44
180
  MapEntryView,
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const associateInteractionNodeSchema = z.object({
7
+ kind: z.literal("associateInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ simpleAssociableChoices: z
10
+ .array(z.looseObject({ identifier: z.string().min(1), matchMax: z.number().int().optional() }))
11
+ .min(2),
12
+ maxAssociations: z.number().int().optional(),
13
+ });
14
+
15
+ export const associateInteraction: InteractionDescriptor<"associateInteraction"> = defineInteraction({
16
+ kind: "associateInteraction",
17
+ schema: associateInteractionNodeSchema,
18
+ scoring: "qti-standard",
19
+ initialResponse(): ResponseValue {
20
+ return null;
21
+ },
22
+ });
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
 
3
- import { defineInteraction } from "../runtime";
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
4
  import type { ResponseValue } from "../types";
5
5
 
6
6
  /** Minimal node shape the runtime/skin rely on; whole-item validation uses the contract. */
@@ -11,7 +11,7 @@ const choiceInteractionNodeSchema = z.object({
11
11
  maxChoices: z.number().int().optional(),
12
12
  });
13
13
 
14
- export const choiceInteraction = defineInteraction({
14
+ export const choiceInteraction: InteractionDescriptor<"choiceInteraction"> = defineInteraction({
15
15
  kind: "choiceInteraction",
16
16
  schema: choiceInteractionNodeSchema,
17
17
  scoring: "qti-standard",
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const drawingInteractionNodeSchema = z.object({
7
+ kind: z.literal("drawingInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ object: z.object({
10
+ data: z.string().min(1),
11
+ width: z.number().optional(),
12
+ height: z.number().optional(),
13
+ type: z.string().optional(),
14
+ }),
15
+ });
16
+
17
+ export const drawingInteraction: InteractionDescriptor<"drawingInteraction"> = defineInteraction({
18
+ kind: "drawingInteraction",
19
+ schema: drawingInteractionNodeSchema,
20
+ scoring: "qti-standard",
21
+ initialResponse(): ResponseValue {
22
+ return null;
23
+ },
24
+ });
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const endAttemptInteractionNodeSchema = z.object({
7
+ kind: z.literal("endAttemptInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ title: z.string().min(1),
10
+ });
11
+
12
+ export const endAttemptInteraction: InteractionDescriptor<"endAttemptInteraction"> = defineInteraction({
13
+ kind: "endAttemptInteraction",
14
+ schema: endAttemptInteractionNodeSchema,
15
+ scoring: "qti-standard",
16
+ initialResponse(): ResponseValue {
17
+ return null;
18
+ },
19
+ });
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const extendedTextInteractionNodeSchema = z.object({
7
+ kind: z.literal("extendedTextInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ expectedLength: z.number().int().optional(),
10
+ expectedLines: z.number().int().optional(),
11
+ placeholderText: z.string().optional(),
12
+ });
13
+
14
+ export const extendedTextInteraction: InteractionDescriptor<"extendedTextInteraction"> = defineInteraction({
15
+ kind: "extendedTextInteraction",
16
+ schema: extendedTextInteractionNodeSchema,
17
+ scoring: "qti-standard",
18
+ initialResponse(): ResponseValue {
19
+ return null;
20
+ },
21
+ });
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const gapMatchInteractionNodeSchema = z.object({
7
+ kind: z.literal("gapMatchInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ gapTexts: z.array(z.looseObject({ identifier: z.string().min(1), matchMax: z.number().int().optional() })).min(1),
10
+ // Flow content with `kind: "gap"` nodes nested anywhere inside it. Responses are
11
+ // directedPairs gapText→gap.
12
+ content: z.array(z.looseObject({ kind: z.string().min(1) })).min(1),
13
+ });
14
+
15
+ export const gapMatchInteraction: InteractionDescriptor<"gapMatchInteraction"> = defineInteraction({
16
+ kind: "gapMatchInteraction",
17
+ schema: gapMatchInteractionNodeSchema,
18
+ scoring: "qti-standard",
19
+ initialResponse(): ResponseValue {
20
+ return null;
21
+ },
22
+ });
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The graphic interaction family: descriptors share the object (stage image) and
3
+ * hotspot (shape/coords) schemas. Coordinates are numbers in image space, normalized
4
+ * upstream from the QTI coords attribute.
5
+ */
6
+
7
+ import { z } from "zod";
8
+
9
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
10
+ import type { ResponseValue } from "../types";
11
+
12
+ const objectSchema = z.object({
13
+ data: z.string().min(1),
14
+ width: z.number().optional(),
15
+ height: z.number().optional(),
16
+ type: z.string().optional(),
17
+ });
18
+
19
+ const hotspotSchema = z.looseObject({
20
+ identifier: z.string().min(1),
21
+ shape: z.string().min(1),
22
+ coords: z.array(z.number()),
23
+ });
24
+
25
+ function nullInitial(): ResponseValue {
26
+ return null;
27
+ }
28
+
29
+ export const hotspotInteraction: InteractionDescriptor<"hotspotInteraction"> = defineInteraction({
30
+ kind: "hotspotInteraction",
31
+ schema: z.object({
32
+ kind: z.literal("hotspotInteraction"),
33
+ responseIdentifier: z.string().min(1),
34
+ object: objectSchema,
35
+ hotspotChoices: z.array(hotspotSchema).min(1),
36
+ maxChoices: z.number().int().optional(),
37
+ }),
38
+ scoring: "qti-standard",
39
+ initialResponse: nullInitial,
40
+ });
41
+
42
+ export const graphicOrderInteraction: InteractionDescriptor<"graphicOrderInteraction"> = defineInteraction({
43
+ kind: "graphicOrderInteraction",
44
+ schema: z.object({
45
+ kind: z.literal("graphicOrderInteraction"),
46
+ responseIdentifier: z.string().min(1),
47
+ object: objectSchema,
48
+ hotspotChoices: z.array(hotspotSchema).min(1),
49
+ }),
50
+ scoring: "qti-standard",
51
+ initialResponse: nullInitial,
52
+ });
53
+
54
+ export const graphicAssociateInteraction: InteractionDescriptor<"graphicAssociateInteraction"> = defineInteraction({
55
+ kind: "graphicAssociateInteraction",
56
+ schema: z.object({
57
+ kind: z.literal("graphicAssociateInteraction"),
58
+ responseIdentifier: z.string().min(1),
59
+ object: objectSchema,
60
+ associableHotspots: z.array(hotspotSchema).min(2),
61
+ maxAssociations: z.number().int().optional(),
62
+ }),
63
+ scoring: "qti-standard",
64
+ initialResponse: nullInitial,
65
+ });
66
+
67
+ export const graphicGapMatchInteraction: InteractionDescriptor<"graphicGapMatchInteraction"> = defineInteraction({
68
+ kind: "graphicGapMatchInteraction",
69
+ schema: z.object({
70
+ kind: z.literal("graphicGapMatchInteraction"),
71
+ responseIdentifier: z.string().min(1),
72
+ object: objectSchema,
73
+ gapImgs: z.array(z.looseObject({ identifier: z.string().min(1), object: objectSchema.optional() })).min(1),
74
+ associableHotspots: z.array(hotspotSchema).min(1),
75
+ }),
76
+ scoring: "qti-standard",
77
+ initialResponse: nullInitial,
78
+ });
79
+
80
+ export const selectPointInteraction: InteractionDescriptor<"selectPointInteraction"> = defineInteraction({
81
+ kind: "selectPointInteraction",
82
+ schema: z.object({
83
+ kind: z.literal("selectPointInteraction"),
84
+ responseIdentifier: z.string().min(1),
85
+ object: objectSchema,
86
+ maxChoices: z.number().int().optional(),
87
+ }),
88
+ scoring: "qti-standard",
89
+ initialResponse: nullInitial,
90
+ });
91
+
92
+ /** The common single-interaction stage; multi-interaction stages fail validation. */
93
+ export const positionObjectStage: InteractionDescriptor<"positionObjectStage"> = defineInteraction({
94
+ kind: "positionObjectStage",
95
+ schema: z.object({
96
+ kind: z.literal("positionObjectStage"),
97
+ responseIdentifier: z.string().min(1),
98
+ stageObject: objectSchema,
99
+ object: objectSchema,
100
+ maxChoices: z.number().int().optional(),
101
+ }),
102
+ scoring: "qti-standard",
103
+ initialResponse: nullInitial,
104
+ });
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const hottextInteractionNodeSchema = z.object({
7
+ kind: z.literal("hottextInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ maxChoices: z.number().int().optional(),
10
+ // Flow content with `kind: "hottext"` nodes nested anywhere inside it.
11
+ content: z.array(z.looseObject({ kind: z.string().min(1) })).min(1),
12
+ });
13
+
14
+ export const hottextInteraction: InteractionDescriptor<"hottextInteraction"> = defineInteraction({
15
+ kind: "hottextInteraction",
16
+ schema: hottextInteractionNodeSchema,
17
+ scoring: "qti-standard",
18
+ initialResponse(): ResponseValue {
19
+ return null;
20
+ },
21
+ });
@@ -1,16 +1,70 @@
1
1
  import type { InteractionDescriptor } from "../runtime";
2
-
2
+ import { associateInteraction } from "./associate";
3
3
  import { choiceInteraction } from "./choice";
4
+ import { drawingInteraction } from "./drawing";
5
+ import { endAttemptInteraction } from "./end-attempt";
6
+ import { extendedTextInteraction } from "./extended-text";
7
+ import { gapMatchInteraction } from "./gap-match";
8
+ import {
9
+ graphicAssociateInteraction,
10
+ graphicGapMatchInteraction,
11
+ graphicOrderInteraction,
12
+ hotspotInteraction,
13
+ positionObjectStage,
14
+ selectPointInteraction,
15
+ } from "./graphic";
16
+ import { hottextInteraction } from "./hottext";
4
17
  import { inlineChoiceInteraction } from "./inline-choice";
18
+ import { matchInteraction } from "./match";
19
+ import { mediaInteraction } from "./media";
20
+ import { orderInteraction } from "./order";
21
+ import { sliderInteraction } from "./slider";
5
22
  import { textEntryInteraction } from "./text-entry";
23
+ import { uploadInteraction } from "./upload";
6
24
 
25
+ export { associateInteraction } from "./associate";
7
26
  export { choiceInteraction } from "./choice";
27
+ export { drawingInteraction } from "./drawing";
28
+ export { endAttemptInteraction } from "./end-attempt";
29
+ export { extendedTextInteraction } from "./extended-text";
30
+ export { gapMatchInteraction } from "./gap-match";
31
+ export {
32
+ graphicAssociateInteraction,
33
+ graphicGapMatchInteraction,
34
+ graphicOrderInteraction,
35
+ hotspotInteraction,
36
+ positionObjectStage,
37
+ selectPointInteraction,
38
+ } from "./graphic";
39
+ export { hottextInteraction } from "./hottext";
8
40
  export { inlineChoiceInteraction } from "./inline-choice";
41
+ export { matchInteraction } from "./match";
42
+ export { mediaInteraction } from "./media";
43
+ export { orderInteraction } from "./order";
44
+ export { sliderInteraction } from "./slider";
9
45
  export { textEntryInteraction } from "./text-entry";
46
+ export { uploadInteraction } from "./upload";
10
47
 
11
- /** The v0 interaction set conform-ed ships; emergent assembles these plus its extensions. */
48
+ /** The interaction set conform-ed ships; consumers assemble these plus their extensions. */
12
49
  export const qtiCoreInteractions: readonly InteractionDescriptor[] = [
50
+ associateInteraction,
13
51
  choiceInteraction,
14
- textEntryInteraction,
52
+ drawingInteraction,
53
+ endAttemptInteraction,
54
+ extendedTextInteraction,
55
+ gapMatchInteraction,
56
+ graphicAssociateInteraction,
57
+ graphicGapMatchInteraction,
58
+ graphicOrderInteraction,
59
+ hotspotInteraction,
60
+ hottextInteraction,
15
61
  inlineChoiceInteraction,
62
+ matchInteraction,
63
+ mediaInteraction,
64
+ orderInteraction,
65
+ positionObjectStage,
66
+ selectPointInteraction,
67
+ sliderInteraction,
68
+ textEntryInteraction,
69
+ uploadInteraction,
16
70
  ];
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
 
3
- import { defineInteraction } from "../runtime";
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
4
  import type { ResponseValue } from "../types";
5
5
 
6
6
  const inlineChoiceInteractionNodeSchema = z.object({
@@ -9,7 +9,7 @@ const inlineChoiceInteractionNodeSchema = z.object({
9
9
  inlineChoices: z.array(z.object({ identifier: z.string().min(1) })).min(1),
10
10
  });
11
11
 
12
- export const inlineChoiceInteraction = defineInteraction({
12
+ export const inlineChoiceInteraction: InteractionDescriptor<"inlineChoiceInteraction"> = defineInteraction({
13
13
  kind: "inlineChoiceInteraction",
14
14
  schema: inlineChoiceInteractionNodeSchema,
15
15
  scoring: "qti-standard",
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const simpleMatchSetSchema = z.object({
7
+ simpleAssociableChoices: z
8
+ .array(z.looseObject({ identifier: z.string().min(1), matchMax: z.number().int().optional() }))
9
+ .min(1),
10
+ });
11
+
12
+ const matchInteractionNodeSchema = z.object({
13
+ kind: z.literal("matchInteraction"),
14
+ responseIdentifier: z.string().min(1),
15
+ // QTI: exactly two match sets; responses are directedPairs source→target.
16
+ simpleMatchSets: z.array(simpleMatchSetSchema).length(2),
17
+ maxAssociations: z.number().int().optional(),
18
+ });
19
+
20
+ export const matchInteraction: InteractionDescriptor<"matchInteraction"> = defineInteraction({
21
+ kind: "matchInteraction",
22
+ schema: matchInteractionNodeSchema,
23
+ scoring: "qti-standard",
24
+ initialResponse(): ResponseValue {
25
+ return null;
26
+ },
27
+ });
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const mediaInteractionNodeSchema = z.object({
7
+ kind: z.literal("mediaInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ autostart: z.boolean().optional(),
10
+ minPlays: z.number().int().optional(),
11
+ maxPlays: z.number().int().optional(),
12
+ loop: z.boolean().optional(),
13
+ // Flow content containing the audio/video element the interaction wraps.
14
+ content: z.array(z.looseObject({ kind: z.string().min(1) })).min(1),
15
+ });
16
+
17
+ export const mediaInteraction: InteractionDescriptor<"mediaInteraction"> = defineInteraction({
18
+ kind: "mediaInteraction",
19
+ schema: mediaInteractionNodeSchema,
20
+ scoring: "qti-standard",
21
+ initialResponse(): ResponseValue {
22
+ return null;
23
+ },
24
+ });
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const orderInteractionNodeSchema = z.object({
7
+ kind: z.literal("orderInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ simpleChoices: z.array(z.looseObject({ identifier: z.string().min(1) })).min(1),
10
+ shuffle: z.boolean().optional(),
11
+ orientation: z.enum(["horizontal", "vertical"]).optional(),
12
+ });
13
+
14
+ export const orderInteraction: InteractionDescriptor<"orderInteraction"> = defineInteraction({
15
+ kind: "orderInteraction",
16
+ schema: orderInteractionNodeSchema,
17
+ scoring: "qti-standard",
18
+ initialResponse(): ResponseValue {
19
+ return null;
20
+ },
21
+ });
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const sliderInteractionNodeSchema = z.object({
7
+ kind: z.literal("sliderInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ lowerBound: z.number(),
10
+ upperBound: z.number(),
11
+ step: z.number().optional(),
12
+ stepLabel: z.boolean().optional(),
13
+ orientation: z.enum(["horizontal", "vertical"]).optional(),
14
+ reverse: z.boolean().optional(),
15
+ });
16
+
17
+ export const sliderInteraction: InteractionDescriptor<"sliderInteraction"> = defineInteraction({
18
+ kind: "sliderInteraction",
19
+ schema: sliderInteractionNodeSchema,
20
+ scoring: "qti-standard",
21
+ initialResponse(): ResponseValue {
22
+ return null;
23
+ },
24
+ });
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
 
3
- import { defineInteraction } from "../runtime";
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
4
  import type { ResponseValue } from "../types";
5
5
 
6
6
  const textEntryInteractionNodeSchema = z.object({
@@ -11,7 +11,7 @@ const textEntryInteractionNodeSchema = z.object({
11
11
  patternMask: z.string().optional(),
12
12
  });
13
13
 
14
- export const textEntryInteraction = defineInteraction({
14
+ export const textEntryInteraction: InteractionDescriptor<"textEntryInteraction"> = defineInteraction({
15
15
  kind: "textEntryInteraction",
16
16
  schema: textEntryInteractionNodeSchema,
17
17
  scoring: "qti-standard",
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+
3
+ import { defineInteraction, type InteractionDescriptor } from "../runtime";
4
+ import type { ResponseValue } from "../types";
5
+
6
+ const uploadInteractionNodeSchema = z.object({
7
+ kind: z.literal("uploadInteraction"),
8
+ responseIdentifier: z.string().min(1),
9
+ type: z.string().optional(),
10
+ });
11
+
12
+ export const uploadInteraction: InteractionDescriptor<"uploadInteraction"> = defineInteraction({
13
+ kind: "uploadInteraction",
14
+ schema: uploadInteractionNodeSchema,
15
+ scoring: "qti-standard",
16
+ initialResponse(): ResponseValue {
17
+ return null;
18
+ },
19
+ });