@khanacademy/perseus-core 10.1.0 → 11.0.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 +10 -8
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/parse-perseus-json/index.d.ts +8 -7
- package/dist/utils/random-util.d.ts +12 -2
- package/dist/utils/range.d.ts +1 -0
- package/dist/utils/registry.d.ts +13 -0
- package/dist/widgets/core-widget-registry.d.ts +3 -3
- package/dist/widgets/matcher/matcher-util.d.ts +1 -1
- package/dist/widgets/sorter/sorter-util.d.ts +4 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -89,6 +89,7 @@ export { default as videoLogic } from "./widgets/video";
|
|
|
89
89
|
export type { VideoDefaultWidgetOptions } from "./widgets/video";
|
|
90
90
|
export { getUpgradedWidgetOptions, upgradeWidgetInfoToLatestVersion, } from "./widgets/upgrade";
|
|
91
91
|
export { default as splitPerseusItem } from "./utils/split-perseus-item";
|
|
92
|
+
export { default as Registry } from "./utils/registry";
|
|
92
93
|
export type * from "./widgets/logic-export.types";
|
|
93
94
|
export * as CoreWidgetRegistry from "./widgets/core-widget-registry";
|
|
94
95
|
export { default as getOrdererPublicWidgetOptions } from "./widgets/orderer/orderer-util";
|
|
@@ -102,7 +103,7 @@ export type { GrapherPublicWidgetOptions } from "./widgets/grapher/grapher-util"
|
|
|
102
103
|
export { default as getGroupPublicWidgetOptions } from "./widgets/group/group-util";
|
|
103
104
|
export { default as getInteractiveGraphPublicWidgetOptions, type InteractiveGraphPublicWidgetOptions, } from "./widgets/interactive-graph/interactive-graph-util";
|
|
104
105
|
export { default as getLabelImagePublicWidgetOptions } from "./widgets/label-image/label-image-util";
|
|
105
|
-
export { default as getSorterPublicWidgetOptions } from "./widgets/sorter/sorter-util";
|
|
106
|
+
export { default as getSorterPublicWidgetOptions, shuffleSorter, } from "./widgets/sorter/sorter-util";
|
|
106
107
|
export { default as getDropdownPublicWidgetOptions } from "./widgets/dropdown/dropdown-util";
|
|
107
108
|
export type { DropdownPublicWidgetOptions } from "./widgets/dropdown/dropdown-util";
|
|
108
109
|
export { default as getNumericInputPublicWidgetOptions } from "./widgets/numeric-input/numeric-input-util";
|
|
@@ -117,6 +118,7 @@ export type { MatrixPublicWidgetOptions } from "./widgets/matrix/matrix-util";
|
|
|
117
118
|
export { default as getPlotterPublicWidgetOptions } from "./widgets/plotter/plotter-util";
|
|
118
119
|
export type { PlotterPublicWidgetOptions } from "./widgets/plotter/plotter-util";
|
|
119
120
|
export { default as getMatcherPublicWidgetOptions, shuffleMatcher, } from "./widgets/matcher/matcher-util";
|
|
121
|
+
export type { MatcherPublicWidgetOptions } from "./widgets/matcher/matcher-util";
|
|
120
122
|
export { shuffle, seededRNG, random } from "./utils/random-util";
|
|
121
123
|
export { default as PerseusFeatureFlags } from "./feature-flags";
|
|
122
124
|
export { registerCoreWidgets } from "./widgets/core-widget-registry";
|
package/dist/index.js
CHANGED
|
@@ -203,9 +203,9 @@ const parsePerseusAnswerArea=pipeParsers(defaulted(object({}),()=>({}))).then(co
|
|
|
203
203
|
|
|
204
204
|
const parsePerseusItem$1=object({question:parsePerseusRenderer,hints:defaulted(array(parseHint),()=>[]),answerArea:parsePerseusAnswerArea});
|
|
205
205
|
|
|
206
|
-
function parsePerseusItem(json){if(isRealJSONParse(JSON.parse)){return JSON.parse(json)}throw new Error("Something went wrong.")}function parseAndMigratePerseusItem(
|
|
206
|
+
function parsePerseusItem(json){if(isRealJSONParse(JSON.parse)){return JSON.parse(json)}throw new Error("Something went wrong.")}function parseAndMigratePerseusItem(data){throwErrorIfCheatingDetected();const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusItem$1);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigratePerseusArticle(data){throwErrorIfCheatingDetected();const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusArticle);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function throwErrorIfCheatingDetected(){if(!isRealJSONParse(JSON.parse)){throw new Error("Something went wrong.")}}
|
|
207
207
|
|
|
208
|
-
const libName="@khanacademy/perseus-core";const libVersion="
|
|
208
|
+
const libName="@khanacademy/perseus-core";const libVersion="11.0.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
209
209
|
|
|
210
210
|
const Errors=Object.freeze({Unknown:"Unknown",Internal:"Internal",InvalidInput:"InvalidInput",NotAllowed:"NotAllowed",TransientService:"TransientService",Service:"Service"});
|
|
211
211
|
|
|
@@ -243,6 +243,8 @@ function getGrapherPublicWidgetOptions(options){const{correct:_,...publicOptions
|
|
|
243
243
|
|
|
244
244
|
const defaultWidgetOptions$m={graph:{labels:["x","y"],range:[[-10,10],[-10,10]],step:[1,1],backgroundImage:{url:null},markings:"graph",rulerLabel:"",rulerTicks:10,valid:true,showTooltips:false},correct:{type:"linear",coords:null},availableTypes:["linear"]};const grapherWidgetLogic={name:"grapher",defaultWidgetOptions: defaultWidgetOptions$m,getPublicWidgetOptions:getGrapherPublicWidgetOptions};
|
|
245
245
|
|
|
246
|
+
class Registry{throwIfUnregistered(){if(!this.anythingRegistered){throw new Error(`${this.name} accessed before initialization!`)}}has(key){this.throwIfUnregistered();return Object.prototype.hasOwnProperty.call(this.contents,key)}get(key){this.throwIfUnregistered();return this.contents[key]}keys(){this.throwIfUnregistered();return Object.keys(this.contents)}entries(){this.throwIfUnregistered();return Object.entries(this.contents)}set(key,value){this.anythingRegistered=true;this.contents[key]=value;}constructor(name="Registry"){this.contents={};this.anythingRegistered=false;this.name=name;}}
|
|
247
|
+
|
|
246
248
|
function getIFramePublicWidgetOptions(options){return options}
|
|
247
249
|
|
|
248
250
|
const defaultWidgetOptions$l={url:"",settings:[{name:"",value:""}],width:"400",height:"400",allowFullScreen:false,allowTopNavigation:false};const iframeWidgetLogic={name:"iframe",defaultWidgetOptions: defaultWidgetOptions$l,getPublicWidgetOptions:getIFramePublicWidgetOptions};
|
|
@@ -263,9 +265,9 @@ function getLabelImagePublicWidgetOptions(options){return {...options,markers:op
|
|
|
263
265
|
|
|
264
266
|
const defaultWidgetOptions$g={choices:[],imageAlt:"",imageUrl:"",imageWidth:0,imageHeight:0,markers:[],multipleAnswers:false,hideChoicesFromInstructions:false};const labelImageWidgetLogic={name:"label-image",defaultWidgetOptions: defaultWidgetOptions$g,getPublicWidgetOptions:getLabelImagePublicWidgetOptions};
|
|
265
267
|
|
|
266
|
-
const seededRNG=function(seed){let randomSeed=seed;return function(){let seed=randomSeed;seed=seed+0x7ed55d16+(seed<<12)&0xffffffff;seed=(seed^0xc761c23c^seed>>>19)&0xffffffff;seed=seed+0x165667b1+(seed<<5)&0xffffffff;seed=(seed+0xd3a2646c^seed<<9)&0xffffffff;seed=seed+0xfd7046c5+(seed<<3)&0xffffffff;seed=(seed^0xb55a4f09^seed>>>16)&0xffffffff;return (randomSeed=seed&0xfffffff)/0x10000000}};function shuffle(array,randomSeed,ensurePermuted=false){
|
|
268
|
+
const seededRNG=function(seed){let randomSeed=seed;return function(){let seed=randomSeed;seed=seed+0x7ed55d16+(seed<<12)&0xffffffff;seed=(seed^0xc761c23c^seed>>>19)&0xffffffff;seed=seed+0x165667b1+(seed<<5)&0xffffffff;seed=(seed+0xd3a2646c^seed<<9)&0xffffffff;seed=seed+0xfd7046c5+(seed<<3)&0xffffffff;seed=(seed^0xb55a4f09^seed>>>16)&0xffffffff;return (randomSeed=seed&0xfffffff)/0x10000000}};function shuffle(array,randomSeed,ensurePermuted=false){let random;if(typeof randomSeed==="function"){random=randomSeed;}else {random=seededRNG(randomSeed);}function isValidShuffle(shuffled){return ensurePermuted?!___default.default.isEqual(array,shuffled):true}return constrainedShuffle(array,random,isValidShuffle)}function constrainedShuffle(array,random,isValidShuffle){const maxIterations=100;const shuffled=[...array];if(shuffled.every(value=>___default.default.isEqual(value,shuffled[0]))){return shuffled}for(let i=0;i<maxIterations;i++){shuffleInPlace(shuffled,random);if(isValidShuffle(shuffled)){return shuffled}}throw new Error(`constrainedShuffle: constraint not met after ${maxIterations} attempts`)}function shuffleInPlace(a,random){for(let i=a.length-1;i>0;i--){const k=randomIntInRange(0,i,random);[a[k],a[i]]=[a[i],a[k]];}}function randomIntInRange(min,max,random){return Math.floor(random()*(max-min+1))+min}const random=seededRNG(new Date().getTime()&0xffffffff);
|
|
267
269
|
|
|
268
|
-
const shuffleMatcher=props=>{const rng=seededRNG(props.problemNum);
|
|
270
|
+
const shuffleMatcher=props=>{const rng=seededRNG(props.problemNum);return {left:!props.orderMatters?props.left:shuffleDisplacingFirst$1(props.left,rng),right:shuffleDisplacingFirst$1(props.right,rng)}};function getMatcherPublicWidgetOptions(options){return {...options,left:options.orderMatters?sortAllButFirst$1(options.left):options.left,right:sortAllButFirst$1(options.right)}}function sortAllButFirst$1([first,...rest]){return [first,...rest.sort()]}function shuffleDisplacingFirst$1(array,rng){function isFirstElementDisplaced(shuffled){return shuffled[0]!==array[0]}return constrainedShuffle(array,rng,isFirstElementDisplaced)}
|
|
269
271
|
|
|
270
272
|
const defaultWidgetOptions$f={left:["$x$","$y$","$z$"],right:["$1$","$2$","$3$"],labels:["test","label"],orderMatters:false,padding:true};const matcherWidgetLogic={name:"matcher",defaultWidgetOptions: defaultWidgetOptions$f,getPublicWidgetOptions:getMatcherPublicWidgetOptions};
|
|
271
273
|
|
|
@@ -309,7 +311,7 @@ function getRadioChoicePublicData(choice){const{content,isNoneOfTheAbove,widgets
|
|
|
309
311
|
|
|
310
312
|
const radioWidgetLogic={name:"radio",version:currentVersion$3,widgetOptionsUpgrades:widgetOptionsUpgrades$2,defaultWidgetOptions:defaultWidgetOptions$v,getPublicWidgetOptions:getRadioPublicWidgetOptions};
|
|
311
313
|
|
|
312
|
-
function getSorterPublicWidgetOptions(options){
|
|
314
|
+
function getSorterPublicWidgetOptions(options){return {...options,correct:sortAllButFirst(options.correct)}}function shuffleSorter(props){const{correct,problemNum}=props;const rng=seededRNG(problemNum??0);return shuffleDisplacingFirst(correct,rng)}function sortAllButFirst([first,...rest]){return [first,...rest.sort()]}function shuffleDisplacingFirst(array,rng){function isFirstElementDisplaced(shuffled){return shuffled[0]!==array[0]}return constrainedShuffle(array,rng,isFirstElementDisplaced)}
|
|
313
315
|
|
|
314
316
|
const defaultWidgetOptions$3={correct:["$x$","$y$","$z$"],layout:"horizontal",padding:true};const sorterWidgetLogic={name:"sorter",defaultWidgetOptions: defaultWidgetOptions$3,getPublicWidgetOptions:getSorterPublicWidgetOptions};
|
|
315
317
|
|
|
@@ -319,7 +321,7 @@ const defaultRows=4;const defaultColumns=1;const answers=new Array(defaultRows).
|
|
|
319
321
|
|
|
320
322
|
const defaultWidgetOptions$1={location:""};const videoWidgetLogic={name:"video",defaultWidgetOptions: defaultWidgetOptions$1,supportedAlignments:["block","float-left","float-right","full-width"],defaultAlignment:"block"};
|
|
321
323
|
|
|
322
|
-
const widgets=
|
|
324
|
+
const widgets=new Registry("Core widget registry");function registerWidget(type,logic){widgets.set(type,logic);}function isWidgetRegistered(type){const widgetLogic=widgets.get(type);return !!widgetLogic}function getCurrentVersion(type){const widgetLogic=widgets.get(type);return widgetLogic?.version||{major:0,minor:0}}const getPublicWidgetOptionsFunction=type=>{return widgets.get(type)?.getPublicWidgetOptions??(i=>i)};function getWidgetOptionsUpgrades(type){const widgetLogic=widgets.get(type);return widgetLogic?.widgetOptionsUpgrades||{}}function getDefaultWidgetOptions(type){const widgetLogic=widgets.get(type);return widgetLogic?.defaultWidgetOptions||{}}const getSupportedAlignments=type=>{const widgetLogic=widgets.get(type);if(!widgetLogic?.supportedAlignments?.[0]){return ["default"]}return widgetLogic?.supportedAlignments};const getDefaultAlignment=type=>{const widgetLogic=widgets.get(type);if(!widgetLogic?.defaultAlignment){return "block"}return widgetLogic.defaultAlignment};function registerCoreWidgets(){const widgets=[categorizerWidgetLogic,csProgramWidgetLogic,definitionWidgetLogic,dropdownWidgetLogic,explanationWidgetLogic,expressionWidgetLogic,gradedGroupWidgetLogic,gradedGroupSetWidgetLogic,grapherWidgetLogic,groupWidgetLogic,iframeWidgetLogic,imageWidgetLogic,inputNumberWidgetLogic,interactionWidgetLogic,interactiveGraphWidgetLogic,labelImageWidgetLogic,matcherWidgetLogic,matrixWidgetLogic,measurerWidgetLogic,numberLineWidgetLogic,numericInputWidgetLogic,ordererWidgetLogic,passageWidgetLogic,passageRefWidgetLogic,passageRefTargetWidgetLogic,phetSimulationWidgetLogic,plotterWidgetLogic,pythonProgramWidgetLogic,radioWidgetLogic,sorterWidgetLogic,tableWidgetLogic,videoWidgetLogic];widgets.forEach(w=>{registerWidget(w.name,w);});}
|
|
323
325
|
|
|
324
326
|
var coreWidgetRegistry = /*#__PURE__*/Object.freeze({
|
|
325
327
|
__proto__: null,
|
|
@@ -333,7 +335,7 @@ var coreWidgetRegistry = /*#__PURE__*/Object.freeze({
|
|
|
333
335
|
registerCoreWidgets: registerCoreWidgets
|
|
334
336
|
});
|
|
335
337
|
|
|
336
|
-
const DEFAULT_STATIC=false;const upgradeWidgetInfoToLatestVersion=oldWidgetInfo=>{const type=oldWidgetInfo.type;if(!___default.default.isString(type)){throw new PerseusError("widget type must be a string, but was: "+type,Errors.Internal)}if(!isWidgetRegistered(type)){return oldWidgetInfo}const initialVersion=oldWidgetInfo.version||{major:0,minor:0};const latestVersion=getCurrentVersion(type);if(initialVersion.major>latestVersion.major||initialVersion.major===latestVersion.major&&initialVersion.minor>latestVersion.minor){return oldWidgetInfo}let newEditorOptions=___default.default.clone(oldWidgetInfo.options)||{};const upgradePropsMap=getWidgetOptionsUpgrades(type);if(___default.default.keys(newEditorOptions).length!==0){for(let nextVersion=initialVersion.major+1;nextVersion<=latestVersion.major;nextVersion++){if(upgradePropsMap[String(nextVersion)]){newEditorOptions=upgradePropsMap[String(nextVersion)](newEditorOptions);}else {throw new PerseusError("No upgrade found for widget. Cannot render.",Errors.Internal,{metadata:{type,fromMajorVersion:nextVersion-1,toMajorVersion:nextVersion,oldWidgetInfo:JSON.stringify(oldWidgetInfo)}})}}}const defaultOptions=getDefaultWidgetOptions(type);newEditorOptions={...defaultOptions,...newEditorOptions};let alignment=oldWidgetInfo.alignment;if(alignment==null||alignment==="default"){alignment=getSupportedAlignments(type)?.[0];if(!alignment){throw new PerseusError("No default alignment found when upgrading widget",Errors.Internal,{metadata:{widgetType:type}})}}let widgetStatic=oldWidgetInfo.static;if(widgetStatic==null){widgetStatic=DEFAULT_STATIC;}return {...oldWidgetInfo,version:latestVersion,graded:oldWidgetInfo.graded!=null?oldWidgetInfo.graded:true,alignment:alignment,static:widgetStatic,options:newEditorOptions}};function getUpgradedWidgetOptions(oldWidgetOptions){return mapObject(oldWidgetOptions,(widgetInfo,widgetId)=>{if(!widgetInfo.type||!widgetInfo.alignment){const newValues={};if(!widgetInfo.type){newValues.type=widgetId.split(" ")[0];}if(!widgetInfo.alignment){newValues.alignment="default";}widgetInfo={...widgetInfo,...newValues};}return upgradeWidgetInfoToLatestVersion(widgetInfo)})}
|
|
338
|
+
const DEFAULT_STATIC=false;const upgradeWidgetInfoToLatestVersion=oldWidgetInfo=>{const type=oldWidgetInfo.type;if(!___default.default.isString(type)){throw new PerseusError("widget type must be a string, but was: "+type,Errors.Internal)}if(!isWidgetRegistered(type)){return oldWidgetInfo}const initialVersion=oldWidgetInfo.version||{major:0,minor:0};const latestVersion=getCurrentVersion(type);if(initialVersion.major>latestVersion.major||initialVersion.major===latestVersion.major&&initialVersion.minor>latestVersion.minor){return oldWidgetInfo}let newEditorOptions=___default.default.clone(oldWidgetInfo.options)||{};const upgradePropsMap=getWidgetOptionsUpgrades(type);if(___default.default.keys(newEditorOptions).length!==0){for(let nextVersion=initialVersion.major+1;nextVersion<=latestVersion.major;nextVersion++){if(upgradePropsMap[String(nextVersion)]!=null){newEditorOptions=upgradePropsMap[String(nextVersion)](newEditorOptions);}else {throw new PerseusError("No upgrade found for widget. Cannot render.",Errors.Internal,{metadata:{type,fromMajorVersion:nextVersion-1,toMajorVersion:nextVersion,oldWidgetInfo:JSON.stringify(oldWidgetInfo)}})}}}const defaultOptions=getDefaultWidgetOptions(type);newEditorOptions={...defaultOptions,...newEditorOptions};let alignment=oldWidgetInfo.alignment;if(alignment==null||alignment==="default"){alignment=getSupportedAlignments(type)?.[0];if(!alignment){throw new PerseusError("No default alignment found when upgrading widget",Errors.Internal,{metadata:{widgetType:type}})}}let widgetStatic=oldWidgetInfo.static;if(widgetStatic==null){widgetStatic=DEFAULT_STATIC;}return {...oldWidgetInfo,version:latestVersion,graded:oldWidgetInfo.graded!=null?oldWidgetInfo.graded:true,alignment:alignment,static:widgetStatic,options:newEditorOptions}};function getUpgradedWidgetOptions(oldWidgetOptions){return mapObject(oldWidgetOptions,(widgetInfo,widgetId)=>{if(!widgetInfo.type||!widgetInfo.alignment){const newValues={};if(!widgetInfo.type){newValues.type=widgetId.split(" ")[0];}if(!widgetInfo.alignment){newValues.alignment="default";}widgetInfo={...widgetInfo,...newValues};}return upgradeWidgetInfoToLatestVersion(widgetInfo)})}
|
|
337
339
|
|
|
338
340
|
function splitPerseusRenderer(original){const clone=deepClone(original);const originalWidgets=clone.widgets??{};const upgradedWidgets=getUpgradedWidgetOptions(originalWidgets);const splitWidgets={};for(const[id,widget]of Object.entries(upgradedWidgets)){const publicWidgetOptionsFun=getPublicWidgetOptionsFunction(widget.type);splitWidgets[id]={...widget,options:publicWidgetOptionsFun(widget.options)};}return {...original,widgets:splitWidgets}}
|
|
339
341
|
|
|
@@ -352,6 +354,7 @@ exports.ItemExtras = ItemExtras;
|
|
|
352
354
|
exports.PerseusError = PerseusError;
|
|
353
355
|
exports.PerseusExpressionAnswerFormConsidered = PerseusExpressionAnswerFormConsidered;
|
|
354
356
|
exports.PerseusFeatureFlags = PerseusFeatureFlags;
|
|
357
|
+
exports.Registry = Registry;
|
|
355
358
|
exports.addWidget = addWidget;
|
|
356
359
|
exports.approximateDeepEqual = approximateDeepEqual;
|
|
357
360
|
exports.approximateEqual = approximateEqual;
|
|
@@ -431,6 +434,7 @@ exports.registerCoreWidgets = registerCoreWidgets;
|
|
|
431
434
|
exports.seededRNG = seededRNG;
|
|
432
435
|
exports.shuffle = shuffle;
|
|
433
436
|
exports.shuffleMatcher = shuffleMatcher;
|
|
437
|
+
exports.shuffleSorter = shuffleSorter;
|
|
434
438
|
exports.sorterLogic = sorterWidgetLogic;
|
|
435
439
|
exports.splitPerseusItem = splitPerseusItem;
|
|
436
440
|
exports.tableLogic = tableWidgetLogic;
|