@khanacademy/perseus-score 8.0.10 → 8.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.
- package/dist/es/index.js +13 -5
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/score.d.ts +3 -8
- package/dist/util/flatten-scores.d.ts +4 -0
- package/dist/util/get-scoreable-widgets.d.ts +9 -0
- package/dist/util/is-widget-scoreable.d.ts +6 -0
- package/dist/util/score-is-empty.d.ts +6 -0
- package/dist/validate.d.ts +12 -2
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -27,8 +27,9 @@ export { default as validateSorter } from "./widgets/sorter/validate-sorter";
|
|
|
27
27
|
export { default as scoreTable } from "./widgets/table/score-table";
|
|
28
28
|
export { default as validateTable } from "./widgets/table/validate-table";
|
|
29
29
|
export { default as scoreInputNumber, inputNumberAnswerTypes, } from "./widgets/input-number/score-input-number";
|
|
30
|
-
export { scorePerseusItem, scoreWidgetsFunctional
|
|
31
|
-
export {
|
|
30
|
+
export { scorePerseusItem, scoreWidgetsFunctional } from "./score";
|
|
31
|
+
export { default as flattenScores } from "./util/flatten-scores";
|
|
32
|
+
export { validateUserInput, emptyWidgetsFunctional } from "./validate";
|
|
32
33
|
export { default as hasEmptyDINERWidgets } from "./has-empty-diner-widgets";
|
|
33
34
|
export type { PerseusMockWidgetRubric, PerseusMockWidgetUserInput, } from "./widgets/mock-widget/mock-widget-validation.types";
|
|
34
35
|
export * from "./widgets/widget-registry";
|
package/dist/index.js
CHANGED
|
@@ -90,6 +90,12 @@ function scoreTable(userInput,rubric){const validationResult=validateTable(userI
|
|
|
90
90
|
|
|
91
91
|
const inputNumberAnswerTypes={number:{name:"Numbers",forms:"integer, decimal, proper, improper, mixed"},decimal:{name:"Decimals",forms:"decimal"},integer:{name:"Integers",forms:"integer"},rational:{name:"Fractions and mixed numbers",forms:"integer, proper, improper, mixed"},improper:{name:"Improper numbers (no mixed)",forms:"integer, proper, improper"},mixed:{name:"Mixed numbers (no improper)",forms:"integer, proper, mixed"},percent:{name:"Numbers or percents",forms:"integer, decimal, proper, improper, mixed, percent"},pi:{name:"Numbers with pi",forms:"pi"}};function scoreInputNumber(userInput,rubric,locale){if(userInput==null){return {type:"invalid",message:null}}if(rubric.answerType==null){rubric.answerType="number";}const stringValue=`${rubric.value}`;const val=KhanAnswerTypes.number.createValidatorFunctional(stringValue,{simplify:rubric.simplify,inexact:rubric.inexact||undefined,maxError:rubric.maxError,forms:inputNumberAnswerTypes[rubric.answerType].forms,...locale&&{decimal_separator:perseusCore.getDecimalSeparator(locale)}});const currentValue=parseTex(userInput.currentValue);const result=val(currentValue);if(result.empty){return {type:"invalid",message:result.message}}return {type:"points",earned:result.correct?1:0,total:1,message:result.message}}
|
|
92
92
|
|
|
93
|
+
const noScore={type:"points",earned:0,total:0,message:null};function combineScores(scoreA,scoreB){let message;if(scoreA.type==="points"&&scoreB.type==="points"){if(scoreA.message&&scoreB.message&&scoreA.message!==scoreB.message){message=null;}else {message=scoreA.message||scoreB.message;}return {type:"points",earned:scoreA.earned+scoreB.earned,total:scoreA.total+scoreB.total,message:message}}if(scoreA.type==="points"&&scoreB.type==="invalid"){return scoreB}if(scoreA.type==="invalid"&&scoreB.type==="points"){return scoreA}if(scoreA.type==="invalid"&&scoreB.type==="invalid"){if(scoreA.message&&scoreB.message&&scoreA.message!==scoreB.message){message=null;}else {message=scoreA.message||scoreB.message;}return {type:"invalid",message:message}}throw new perseusCore.PerseusError("PerseusScore with unknown type encountered",perseusCore.Errors.InvalidInput,{metadata:{scoreA:JSON.stringify(scoreA),scoreB:JSON.stringify(scoreB)}})}function flattenScores(widgetScoreMap){return Object.values(widgetScoreMap).reduce(combineScores,noScore)}
|
|
94
|
+
|
|
95
|
+
function isWidgetScoreable(widget){if(!widget){return false}const widgetIsGraded=widget.graded==null||widget.graded;const widgetIsStatic=!!widget.static;return widgetIsGraded&&!widgetIsStatic}
|
|
96
|
+
|
|
97
|
+
function getScoreableWidgets(perseusRenderData){const usedWidgetIds=perseusCore.getWidgetIdsFromContent(perseusRenderData.content);const upgradedWidgets=perseusCore.applyDefaultsToWidgets(perseusRenderData.widgets);const scoreableWidgetIds=usedWidgetIds.filter(id=>isWidgetScoreable(upgradedWidgets[id]));return {upgradedWidgets,scoreableWidgetIds}}
|
|
98
|
+
|
|
93
99
|
function scoreNoop(points=0){return {type:"points",earned:points,total:points,message:null}}
|
|
94
100
|
|
|
95
101
|
function scoreFreeResponse(userInput,rubric,locale){return scoreNoop()}
|
|
@@ -98,9 +104,11 @@ function validateFreeResponse(userInput,widgetOptions){const userInputLength=use
|
|
|
98
104
|
|
|
99
105
|
function scoreGroup(userInput,rubric,locale){if(userInput==null){return {type:"invalid",message:null}}const scores=scoreWidgetsFunctional(rubric.widgets,Object.keys(rubric.widgets),userInput,locale);return flattenScores(scores)}
|
|
100
106
|
|
|
101
|
-
function
|
|
107
|
+
function scoreIsEmpty(score){return score.type==="invalid"&&(!score.message||score.message.length===0)}
|
|
108
|
+
|
|
109
|
+
function validateUserInput(perseusRenderData,userInputMap,locale){const{upgradedWidgets,scoreableWidgetIds}=getScoreableWidgets(perseusRenderData);const validationErrors={};scoreableWidgetIds.forEach(id=>{const widget=upgradedWidgets[id];const userInput=userInputMap[id];const validator=getWidgetValidator(widget.type);const validationError=validator?.(userInput,widget.options,locale);if(validationError!=null){validationErrors[id]=validationError;}});return Object.keys(validationErrors).length>0?flattenScores(validationErrors):null}function emptyWidgetsFunctional(widgets,widgetIds,userInputMap,locale){return widgetIds.filter(id=>{const widget=widgets[id];if(!isWidgetScoreable(widget)){return false}const validator=getWidgetValidator(widget.type);const userInput=userInputMap[id];const validationData=widget.options;const score=validator?.(userInput,validationData,locale);if(score){return scoreIsEmpty(score)}return false})}
|
|
102
110
|
|
|
103
|
-
function validateGroup(userInput,validationData,locale){if(userInput==null){return {type:"invalid",message:null}}const
|
|
111
|
+
function validateGroup(userInput,validationData,locale){if(userInput==null){return {type:"invalid",message:null}}const widgetIds=perseusCore.getWidgetIdsFromContent(validationData.content);const emptyWidgets=emptyWidgetsFunctional(validationData.widgets,widgetIds,userInput,locale);if(emptyWidgets.length===0){return null}return {type:"invalid",message:null}}
|
|
104
112
|
|
|
105
113
|
function validateLabelImage(userInput){if(userInput==null){return {type:"invalid",message:null}}let numAnswered=0;for(let i=0;i<userInput.markers.length;i++){const userSelection=userInput.markers[i].selected;if(userSelection&&userSelection.length>0){numAnswered++;}}if(numAnswered!==userInput.markers.length){return {type:"invalid",message:null}}return null}
|
|
106
114
|
|
|
@@ -110,7 +118,7 @@ function scoreMockWidget(userInput,rubric){const validationResult=validateMockWi
|
|
|
110
118
|
|
|
111
119
|
const widgets=new perseusCore.Registry("Score widget registry");function registerWidget(type,scorer,validator){const logic={scorer,validator};widgets.set(type,logic);}const getWidgetValidator=type=>{return widgets.get(type)?.validator??null};const getWidgetScorer=type=>{return widgets.get(type)?.scorer??null};registerWidget("categorizer",scoreCategorizer,validateCategorizer);registerWidget("cs-program",scoreCSProgram);registerWidget("dropdown",scoreDropdown,validateDropdown);registerWidget("expression",scoreExpression,validateExpression);registerWidget("free-response",scoreFreeResponse,validateFreeResponse);registerWidget("grapher",scoreGrapher);registerWidget("group",scoreGroup,validateGroup);registerWidget("iframe",scoreIframe);registerWidget("input-number",scoreInputNumber);registerWidget("interactive-graph",scoreInteractiveGraph);registerWidget("label-image",scoreLabelImage,validateLabelImage);registerWidget("matcher",scoreMatcher);registerWidget("matrix",scoreMatrix,validateMatrix);registerWidget("mock-widget",scoreMockWidget,scoreMockWidget);registerWidget("number-line",scoreNumberLine);registerWidget("numeric-input",scoreNumericInput);registerWidget("orderer",scoreOrderer,validateOrderer);registerWidget("plotter",scorePlotter,validatePlotter);registerWidget("radio",scoreRadio,validateRadio);registerWidget("sorter",scoreSorter,validateSorter);registerWidget("table",scoreTable,validateTable);registerWidget("deprecated-standin",()=>scoreNoop(1));registerWidget("measurer",()=>scoreNoop(1));registerWidget("definition",scoreNoop);registerWidget("explanation",scoreNoop);registerWidget("image",scoreNoop);registerWidget("interaction",scoreNoop);registerWidget("molecule",scoreNoop);registerWidget("passage",scoreNoop);registerWidget("passage-ref",scoreNoop);registerWidget("passage-ref-target",scoreNoop);registerWidget("video",scoreNoop);
|
|
112
120
|
|
|
113
|
-
|
|
121
|
+
function scorePerseusItem(perseusRenderData,userInputMap,locale){const{upgradedWidgets,scoreableWidgetIds}=getScoreableWidgets(perseusRenderData);const scores=scoreWidgetsFunctional(upgradedWidgets,scoreableWidgetIds,userInputMap,locale);return flattenScores(scores)}function scoreWidgetsFunctional(widgets,widgetIds,userInputMap,locale){const upgradedWidgets=perseusCore.applyDefaultsToWidgets(widgets);const gradedWidgetIds=widgetIds.filter(id=>isWidgetScoreable(upgradedWidgets[id]));const widgetScores={};gradedWidgetIds.forEach(id=>{const widget=upgradedWidgets[id];const userInput=userInputMap[id];const validator=getWidgetValidator(widget.type);const scorer=getWidgetScorer(widget.type);const score=validator?.(userInput,widget.options,locale)??scorer?.(userInput,widget.options,locale);if(score!=null){widgetScores[id]=score;}});return widgetScores}
|
|
114
122
|
|
|
115
123
|
function hasEmptyDINERWidgets(itemData,userInputMap){const usedWidgetIds=perseusCore.getWidgetIdsFromContent(itemData.question.content);const widgets=itemData.question.widgets;for(const widgetId of usedWidgetIds){const widget=widgets[widgetId];const input=userInputMap[widgetId];switch(widget.type){case "dropdown":{if(input.value===0){return true}break}case "interactive-graph":{break}case "numeric-input":{if(!input.currentValue&&!widget.options.coefficient){return true}break}case "expression":{if(!input){return true}break}case "radio":{if(input.selectedChoiceIds.length===0){return true}break}}}return false}
|
|
116
124
|
|
|
@@ -152,4 +160,5 @@ exports.validatePlotter = validatePlotter;
|
|
|
152
160
|
exports.validateRadio = validateRadio;
|
|
153
161
|
exports.validateSorter = validateSorter;
|
|
154
162
|
exports.validateTable = validateTable;
|
|
163
|
+
exports.validateUserInput = validateUserInput;
|
|
155
164
|
//# sourceMappingURL=index.js.map
|