Skip to content

@astrolabe/engine

The isomorphic engine: parse, sanitise, validate, compile (view, answer key, metadata) and grade. Runs in browsers, Node, Deno, Bun and Workers.

Property Modifier Type Description
detail readonly string -
element readonly string | null Source id of the component, when known.
kind readonly "attribute" | "value" | "child" | "structure" - value: a private attribute value or private child text appears in the component's view element; - attribute / child: a private attribute or private child tag is present in the view; - structure: source and view components do not line up.
tag readonly string Component tag.

Property Modifier Type Description
checksLeft readonly number | null Checks left in this attempt; null = unlimited.
check(request): Promise<CheckResponse>;

Practice only. Rejects with CheckerError (check_not_allowed) under other policies.

Parameter Type
request CheckRequest

Promise<CheckResponse>

Checker.check

submit(request): Promise<SubmitResponse>;
Parameter Type
request SubmitRequest

Promise<SubmitResponse>

Checker.submit

type ChoiceKey = object;
readonly correct: string;

The correct value: an opaque option id, or a fixed public value such as true / false.


type FlagKey = object;
readonly correct: boolean;

Whether the option should be selected.


type LetterKey = object;
readonly lang: string;

The language capitals are made in (Turkish i and İ).

readonly letter: string;

One letter (one code point) in NFC capitals, as the cell shows it.


type NumberKey = object;
readonly lang: string;
readonly tolerance: number;

Accepted distance from a value.

readonly values: readonly number[];

Accepted values; the first one is the solution.


type ProfileData = { readonly [K in keyof NormalisationProfile]: NormalisationProfile[K] };

A NormalisationProfile as JSON data (an object type, so it fits JsonObject).


type RefResolver = (ref) => Promise<string>;

Maps a fixture ref to the opaque id the compiler gives it.

Parameter Type
ref string

Promise<string>


type TextKey = object;
readonly accept: readonly string[];

Accepted answers as the author wrote them; the first one is the solution.

readonly lang: string;
readonly profile: ProfileData;
const choiceSlot: SlotKind<ChoiceKey>;

One picked value: an option's opaque id, or one of a fixed set of public values.


const engineMessages: readonly MessageCatalog[];

Messages for every engine issue code (namespace astl.engine).


const flagSlot: SlotKind<FlagKey>;

A selectable option ('true' when selected). Unselected flags are graded by the engine (see scoring).


const letterSlot: SlotKind<LetterKey>;

One letter in a square (a crossword cell): the answer in NFC capitals of the key's language, spaces around it ignored, equals the key's letter. Anything longer is wrong.


const numberSlot: SlotKind<NumberKey>;

A number in the content language's notation, within a tolerance.


const textSlot: SlotKind<TextKey>;

Typed text compared with the stored normalisation profile.

function createEngine(options): Engine;

Creates an engine. Throws a TypeError for a secret under 16 bytes, a tag, slot kind or style template registered twice, a manifest slot kind that is not registered, a child tag two manifests declare differently, or a manifest that fails its sanity checks. Without a secret it validates, grades, solves and describes, and compile throws a TypeError.

Parameter Type
options EngineOptions

Engine


function leakProbe(
source,
view,
manifests
): Leak[];

Looks for answer data in a compiled view, with the same rules the compiler enforces (see findLeaks in the view guard): components are matched by document order; a leak is a private attribute or child present in the view, or a secret value (private strings, private child texts) found in the view's text or free-text attributes that the author did not also write in the element's public content.

Parameter Type
source string
view string
manifests readonly ComponentManifest[]

Leak[]


function localChecker(
engine,
key,
policy?
): LocalChecker;

A stateful Checker for one attempt: check only under a practice policy and within maxChecks, one submit, and reveal / passMark applied to the submit response.

Parameter Type Default value
engine Engine undefined
key AnswerKey undefined
policy? AttemptPolicy PRACTICE_POLICY

LocalChecker


function normalise(
text,
profile,
lang
): string;

Normalises typed text for comparison. Steps, each only when the profile asks for it: Unicode form, quote and dash folding, space collapsing, edge punctuation, case (locale-aware, so Turkish İ and I work) and diacritics. A late step can leave work for an earlier one (a dropped combining mark between two spaces, or after a final full stop), so the steps repeat until the text stops changing: the result is always a fixpoint.

Parameter Type
text string
profile NormalisationProfile
lang string

string


function parseHtml(html): Node[];

Parses HTML (a whole source or a single element snippet) into core nodes. Comments and doctypes are dropped, tag and attribute names are lowercased, <template> content is dropped and adjacent text nodes are merged.

The result is stable: serialising it and parsing again gives the same tree. The HTML parser alone does not promise that (<h3><table><h6> puts the h6 inside the h3, and re-parsing <h3><h6> closes the h3), so the serialisation is re-parsed until it stops changing; well-formed input settles after one check.

Throws a RangeError for input nested deeper than MAX_NESTING_DEPTH elements or with an element carrying more than MAX_ATTRIBUTES_PER_ELEMENT attributes (validate reports SOURCE_TOO_DEEP and SOURCE_TOO_COMPLEX instead).

Parameter Type
html string

Node[]


function parseNumber(text, lang): number | null;

Parses a number as a student types it in the content language. Spaces may group digits; U+2212 is a minus sign. Decimal-comma languages accept 0,5, 1.234,5 and a dot as the only separator: 1.234.567 is grouped, and a single 1.234 is grouped where the language groups with dots (German) but a decimal elsewhere (Polish). Other languages accept 0.5 and 1,234.5. Returns null for anything else.

Parameter Type
text string
lang string

number | null


function refResolver(secret, salt?): RefResolver;

Resolves fixture refs for a secret and compile salt: g1 (an element: its group or single slot), q1/a (a local id: an option or its flag slot), page:p1 (a page) and page:#0 (the implicit page).

Parameter Type Default value
secret string | Uint8Array<ArrayBufferLike> undefined
salt? string ''

RefResolver


function serializeHtml(nodes): string;

Serialises nodes to HTML. Text escapes &, <, > and U+00A0 (&nbsp;); attribute values escape &, " and U+00A0; empty attributes are written bare (multiple); void elements have no end tag. Text is kept as is. Parsing the output gives the same tree back (a fixpoint), including the parser's special cases: raw text elements, the newline after <pre>, <plaintext> (which never ends) and SVG / MathML content.

Parameter Type
nodes readonly Node[]

string