@conform-ed/qti-react 0.0.14 → 0.0.16
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/index.d.ts +6 -4
- package/dist/index.js +2492 -408
- package/dist/normalized-item.d.ts +7 -5
- package/dist/pnp.d.ts +115 -0
- package/dist/response-validity.d.ts +28 -0
- package/dist/rp/evaluate.d.ts +6 -1
- package/dist/rp/index.d.ts +2 -2
- package/dist/rp/interpreter.d.ts +7 -1
- package/dist/rp/lookup-table.d.ts +17 -0
- package/dist/rp/template-processing.d.ts +5 -0
- package/dist/rp/types.d.ts +71 -7
- package/dist/runtime.d.ts +95 -0
- package/dist/store.d.ts +47 -0
- package/dist/test/controller.d.ts +22 -0
- package/dist/test/index.d.ts +2 -1
- package/dist/test/results.d.ts +102 -0
- package/dist/test/session-store.d.ts +32 -0
- package/dist/test/types.d.ts +173 -5
- package/dist/types.d.ts +5 -0
- package/package.json +5 -1
- package/src/content-model.ts +44 -4
- package/src/index.ts +43 -1
- package/src/normalized-item.ts +106 -4
- package/src/pci/mount.ts +11 -3
- package/src/pnp.ts +333 -0
- package/src/reference-skin/choice.ts +3 -0
- package/src/response-validity.ts +163 -0
- package/src/rp/evaluate.ts +280 -32
- package/src/rp/index.ts +5 -0
- package/src/rp/interpreter.ts +81 -1
- package/src/rp/lookup-table.ts +46 -0
- package/src/rp/template-processing.ts +41 -0
- package/src/rp/types.ts +75 -7
- package/src/runtime.ts +397 -20
- package/src/store.ts +146 -8
- package/src/test/controller.ts +856 -82
- package/src/test/index.ts +23 -0
- package/src/test/results.ts +378 -0
- package/src/test/session-store.ts +109 -1
- package/src/test/types.ts +172 -5
- package/src/types.ts +1 -0
- package/src/xspattern.d.ts +11 -0
|
@@ -11,18 +11,20 @@
|
|
|
11
11
|
* - `gapChoices` split into the runtime's `gapTexts` (gapMatch) / `gapImgs` (graphic)
|
|
12
12
|
* - media/upload/positionObjectStage flatten to the descriptor fields
|
|
13
13
|
* - processing trees: `children` → `expressions`, `actions` → `rules`,
|
|
14
|
-
* `responseElseIf`/`templateElseIf` pluralize
|
|
14
|
+
* `responseElseIf`/`templateElseIf` pluralize; fragment rules keep their
|
|
15
|
+
* nested `rules` verbatim
|
|
15
16
|
*
|
|
16
17
|
* Used by the corpus delivery meter (ADR-0002) and by any consumer ingesting
|
|
17
18
|
* normalized XML.
|
|
18
19
|
*/
|
|
19
|
-
import type { AssessmentItemView } from "./runtime";
|
|
20
|
+
import type { AssessmentItemView, StimulusContentView } from "./runtime";
|
|
20
21
|
import type { AssessmentTestView } from "./test";
|
|
22
|
+
export declare function assessmentItemViewFromNormalized(document: unknown): AssessmentItemView | null;
|
|
21
23
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
+
* The renderable body of a normalized AssessmentStimulus document, for
|
|
25
|
+
* `QtiRuntimeConfig.resolveStimulus`. Returns null for non-stimulus documents.
|
|
24
26
|
*/
|
|
25
|
-
export declare function
|
|
27
|
+
export declare function stimulusContentFromNormalized(document: unknown): StimulusContentView | null;
|
|
26
28
|
/**
|
|
27
29
|
* Reshape a normalized QTI document into the Test Controller's `AssessmentTestView`,
|
|
28
30
|
* or null when it is not an assessment test.
|
package/dist/pnp.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AfA PNP (QTI 3.0 profile) views and catalog support resolution.
|
|
3
|
+
*
|
|
4
|
+
* The catalog holds "support-specific dormant content that can be made active … based
|
|
5
|
+
* on the candidate's PNP information (or an assessment program's settings)" (§5.28).
|
|
6
|
+
* This module owns the two halves of that sentence: which supports are active for a
|
|
7
|
+
* candidate (activation), and which card content realises an active support
|
|
8
|
+
* (matching). Rendering is the runtime's job; time-limit adjustments are the test
|
|
9
|
+
* controller's.
|
|
10
|
+
*
|
|
11
|
+
* Views are structural mirrors of the contracts AfA PNP and catalog schemas — the
|
|
12
|
+
* package depends on contracts only in tests, like the rest of qti-react.
|
|
13
|
+
*/
|
|
14
|
+
import type { BodyNode } from "./runtime";
|
|
15
|
+
export interface PnpReplaceAccessModeView {
|
|
16
|
+
readonly replaceAccessModes?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
export interface PnpLanguageModeView extends PnpReplaceAccessModeView {
|
|
19
|
+
readonly xmlLang: string;
|
|
20
|
+
}
|
|
21
|
+
/** additional-testing-time: "Only one of the available options can be selected." */
|
|
22
|
+
export interface PnpAdditionalTestingTimeView extends PnpReplaceAccessModeView {
|
|
23
|
+
readonly timeMultiplier?: number;
|
|
24
|
+
readonly fixedMinutes?: number;
|
|
25
|
+
readonly unlimited?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface PnpFeatureSetView {
|
|
28
|
+
readonly features?: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The candidate's preferences, shaped like the normalized access-for-all-pnp
|
|
32
|
+
* document. Feature preference objects carry the fields card-entry discriminators
|
|
33
|
+
* match against (xmlLang, readingType, …); unknown fields are preserved.
|
|
34
|
+
*/
|
|
35
|
+
export interface PnpView {
|
|
36
|
+
readonly [feature: string]: unknown;
|
|
37
|
+
readonly languageOfInterface?: readonly PnpLanguageModeView[];
|
|
38
|
+
readonly keywordTranslation?: PnpLanguageModeView;
|
|
39
|
+
readonly itemTranslation?: PnpLanguageModeView;
|
|
40
|
+
readonly signLanguage?: PnpLanguageModeView;
|
|
41
|
+
readonly additionalTestingTime?: PnpAdditionalTestingTimeView;
|
|
42
|
+
readonly activateAtInitializationSet?: PnpFeatureSetView;
|
|
43
|
+
readonly activateAsOptionSet?: PnpFeatureSetView;
|
|
44
|
+
readonly prohibitSet?: PnpFeatureSetView;
|
|
45
|
+
}
|
|
46
|
+
export interface CatalogFileHrefView {
|
|
47
|
+
readonly href: string;
|
|
48
|
+
readonly mimeType: string;
|
|
49
|
+
}
|
|
50
|
+
export interface CatalogContentView {
|
|
51
|
+
readonly xmlLang?: string;
|
|
52
|
+
readonly dataAttributes?: Readonly<Record<string, string>>;
|
|
53
|
+
readonly content?: readonly BodyNode[];
|
|
54
|
+
}
|
|
55
|
+
export interface CatalogCardEntryView {
|
|
56
|
+
readonly xmlLang?: string;
|
|
57
|
+
readonly default?: boolean;
|
|
58
|
+
readonly dataAttributes?: Readonly<Record<string, string>>;
|
|
59
|
+
readonly htmlContent?: CatalogContentView;
|
|
60
|
+
readonly fileHrefs?: readonly CatalogFileHrefView[];
|
|
61
|
+
}
|
|
62
|
+
export interface CatalogCardView {
|
|
63
|
+
readonly support: string;
|
|
64
|
+
readonly xmlLang?: string;
|
|
65
|
+
readonly htmlContent?: CatalogContentView;
|
|
66
|
+
readonly fileHrefs?: readonly CatalogFileHrefView[];
|
|
67
|
+
readonly cardEntries?: readonly CatalogCardEntryView[];
|
|
68
|
+
}
|
|
69
|
+
export interface CatalogView {
|
|
70
|
+
readonly id: string;
|
|
71
|
+
readonly cards: readonly CatalogCardView[];
|
|
72
|
+
}
|
|
73
|
+
export interface PnpActivation {
|
|
74
|
+
/** Supports in effect from the start of the session. */
|
|
75
|
+
readonly active: ReadonlySet<string>;
|
|
76
|
+
/** Supports the candidate may turn on during the session (activate-as-option-set). */
|
|
77
|
+
readonly optional: ReadonlySet<string>;
|
|
78
|
+
/** Supports that must not be offered (prohibit-set) — wins over everything. */
|
|
79
|
+
readonly prohibited: ReadonlySet<string>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolve the activation policy: prohibit-set wins; activate-at-initialization-set is
|
|
83
|
+
* active; activate-as-option-set is offered but off. A preference stated outside any
|
|
84
|
+
* set (e.g. a bare keyword-translation) is honored from the start — the PNP records
|
|
85
|
+
* the need, and without an activation policy there is nothing to defer to (designed
|
|
86
|
+
* policy, see the ADR).
|
|
87
|
+
*/
|
|
88
|
+
export declare function resolvePnpActivation(pnp: PnpView | undefined): PnpActivation;
|
|
89
|
+
/**
|
|
90
|
+
* The PNP preference object stated for a feature — what card entries discriminate
|
|
91
|
+
* against, and what results reporting reads detail (language, time values) from.
|
|
92
|
+
*/
|
|
93
|
+
export declare function pnpFeaturePreference(pnp: PnpView | undefined, feature: string): Record<string, unknown> | undefined;
|
|
94
|
+
/** A support's resolved alternative content for one catalog. */
|
|
95
|
+
export interface ResolvedCatalogSupport {
|
|
96
|
+
readonly support: string;
|
|
97
|
+
readonly xmlLang?: string;
|
|
98
|
+
readonly content?: readonly BodyNode[];
|
|
99
|
+
readonly fileHrefs?: readonly CatalogFileHrefView[];
|
|
100
|
+
}
|
|
101
|
+
export interface CatalogResolution {
|
|
102
|
+
readonly activation: PnpActivation;
|
|
103
|
+
readonly byCatalogId: ReadonlyMap<string, readonly ResolvedCatalogSupport[]>;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolve every catalog's active alternative content for a candidate. `activeSupports`
|
|
107
|
+
* is the delivery-engine channel — program settings and candidate-toggled options
|
|
108
|
+
* ("or an assessment program's settings", §5.28); prohibited supports stay out even
|
|
109
|
+
* when named there.
|
|
110
|
+
*/
|
|
111
|
+
export declare function resolveCatalogSupports(options: {
|
|
112
|
+
readonly catalogs?: readonly CatalogView[] | undefined;
|
|
113
|
+
readonly pnp?: PnpView | undefined;
|
|
114
|
+
readonly activeSupports?: readonly string[] | undefined;
|
|
115
|
+
}): CatalogResolution;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response validity (ItemSessionControl validate-responses): "An invalid response is
|
|
3
|
+
* defined to be a response which does not satisfy the constraints imposed by the
|
|
4
|
+
* interaction with which it is associated." The constraint vocabulary is what the
|
|
5
|
+
* view model carries on interaction nodes — min/max-choices, min/max-associations,
|
|
6
|
+
* min-strings, pattern-mask, min-plays. Only authored attributes are validated:
|
|
7
|
+
* rendering defaults (e.g. a radio group's single choice) are interaction behavior,
|
|
8
|
+
* not submission constraints.
|
|
9
|
+
*/
|
|
10
|
+
import type { BodyNode } from "./runtime";
|
|
11
|
+
import type { ResponseValue } from "./types";
|
|
12
|
+
export type ResponseConstraintKind = "minChoices" | "maxChoices" | "minAssociations" | "maxAssociations" | "minStrings" | "patternMask" | "minPlays";
|
|
13
|
+
export interface InteractionConstraint {
|
|
14
|
+
readonly responseIdentifier: string;
|
|
15
|
+
readonly kind: ResponseConstraintKind;
|
|
16
|
+
/** The declared bound: a count for the min/max constraints, the XSD regex for patternMask. */
|
|
17
|
+
readonly bound: number | string;
|
|
18
|
+
}
|
|
19
|
+
/** A constraint the current response fails — the reason a submission is invalid. */
|
|
20
|
+
export type ResponseViolation = InteractionConstraint;
|
|
21
|
+
/**
|
|
22
|
+
* Walk the item body and collect the constraint attributes its interactions carry.
|
|
23
|
+
* Zero bounds impose nothing: "If max-choices is 0 then there is no restriction";
|
|
24
|
+
* "If min-choices is 0 then the candidate is not required to select any choices."
|
|
25
|
+
*/
|
|
26
|
+
export declare function collectInteractionConstraints(content: readonly BodyNode[] | undefined): InteractionConstraint[];
|
|
27
|
+
/** The constraints the current responses fail; empty means the responses are valid. */
|
|
28
|
+
export declare function collectResponseViolations(constraints: readonly InteractionConstraint[], responses: Readonly<Record<string, ResponseValue>>): ResponseViolation[];
|
package/dist/rp/evaluate.d.ts
CHANGED
|
@@ -17,8 +17,13 @@ export interface EvalEnv {
|
|
|
17
17
|
readonly random?: (() => number) | undefined;
|
|
18
18
|
/** `testVariables` aggregation; present only in test-level outcome processing. */
|
|
19
19
|
readonly testVariables?: (expression: RpExpressionView) => MaybeRpValue;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* The test-level subset aggregates (`number*`, `outcomeMinimum`/`outcomeMaximum`);
|
|
22
|
+
* present only in test-level outcome processing.
|
|
23
|
+
*/
|
|
21
24
|
readonly testAggregate?: (expression: RpExpressionView) => MaybeRpValue;
|
|
25
|
+
/** Declared default of any item variable, for the `default` expression (§2.11.1.3). */
|
|
26
|
+
readonly variableDefault?: (identifier: string) => MaybeRpValue;
|
|
22
27
|
/** Registered vendor operators by class; unregistered classes stay unsupported. */
|
|
23
28
|
readonly customOperators?: Readonly<Record<string, CustomOperatorImplementation>> | undefined;
|
|
24
29
|
}
|
package/dist/rp/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { collectRpIssues, executeResponseProcessing } from "./interpreter";
|
|
2
|
-
export { applyCorrectResponseOverrides, collectTemplateIssues, executeTemplateProcessing, mulberry32, type TemplateConditionBranch, type TemplateProcessingContext, type TemplateProcessingResult, type TemplateProcessingView, type TemplateRuleView, } from "./template-processing";
|
|
2
|
+
export { applyCorrectResponseOverrides, applyTemplateDefaultOverrides, collectTemplateIssues, executeTemplateProcessing, mulberry32, type TemplateConditionBranch, type TemplateProcessingContext, type TemplateProcessingResult, type TemplateProcessingView, type TemplateRuleView, } from "./template-processing";
|
|
3
3
|
export { resolveTemplate } from "./templates";
|
|
4
|
-
export type { CustomOperatorImplementation, MaybeRpValue, OutcomeDeclarationView, OutcomeValue, ResponseNormalization, ResponseProcessingContext, ResponseProcessingResult, ResponseProcessingView, RpConditionBranch, RpExpressionView, RpRecordField, RpRuleView, RpScalar, RpValue, TemplateDeclarationView, } from "./types";
|
|
4
|
+
export type { CustomOperatorImplementation, InterpolationTableEntryView, InterpolationTableView, MatchTableEntryView, MatchTableView, MaybeRpValue, OutcomeDeclarationView, OutcomeValue, ResponseNormalization, ResponseProcessingContext, ResponseProcessingResult, ResponseProcessingView, RpConditionBranch, RpExpressionView, RpRecordField, RpRuleView, RpScalar, RpValue, TemplateDeclarationView, } from "./types";
|
package/dist/rp/interpreter.d.ts
CHANGED
|
@@ -5,11 +5,17 @@
|
|
|
5
5
|
* and is reported as an `unsupported-rp` Capability issue — never partial scoring.
|
|
6
6
|
*/
|
|
7
7
|
import type { CapabilityIssue } from "../capability";
|
|
8
|
-
import type { ResponseProcessingContext, ResponseProcessingResult, ResponseProcessingView } from "./types";
|
|
8
|
+
import type { OutcomeDeclarationView, ResponseProcessingContext, ResponseProcessingResult, ResponseProcessingView } from "./types";
|
|
9
9
|
export declare function executeResponseProcessing(view: ResponseProcessingView | undefined, context: ResponseProcessingContext): ResponseProcessingResult;
|
|
10
10
|
export interface RpIssueOptions {
|
|
11
11
|
/** `customOperator` classes the consumer has registered implementations for. */
|
|
12
12
|
readonly customOperatorClasses?: ReadonlySet<string>;
|
|
13
|
+
/**
|
|
14
|
+
* The item's outcome declarations; when supplied, a `lookupOutcomeValue` rule whose
|
|
15
|
+
* declaration carries no lookupTable is reported statically (gate parity with the
|
|
16
|
+
* runtime refusal).
|
|
17
|
+
*/
|
|
18
|
+
readonly outcomeDeclarations?: readonly OutcomeDeclarationView[];
|
|
13
19
|
}
|
|
14
20
|
/** Static coverage walk for `canDeliver`: reports constructs the interpreter lacks without executing. */
|
|
15
21
|
export declare function collectRpIssues(view: ResponseProcessingView | undefined, options?: RpIssueOptions): readonly CapabilityIssue[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lookupTable evaluation for the `lookupOutcomeValue` rule (§5.87): "sets the value
|
|
3
|
+
* of an outcome variable to the value obtained by looking up the value of the
|
|
4
|
+
* associated expression in the lookupTable associated with the outcome's
|
|
5
|
+
* declaration." Shared by the item interpreter and the test controller — the test's
|
|
6
|
+
* own outcome declarations use the same view type.
|
|
7
|
+
*/
|
|
8
|
+
import type { OutcomeDeclarationView } from "./types";
|
|
9
|
+
import { type MaybeRpValue } from "./values";
|
|
10
|
+
export declare function hasLookupTable(declaration: OutcomeDeclarationView | undefined): declaration is OutcomeDeclarationView;
|
|
11
|
+
/**
|
|
12
|
+
* Look `source` up in the declaration's lookupTable. A NULL or non-numeric source is
|
|
13
|
+
* read as "no matching table entry is found" (§5.90.1) — an interpretive call the
|
|
14
|
+
* spec leaves open — so it takes the defaultValue path, never a refusal. "If
|
|
15
|
+
* omitted, the NULL value is used." (§5.90.1/§5.78.1)
|
|
16
|
+
*/
|
|
17
|
+
export declare function lookupTableValue(declaration: OutcomeDeclarationView, source: MaybeRpValue): MaybeRpValue;
|
|
@@ -41,6 +41,11 @@ export interface TemplateProcessingResult {
|
|
|
41
41
|
/** mulberry32: a tiny, fast, seeded PRNG — deterministic across platforms. */
|
|
42
42
|
export declare function mulberry32(seed: number): () => number;
|
|
43
43
|
export declare function executeTemplateProcessing(view: TemplateProcessingView | undefined, context: TemplateProcessingContext): TemplateProcessingResult;
|
|
44
|
+
/**
|
|
45
|
+
* The effective template declarations for a clone: test-level `templateDefault`
|
|
46
|
+
* values (§5.152) replace the declared defaults. A NULL value clears the default.
|
|
47
|
+
*/
|
|
48
|
+
export declare function applyTemplateDefaultOverrides(declarations: readonly TemplateDeclarationView[], overrides: Readonly<Record<string, OutcomeValue>>): readonly TemplateDeclarationView[];
|
|
44
49
|
/** The effective response declarations for a clone: setCorrectResponse overrides applied. */
|
|
45
50
|
export declare function applyCorrectResponseOverrides(declarations: readonly ResponseDeclarationView[], overrides: Readonly<Record<string, CorrectResponseView>>): readonly ResponseDeclarationView[];
|
|
46
51
|
/** Static coverage walk for `canDeliver` over a templateProcessing tree. */
|
package/dist/rp/types.d.ts
CHANGED
|
@@ -25,6 +25,38 @@ export interface RpValue {
|
|
|
25
25
|
readonly fields?: readonly RpRecordField[];
|
|
26
26
|
}
|
|
27
27
|
export type MaybeRpValue = RpValue | null;
|
|
28
|
+
/** One matchTable row: exact integer source → target (§7.23). */
|
|
29
|
+
export interface MatchTableEntryView {
|
|
30
|
+
readonly sourceValue: number;
|
|
31
|
+
readonly targetValue: RpScalar;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* "A matchTable transforms a source integer by finding the first
|
|
35
|
+
* qti-match-table-entry with an exact match to the source." (§5.90)
|
|
36
|
+
*/
|
|
37
|
+
export interface MatchTableView {
|
|
38
|
+
/** "The default outcome value to be used when no matching table entry is found.
|
|
39
|
+
* If omitted, the NULL value is used." (§5.90.1) */
|
|
40
|
+
readonly defaultValue?: RpScalar;
|
|
41
|
+
readonly matchTableEntries: readonly MatchTableEntryView[];
|
|
42
|
+
}
|
|
43
|
+
/** One interpolationTable row; sourceValue is "the lower bound … to match this entry" (§7.18.1). */
|
|
44
|
+
export interface InterpolationTableEntryView {
|
|
45
|
+
readonly sourceValue: number;
|
|
46
|
+
readonly targetValue: RpScalar;
|
|
47
|
+
/** "If 'true', the default, then an exact match of the value is considered a match
|
|
48
|
+
* of this entry." (§7.18.2) */
|
|
49
|
+
readonly includeBoundary?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* "An interpolationTable transforms a source float (or integer) by finding the first
|
|
53
|
+
* interpolationTableEntry with a sourceValue that is less than or equal to (subject
|
|
54
|
+
* to includeBoundary) the source value." (§5.78)
|
|
55
|
+
*/
|
|
56
|
+
export interface InterpolationTableView {
|
|
57
|
+
readonly defaultValue?: RpScalar;
|
|
58
|
+
readonly interpolationTableEntries: readonly InterpolationTableEntryView[];
|
|
59
|
+
}
|
|
28
60
|
export interface OutcomeDeclarationView {
|
|
29
61
|
readonly identifier: string;
|
|
30
62
|
readonly cardinality: Cardinality;
|
|
@@ -34,6 +66,12 @@ export interface OutcomeDeclarationView {
|
|
|
34
66
|
readonly value: RpScalar;
|
|
35
67
|
}>;
|
|
36
68
|
};
|
|
69
|
+
/** The declaration's lookupTable (at most one of the two), read by `lookupOutcomeValue` (§5.87). */
|
|
70
|
+
readonly matchTable?: MatchTableView;
|
|
71
|
+
readonly interpolationTable?: InterpolationTableView;
|
|
72
|
+
/** Declared score bounds, aggregated by `outcomeMaximum`/`outcomeMinimum` (§2.11.2.6-7). */
|
|
73
|
+
readonly normalMaximum?: number;
|
|
74
|
+
readonly normalMinimum?: number;
|
|
37
75
|
}
|
|
38
76
|
/**
|
|
39
77
|
* One expression node. Deliberately loose (`kind: string`): kinds the interpreter
|
|
@@ -45,11 +83,14 @@ export interface RpExpressionView {
|
|
|
45
83
|
readonly baseType?: string;
|
|
46
84
|
readonly value?: RpScalar;
|
|
47
85
|
readonly expressions?: readonly RpExpressionView[];
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Bounds/step for the random operators and `anyN`; string values are variable
|
|
88
|
+
* references resolved at runtime (§2.11.3.6), bare or brace-enclosed (§7.13).
|
|
89
|
+
*/
|
|
90
|
+
readonly min?: number | string;
|
|
91
|
+
readonly max?: number | string;
|
|
92
|
+
readonly step?: number | string;
|
|
93
|
+
/** `equal` tolerance window; string entries are variable references. */
|
|
53
94
|
readonly toleranceMode?: "exact" | "absolute" | "relative";
|
|
54
95
|
readonly tolerance?: ReadonlyArray<number | string>;
|
|
55
96
|
readonly includeLowerBound?: boolean;
|
|
@@ -63,14 +104,18 @@ export interface RpExpressionView {
|
|
|
63
104
|
readonly figures?: number | string;
|
|
64
105
|
/** Pass count for `repeat`. */
|
|
65
106
|
readonly numberRepeats?: number | string;
|
|
107
|
+
/** XSD-dialect pattern for `patternMatch`; "{ref}" resolves from a variable (§7.13). */
|
|
108
|
+
readonly pattern?: string;
|
|
66
109
|
/** String comparison controls for `stringMatch` and `substring`. */
|
|
67
110
|
readonly caseSensitive?: boolean;
|
|
68
111
|
readonly substring?: boolean;
|
|
69
112
|
/** Area for `inside` (QTI shape + coords string). */
|
|
70
113
|
readonly shape?: string;
|
|
71
114
|
readonly coords?: string;
|
|
72
|
-
/** Test-level subset selection (`testVariables`
|
|
115
|
+
/** Test-level subset selection (`testVariables`, `outcomeMinimum`/`outcomeMaximum`, `number*`). */
|
|
73
116
|
readonly variableIdentifier?: string;
|
|
117
|
+
/** Outcome variable whose declared bounds `outcomeMinimum`/`outcomeMaximum` look up (§7.28.4). */
|
|
118
|
+
readonly outcomeIdentifier?: string;
|
|
74
119
|
readonly weightIdentifier?: string;
|
|
75
120
|
readonly sectionIdentifier?: string;
|
|
76
121
|
readonly includeCategory?: string | readonly string[];
|
|
@@ -93,11 +138,16 @@ export interface RpConditionBranch {
|
|
|
93
138
|
readonly expression: RpExpressionView;
|
|
94
139
|
readonly rules: readonly RpRuleView[];
|
|
95
140
|
}
|
|
96
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* One response rule: responseCondition, setOutcomeValue, lookupOutcomeValue,
|
|
143
|
+
* responseProcessingFragment, or exitResponse.
|
|
144
|
+
*/
|
|
97
145
|
export interface RpRuleView {
|
|
98
146
|
readonly kind: string;
|
|
99
147
|
readonly identifier?: string;
|
|
100
148
|
readonly expression?: RpExpressionView;
|
|
149
|
+
/** Nested rules of a `responseProcessingFragment` (§5.118). */
|
|
150
|
+
readonly rules?: readonly RpRuleView[];
|
|
101
151
|
readonly responseIf?: RpConditionBranch;
|
|
102
152
|
readonly responseElseIfs?: readonly RpConditionBranch[];
|
|
103
153
|
readonly responseElse?: {
|
|
@@ -148,6 +198,20 @@ export interface ResponseProcessingContext {
|
|
|
148
198
|
* submission sequence then replays the exact same outcomes (ADR-0004 determinism).
|
|
149
199
|
*/
|
|
150
200
|
readonly random?: (() => number) | undefined;
|
|
201
|
+
/**
|
|
202
|
+
* Built-in session variables (reserved identifiers; items must not declare them).
|
|
203
|
+
* `duration` is the item session's elapsed seconds; `numAttempts` "increases by 1
|
|
204
|
+
* at the start of each attempt", so it includes the attempt being scored.
|
|
205
|
+
*/
|
|
206
|
+
readonly duration?: number | undefined;
|
|
207
|
+
readonly numAttempts?: number | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* The session's current `completionStatus` — the third built-in, "declared
|
|
210
|
+
* implicitly"; it enters the outcome map (defaulting to "not_attempted") so
|
|
211
|
+
* `setOutcomeValue` can change it (§2.2.2.3). An explicit declaration (legacy
|
|
212
|
+
* content) wins over this value.
|
|
213
|
+
*/
|
|
214
|
+
readonly completionStatus?: string | undefined;
|
|
151
215
|
/** Registered vendor `customOperator` implementations by class (opt-in). */
|
|
152
216
|
readonly customOperators?: Readonly<Record<string, CustomOperatorImplementation>> | undefined;
|
|
153
217
|
}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -11,12 +11,15 @@ import { type ComponentType, type ReactNode } from "react";
|
|
|
11
11
|
import type { ZodType } from "zod";
|
|
12
12
|
import type { CapabilityReport } from "./capability";
|
|
13
13
|
import { type ContentModel } from "./content-model";
|
|
14
|
+
import { type CatalogView, type PnpView, type ResolvedCatalogSupport } from "./pnp";
|
|
14
15
|
import type { CustomOperatorImplementation, OutcomeDeclarationView, OutcomeValue, ResponseNormalization, ResponseProcessingView, TemplateDeclarationView, TemplateProcessingView } from "./rp";
|
|
15
16
|
import { type AttemptSnapshot, type AttemptStore } from "./store";
|
|
16
17
|
import type { ResponseDeclarationView, ResponseValue, ScoreResult } from "./types";
|
|
17
18
|
export type { CapabilityIssue, CapabilityIssueType, CapabilityReport } from "./capability";
|
|
18
19
|
export interface XmlContentNode {
|
|
19
20
|
kind: "xml";
|
|
21
|
+
/** XML namespace URI; foreign vocabularies (SSML) are recognized by it. */
|
|
22
|
+
namespace?: string;
|
|
20
23
|
name: string;
|
|
21
24
|
value?: string;
|
|
22
25
|
attributes?: Record<string, unknown>;
|
|
@@ -39,6 +42,31 @@ export interface FeedbackView {
|
|
|
39
42
|
showHide?: "show" | "hide";
|
|
40
43
|
content?: readonly BodyNode[];
|
|
41
44
|
}
|
|
45
|
+
/** An item's reference to a shared AssessmentStimulus document (§7.6). */
|
|
46
|
+
export interface AssessmentStimulusRefView {
|
|
47
|
+
readonly identifier: string;
|
|
48
|
+
readonly href: string;
|
|
49
|
+
readonly title?: string;
|
|
50
|
+
}
|
|
51
|
+
/** Companion materials, structurally as normalized (calculators, rules, protractors, materials). */
|
|
52
|
+
export interface CompanionMaterialsView {
|
|
53
|
+
readonly calculators?: readonly Record<string, unknown>[];
|
|
54
|
+
readonly rules?: readonly Record<string, unknown>[];
|
|
55
|
+
readonly protractors?: readonly Record<string, unknown>[];
|
|
56
|
+
readonly digitalMaterials?: readonly {
|
|
57
|
+
readonly fileHref: string;
|
|
58
|
+
readonly label?: string;
|
|
59
|
+
readonly mimeType?: string;
|
|
60
|
+
readonly resourceIcon?: string;
|
|
61
|
+
}[];
|
|
62
|
+
readonly physicalMaterials?: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
/** The resolved stimulus body, rendered through the same content walk as the item body. */
|
|
65
|
+
export interface StimulusContentView {
|
|
66
|
+
readonly content: readonly BodyNode[];
|
|
67
|
+
/** The stimulus document's catalogs (dormant alternative content, §5.29). */
|
|
68
|
+
readonly catalogs?: readonly CatalogView[];
|
|
69
|
+
}
|
|
42
70
|
export interface AssessmentItemView {
|
|
43
71
|
responseDeclarations: readonly ResponseDeclarationView[];
|
|
44
72
|
outcomeDeclarations?: readonly OutcomeDeclarationView[];
|
|
@@ -48,6 +76,15 @@ export interface AssessmentItemView {
|
|
|
48
76
|
/** QTI adaptive item: multiple attempts until completionStatus reaches "completed". */
|
|
49
77
|
adaptive?: boolean;
|
|
50
78
|
modalFeedbacks?: readonly FeedbackView[];
|
|
79
|
+
assessmentStimulusRefs?: readonly AssessmentStimulusRefView[];
|
|
80
|
+
/** Every catalog in the item (item-level and nested), pooled for idref resolution. */
|
|
81
|
+
catalogs?: readonly CatalogView[];
|
|
82
|
+
/**
|
|
83
|
+
* Companion materials (§2.13.1): "content props that provide key information to be
|
|
84
|
+
* used when answering an Item, e.g. a calculator, protractor, lookup chart". The
|
|
85
|
+
* runtime exposes them; the delivery platform owns the tools themselves.
|
|
86
|
+
*/
|
|
87
|
+
companionMaterials?: CompanionMaterialsView;
|
|
51
88
|
itemBody: {
|
|
52
89
|
content?: BodyNode[];
|
|
53
90
|
};
|
|
@@ -100,6 +137,12 @@ export interface InteractionRenderProps {
|
|
|
100
137
|
* interactions like PCI own their response state). Returns the unregister function.
|
|
101
138
|
*/
|
|
102
139
|
registerResponseCollector: (collector: () => ResponseValue | undefined) => () => void;
|
|
140
|
+
/**
|
|
141
|
+
* Render the active catalog supports for a skin-owned node's data-catalog-idref
|
|
142
|
+
* (e.g. a choice label) — the same resolution and presentation the core walk
|
|
143
|
+
* applies to generic flow nodes. Null when nothing is active.
|
|
144
|
+
*/
|
|
145
|
+
renderCatalogSupports: (catalogIdref: string | undefined) => ReactNode;
|
|
103
146
|
}
|
|
104
147
|
/** Per-kind render overrides a skin passes to `renderContent` for nodes it owns. */
|
|
105
148
|
export type NodeOverrides = Readonly<Record<string, (node: BodyNode, key: number) => ReactNode>>;
|
|
@@ -123,6 +166,19 @@ export interface QtiRuntimeConfig {
|
|
|
123
166
|
* registered classes pass the capability gate; everything else stays unsupported.
|
|
124
167
|
*/
|
|
125
168
|
readonly customOperators?: Readonly<Record<string, CustomOperatorImplementation>>;
|
|
169
|
+
/**
|
|
170
|
+
* Resolve an item's shared-stimulus reference to its normalized body content
|
|
171
|
+
* (synchronous by design, like the session store's resolveItem: load the package's
|
|
172
|
+
* stimuli before mounting; `stimulusContentFromNormalized` reshapes a normalized
|
|
173
|
+
* document). Unresolved refs are capability issues, never silent drops (ADR-0003).
|
|
174
|
+
*/
|
|
175
|
+
readonly resolveStimulus?: (ref: AssessmentStimulusRefView) => StimulusContentView | null;
|
|
176
|
+
/**
|
|
177
|
+
* Replaces the default rendering of an active catalog support (the note-role span
|
|
178
|
+
* appended beside the referenced content). The delivery engine owns presentation —
|
|
179
|
+
* tooltips, players, glossary panels — the runtime owns resolution.
|
|
180
|
+
*/
|
|
181
|
+
readonly renderCatalogSupport?: (support: ResolvedCatalogSupport, catalogIdref: string) => ReactNode;
|
|
126
182
|
}
|
|
127
183
|
export interface ItemRendererProps {
|
|
128
184
|
item: AssessmentItemView;
|
|
@@ -134,12 +190,42 @@ export interface ItemRendererProps {
|
|
|
134
190
|
store?: AttemptStore | undefined;
|
|
135
191
|
/** Clone seed for template processing; store it to replay the same clone. */
|
|
136
192
|
seed?: number | undefined;
|
|
193
|
+
/**
|
|
194
|
+
* The item-session state to render. `review` is read-only: "the candidate can
|
|
195
|
+
* review the qti-item-body along with the responses they gave, but cannot update
|
|
196
|
+
* or resubmit them". `solution` additionally swaps in the clone's resolved correct
|
|
197
|
+
* responses ("a way of entering the solution state"); the show-solution gate is
|
|
198
|
+
* the consumer's (effective ItemSessionControl). Default: "interact".
|
|
199
|
+
*/
|
|
200
|
+
mode?: ItemRenderMode | undefined;
|
|
201
|
+
/**
|
|
202
|
+
* Effective ItemSessionControl show-feedback; consulted only outside `interact`.
|
|
203
|
+
* `false` withholds modal and integrated feedback — visibility is then
|
|
204
|
+
* "determined by the default values of the outcome variables" — and is ignored
|
|
205
|
+
* for adaptive items, per spec.
|
|
206
|
+
*/
|
|
207
|
+
showFeedback?: boolean | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* The candidate's AfA PNP. Activates the item's dormant catalog supports (§5.29):
|
|
210
|
+
* "A candidate's profile (or assessment program settings) will indicate whether the
|
|
211
|
+
* candidate should be presented any of the possible supports."
|
|
212
|
+
*/
|
|
213
|
+
pnp?: PnpView | undefined;
|
|
214
|
+
/**
|
|
215
|
+
* Supports in effect beyond the PNP's initial activation — program settings and
|
|
216
|
+
* candidate-toggled options (activate-as-option-set). Prohibited supports stay out.
|
|
217
|
+
*/
|
|
218
|
+
activeSupports?: readonly string[] | undefined;
|
|
137
219
|
children?: ReactNode;
|
|
138
220
|
}
|
|
139
221
|
export interface ContentRendererProps {
|
|
140
222
|
nodes?: readonly BodyNode[] | undefined;
|
|
141
223
|
/** Values for printedVariable (and showHide-gated feedback) inside the content. */
|
|
142
224
|
outcomes?: Readonly<Record<string, OutcomeValue>> | undefined;
|
|
225
|
+
/** Catalogs referenced by this content (e.g. a test rubric block's catalogInfo). */
|
|
226
|
+
catalogs?: readonly CatalogView[] | undefined;
|
|
227
|
+
pnp?: PnpView | undefined;
|
|
228
|
+
activeSupports?: readonly string[] | undefined;
|
|
143
229
|
}
|
|
144
230
|
export interface QtiRuntime {
|
|
145
231
|
ItemRenderer: ComponentType<ItemRendererProps>;
|
|
@@ -149,6 +235,13 @@ export interface QtiRuntime {
|
|
|
149
235
|
*/
|
|
150
236
|
ContentRenderer: ComponentType<ContentRendererProps>;
|
|
151
237
|
useAttempt: () => AttemptController;
|
|
238
|
+
/**
|
|
239
|
+
* The active supports resolved for a catalog idref — for skins whose own nodes
|
|
240
|
+
* carry data-catalog-idref (e.g. a choice label) and consumers building support
|
|
241
|
+
* UI (glossary panels, toggles). The core walk already decorates generic flow
|
|
242
|
+
* and block nodes; this is the same resolution by hand.
|
|
243
|
+
*/
|
|
244
|
+
useCatalogSupports: (catalogIdref: string | undefined) => readonly ResolvedCatalogSupport[];
|
|
152
245
|
/**
|
|
153
246
|
* The Capability Report for an item against this runtime's injected descriptors,
|
|
154
247
|
* skins, and content model. Consumers gate delivery on it (ADR-0003); the
|
|
@@ -161,4 +254,6 @@ export interface AttemptController extends AttemptSnapshot {
|
|
|
161
254
|
submit: () => readonly ScoreResult[];
|
|
162
255
|
reset: () => void;
|
|
163
256
|
}
|
|
257
|
+
/** The item-session states the renderer knows (ItemSessionControl review/solution). */
|
|
258
|
+
export type ItemRenderMode = "interact" | "review" | "solution";
|
|
164
259
|
export declare function createQtiRuntime(config: QtiRuntimeConfig): QtiRuntime;
|
package/dist/store.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* support multiple attempts: outcomes carry over between RP runs and the item locks
|
|
12
12
|
* only when `completionStatus` reaches "completed".
|
|
13
13
|
*/
|
|
14
|
+
import type { InteractionConstraint, ResponseViolation } from "./response-validity";
|
|
14
15
|
import type { CustomOperatorImplementation, OutcomeDeclarationView, OutcomeValue, ResponseNormalization, ResponseProcessingView, TemplateDeclarationView, TemplateProcessingView } from "./rp";
|
|
15
16
|
import type { ResponseDeclarationView, ResponseValue, ScoreResult } from "./types";
|
|
16
17
|
export interface AttemptSnapshot {
|
|
@@ -24,6 +25,23 @@ export interface AttemptSnapshot {
|
|
|
24
25
|
readonly templateValues: Readonly<Record<string, OutcomeValue>>;
|
|
25
26
|
/** Completed attempts so far (only ever exceeds 1 for adaptive items). */
|
|
26
27
|
readonly attemptCount: number;
|
|
28
|
+
/**
|
|
29
|
+
* Elapsed session seconds at the latest submit (the built-in `duration` response
|
|
30
|
+
* variable handed to RP); null before the first submit. Persist it alongside the
|
|
31
|
+
* responses for server-side replay parity (ADR-0004).
|
|
32
|
+
*/
|
|
33
|
+
readonly durationSeconds: number | null;
|
|
34
|
+
/**
|
|
35
|
+
* Interaction constraints the current responses fail (see response-validity).
|
|
36
|
+
* Always visible so UIs can explain themselves; submission is blocked on them
|
|
37
|
+
* only under `validateResponses`.
|
|
38
|
+
*/
|
|
39
|
+
readonly responseViolations: readonly ResponseViolation[];
|
|
40
|
+
/**
|
|
41
|
+
* This clone's resolved correct responses (template `setCorrectResponse` overrides
|
|
42
|
+
* applied), keyed by response identifier. The solution state renders these.
|
|
43
|
+
*/
|
|
44
|
+
readonly correctResponses: Readonly<Record<string, ResponseValue>>;
|
|
27
45
|
}
|
|
28
46
|
/**
|
|
29
47
|
* Consumer-supplied input. Optional members deliberately admit explicit
|
|
@@ -38,12 +56,32 @@ export interface AttemptStoreOptions {
|
|
|
38
56
|
readonly normalization?: ResponseNormalization | undefined;
|
|
39
57
|
readonly templateDeclarations?: readonly TemplateDeclarationView[] | undefined;
|
|
40
58
|
readonly templateProcessing?: TemplateProcessingView | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Test-level `templateDefault` values (§5.152) overriding the template
|
|
61
|
+
* declarations' defaults for this clone; the test session store supplies them from
|
|
62
|
+
* the controller's recorded `templateDefaultValues`.
|
|
63
|
+
*/
|
|
64
|
+
readonly templateDefaultValues?: Readonly<Record<string, OutcomeValue>> | undefined;
|
|
41
65
|
/** Clone seed for template processing; store it to replay the same clone. */
|
|
42
66
|
readonly seed?: number | undefined;
|
|
43
67
|
/** QTI adaptive item: multiple attempts, outcome carry-over, completionStatus lock. */
|
|
44
68
|
readonly adaptive?: boolean | undefined;
|
|
45
69
|
/** Registered vendor `customOperator` implementations by class (opt-in). */
|
|
46
70
|
readonly customOperators?: Readonly<Record<string, CustomOperatorImplementation>> | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Millisecond clock backing the built-in `duration` response variable (wall-clock
|
|
73
|
+
* from session start to submit). Injectable for deterministic tests and replays;
|
|
74
|
+
* defaults to Date.now.
|
|
75
|
+
*/
|
|
76
|
+
readonly now?: (() => number) | undefined;
|
|
77
|
+
/** The item's interaction constraints (collectInteractionConstraints over the body). */
|
|
78
|
+
readonly constraints?: readonly InteractionConstraint[] | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* ItemSessionControl validate-responses: "candidates are not allowed to submit the
|
|
81
|
+
* item until they have provided valid responses for all interactions". When set,
|
|
82
|
+
* submit() refuses while `responseViolations` is non-empty.
|
|
83
|
+
*/
|
|
84
|
+
readonly validateResponses?: boolean | undefined;
|
|
47
85
|
}
|
|
48
86
|
export interface AttemptStore {
|
|
49
87
|
readonly getSnapshot: () => AttemptSnapshot;
|
|
@@ -57,5 +95,14 @@ export interface AttemptStore {
|
|
|
57
95
|
readonly registerResponseCollector: (responseIdentifier: string, collector: () => ResponseValue | undefined) => () => void;
|
|
58
96
|
readonly submit: () => readonly ScoreResult[];
|
|
59
97
|
readonly reset: () => void;
|
|
98
|
+
/**
|
|
99
|
+
* Stop the session clock: duration "records the accumulated time (in seconds) of
|
|
100
|
+
* all Candidate Sessions for all Attempts … minus any time the session was in the
|
|
101
|
+
* suspended state". Navigating away from an item suspends its session (spec);
|
|
102
|
+
* the test session store drives this. Idempotent.
|
|
103
|
+
*/
|
|
104
|
+
readonly suspend: () => void;
|
|
105
|
+
/** Restart the session clock after `suspend()`. Idempotent. */
|
|
106
|
+
readonly resume: () => void;
|
|
60
107
|
}
|
|
61
108
|
export declare function createAttemptStore(declarations: readonly ResponseDeclarationView[], initialResponses: Readonly<Record<string, ResponseValue>>, options?: AttemptStoreOptions): AttemptStore;
|
|
@@ -4,8 +4,30 @@
|
|
|
4
4
|
* navigation, branching, and outcome-processing question as a pure transition over the
|
|
5
5
|
* consumer-persisted session state. It owns no storage and renders nothing.
|
|
6
6
|
*/
|
|
7
|
+
import { type PnpView } from "../pnp";
|
|
8
|
+
import type { OutcomeDeclarationView } from "../rp/types";
|
|
7
9
|
import type { AssessmentTestView, TestController } from "./types";
|
|
8
10
|
export interface TestControllerOptions {
|
|
9
11
|
readonly seed: number;
|
|
12
|
+
/**
|
|
13
|
+
* Each item's outcome declarations, keyed by item-ref identifier (shared by every
|
|
14
|
+
* selected instance of the ref). Feeds `outcomeMaximum`/`outcomeMinimum` with the declared
|
|
15
|
+
* `normal-maximum`/`normal-minimum`; items absent here degrade per spec — maximum
|
|
16
|
+
* → NULL (§2.11.2.7), minimum → ignored (§2.11.2.6) — never a refusal. Consumers
|
|
17
|
+
* can pass `assessmentItemViewFromNormalized(...).outcomeDeclarations` verbatim.
|
|
18
|
+
*/
|
|
19
|
+
readonly itemOutcomeDeclarations?: Readonly<Record<string, readonly OutcomeDeclarationView[]>> | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Millisecond clock backing the built-in test/part/section `duration` variables and
|
|
22
|
+
* timeLimits enforcement. Injectable for deterministic tests and replays; defaults
|
|
23
|
+
* to Date.now.
|
|
24
|
+
*/
|
|
25
|
+
readonly now?: (() => number) | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* The candidate's AfA PNP. The controller consumes additional-testing-time:
|
|
28
|
+
* "the durations may be changed depending on the relevant accessibility values
|
|
29
|
+
* in the Personal Needs & Preferences settings for the learner" (§2.8.5).
|
|
30
|
+
*/
|
|
31
|
+
readonly pnp?: PnpView | undefined;
|
|
10
32
|
}
|
|
11
33
|
export declare function createTestController(view: AssessmentTestView, options: TestControllerOptions): TestController;
|
package/dist/test/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { createTestController, type TestControllerOptions } from "./controller";
|
|
2
|
+
export { assessmentResultFromNormalized, buildAssessmentResult, type AssessmentResultDocumentView, type AssessmentResultInput, type AssessmentResultItemDetails, type AssessmentResultView, type ItemResultView, type ResultContextView, type ResultOutcomeVariableView, type ResultResponseVariableView, type ResultSessionIdentifierView, type ResultSessionStatus, type ResultSupportView, type ResultValueView, type TestResultView, } from "./results";
|
|
2
3
|
export { createTestSessionStore, type TestSessionSnapshot, type TestSessionStore, type TestSessionStoreOptions, } from "./session-store";
|
|
3
|
-
export type { AssessmentItemRefView, AssessmentSectionView, AssessmentTestView, BranchRuleView, ItemSessionControlView, OutcomeConditionBranch, OutcomeRuleView, TestController, TestFeedbackView, TestItemResult, TestPartView, TestPlan, TestPlanItem, TestPlanPart, TestSessionState, TimeLimitsView, } from "./types";
|
|
4
|
+
export type { AssessmentItemRefView, RecordedAttempt, AssessmentSectionView, AssessmentTestView, BranchRuleView, ItemSessionControlView, OutcomeConditionBranch, OutcomeRuleView, RejectedSubmission, TemplateDefaultView, TestController, TestFeedbackView, TestItemResult, TestPartView, TestPlan, TestPlanItem, TestPlanPart, TestPlanSection, TestSessionState, TestTimingState, TimeLimitsView, TimingScopeRef, } from "./types";
|