@conform-ed/pci-math-entry 0.0.13 → 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.
- package/dist/checker.d.ts +25 -0
- package/dist/index.d.ts +5 -0
- package/dist/mathlive-input.d.ts +8 -0
- package/dist/module-mathlive.d.ts +11 -0
- package/dist/module.d.ts +28 -0
- package/dist/operator.d.ts +15 -0
- package/package.json +10 -10
- package/src/checker.ts +3 -3
- package/src/module-mathlive.ts +3 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure math checker: LaTeX in, verdict out (compute-engine under the hood).
|
|
3
|
+
* Framework-free and I/O-free by design — the identical function produces the PCI's
|
|
4
|
+
* advisory client-side verdict and the platform's authoritative re-score, so the two
|
|
5
|
+
* can only disagree across package versions, never across code paths.
|
|
6
|
+
*
|
|
7
|
+
* Modes: "equivalent" accepts any mathematically equal form (symbolic equality with
|
|
8
|
+
* compute-engine's numeric probing); "literal" compares the non-canonical parse trees,
|
|
9
|
+
* so the written form matters (\frac{2}{4} ≠ \frac{1}{2}). An absolute `tolerance`
|
|
10
|
+
* widens numeric comparison in equivalent mode (float answers like the sine-rule item).
|
|
11
|
+
*/
|
|
12
|
+
export type MathCheckMode = "equivalent" | "literal";
|
|
13
|
+
export interface MathCheckOptions {
|
|
14
|
+
/** Default "equivalent". */
|
|
15
|
+
readonly mode?: MathCheckMode;
|
|
16
|
+
/** Absolute numeric window; only meaningful in equivalent mode. */
|
|
17
|
+
readonly tolerance?: number;
|
|
18
|
+
}
|
|
19
|
+
export type MathCheckReason = "candidate-parse-error" | "correct-parse-error" | "undecidable";
|
|
20
|
+
export interface MathCheckResult {
|
|
21
|
+
/** true/false when judged; null when the input could not be judged at all. */
|
|
22
|
+
readonly verdict: boolean | null;
|
|
23
|
+
readonly reason?: MathCheckReason;
|
|
24
|
+
}
|
|
25
|
+
export declare function checkMathExpression(candidate: string, correct: string, options?: MathCheckOptions): MathCheckResult;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { checkMathExpression } from "./checker";
|
|
2
|
+
export type { MathCheckMode, MathCheckOptions, MathCheckReason, MathCheckResult } from "./checker";
|
|
3
|
+
export { mathEquivalentClass, mathEquivalentOperator } from "./operator";
|
|
4
|
+
export { createMathEntryModule, mathEntryTypeIdentifier } from "./module";
|
|
5
|
+
export type { MathInputFactory, MathInputHandle, MathInputOptions } from "./module";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MathLive input adapter: a <math-field> custom element inside the module-owned
|
|
3
|
+
* container. Importing this file registers the element and pulls MathLive's full
|
|
4
|
+
* bundle — browser-only and heavy by design; consumers reach it through the ./module
|
|
5
|
+
* subpath via lazy import() (ADR-0007: descriptors eager, implementations lazy).
|
|
6
|
+
*/
|
|
7
|
+
import type { MathInputFactory } from "./module";
|
|
8
|
+
export declare const mathLiveInput: MathInputFactory;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser-ready math-entry PCI: MathLive input + checker verdicts. Heavy by
|
|
3
|
+
* design (MathLive + compute-engine) — load via lazy import() just before an item
|
|
4
|
+
* using the interaction mounts, and register with the consumer's PCI registry:
|
|
5
|
+
*
|
|
6
|
+
* const { mathEntryModule } = await import("@conform-ed/pci-math-entry/module");
|
|
7
|
+
* registry.registerModule("math-entry", mathEntryModule);
|
|
8
|
+
*/
|
|
9
|
+
import type { PciModule } from "@conform-ed/qti-react";
|
|
10
|
+
export declare const mathEntryModule: PciModule;
|
|
11
|
+
export { mathEntryTypeIdentifier } from "./module";
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The math-entry PCI module (IMS PCI v1 against the qti-react host contract). The
|
|
3
|
+
* input widget is injected (`MathInputFactory`) so the module core stays testable and
|
|
4
|
+
* DOM-library-free; the MathLive adapter lives in ./mathlive-input and the bundled
|
|
5
|
+
* browser module in ./module-mathlive.
|
|
6
|
+
*
|
|
7
|
+
* Response of record (design decisions, BACKLOG #1): a PCI JSON record with the
|
|
8
|
+
* learner's LaTeX `expression` plus an advisory `verdict` computed by the same pure
|
|
9
|
+
* checker the platform re-scores with. The verdict exists only when the item carries
|
|
10
|
+
* checker config (`correct`, optional `mode`/`tolerance` properties — authored as
|
|
11
|
+
* data-* attributes); high-stakes deliveries redact those properties and the module
|
|
12
|
+
* degrades to expression-only, leaving scoring entirely server-side. An unjudgeable
|
|
13
|
+
* expression omits the verdict rather than guessing.
|
|
14
|
+
*/
|
|
15
|
+
import type { PciModule } from "@conform-ed/qti-react";
|
|
16
|
+
export declare const mathEntryTypeIdentifier = "urn:conform-ed:pci:math-entry";
|
|
17
|
+
export interface MathInputOptions {
|
|
18
|
+
readonly initialLatex: string;
|
|
19
|
+
readonly disabled?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface MathInputHandle {
|
|
22
|
+
readonly getValue: () => string;
|
|
23
|
+
readonly setValue: (latex: string) => void;
|
|
24
|
+
readonly destroy?: () => void;
|
|
25
|
+
}
|
|
26
|
+
/** Creates the actual input widget inside the module-owned container. */
|
|
27
|
+
export type MathInputFactory = (container: Element, options: MathInputOptions) => MathInputHandle;
|
|
28
|
+
export declare function createMathEntryModule(input: MathInputFactory): PciModule;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The math checker exposed to QTI response processing as a `customOperator`
|
|
3
|
+
* (qti-react extension seam, ADR-0007 vocabulary). Positional arguments, all
|
|
4
|
+
* authorable as plain `qti-base-value`:
|
|
5
|
+
*
|
|
6
|
+
* 1. candidate LaTeX (usually `qti-variable` / `qti-field-value`)
|
|
7
|
+
* 2. correct LaTeX
|
|
8
|
+
* 3. optional mode: "equivalent" (default) | "literal"
|
|
9
|
+
* 4. optional absolute tolerance (float)
|
|
10
|
+
*
|
|
11
|
+
* NULL propagates per QTI convention; an unjudgeable verdict is NULL, never a guess.
|
|
12
|
+
*/
|
|
13
|
+
import type { CustomOperatorImplementation } from "@conform-ed/qti-react";
|
|
14
|
+
export declare const mathEquivalentClass = "org.conform-ed.mathEquivalent";
|
|
15
|
+
export declare const mathEquivalentOperator: CustomOperatorImplementation;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conform-ed/pci-math-entry",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"files": [
|
|
5
5
|
"src",
|
|
6
6
|
"dist"
|
|
@@ -9,35 +9,35 @@
|
|
|
9
9
|
"module": "src/index.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
-
"types": "./
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
13
|
"import": "./dist/index.js"
|
|
14
14
|
},
|
|
15
15
|
"./checker": {
|
|
16
|
-
"types": "./
|
|
16
|
+
"types": "./dist/checker.d.ts",
|
|
17
17
|
"import": "./dist/checker.js"
|
|
18
18
|
},
|
|
19
19
|
"./operator": {
|
|
20
|
-
"types": "./
|
|
20
|
+
"types": "./dist/operator.d.ts",
|
|
21
21
|
"import": "./dist/operator.js"
|
|
22
22
|
},
|
|
23
23
|
"./module": {
|
|
24
|
-
"types": "./
|
|
24
|
+
"types": "./dist/module-mathlive.d.ts",
|
|
25
25
|
"import": "./dist/module-mathlive.js"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
|
-
"build": "bun build ./src/index.ts ./src/checker.ts ./src/operator.ts ./src/module-mathlive.ts --outdir dist --format esm --target browser --splitting --external mathlive --external @cortex-js/compute-engine --external @conform-ed/qti-react",
|
|
30
|
-
"typecheck": "tsgo --noEmit",
|
|
31
|
-
"lint": "oxlint --config ../../.oxlintrc.jsonc .",
|
|
29
|
+
"build": "bun build ./src/index.ts ./src/checker.ts ./src/operator.ts ./src/module-mathlive.ts --outdir dist --format esm --target browser --splitting --external mathlive --external @cortex-js/compute-engine --external @conform-ed/qti-react && tsgo -p tsconfig.build.json",
|
|
32
30
|
"format": "oxfmt --config ../../.oxfmtrc.jsonc --check .",
|
|
33
|
-
"
|
|
31
|
+
"lint": "oxlint --config ../../.oxlintrc.jsonc .",
|
|
32
|
+
"test": "bun test",
|
|
33
|
+
"typecheck": "tsgo --noEmit"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@cortex-js/compute-engine": "^0.59.0",
|
|
37
37
|
"mathlive": "^0.110.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@conform-ed/qti-react": "0.0.
|
|
40
|
+
"@conform-ed/qti-react": "0.0.14",
|
|
41
41
|
"happy-dom": "^20.10.2"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
package/src/checker.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { ComputeEngine } from "@cortex-js/compute-engine";
|
|
14
|
-
import type {
|
|
14
|
+
import type { Expression } from "@cortex-js/compute-engine";
|
|
15
15
|
|
|
16
16
|
export type MathCheckMode = "equivalent" | "literal";
|
|
17
17
|
|
|
@@ -86,7 +86,7 @@ function sameJson(a: unknown, b: unknown): boolean {
|
|
|
86
86
|
return a === b;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function parseLatex(latex: string, form: "canonical" | "structural"):
|
|
89
|
+
function parseLatex(latex: string, form: "canonical" | "structural"): Expression | null {
|
|
90
90
|
if (latex.trim() === "") {
|
|
91
91
|
return null;
|
|
92
92
|
}
|
|
@@ -97,7 +97,7 @@ function parseLatex(latex: string, form: "canonical" | "structural"): BoxedExpre
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/** Finite real value of an expression, or null when it is not plainly numeric. */
|
|
100
|
-
function realValue(expression:
|
|
100
|
+
function realValue(expression: Expression): number | null {
|
|
101
101
|
const numeric = expression.N();
|
|
102
102
|
const real = numeric.re;
|
|
103
103
|
const imaginary = numeric.im;
|
package/src/module-mathlive.ts
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* registry.registerModule("math-entry", mathEntryModule);
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type { PciModule } from "@conform-ed/qti-react";
|
|
11
|
+
|
|
10
12
|
import { mathLiveInput } from "./mathlive-input";
|
|
11
13
|
import { createMathEntryModule } from "./module";
|
|
12
14
|
|
|
13
|
-
export const mathEntryModule = createMathEntryModule(mathLiveInput);
|
|
15
|
+
export const mathEntryModule: PciModule = createMathEntryModule(mathLiveInput);
|
|
14
16
|
export { mathEntryTypeIdentifier } from "./module";
|