Guide and reference
Tool and calculator providers
Load tools and configure Desmos, GeoGebra or Cortex.
From the pie-players documentation · View source(opens in new tab)
The packaged PIE assessment tools: which capabilities exist in a deployment, how they load, and which of them a program grants to everyone. This README is for host integrators choosing a tool set and a calculator, and for contributors adding a packaged capability.
The package owns the concrete pie-tool-* dependencies and the Desmos and
GeoGebra calculator adapters (pie-calculator-desmos and -geogebra), so
toolkit core stays dependency-light and cycle-safe. Core knows the concepts — support ids,
placement levels, activation kinds and precedence rules — and no concrete
capability id. A support id is the tool id a profile grants.
| Export | What it decides |
|---|---|
PACKAGED_TOOL_REGISTRATIONS, createPackagedToolRegistry |
Which capabilities exist, and their toolbar and surface contracts |
PACKAGED_TOOL_TAG_MAP |
Which custom element each one renders as |
createCalculatorToolRegistration |
Which calculator backends provider.id selects among |
SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT |
Where they appear and in what order |
createUniversalPersonalNeedsProfile, createEmptyPersonalNeedsProfile |
Which of them the program grants to everyone, or to no one |
createPersonalNeedsProfileFromAfa |
Which of them a student's AfA PNP 3.0 record grants, prohibits and turns on at start, and with which settings |
DEFAULT_TOOL_MODULE_LOADERS |
When each one's bundle loads |
CONTENT_ALTERNATE_REGISTRATIONS |
Which of them carry an authored alternate that renders as a region; the print player mounts these |
The individual registrations are exported too, so a host can compose its own set (Custom sets).
Usage
import { createPackagedToolRegistry } from "@pie-players/pie-default-tool-loaders";
// The packaged capability set, lazily loaded.
const registry = createPackagedToolRegistry();
// The same registrations for a host that defines the tool elements itself.
const preloaded = createPackagedToolRegistry({ toolModuleLoaders: {} });
One loader set serves every host shape. DEFAULT_TOOL_MODULE_LOADERS holds a
loader per packaged capability and is what createPackagedToolRegistry
installs unless toolModuleLoaders replaces it. A registry loads a module only
when a tool first renders, so an item player, a section player and an
assessment player share the set and load only the tools they place.
createPackagedToolRegistry is lenient with host input. Registration, tag-map
and component-factory overrides take precedence over the packaged data. An
empty toolIds array selects the full packaged set, and unknown ids in it are
ignored while the known ones register.
Calculator providers
The calculator is one element, <pie-tool-calculator>, for every provider. The
toolkit picks the provider from tools.providers.calculator when the element
mounts, and an open calculator remounts on the new provider when a tool-config
update replaces it.
Desmos is the provider when none is configured, and it needs an API key: pass
it through provider.runtime.authFetcher, a provider.init.proxyEndpoint that
returns it, or provider.init.apiKey in development
(Calculator with host auth).
Without one the calculator fails to load. provider.id: "calculator-geogebra"
selects GeoGebra, which needs no key.
const tools = {
providers: {
calculator: {
provider: {
id: "calculator-geogebra",
init: { appletTimeoutMs: 20_000 },
},
settings: { showResetIcon: true },
},
},
};
Adding a backend
The packaged registration selects among Desmos and GeoGebra only, because a
bundler that inlines dynamic imports inlines every backend the registration
names, selected or not. createCalculatorToolRegistration({ providers }) builds
the registration with more backends, keyed by provider.id; an id the packaged
set already holds is replaced. The keyless, offline-capable Cortex calculator,
which needs no runtime CDN, is composed in this way from
@pie-players/pie-calculator-cortex, which the host installs:
import {
createCalculatorToolRegistration,
createPackagedToolRegistry,
} from "@pie-players/pie-default-tool-loaders";
const registry = createPackagedToolRegistry({
overrides: {
calculator: createCalculatorToolRegistration({
providers: {
"calculator-cortex": {
providerName: "PIE Open-Source Calculator",
version: "1",
requiresAuth: false,
backend: "cortex",
load: async () =>
(await import("@pie-players/pie-calculator-cortex"))
.CortexCalculatorProvider,
initializationErrorMessage:
"Failed to initialize the Cortex calculator provider.",
},
},
}),
},
});
provider.id: "calculator-cortex" then selects it. Its settings take the
CortexCalculatorSettings type that @pie-players/pie-calculator-cortex
exports: angleMode, calculationPrecision, displayPrecision,
historyLimit, evaluationTimeLimitMs, allowedFunctions, allowClipboard,
messages, direction and graph. Clipboard blocking follows
restrictedMode; allowClipboard alone blocks nothing. The
Cortex README covers localization, message
overrides and the keypad.
Custom sets
A host composing its own set starts from the toolkit's empty ToolRegistry,
registers into it, and installs the tag map its registrations create elements
from.
import { ToolRegistry } from "@pie-players/pie-assessment-toolkit";
import {
calculatorToolRegistration,
DEFAULT_TOOL_MODULE_LOADERS,
PACKAGED_TOOL_TAG_MAP,
ttsToolRegistration,
} from "@pie-players/pie-default-tool-loaders";
const registry = new ToolRegistry();
registry.register(calculatorToolRegistration);
registry.register(ttsToolRegistration);
registry.setComponentOverrides({ toolTagMap: PACKAGED_TOOL_TAG_MAP });
registry.setToolModuleLoaders(DEFAULT_TOOL_MODULE_LOADERS);
A later setToolModuleLoaders call adds or replaces entries. A replacement
registered after a tool's module has loaded is ignored with a warning, since the
elements it defines are already in place.
Content-dependent capabilities
A content-dependent capability declares requiresAuthoredContent: it renders
only where the content carries what it needs, and
createUniversalPersonalNeedsProfile() never grants one. It ships in
PACKAGED_TOOL_REGISTRATIONS only when it has a useful presentation path
without a grant and declares resolvesWithoutGrant. Audio transcript is the
shipped example: an authored visibility: "always" transcript reaches every
player, while its accommodation path stays policy-gated and transcript stays
out of the universal profile.
A content-dependent capability with no such path is an explicit deployment
choice. Signing is the shipped example: install
@pie-players/pie-tool-sign-language and register it, the same two lines a
host writes for a capability of its own.
import { signLanguageRegistration } from "@pie-players/pie-tool-sign-language";
registry.register(signLanguageRegistration);
Universal and empty profiles
createUniversalPersonalNeedsProfile() builds a fresh PersonalNeedsProfile
granting the tool ids of the capabilities the packaged set treats as universal
features. Tool policy reads the profile from the assessment entity, so set it
there: on the player's assessment property, or through
coordinator.updateAssessment(...) on a coordinator you pass. A
section.personalNeedsProfile is ignored with a console warning.
import { createUniversalPersonalNeedsProfile } from "@pie-players/pie-default-tool-loaders";
sectionPlayer.assessment = {
...authoredAssessment,
personalNeedsProfile: createUniversalPersonalNeedsProfile(),
};
The toolkit ships no populated default, and createEmptyPersonalNeedsProfile()
builds a profile granting nothing. Which capabilities a deployment grants by
default is a property of the program: TTS is a universal feature in one program
and a documented accommodation in another. The universal profile is data to
adopt, extend or replace alongside the district and test-administration
configuration, and it excludes every capability that declares a content
dependency.
An assessment carrying no profile is left alone. pnpEnforcement
auto-detection engages only on host policy material, so with no profile,
placement alone decides which tools appear.
AfA profiles
createPersonalNeedsProfileFromAfa(record) builds a fresh profile from a
student's AfA PNP 3.0 record, held as JSON keyed by the spec's terms. Features
become support ids in the packaged set's names, the activation sets fill
activateAtInit and prohibitedSupports, and the settings the packaged tools
read become toolParameters: read-aloud speed, pitch and volume, the calculator
type, the sign language and the magnifier's starting zoom. The toolkit's PNP
configuration guide gives each AfA feature's disposition.
import { createPersonalNeedsProfileFromAfa } from "@pie-players/pie-default-tool-loaders";
sectionPlayer.assessment = {
...authoredAssessment,
personalNeedsProfile: createPersonalNeedsProfileFromAfa(afaRecord),
};
Packaged capability composition
The exports are projections of one internal composition. Each packaged capability is authored once with its registration, element delivery, module loader, preferred placement and explicit universal-support flag.
The package build rejects contradictory PIE-owned data, such as a region capability with a toolbar tag or a content-dependent capability marked universal, so release tests catch a missing facet before it ships. The browser skips that strict check at import time: a PIE authoring defect blocks publication and never an otherwise usable assessment.