@pie-players/pie-default-tool-loaders 1.0.0-beta.0 → 1.0.0-beta.10
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/LICENSE +21 -0
- package/README.md +116 -12
- package/dist/afa-profile.d.ts +65 -0
- package/dist/afa-profile.js +135 -0
- package/dist/calculator-providers/LazyCalculatorToolProvider.d.ts +32 -18
- package/dist/calculator-providers/LazyCalculatorToolProvider.js +24 -12
- package/dist/calculator-providers/packaged-calculator-providers.js +26 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +10 -5
- package/dist/packaged-capability-composition.js +11 -1
- package/dist/registrations/accessibility-tools.d.ts +8 -0
- package/dist/registrations/accessibility-tools.js +38 -0
- package/dist/registrations/audio-transcript.d.ts +0 -7
- package/dist/registrations/audio-transcript.js +1 -7
- package/dist/registrations/calculator.d.ts +16 -5
- package/dist/registrations/calculator.js +171 -176
- package/dist/registrations/interaction-tools.d.ts +15 -2
- package/dist/registrations/interaction-tools.js +110 -13
- package/dist/registrations/tts.d.ts +23 -2
- package/dist/registrations/tts.js +121 -93
- package/package.json +27 -25
- package/dist/calculator-providers/CortexToolProvider.d.ts +0 -10
- package/dist/calculator-providers/CortexToolProvider.js +0 -18
- package/dist/calculator-providers/DesmosToolProvider.d.ts +0 -11
- package/dist/calculator-providers/DesmosToolProvider.js +0 -18
- package/dist/calculator-providers/GeoGebraToolProvider.d.ts +0 -13
- package/dist/calculator-providers/GeoGebraToolProvider.js +0 -18
- package/dist/registrations/overlay-element-cache.d.ts +0 -23
- package/dist/registrations/overlay-toolbar-render.d.ts +0 -33
- package/dist/registrations/selection-actions.d.ts +0 -24
|
@@ -4,12 +4,100 @@
|
|
|
4
4
|
* Registers tools for interacting with question content:
|
|
5
5
|
* - Answer Eliminator (strike through answer choices)
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { elementSupports } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
8
8
|
import { createToolElement, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
9
9
|
import { createScopedVisibilityBinding, syncButtonAndOverlayVisibility, } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
10
10
|
import { resolveOverlayElement } from "./overlay-element-cache.js";
|
|
11
11
|
/** The policy parameters' `strategy`, defaulting to strikethrough. */
|
|
12
12
|
const normalizeEliminationStrategy = (value) => value === "mask" ? "mask" : "strikethrough";
|
|
13
|
+
/** The AfA PNP 3.0 support term an element declares to take the eliminator. */
|
|
14
|
+
const ANSWER_MASKING = "answer-masking";
|
|
15
|
+
/**
|
|
16
|
+
* pie-item contract compatibility: legacy pie-elements, and pie-elements-ng
|
|
17
|
+
* releases from before elements declared their supports, render the markup the
|
|
18
|
+
* eliminator's built-in adapters read for these two. An element that declares
|
|
19
|
+
* its supports is decided by its declaration, these two included.
|
|
20
|
+
*/
|
|
21
|
+
const UNDECLARED_ANSWER_MASKING_ELEMENTS = new Set(["multiple-choice", "ebsr"]);
|
|
22
|
+
function elementName(tag) {
|
|
23
|
+
return tag
|
|
24
|
+
.toLowerCase()
|
|
25
|
+
.replace(/--version-[0-9a-z-]+$/, "")
|
|
26
|
+
.replace(/^pie-(element-)?/, "");
|
|
27
|
+
}
|
|
28
|
+
// Content names one element several ways: `multiple-choice`,
|
|
29
|
+
// `pie-multiple-choice`, `pie-element-multiple-choice`, a runtime `--version-*`
|
|
30
|
+
// tag, or any tag the item's `elements` map binds to `@pie-element/multiple-choice`.
|
|
31
|
+
function elementNames(tag, packageSpec) {
|
|
32
|
+
const names = [elementName(tag)];
|
|
33
|
+
const packageName = pieElementPackageName(packageSpec);
|
|
34
|
+
if (packageName)
|
|
35
|
+
names.push(packageName);
|
|
36
|
+
return names;
|
|
37
|
+
}
|
|
38
|
+
function pieElementPackageName(packageSpec) {
|
|
39
|
+
return packageSpec?.match(/^@pie-element\/([^@]+)/)?.[1]?.toLowerCase() ?? null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The name an `elements` list matches: the `@pie-element/<name>` package the
|
|
43
|
+
* item binds the tag to, else the tag's own name. A tag bound to another
|
|
44
|
+
* package matches no name, whatever the tag says.
|
|
45
|
+
*/
|
|
46
|
+
function listedName(tag, packageSpec) {
|
|
47
|
+
return packageSpec ? pieElementPackageName(packageSpec) : elementName(tag);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The element names `config.elements` allows, or `null` for every element. An
|
|
51
|
+
* `elements` that is not a list allows none: validation reports it, and an
|
|
52
|
+
* element a host has not vetted stays without the eliminator.
|
|
53
|
+
*/
|
|
54
|
+
function allowedElementNames(config) {
|
|
55
|
+
const elements = config
|
|
56
|
+
?.elements;
|
|
57
|
+
if (elements === undefined)
|
|
58
|
+
return null;
|
|
59
|
+
if (!Array.isArray(elements))
|
|
60
|
+
return new Set();
|
|
61
|
+
return new Set(elements
|
|
62
|
+
.filter((name) => typeof name === "string")
|
|
63
|
+
.map(elementName));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The model ids of the context's elements that support answer masking and the
|
|
67
|
+
* host config allows.
|
|
68
|
+
*/
|
|
69
|
+
function answerMaskingElementIds(context, config) {
|
|
70
|
+
const allowed = allowedElementNames(config);
|
|
71
|
+
return elementSupports(context)
|
|
72
|
+
.filter(({ supports, tag, packageSpec }) => {
|
|
73
|
+
if (allowed) {
|
|
74
|
+
const name = listedName(tag, packageSpec);
|
|
75
|
+
if (name === null || !allowed.has(name))
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return supports
|
|
79
|
+
? supports.includes(ANSWER_MASKING)
|
|
80
|
+
: elementNames(tag, packageSpec).some((name) => UNDECLARED_ANSWER_MASKING_ELEMENTS.has(name));
|
|
81
|
+
})
|
|
82
|
+
.flatMap(({ elementId }) => (elementId ? [elementId] : []));
|
|
83
|
+
}
|
|
84
|
+
function validateAnswerEliminatorConfig(config) {
|
|
85
|
+
const { elements } = config;
|
|
86
|
+
if (elements === undefined)
|
|
87
|
+
return [];
|
|
88
|
+
if (Array.isArray(elements) &&
|
|
89
|
+
elements.every((name) => typeof name === "string" && name.trim() !== "")) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
return [
|
|
93
|
+
{
|
|
94
|
+
code: "tools.invalidProviderConfig",
|
|
95
|
+
severity: "error",
|
|
96
|
+
path: "providers.answerEliminator.elements",
|
|
97
|
+
message: '`elements` must be a list of element names, such as ["multiple-choice"].',
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
}
|
|
13
101
|
/** The state-store key of each PIE element in the item, by model id. */
|
|
14
102
|
function resolveElementStateKeys(context, toolbarContext) {
|
|
15
103
|
const keys = {};
|
|
@@ -29,7 +117,7 @@ function resolveElementStateKeys(context, toolbarContext) {
|
|
|
29
117
|
* Answer Eliminator tool registration
|
|
30
118
|
*
|
|
31
119
|
* Allows students to strike through incorrect answer choices.
|
|
32
|
-
* Only appears on
|
|
120
|
+
* Only appears on items with an element that supports answer masking.
|
|
33
121
|
*/
|
|
34
122
|
export const answerEliminatorToolRegistration = {
|
|
35
123
|
toolId: "answerEliminator",
|
|
@@ -39,22 +127,25 @@ export const answerEliminatorToolRegistration = {
|
|
|
39
127
|
descriptionKey: "tools.answerEliminator.description",
|
|
40
128
|
icon: "strikethrough",
|
|
41
129
|
supportedLevels: ["item"],
|
|
130
|
+
validateConfig: validateAnswerEliminatorConfig,
|
|
42
131
|
/**
|
|
43
|
-
* Pass 2:
|
|
132
|
+
* Pass 2: relevant where an element supports answer masking. An element
|
|
133
|
+
* declares it on its class, and the answer eliminator's README says what the
|
|
134
|
+
* element then supplies.
|
|
44
135
|
*/
|
|
45
136
|
isVisibleInContext(context) {
|
|
46
|
-
return
|
|
137
|
+
return answerMaskingElementIds(context, null).length > 0;
|
|
47
138
|
},
|
|
48
139
|
/**
|
|
49
|
-
* Pass 3: the same question, asked as a capability
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
140
|
+
* Pass 3: the same question, asked as a capability and narrowed to the
|
|
141
|
+
* elements the host config allows. Elimination controls are rendered per
|
|
142
|
+
* choice, so an item none of whose allowed elements supports answer masking
|
|
143
|
+
* gives this tool nothing to act on. Answering the relevance gate alone left
|
|
144
|
+
* the button on such items for any learner whose profile grants answer
|
|
145
|
+
* masking.
|
|
55
146
|
*/
|
|
56
|
-
isApplicableToContent(context) {
|
|
57
|
-
return
|
|
147
|
+
isApplicableToContent(context, config) {
|
|
148
|
+
return answerMaskingElementIds(context, config).length > 0;
|
|
58
149
|
},
|
|
59
150
|
renderToolbar(context, toolbarContext) {
|
|
60
151
|
const visibility = createScopedVisibilityBinding(this.toolId, toolbarContext);
|
|
@@ -65,7 +156,7 @@ export const answerEliminatorToolRegistration = {
|
|
|
65
156
|
const button = {
|
|
66
157
|
toolId: this.toolId,
|
|
67
158
|
label: this.name,
|
|
68
|
-
icon:
|
|
159
|
+
icon: typeof this.icon === "function" ? this.icon(context) : this.icon,
|
|
69
160
|
disabled: false,
|
|
70
161
|
ariaLabel: toolbarContext.i18n.t("tools.answerEliminator.buttonA11y"),
|
|
71
162
|
tooltip: toolbarContext.i18n.t("tools.answerEliminator.tooltip"),
|
|
@@ -83,6 +174,12 @@ export const answerEliminatorToolRegistration = {
|
|
|
83
174
|
isActive: visibility.isActive,
|
|
84
175
|
});
|
|
85
176
|
overlay.elementStateKeys = resolveElementStateKeys(context, toolbarContext);
|
|
177
|
+
const config = toolbarContext.toolkitCoordinator?.getToolConfig(this.toolId) ??
|
|
178
|
+
null;
|
|
179
|
+
overlay.elementIds =
|
|
180
|
+
allowedElementNames(config) === null
|
|
181
|
+
? undefined
|
|
182
|
+
: answerMaskingElementIds(context, config);
|
|
86
183
|
},
|
|
87
184
|
subscribeActive: visibility.subscribeActive,
|
|
88
185
|
};
|
|
@@ -4,12 +4,33 @@
|
|
|
4
4
|
* Registers the TTS tool for reading content aloud.
|
|
5
5
|
*/
|
|
6
6
|
import type { ToolRegistration } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
7
|
+
import { TTSToolProvider } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
8
|
+
type TTSToolProviderOptions = NonNullable<ConstructorParameters<typeof TTSToolProvider>[1]>;
|
|
9
|
+
/** A host's own text-to-speech provider, selected by `provider.id`. */
|
|
10
|
+
export interface TTSHostProviderDescriptor {
|
|
11
|
+
/** Resolves the host's `ITTSProvider` class; imported only when selected. */
|
|
12
|
+
load: NonNullable<TTSToolProviderOptions["loadHostProvider"]>;
|
|
13
|
+
/** Wait on `provider.runtime.authFetcher` before initializing. Default `false`. */
|
|
14
|
+
requiresAuth?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface TTSRegistrationOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Host providers by `provider.id`. A `textToSpeech` config whose
|
|
19
|
+
* `provider.id` names none of them, or names none at all, keeps the browser
|
|
20
|
+
* or server backend its settings select.
|
|
21
|
+
*/
|
|
22
|
+
providers?: Readonly<Record<string, TTSHostProviderDescriptor>>;
|
|
23
|
+
}
|
|
7
24
|
/**
|
|
8
|
-
*
|
|
25
|
+
* Builds the text-to-speech registration over the browser and server backends
|
|
26
|
+
* plus any host providers, so a host bundles its provider only by naming it.
|
|
9
27
|
*
|
|
10
28
|
* Supports:
|
|
11
|
-
* - Reading content aloud using browser TTS or
|
|
29
|
+
* - Reading content aloud using browser TTS, a TTS server or a host provider
|
|
12
30
|
* - Context-aware visibility (shows when readable text is available)
|
|
13
31
|
* - Item and passage levels
|
|
14
32
|
*/
|
|
33
|
+
export declare function createTTSToolRegistration(options?: TTSRegistrationOptions): ToolRegistration;
|
|
34
|
+
/** The text-to-speech registration with the browser and server backends only. */
|
|
15
35
|
export declare const ttsToolRegistration: ToolRegistration;
|
|
36
|
+
export {};
|
|
@@ -11,107 +11,135 @@ import { resolveOverlayElement } from "./overlay-element-cache.js";
|
|
|
11
11
|
// This package owns the server adapter's import, so the toolkit never names it
|
|
12
12
|
// and a bundler building the toolkit alone has nothing to resolve.
|
|
13
13
|
const loadServerTTSProvider = async () => (await import("@pie-players/tts-client-server")).ServerTTSProvider;
|
|
14
|
+
const numberOrUndefined = (value) => typeof value === "number" ? value : undefined;
|
|
15
|
+
/** The host-provider path, with the descriptor's auth requirement. */
|
|
16
|
+
class HostTTSToolProvider extends TTSToolProvider {
|
|
17
|
+
constructor(descriptor) {
|
|
18
|
+
super("browser", { loadHostProvider: descriptor.load });
|
|
19
|
+
this.requiresAuth = descriptor.requiresAuth === true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const selectHostProvider = (config, providers) => {
|
|
23
|
+
const id = config?.provider?.id;
|
|
24
|
+
return typeof id === "string" && Object.hasOwn(providers, id)
|
|
25
|
+
? providers[id]
|
|
26
|
+
: undefined;
|
|
27
|
+
};
|
|
14
28
|
/**
|
|
15
|
-
*
|
|
29
|
+
* Builds the text-to-speech registration over the browser and server backends
|
|
30
|
+
* plus any host providers, so a host bundles its provider only by naming it.
|
|
16
31
|
*
|
|
17
32
|
* Supports:
|
|
18
|
-
* - Reading content aloud using browser TTS or
|
|
33
|
+
* - Reading content aloud using browser TTS, a TTS server or a host provider
|
|
19
34
|
* - Context-aware visibility (shows when readable text is available)
|
|
20
35
|
* - Item and passage levels
|
|
21
36
|
*/
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
export function createTTSToolRegistration(options = {}) {
|
|
38
|
+
const providers = { ...options.providers };
|
|
39
|
+
return {
|
|
40
|
+
toolId: "textToSpeech",
|
|
41
|
+
name: "Text to Speech",
|
|
42
|
+
description: "Read content aloud",
|
|
43
|
+
nameKey: "tools.textToSpeech.name",
|
|
44
|
+
descriptionKey: "tools.textToSpeech.description",
|
|
45
|
+
icon: "volume-up",
|
|
46
|
+
provider: {
|
|
47
|
+
createProvider: (config) => {
|
|
48
|
+
const hostProvider = selectHostProvider(config, providers);
|
|
49
|
+
if (hostProvider)
|
|
50
|
+
return new HostTTSToolProvider(hostProvider);
|
|
51
|
+
return new TTSToolProvider(resolveTTSRuntimeSettings(config).backend, {
|
|
52
|
+
loadServerProvider: loadServerTTSProvider,
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
getInitConfig: (config) => buildRuntimeTTSConfig(resolveTTSRuntimeSettings(config)),
|
|
56
|
+
getAuthFetcher: (config) => {
|
|
57
|
+
const runtimeAuthFetcher = config?.provider?.runtime?.authFetcher;
|
|
58
|
+
return typeof runtimeAuthFetcher === "function"
|
|
59
|
+
? runtimeAuthFetcher
|
|
60
|
+
: undefined;
|
|
61
|
+
},
|
|
62
|
+
lazy: true,
|
|
34
63
|
},
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
64
|
+
sanitizeConfig: (config) => {
|
|
65
|
+
const normalizedConfig = {
|
|
66
|
+
...config,
|
|
67
|
+
};
|
|
68
|
+
if ("speedOptions" in normalizedConfig) {
|
|
69
|
+
normalizedConfig.speedOptions = normalizeTTSSpeedControlOptions(normalizedConfig.speedOptions);
|
|
70
|
+
}
|
|
71
|
+
return normalizedConfig;
|
|
41
72
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
reserveSpace: hostLayout.controlsRow.reserveSpace,
|
|
96
|
-
showWhenToolActive: hostLayout.controlsRow.expandWhenToolActive,
|
|
97
|
-
},
|
|
98
|
-
headerOverlay: {
|
|
99
|
-
showWhenToolActive: hostLayout.headerOverlay.expandWhenToolActive,
|
|
73
|
+
// TTS is inline-only and scoped to item/passage contexts.
|
|
74
|
+
supportedLevels: ["item", "passage"],
|
|
75
|
+
/**
|
|
76
|
+
* Pass 2: Determine if TTS is relevant in this context
|
|
77
|
+
*
|
|
78
|
+
* TTS is relevant when the context holds readable text or a catalog idref.
|
|
79
|
+
*/
|
|
80
|
+
isVisibleInContext(context) {
|
|
81
|
+
return hasSpokenContent(context);
|
|
82
|
+
},
|
|
83
|
+
renderToolbar(context, toolbarContext) {
|
|
84
|
+
const resolveRuntimeSettings = () => resolveTTSRuntimeSettings(toolbarContext.toolkitCoordinator?.getToolConfig(this.toolId) ||
|
|
85
|
+
undefined);
|
|
86
|
+
const resolveElementSpeedOptions = () => {
|
|
87
|
+
const runtimeSettings = resolveRuntimeSettings();
|
|
88
|
+
return normalizeTTSSpeedControlOptions(runtimeSettings.speedOptions);
|
|
89
|
+
};
|
|
90
|
+
const fullToolId = createScopedToolId(this.toolId, toolbarContext.scope.level, toolbarContext.scope.scopeId);
|
|
91
|
+
const resolveControlSize = () => {
|
|
92
|
+
const raw = toolbarContext.ui?.size;
|
|
93
|
+
return raw === "sm" || raw === "lg" ? raw : "md";
|
|
94
|
+
};
|
|
95
|
+
const element = resolveOverlayElement(toolbarContext, fullToolId, () => createToolElement(this.toolId, context, toolbarContext, toolbarContext.componentOverrides));
|
|
96
|
+
const applyAttributes = () => {
|
|
97
|
+
element.setAttribute("catalog-id", toolbarContext.catalogId || toolbarContext.itemId);
|
|
98
|
+
element.setAttribute("size", resolveControlSize());
|
|
99
|
+
element.setAttribute("layout-mode", resolveRuntimeSettings().layoutMode);
|
|
100
|
+
element.speedOptions = resolveElementSpeedOptions();
|
|
101
|
+
element.showSingleSpeedOption =
|
|
102
|
+
resolveRuntimeSettings().showSingleSpeedOption === true;
|
|
103
|
+
// The element range-checks these; a non-number means the default.
|
|
104
|
+
const speech = toolbarContext.getToolParameters?.("textToSpeech");
|
|
105
|
+
element.baseRate = numberOrUndefined(speech?.rate);
|
|
106
|
+
element.pitch = numberOrUndefined(speech?.pitch);
|
|
107
|
+
element.volume = numberOrUndefined(speech?.volume);
|
|
108
|
+
};
|
|
109
|
+
applyAttributes();
|
|
110
|
+
const hostLayout = resolveTTSHostToolbarLayout(resolveRuntimeSettings());
|
|
111
|
+
return {
|
|
112
|
+
toolId: this.toolId,
|
|
113
|
+
button: null,
|
|
114
|
+
elements: [
|
|
115
|
+
{
|
|
116
|
+
element,
|
|
117
|
+
mount: "before-buttons",
|
|
118
|
+
layoutHints: {
|
|
119
|
+
controlsRow: {
|
|
120
|
+
reserveSpace: hostLayout.controlsRow.reserveSpace,
|
|
121
|
+
showWhenToolActive: hostLayout.controlsRow.expandWhenToolActive,
|
|
122
|
+
},
|
|
123
|
+
headerOverlay: {
|
|
124
|
+
showWhenToolActive: hostLayout.headerOverlay.expandWhenToolActive,
|
|
125
|
+
},
|
|
100
126
|
},
|
|
101
127
|
},
|
|
128
|
+
],
|
|
129
|
+
subscribeActive: (callback) => {
|
|
130
|
+
const handler = (event) => {
|
|
131
|
+
const detail = event.detail;
|
|
132
|
+
callback(detail?.active === true);
|
|
133
|
+
};
|
|
134
|
+
element.addEventListener(TOOL_ACTIVE_CHANGE_EVENT, handler);
|
|
135
|
+
return () => {
|
|
136
|
+
element.removeEventListener(TOOL_ACTIVE_CHANGE_EVENT, handler);
|
|
137
|
+
};
|
|
102
138
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return () => {
|
|
111
|
-
element.removeEventListener(TOOL_ACTIVE_CHANGE_EVENT, handler);
|
|
112
|
-
};
|
|
113
|
-
},
|
|
114
|
-
sync: applyAttributes,
|
|
115
|
-
};
|
|
116
|
-
},
|
|
117
|
-
};
|
|
139
|
+
sync: applyAttributes,
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/** The text-to-speech registration with the browser and server backends only. */
|
|
145
|
+
export const ttsToolRegistration = createTTSToolRegistration();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-default-tool-loaders",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Composition layer for the packaged PIE assessment tools: registrations, tag map, placement preset, universal and empty profiles, and lazy module loaders",
|
|
6
6
|
"repository": {
|
|
@@ -17,15 +17,17 @@
|
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
19
|
"types": "./dist/index.d.ts",
|
|
20
|
-
"import": "./dist/index.js"
|
|
21
|
-
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./package.json": "./package.json"
|
|
22
24
|
},
|
|
23
25
|
"files": [
|
|
24
26
|
"dist",
|
|
25
27
|
"README.md"
|
|
26
28
|
],
|
|
27
29
|
"scripts": {
|
|
28
|
-
"build": "bun run check:composition && tsc -p tsconfig.json",
|
|
30
|
+
"build": "bun run check:composition && tsc -p tsconfig.json && bun ../../scripts/prune-unreachable-declarations.mjs",
|
|
29
31
|
"check:composition": "bun test tests/packaged-capability-composition.test.ts",
|
|
30
32
|
"dev": "tsc -p tsconfig.json --watch",
|
|
31
33
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
@@ -33,29 +35,29 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@pie-players/pie-assessment-toolkit": "1.0.0-beta.
|
|
37
|
-
"@pie-players/pie-calculator": "1.0.0-beta.
|
|
38
|
-
"@pie-players/pie-calculator-
|
|
39
|
-
"@pie-players/pie-calculator-
|
|
40
|
-
"@pie-players/pie-
|
|
41
|
-
"@pie-players/pie-
|
|
42
|
-
"@pie-players/pie-tool-
|
|
43
|
-
"@pie-players/pie-tool-
|
|
44
|
-
"@pie-players/pie-tool-
|
|
45
|
-
"@pie-players/pie-tool-
|
|
46
|
-
"@pie-players/pie-tool-
|
|
47
|
-
"@pie-players/pie-tool-
|
|
48
|
-
"@pie-players/pie-tool-periodic-table": "1.0.0-beta.
|
|
49
|
-
"@pie-players/pie-tool-picture-dictionary": "1.0.0-beta.
|
|
50
|
-
"@pie-players/pie-tool-protractor": "1.0.0-beta.
|
|
51
|
-
"@pie-players/pie-tool-ruler": "1.0.0-beta.
|
|
52
|
-
"@pie-players/pie-tool-theme": "1.0.0-beta.
|
|
53
|
-
"@pie-players/pie-tool-tts-inline": "1.0.0-beta.
|
|
54
|
-
"@pie-players/tts-client-server": "1.0.0-beta.
|
|
38
|
+
"@pie-players/pie-assessment-toolkit": "1.0.0-beta.10",
|
|
39
|
+
"@pie-players/pie-calculator": "1.0.0-beta.10",
|
|
40
|
+
"@pie-players/pie-calculator-desmos": "1.0.0-beta.10",
|
|
41
|
+
"@pie-players/pie-calculator-geogebra": "1.0.0-beta.10",
|
|
42
|
+
"@pie-players/pie-players-shared": "1.0.0-beta.10",
|
|
43
|
+
"@pie-players/pie-tool-annotation-toolbar": "1.0.0-beta.10",
|
|
44
|
+
"@pie-players/pie-tool-answer-eliminator": "1.0.0-beta.10",
|
|
45
|
+
"@pie-players/pie-tool-calculator-shared": "1.0.0-beta.10",
|
|
46
|
+
"@pie-players/pie-tool-dictionary": "1.0.0-beta.10",
|
|
47
|
+
"@pie-players/pie-tool-graph": "1.0.0-beta.10",
|
|
48
|
+
"@pie-players/pie-tool-line-reader": "1.0.0-beta.10",
|
|
49
|
+
"@pie-players/pie-tool-magnifier": "1.0.0-beta.10",
|
|
50
|
+
"@pie-players/pie-tool-periodic-table": "1.0.0-beta.10",
|
|
51
|
+
"@pie-players/pie-tool-picture-dictionary": "1.0.0-beta.10",
|
|
52
|
+
"@pie-players/pie-tool-protractor": "1.0.0-beta.10",
|
|
53
|
+
"@pie-players/pie-tool-ruler": "1.0.0-beta.10",
|
|
54
|
+
"@pie-players/pie-tool-theme": "1.0.0-beta.10",
|
|
55
|
+
"@pie-players/pie-tool-tts-inline": "1.0.0-beta.10",
|
|
56
|
+
"@pie-players/tts-client-server": "1.0.0-beta.10"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
|
-
"@biomejs/biome": "^2.
|
|
58
|
-
"@happy-dom/global-registrator": "^
|
|
59
|
+
"@biomejs/biome": "^2.6.4",
|
|
60
|
+
"@happy-dom/global-registrator": "^21.0.4",
|
|
59
61
|
"typescript": "^5.9.3"
|
|
60
62
|
},
|
|
61
63
|
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/default-tool-loaders#readme",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/** Fully bundled open-source calculator adapter for the tool-provider registry. */
|
|
2
|
-
import type { CalculatorToolProviderInitConfig, LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
|
|
3
|
-
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
4
|
-
export type CortexToolProviderConfig = CalculatorToolProviderInitConfig;
|
|
5
|
-
export declare class CortexToolProvider extends LazyCalculatorToolProvider<CortexToolProviderConfig> {
|
|
6
|
-
readonly providerName = "PIE Open-Source Calculator";
|
|
7
|
-
readonly version = "1";
|
|
8
|
-
readonly requiresAuth = false;
|
|
9
|
-
protected getDefinition(): LazyCalculatorProviderDefinition<CortexToolProviderConfig>;
|
|
10
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** Fully bundled open-source calculator adapter for the tool-provider registry. */
|
|
2
|
-
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
3
|
-
export class CortexToolProvider extends LazyCalculatorToolProvider {
|
|
4
|
-
providerName = "PIE Open-Source Calculator";
|
|
5
|
-
version = "1";
|
|
6
|
-
requiresAuth = false;
|
|
7
|
-
getDefinition() {
|
|
8
|
-
return {
|
|
9
|
-
backend: "cortex",
|
|
10
|
-
moduleImportOperation: "cortex-provider-module-import",
|
|
11
|
-
loadProvider: async () => {
|
|
12
|
-
const module = await import("@pie-players/pie-calculator-cortex");
|
|
13
|
-
return module.CortexCalculatorProvider;
|
|
14
|
-
},
|
|
15
|
-
initializationErrorMessage: "Failed to initialize the PIE open-source calculator provider. Confirm that this browser supports module workers and that the bundled worker assets are available.",
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/** Desmos calculator adapter for the generic tool-provider registry. */
|
|
2
|
-
import type { CalculatorProviderInit } from "@pie-players/pie-calculator";
|
|
3
|
-
import { LazyCalculatorToolProvider, type LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
|
|
4
|
-
/** Provider initialization is the provider-neutral calculator contract. */
|
|
5
|
-
export type DesmosToolProviderConfig = CalculatorProviderInit;
|
|
6
|
-
export declare class DesmosToolProvider extends LazyCalculatorToolProvider<DesmosToolProviderConfig> {
|
|
7
|
-
readonly providerName = "Desmos Calculator";
|
|
8
|
-
readonly version = "1.12";
|
|
9
|
-
readonly requiresAuth = true;
|
|
10
|
-
protected getDefinition(): LazyCalculatorProviderDefinition<DesmosToolProviderConfig>;
|
|
11
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** Desmos calculator adapter for the generic tool-provider registry. */
|
|
2
|
-
import { LazyCalculatorToolProvider, } from "./LazyCalculatorToolProvider.js";
|
|
3
|
-
export class DesmosToolProvider extends LazyCalculatorToolProvider {
|
|
4
|
-
providerName = "Desmos Calculator";
|
|
5
|
-
version = "1.12";
|
|
6
|
-
requiresAuth = true;
|
|
7
|
-
getDefinition() {
|
|
8
|
-
return {
|
|
9
|
-
backend: "desmos",
|
|
10
|
-
moduleImportOperation: "desmos-provider-module-import",
|
|
11
|
-
loadProvider: async () => {
|
|
12
|
-
const module = await import("@pie-players/pie-calculator-desmos");
|
|
13
|
-
return module.DesmosCalculatorProvider;
|
|
14
|
-
},
|
|
15
|
-
initializationErrorMessage: "Failed to initialize Desmos calculator provider. Check the application key, preloaded API, runtime endpoint, or network access.",
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/** GeoGebra calculator adapter for the generic tool-provider registry. */
|
|
2
|
-
import type { CalculatorToolProviderInitConfig, LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
|
|
3
|
-
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
4
|
-
export interface GeoGebraToolProviderConfig extends CalculatorToolProviderInitConfig {
|
|
5
|
-
scriptUrl?: string;
|
|
6
|
-
appletTimeoutMs?: number;
|
|
7
|
-
}
|
|
8
|
-
export declare class GeoGebraToolProvider extends LazyCalculatorToolProvider<GeoGebraToolProviderConfig> {
|
|
9
|
-
readonly providerName = "GeoGebra Calculator";
|
|
10
|
-
readonly version = "6";
|
|
11
|
-
readonly requiresAuth = false;
|
|
12
|
-
protected getDefinition(): LazyCalculatorProviderDefinition<GeoGebraToolProviderConfig>;
|
|
13
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** GeoGebra calculator adapter for the generic tool-provider registry. */
|
|
2
|
-
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
3
|
-
export class GeoGebraToolProvider extends LazyCalculatorToolProvider {
|
|
4
|
-
providerName = "GeoGebra Calculator";
|
|
5
|
-
version = "6";
|
|
6
|
-
requiresAuth = false;
|
|
7
|
-
getDefinition() {
|
|
8
|
-
return {
|
|
9
|
-
backend: "geogebra",
|
|
10
|
-
moduleImportOperation: "geogebra-provider-module-import",
|
|
11
|
-
loadProvider: async () => {
|
|
12
|
-
const module = await import("@pie-players/pie-calculator-geogebra");
|
|
13
|
-
return module.GeoGebraCalculatorProvider;
|
|
14
|
-
},
|
|
15
|
-
initializationErrorMessage: "Failed to initialize GeoGebra calculator provider. Confirm that the deployment may load GeoGebra and that its script URL is reachable.",
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One overlay element per coordinator and scoped tool id, reused across renders.
|
|
3
|
-
*
|
|
4
|
-
* The toolbar re-derives its rendered tools whenever an input moves — a policy
|
|
5
|
-
* emit, a tool-config update, the interface locale — and mounts whichever
|
|
6
|
-
* element each render returns, swapping out one it has not seen. A registration
|
|
7
|
-
* that creates its overlay on every render therefore remounts it, and the
|
|
8
|
-
* learner loses the ruler's position, the graph's points or the eliminated
|
|
9
|
-
* choices while the tool stays open. Reusing the element keeps the mount a
|
|
10
|
-
* no-op, so per-render attributes are the registration's to re-apply.
|
|
11
|
-
*
|
|
12
|
-
* A Svelte custom element tears its component down once it leaves the document,
|
|
13
|
-
* so a cached element found disconnected is dropped and recreated.
|
|
14
|
-
*/
|
|
15
|
-
import type { ToolbarContext } from "@pie-players/pie-assessment-toolkit/tools/registration";
|
|
16
|
-
/** The property the toolbar calls as it unmounts a tool element. */
|
|
17
|
-
export declare const TOOL_ELEMENT_UNMOUNT_CALLBACK_PROP = "__pieToolElementUnmount";
|
|
18
|
-
/**
|
|
19
|
-
* The element cached for `fullToolId` under this toolbar's coordinator, or the
|
|
20
|
-
* one `create` returns, which is then cached. Without a coordinator there is no
|
|
21
|
-
* session to key by, and every render creates.
|
|
22
|
-
*/
|
|
23
|
-
export declare function resolveOverlayElement<T extends HTMLElement>(toolbarContext: ToolbarContext, fullToolId: string, create: () => T): T;
|