@khanacademy/perseus-core 7.0.2 → 7.1.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.
@@ -0,0 +1,3 @@
1
+ export declare const parseDropdownUserInput: import("../parser-types").Parser<{
2
+ value: number;
3
+ }>;
@@ -0,0 +1 @@
1
+ export declare const parseExpressionUserInput: import("../parser-types").Parser<string>;
@@ -0,0 +1 @@
1
+ export declare const parseInteractiveGraphUserInput: import("../parser-types").Parser<import("../..").PerseusGraphTypeAngle | import("../..").PerseusGraphTypeCircle | import("../..").PerseusGraphTypeLinear | import("../..").PerseusGraphTypeLinearSystem | import("../..").PerseusGraphTypeNone | import("../..").PerseusGraphTypePoint | import("../..").PerseusGraphTypePolygon | import("../..").PerseusGraphTypeQuadratic | import("../..").PerseusGraphTypeRay | import("../..").PerseusGraphTypeSegment | import("../..").PerseusGraphTypeSinusoid>;
@@ -1,4 +1,5 @@
1
- import type { InteractiveGraphWidget } from "../../data-schema";
1
+ import type { InteractiveGraphWidget, PerseusGraphTypeAngle, PerseusGraphTypeCircle, PerseusGraphTypeLinear, PerseusGraphTypeLinearSystem, PerseusGraphTypeNone, PerseusGraphTypePoint, PerseusGraphTypePolygon, PerseusGraphTypeQuadratic, PerseusGraphTypeRay, PerseusGraphTypeSegment, PerseusGraphTypeSinusoid } from "../../data-schema";
2
2
  import type { Parser } from "../parser-types";
3
+ export declare const parsePerseusGraphType: Parser<PerseusGraphTypeAngle | PerseusGraphTypeCircle | PerseusGraphTypeLinear | PerseusGraphTypeLinearSystem | PerseusGraphTypeNone | PerseusGraphTypePoint | PerseusGraphTypePolygon | PerseusGraphTypeQuadratic | PerseusGraphTypeRay | PerseusGraphTypeSegment | PerseusGraphTypeSinusoid>;
3
4
  export declare const parseLockedFunctionDomain: Parser<[number, number]>;
4
5
  export declare const parseInteractiveGraphWidget: Parser<InteractiveGraphWidget>;
@@ -0,0 +1,3 @@
1
+ export declare const parseNumericInputUserInput: import("../parser-types").Parser<{
2
+ currentValue: string;
3
+ }>;
@@ -0,0 +1,3 @@
1
+ export declare const parseRadioUserInput: import("../parser-types").Parser<{
2
+ choicesSelected: boolean[];
3
+ }>;
@@ -0,0 +1,282 @@
1
+ /**
2
+ * This file contains types used for validation and scoring. The types abide by
3
+ * a naming convention so that they're easy to follow and that we remain
4
+ * consistent across all of the widgets.
5
+ *
6
+ * These types are:
7
+ *
8
+ * * `Perseus<Widget>UserInput`: the data from the widget that represents the
9
+ * data the user entered. This is referred to as the 'guess' in some older
10
+ * parts of Perseus.
11
+ *
12
+ * * `Perseus<Widget>ValidationData`: the data needed to do validation of the
13
+ * user input. Validation refers to the different checks that we can do
14
+ * both on the client-side (before submitting user input for scoring) and
15
+ * on the server-side (when we score it). As such, it cannot contain any of
16
+ * the sensitive scoring data that would reveal the answer.
17
+ *
18
+ * * `Perseus<Widget>Rubric` (nee `Perseus<Widget>Rubric`): the data
19
+ * needed to score the user input. By convention, this type is defined as
20
+ * the set of sensitive answer data and then intersected with
21
+ * `Perseus<Widget>ValidationData`.
22
+ *
23
+ * For example:
24
+ * ```
25
+ * type Perseus<Widget>Rubric = {
26
+ * correct: string; // Used _only_ for scoring
27
+ * size: number; // Used _only_ for scoring
28
+ * } & Perseus<Widget>ValidationData;
29
+ * ```
30
+ */
31
+ import type { GrapherAnswerTypes, PerseusDropdownChoice, PerseusExpressionAnswerForm, PerseusGradedGroupSetWidgetOptions, PerseusGradedGroupWidgetOptions, PerseusGraphType, PerseusGroupWidgetOptions, PerseusMatrixWidgetAnswers, PerseusNumericInputAnswer, PerseusOrdererWidgetOptions, PerseusRadioChoice, PerseusGraphCorrectType, MakeWidgetMap } from "./data-schema";
32
+ import type { Relationship } from "./types";
33
+ export type WidgetValidatorFunction = (userInput: UserInput, validationData: ValidationData, locale: string) => ValidationResult;
34
+ export type WidgetScorerFunction = (userInput: UserInput, rubric: Rubric, locale?: string) => PerseusScore;
35
+ export type PerseusScore = {
36
+ type: "invalid";
37
+ message?: string | null | undefined;
38
+ suppressAlmostThere?: boolean | null | undefined;
39
+ } | {
40
+ type: "points";
41
+ earned: number;
42
+ total: number;
43
+ message?: string | null | undefined;
44
+ };
45
+ export type ValidationResult = Extract<PerseusScore, {
46
+ type: "invalid";
47
+ }> | null;
48
+ export type UserInputStatus = "correct" | "incorrect" | "incomplete";
49
+ export type PerseusCategorizerRubric = {
50
+ values: ReadonlyArray<number>;
51
+ } & PerseusCategorizerValidationData;
52
+ export type PerseusCategorizerUserInput = {
53
+ values: PerseusCategorizerRubric["values"];
54
+ };
55
+ export type PerseusCategorizerValidationData = {
56
+ items: ReadonlyArray<string>;
57
+ };
58
+ export type PerseusCSProgramUserInput = {
59
+ status: UserInputStatus;
60
+ message: string | null;
61
+ };
62
+ export type PerseusDropdownRubric = {
63
+ choices: ReadonlyArray<PerseusDropdownChoice>;
64
+ };
65
+ export type PerseusDropdownUserInput = {
66
+ value: number;
67
+ };
68
+ export type PerseusExpressionRubric = {
69
+ answerForms: ReadonlyArray<PerseusExpressionAnswerForm>;
70
+ functions: ReadonlyArray<string>;
71
+ };
72
+ export type PerseusExpressionUserInput = string;
73
+ export type PerseusGroupRubric = PerseusGroupWidgetOptions;
74
+ export type PerseusGroupValidationData = {
75
+ widgets: ValidationDataMap;
76
+ };
77
+ export type PerseusGroupUserInput = UserInputMap;
78
+ export type PerseusGradedGroupRubric = PerseusGradedGroupWidgetOptions;
79
+ export type PerseusGradedGroupSetRubric = PerseusGradedGroupSetWidgetOptions;
80
+ export type PerseusGrapherRubric = {
81
+ correct: GrapherAnswerTypes;
82
+ };
83
+ export type PerseusGrapherUserInput = PerseusGrapherRubric["correct"];
84
+ export type PerseusIFrameUserInput = {
85
+ status: UserInputStatus;
86
+ message: string | null;
87
+ };
88
+ export type PerseusInputNumberRubric = {
89
+ answerType?: "number" | "decimal" | "integer" | "rational" | "improper" | "mixed" | "percent" | "pi";
90
+ inexact?: boolean;
91
+ maxError?: number | string;
92
+ simplify: "required" | "optional" | "enforced";
93
+ value: string | number;
94
+ };
95
+ export type PerseusInputNumberUserInput = {
96
+ currentValue: string;
97
+ };
98
+ export type PerseusInteractiveGraphRubric = {
99
+ correct: PerseusGraphCorrectType;
100
+ graph: PerseusGraphType;
101
+ };
102
+ export type PerseusInteractiveGraphUserInput = PerseusGraphType;
103
+ export type PerseusLabelImageRubric = {
104
+ markers: ReadonlyArray<{
105
+ answers: ReadonlyArray<string>;
106
+ label: string;
107
+ }>;
108
+ };
109
+ export type PerseusLabelImageUserInput = {
110
+ markers: ReadonlyArray<{
111
+ selected?: ReadonlyArray<string>;
112
+ label: string;
113
+ }>;
114
+ };
115
+ export type PerseusMatcherRubric = {
116
+ left: ReadonlyArray<string>;
117
+ right: ReadonlyArray<string>;
118
+ };
119
+ export type PerseusMatcherUserInput = {
120
+ left: ReadonlyArray<string>;
121
+ right: ReadonlyArray<string>;
122
+ };
123
+ export type PerseusMatrixRubric = {
124
+ answers: PerseusMatrixWidgetAnswers;
125
+ } & PerseusMatrixValidationData;
126
+ export type PerseusMatrixValidationData = Empty;
127
+ export type PerseusMatrixUserInput = {
128
+ answers: PerseusMatrixRubric["answers"];
129
+ };
130
+ export type PerseusNumberLineRubric = {
131
+ correctRel: string | null | undefined;
132
+ correctX: number;
133
+ range: ReadonlyArray<number>;
134
+ initialX: number | null | undefined;
135
+ isInequality: boolean;
136
+ };
137
+ export type PerseusNumberLineUserInput = {
138
+ isTickCrtl?: boolean;
139
+ numLinePosition: number;
140
+ rel: Relationship | "eq";
141
+ numDivisions: number;
142
+ divisionRange: ReadonlyArray<number>;
143
+ };
144
+ export type PerseusNumericInputRubric = {
145
+ answers: ReadonlyArray<PerseusNumericInputAnswer>;
146
+ coefficient: boolean;
147
+ };
148
+ export type PerseusNumericInputUserInput = {
149
+ currentValue: string;
150
+ };
151
+ export type PerseusOrdererRubric = PerseusOrdererWidgetOptions;
152
+ export type PerseusOrdererUserInput = {
153
+ current: ReadonlyArray<string>;
154
+ };
155
+ export type PerseusPlotterRubric = {
156
+ correct: ReadonlyArray<number>;
157
+ } & PerseusPlotterValidationData;
158
+ export type PerseusPlotterValidationData = {
159
+ starting: ReadonlyArray<number>;
160
+ };
161
+ export type PerseusPlotterUserInput = ReadonlyArray<number>;
162
+ export type PerseusRadioRubric = {
163
+ choices: ReadonlyArray<PerseusRadioChoice>;
164
+ };
165
+ export type PerseusRadioUserInput = {
166
+ choicesSelected: ReadonlyArray<boolean>;
167
+ };
168
+ export type PerseusSorterRubric = {
169
+ correct: ReadonlyArray<string>;
170
+ };
171
+ export type PerseusSorterUserInput = {
172
+ options: ReadonlyArray<string>;
173
+ changed: boolean;
174
+ };
175
+ export type PerseusTableRubric = {
176
+ answers: ReadonlyArray<ReadonlyArray<string>>;
177
+ };
178
+ export type PerseusTableUserInput = ReadonlyArray<ReadonlyArray<string>>;
179
+ export interface RubricRegistry {
180
+ categorizer: PerseusCategorizerRubric;
181
+ dropdown: PerseusDropdownRubric;
182
+ expression: PerseusExpressionRubric;
183
+ "graded-group-set": PerseusGradedGroupSetRubric;
184
+ "graded-group": PerseusGradedGroupRubric;
185
+ grapher: PerseusGrapherRubric;
186
+ group: PerseusGroupRubric;
187
+ image: PerseusLabelImageRubric;
188
+ "input-number": PerseusInputNumberRubric;
189
+ "interactive-graph": PerseusInteractiveGraphRubric;
190
+ "label-image": PerseusLabelImageRubric;
191
+ matcher: PerseusMatcherRubric;
192
+ matrix: PerseusMatrixRubric;
193
+ "number-line": PerseusNumberLineRubric;
194
+ "numeric-input": PerseusNumericInputRubric;
195
+ orderer: PerseusOrdererRubric;
196
+ plotter: PerseusPlotterRubric;
197
+ radio: PerseusRadioRubric;
198
+ sorter: PerseusSorterRubric;
199
+ table: PerseusTableRubric;
200
+ }
201
+ /**
202
+ * A map of scoring data (previously referred to as "rubric"), keyed by
203
+ * `widgetId`. This data is used to score a learner's guess for a PerseusItem.
204
+ *
205
+ * NOTE: The value in this map is intentionally a subset of WidgetOptions<T>.
206
+ * By using the same shape (minus any unneeded render data), we are able to
207
+ * share functionality that understands how to traverse maps of `widget id` to
208
+ * `options`.
209
+ */
210
+ export type RubricMap = {
211
+ [Property in keyof RubricRegistry as `${Property} ${number}`]: {
212
+ type: Property;
213
+ static?: boolean;
214
+ options: RubricRegistry[Property];
215
+ };
216
+ };
217
+ export type Rubric = RubricRegistry[keyof RubricRegistry];
218
+ /**
219
+ * This is an interface so that it can be extended if a widget is created
220
+ * outside of this Perseus package. See `PerseusWidgetTypes` for a full
221
+ * explanation.
222
+ */
223
+ interface UserInputRegistry {
224
+ categorizer: PerseusCategorizerUserInput;
225
+ "cs-program": PerseusCSProgramUserInput;
226
+ dropdown: PerseusDropdownUserInput;
227
+ expression: PerseusExpressionUserInput;
228
+ grapher: PerseusGrapherUserInput;
229
+ group: PerseusGroupUserInput;
230
+ iframe: PerseusIFrameUserInput;
231
+ "input-number": PerseusInputNumberUserInput;
232
+ "interactive-graph": PerseusInteractiveGraphUserInput;
233
+ "label-image": PerseusLabelImageUserInput;
234
+ matcher: PerseusMatcherUserInput;
235
+ matrix: PerseusMatrixUserInput;
236
+ "number-line": PerseusNumberLineUserInput;
237
+ "numeric-input": PerseusNumericInputUserInput;
238
+ orderer: PerseusOrdererUserInput;
239
+ plotter: PerseusPlotterUserInput;
240
+ radio: PerseusRadioUserInput;
241
+ sorter: PerseusSorterUserInput;
242
+ table: PerseusTableUserInput;
243
+ }
244
+ /** A union type of all the widget user input types */
245
+ export type UserInput = UserInputRegistry[keyof UserInputRegistry];
246
+ /**
247
+ * A map of widget IDs to user input types (strongly typed based on the format
248
+ * of the widget ID).
249
+ */
250
+ export type UserInputMap = MakeWidgetMap<UserInputRegistry>;
251
+ /**
252
+ * deprecated prefer using UserInputMap
253
+ */
254
+ export type UserInputArray = ReadonlyArray<UserInputArray | UserInput | null | undefined>;
255
+ export interface ValidationDataTypes {
256
+ categorizer: PerseusCategorizerValidationData;
257
+ group: PerseusGroupValidationData;
258
+ plotter: PerseusPlotterValidationData;
259
+ }
260
+ /**
261
+ * A map of validation data, keyed by `widgetId`. This data is used to check if
262
+ * a question is answerable. This data represents the minimal intersection of
263
+ * data that's available in the client (widget options) and server (scoring
264
+ * data) and is represented by a group of types known as "validation data".
265
+ *
266
+ * NOTE: The value in this map is intentionally a subset of WidgetOptions<T>.
267
+ * By using the same shape (minus any unneeded data), we are able to pass a
268
+ * `PerseusWidgetsMap` or ` into any function that accepts a
269
+ * `ValidationDataMap` without any mutation of data.
270
+ */
271
+ export type ValidationDataMap = {
272
+ [Property in keyof ValidationDataTypes as `${Property} ${number}`]: {
273
+ type: Property;
274
+ static?: boolean;
275
+ options: ValidationDataTypes[Property];
276
+ };
277
+ };
278
+ /**
279
+ * A union type of all the different widget validation data types that exist.
280
+ */
281
+ export type ValidationData = ValidationDataTypes[keyof ValidationDataTypes];
282
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -3,7 +3,7 @@ import type { PerseusCategorizerWidgetOptions } from "../../data-schema";
3
3
  * For details on the individual options, see the
4
4
  * PerseusCategorizerWidgetOptions type
5
5
  */
6
- type CategorizerPublicWidgetOptions = {
6
+ export type CategorizerPublicWidgetOptions = {
7
7
  items: PerseusCategorizerWidgetOptions["items"];
8
8
  categories: PerseusCategorizerWidgetOptions["categories"];
9
9
  randomizeItems: PerseusCategorizerWidgetOptions["randomizeItems"];
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Shared Perseus infrastructure",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "7.0.2",
6
+ "version": "7.1.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },