@pie-players/pie-assessment-toolkit 0.3.64 → 0.3.66
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/README.md +81 -33
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +9 -8
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-8jgdz50p.js +51 -0
- package/dist/components/chunks/ItemToolBar-cvs646j3.js +36 -0
- package/dist/index.d.ts +7 -8
- package/dist/index.js +10 -5
- package/dist/policy/core/PolicySource.d.ts +2 -2
- package/dist/policy/core/PolicySource.js +2 -2
- package/dist/policy/core/ToolPolicyEngine.d.ts +7 -3
- package/dist/policy/core/ToolPolicyEngine.js +11 -3
- package/dist/policy/core/compose-decision.d.ts +3 -2
- package/dist/policy/core/compose-decision.js +3 -2
- package/dist/policy/core/decision-types.d.ts +2 -2
- package/dist/policy/core/decision-types.js +2 -2
- package/dist/policy/core/feature-decision.d.ts +28 -1
- package/dist/policy/core/feature-decision.js +25 -3
- package/dist/policy/core/pnp-policy-inputs.d.ts +2 -2
- package/dist/policy/core/pnp-policy-inputs.js +2 -2
- package/dist/policy/core/provenance.d.ts +4 -1
- package/dist/policy/core/provenance.js +4 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +2 -1
- package/dist/policy/sources/PnpPolicySource.js +2 -1
- package/dist/runtime/composition-emit-scheduler.d.ts +78 -0
- package/dist/runtime/composition-emit-scheduler.js +154 -0
- package/dist/runtime/core/engine-resolver.d.ts +1 -1
- package/dist/runtime/core/engine-transition.js +3 -1
- package/dist/services/AccessibilityCatalogResolver.d.ts +49 -10
- package/dist/services/AccessibilityCatalogResolver.js +180 -11
- package/dist/services/TTSService.d.ts +11 -0
- package/dist/services/TTSService.js +220 -32
- package/dist/services/ToolRegistry.d.ts +259 -8
- package/dist/services/ToolRegistry.js +181 -11
- package/dist/services/ToolkitCoordinator.d.ts +20 -2
- package/dist/services/ToolkitCoordinator.js +47 -8
- package/dist/services/catalog-owner.d.ts +71 -0
- package/dist/services/catalog-owner.js +64 -0
- package/dist/services/createDefaultToolRegistry.d.ts +25 -58
- package/dist/services/createDefaultToolRegistry.js +24 -104
- package/dist/services/defaultPersonalNeedsProfile.d.ts +16 -14
- package/dist/services/defaultPersonalNeedsProfile.js +17 -38
- package/dist/services/framework-error.d.ts +1 -1
- package/dist/services/interfaces.d.ts +15 -3
- package/dist/services/pnp-standard-features.d.ts +1 -1
- package/dist/services/tool-config-defaults.d.ts +7 -23
- package/dist/services/tool-config-defaults.js +7 -46
- package/dist/services/tool-config-validation.d.ts +1 -1
- package/dist/services/tool-config-validation.js +44 -4
- package/dist/services/tts/browser-provider.js +191 -24
- package/dist/services/tts-runtime-config.js +7 -2
- package/dist/tools/internal.d.ts +35 -0
- package/dist/tools/internal.js +33 -0
- package/dist/tools/tool-tag-map.d.ts +15 -3
- package/dist/tools/tool-tag-map.js +21 -18
- package/package.json +14 -10
- package/dist/components/chunks/ItemToolBar-3cppre9r.js +0 -51
- package/dist/components/chunks/ItemToolBar-7rq2gj8b.js +0 -22
- package/dist/runtime/catalog-registration.d.ts +0 -67
- package/dist/runtime/catalog-registration.js +0 -86
- package/dist/services/sign-language-cards.d.ts +0 -82
- package/dist/services/sign-language-cards.js +0 -133
- package/dist/tools/registrations/accessibility-tools.d.ts +0 -34
- package/dist/tools/registrations/accessibility-tools.js +0 -217
- package/dist/tools/registrations/calculator.d.ts +0 -20
- package/dist/tools/registrations/calculator.js +0 -228
- package/dist/tools/registrations/interaction-tools.d.ts +0 -27
- package/dist/tools/registrations/interaction-tools.js +0 -143
- package/dist/tools/registrations/measurement-tools.d.ts +0 -24
- package/dist/tools/registrations/measurement-tools.js +0 -130
- package/dist/tools/registrations/subject-specific-tools.d.ts +0 -27
- package/dist/tools/registrations/subject-specific-tools.js +0 -158
- package/dist/tools/registrations/tts.d.ts +0 -21
- package/dist/tools/registrations/tts.js +0 -184
|
@@ -29,7 +29,8 @@ import type { SREMathSpeechOptions } from "./tts/math-speech.js";
|
|
|
29
29
|
import { ToolProviderRegistry } from "./tool-providers/index.js";
|
|
30
30
|
import type { ToolProviderApi } from "./tool-providers/ToolProviderApi.js";
|
|
31
31
|
import type { TTSToolProviderConfig } from "./tool-providers/index.js";
|
|
32
|
-
import
|
|
32
|
+
import { ToolRegistry } from "./ToolRegistry.js";
|
|
33
|
+
import type { ResolvedToolContext, ToolContextResolver, ToolContextResolverContext, ToolContextResolverMap } from "./ToolRegistry.js";
|
|
33
34
|
import { type FeaturePolicyDecision, type PnpEnforcementMode, type PolicySource, type ResolvedEngineInputs, type ToolPolicyChangeListener, type ToolPolicyDecision, type ToolPolicyDecisionRequest } from "../policy/engine.js";
|
|
34
35
|
import type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionSessionPersistenceStrategy, SectionPersistenceFactoryDefaults } from "./section-controller-types.js";
|
|
35
36
|
export type { SectionControllerContext, SectionControllerEvent, SectionControllerEventType, SectionControllerFactoryDefaults, SectionControllerHandle, SectionControllerKey, SectionControllerLoadedRenderable, SectionSessionPersistenceConfig, SectionSessionPersistenceStrategy, SectionControllerRuntimeState, SectionControllerSessionState, SectionPersistenceFactoryDefaults, } from "./section-controller-types.js";
|
|
@@ -295,7 +296,7 @@ export interface ToolkitServiceBundle {
|
|
|
295
296
|
* assessmentId: 'demo-three-questions',
|
|
296
297
|
* tools: {
|
|
297
298
|
* providers: {
|
|
298
|
-
* textToSpeech: { enabled: true,
|
|
299
|
+
* textToSpeech: { enabled: true, backend: 'browser' },
|
|
299
300
|
* answerEliminator: { enabled: true, strategy: 'strikethrough' }
|
|
300
301
|
* },
|
|
301
302
|
* placement: {
|
|
@@ -413,6 +414,17 @@ export declare class ToolkitCoordinator {
|
|
|
413
414
|
* frozen snapshot.
|
|
414
415
|
*/
|
|
415
416
|
private boundCurrentItemRef;
|
|
417
|
+
/**
|
|
418
|
+
* Whether {@link decideFeaturePolicy} has already reported serving a decision
|
|
419
|
+
* with no assessment bound.
|
|
420
|
+
*
|
|
421
|
+
* One report per coordinator, not per decision: a feature policy is consulted
|
|
422
|
+
* once per capability per card, so a per-decision warning would bury itself.
|
|
423
|
+
* Never reset — {@link updateAssessment} arriving later fixes the deployment,
|
|
424
|
+
* and re-arming would report the same gap again on the next unbound coordinator
|
|
425
|
+
* lifetime for no new information.
|
|
426
|
+
*/
|
|
427
|
+
private reportedUnboundFeaturePolicy;
|
|
416
428
|
private static resolveConfig;
|
|
417
429
|
constructor(config: ToolkitCoordinatorConfig);
|
|
418
430
|
/**
|
|
@@ -667,6 +679,12 @@ export declare class ToolkitCoordinator {
|
|
|
667
679
|
* Thin shim over the owned tool-policy engine; see
|
|
668
680
|
* {@link ToolPolicyEngine.decideFeature} for the contract, including why
|
|
669
681
|
* `pnpEnforcement` is not consulted.
|
|
682
|
+
*
|
|
683
|
+
* Reports once per coordinator when it is asked about a feature with no
|
|
684
|
+
* assessment bound. A host in that state gets a correct denial for every
|
|
685
|
+
* capability it asks about, which is indistinguishable from a student who was
|
|
686
|
+
* properly declined — so without this, forgetting {@link updateAssessment}
|
|
687
|
+
* presents as an accommodation that silently never appears.
|
|
670
688
|
*/
|
|
671
689
|
decideFeaturePolicy(featureId: string): FeaturePolicyDecision;
|
|
672
690
|
/**
|
|
@@ -25,7 +25,7 @@ import { TTSService } from "./TTSService.js";
|
|
|
25
25
|
import { BrowserTTSProvider } from "./tts/browser-provider.js";
|
|
26
26
|
import { buildRuntimeTTSConfig, resolveTTSBackend, resolveTTSRuntimeSettings, } from "./tts-runtime-config.js";
|
|
27
27
|
import { ToolProviderRegistry } from "./tool-providers/index.js";
|
|
28
|
-
import {
|
|
28
|
+
import { ToolRegistry } from "./ToolRegistry.js";
|
|
29
29
|
import { ToolPolicyEngine, } from "../policy/engine.js";
|
|
30
30
|
import { resolveDefaultPnpEnforcement } from "../policy/internal.js";
|
|
31
31
|
const isPlainRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -70,7 +70,7 @@ const SECTION_SCOPED_EVENT_TYPES = [
|
|
|
70
70
|
* assessmentId: 'demo-three-questions',
|
|
71
71
|
* tools: {
|
|
72
72
|
* providers: {
|
|
73
|
-
* textToSpeech: { enabled: true,
|
|
73
|
+
* textToSpeech: { enabled: true, backend: 'browser' },
|
|
74
74
|
* answerEliminator: { enabled: true, strategy: 'strikethrough' }
|
|
75
75
|
* },
|
|
76
76
|
* placement: {
|
|
@@ -188,9 +188,26 @@ export class ToolkitCoordinator {
|
|
|
188
188
|
* frozen snapshot.
|
|
189
189
|
*/
|
|
190
190
|
boundCurrentItemRef = null;
|
|
191
|
+
/**
|
|
192
|
+
* Whether {@link decideFeaturePolicy} has already reported serving a decision
|
|
193
|
+
* with no assessment bound.
|
|
194
|
+
*
|
|
195
|
+
* One report per coordinator, not per decision: a feature policy is consulted
|
|
196
|
+
* once per capability per card, so a per-decision warning would bury itself.
|
|
197
|
+
* Never reset — {@link updateAssessment} arriving later fixes the deployment,
|
|
198
|
+
* and re-arming would report the same gap again on the next unbound coordinator
|
|
199
|
+
* lifetime for no new information.
|
|
200
|
+
*/
|
|
201
|
+
reportedUnboundFeaturePolicy = false;
|
|
191
202
|
static resolveConfig(config) {
|
|
192
203
|
const strictness = normalizeToolConfigStrictness(config.toolConfigStrictness);
|
|
193
|
-
|
|
204
|
+
// An empty registry when the host supplies none. This package no longer
|
|
205
|
+
// holds the packaged capability set, so there is nothing to fall back to —
|
|
206
|
+
// a host that wants stock tools passes a registry from
|
|
207
|
+
// `@pie-players/pie-default-tool-loaders`. Tool-id validation is skipped
|
|
208
|
+
// against an empty registry (with a diagnostic saying so) rather than
|
|
209
|
+
// rejecting every configured id.
|
|
210
|
+
const toolRegistry = config.toolRegistry ?? new ToolRegistry();
|
|
194
211
|
const normalized = config.deferToolConfigValidation === true
|
|
195
212
|
? normalizeToolsConfig(config.tools)
|
|
196
213
|
: normalizeAndValidateToolsConfig(config.tools, {
|
|
@@ -232,8 +249,7 @@ export class ToolkitCoordinator {
|
|
|
232
249
|
const resolvedConfig = ToolkitCoordinator.resolveConfig(config);
|
|
233
250
|
this.assessmentId = resolvedConfig.assessmentId;
|
|
234
251
|
this.config = resolvedConfig;
|
|
235
|
-
this.toolRegistry =
|
|
236
|
-
resolvedConfig.toolRegistry ?? createPackagedToolRegistry();
|
|
252
|
+
this.toolRegistry = resolvedConfig.toolRegistry ?? new ToolRegistry();
|
|
237
253
|
this.installToolContextResolvers(resolvedConfig.toolContextResolvers);
|
|
238
254
|
this.hooks = resolvedConfig.hooks ?? {};
|
|
239
255
|
this.lazyInit = config.lazyInit === true;
|
|
@@ -1268,13 +1284,16 @@ export class ToolkitCoordinator {
|
|
|
1268
1284
|
if (canUseEventTarget) {
|
|
1269
1285
|
synth.removeEventListener("voiceschanged", onVoicesChanged);
|
|
1270
1286
|
}
|
|
1271
|
-
else if (assignedHandler &&
|
|
1287
|
+
else if (assignedHandler &&
|
|
1288
|
+
synth.onvoiceschanged === onVoicesChanged) {
|
|
1272
1289
|
synth.onvoiceschanged = previousHandler;
|
|
1273
1290
|
}
|
|
1274
1291
|
resolve();
|
|
1275
1292
|
};
|
|
1276
1293
|
const onVoicesChanged = (event) => {
|
|
1277
|
-
if (!canUseEventTarget &&
|
|
1294
|
+
if (!canUseEventTarget &&
|
|
1295
|
+
typeof previousHandler === "function" &&
|
|
1296
|
+
event) {
|
|
1278
1297
|
previousHandler.call(synth, event);
|
|
1279
1298
|
}
|
|
1280
1299
|
finish();
|
|
@@ -1371,6 +1390,15 @@ export class ToolkitCoordinator {
|
|
|
1371
1390
|
if (toolId === "tts") {
|
|
1372
1391
|
throw new Error(`Tool id "tts" is no longer supported. Use "textToSpeech".`);
|
|
1373
1392
|
}
|
|
1393
|
+
// An empty registry means the host supplied none, not that every id is
|
|
1394
|
+
// wrong. There is nothing to check an id against, and throwing turns a
|
|
1395
|
+
// host's every tool-config call into an exception — including the calls
|
|
1396
|
+
// this coordinator's own default-provider block provokes, which is how a
|
|
1397
|
+
// host that passes no registry ended up unable to read its own config.
|
|
1398
|
+
// `normalizeAndValidateToolsConfig` already reports the missing registry
|
|
1399
|
+
// once, as `tools.registryUnavailable`; a second report per call is noise.
|
|
1400
|
+
if (this.toolRegistry.getAllToolIds().length === 0)
|
|
1401
|
+
return;
|
|
1374
1402
|
if (!this.toolRegistry.get(toolId)) {
|
|
1375
1403
|
throw new Error(`Unknown tool id "${toolId}".`);
|
|
1376
1404
|
}
|
|
@@ -1525,9 +1553,20 @@ export class ToolkitCoordinator {
|
|
|
1525
1553
|
* Thin shim over the owned tool-policy engine; see
|
|
1526
1554
|
* {@link ToolPolicyEngine.decideFeature} for the contract, including why
|
|
1527
1555
|
* `pnpEnforcement` is not consulted.
|
|
1556
|
+
*
|
|
1557
|
+
* Reports once per coordinator when it is asked about a feature with no
|
|
1558
|
+
* assessment bound. A host in that state gets a correct denial for every
|
|
1559
|
+
* capability it asks about, which is indistinguishable from a student who was
|
|
1560
|
+
* properly declined — so without this, forgetting {@link updateAssessment}
|
|
1561
|
+
* presents as an accommodation that silently never appears.
|
|
1528
1562
|
*/
|
|
1529
1563
|
decideFeaturePolicy(featureId) {
|
|
1530
|
-
|
|
1564
|
+
const decision = this.policyEngine.decideFeature(featureId);
|
|
1565
|
+
if (!decision.assessmentBound && !this.reportedUnboundFeaturePolicy) {
|
|
1566
|
+
this.reportedUnboundFeaturePolicy = true;
|
|
1567
|
+
console.warn(`[ToolkitCoordinator] Feature policy was asked about "${featureId}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);
|
|
1568
|
+
}
|
|
1569
|
+
return decision;
|
|
1531
1570
|
}
|
|
1532
1571
|
/**
|
|
1533
1572
|
* Subscribe to policy-engine change events. Fires whenever the
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity and traversal rules for one mounted accessibility-catalog owner.
|
|
3
|
+
*
|
|
4
|
+
* The resolver is the public lifecycle boundary. This supporting module keeps
|
|
5
|
+
* its owner identity and direct-lookup helper separate from the runtime event
|
|
6
|
+
* adapter, while keeping the entity walk private to the resolver package.
|
|
7
|
+
*/
|
|
8
|
+
import type { AccessibilityCatalog } from "@pie-players/pie-players-shared/types";
|
|
9
|
+
export type CatalogOwnerKind = "global" | "passage" | "itemModel";
|
|
10
|
+
interface CatalogOwnerScopeContext {
|
|
11
|
+
assessmentId?: string;
|
|
12
|
+
sectionId?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A valid resolver scope for a global, passage, or item/model owner. */
|
|
15
|
+
export type CatalogOwnerContext = (CatalogOwnerScopeContext & {
|
|
16
|
+
ownerKind: "global";
|
|
17
|
+
canonicalItemId?: never;
|
|
18
|
+
itemId?: never;
|
|
19
|
+
passageId?: never;
|
|
20
|
+
modelId?: never;
|
|
21
|
+
}) | (CatalogOwnerScopeContext & {
|
|
22
|
+
ownerKind: "passage";
|
|
23
|
+
passageId: string;
|
|
24
|
+
canonicalItemId?: never;
|
|
25
|
+
itemId?: never;
|
|
26
|
+
modelId?: never;
|
|
27
|
+
}) | (CatalogOwnerScopeContext & {
|
|
28
|
+
ownerKind: "itemModel";
|
|
29
|
+
itemId: string;
|
|
30
|
+
canonicalItemId?: string;
|
|
31
|
+
modelId?: string;
|
|
32
|
+
passageId?: never;
|
|
33
|
+
});
|
|
34
|
+
export interface CatalogOwnerRegistrationEntry {
|
|
35
|
+
context: CatalogOwnerContext;
|
|
36
|
+
catalogs: AccessibilityCatalog[];
|
|
37
|
+
}
|
|
38
|
+
/** The entity shape catalogs hang off: an item, or a passage. */
|
|
39
|
+
export interface CatalogSourceEntity {
|
|
40
|
+
accessibilityCatalogs?: AccessibilityCatalog[];
|
|
41
|
+
config?: {
|
|
42
|
+
extractedCatalogs?: AccessibilityCatalog[];
|
|
43
|
+
models?: Array<{
|
|
44
|
+
id?: string;
|
|
45
|
+
accessibilityCatalogs?: AccessibilityCatalog[];
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Who is rendering the entity — everything owner scoping is derived from. */
|
|
50
|
+
export interface CatalogOwnerIdentity {
|
|
51
|
+
kind: "item" | "passage";
|
|
52
|
+
/** The rendered instance id. */
|
|
53
|
+
itemId: string;
|
|
54
|
+
canonicalItemId?: string;
|
|
55
|
+
assessmentId?: string;
|
|
56
|
+
sectionId?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build the lookup context for a direct resolver client such as inline TTS.
|
|
60
|
+
*
|
|
61
|
+
* Owner registration uses the same function, so direct readers cannot drift
|
|
62
|
+
* from the context the resolver files the entity under.
|
|
63
|
+
*/
|
|
64
|
+
export declare function catalogOwnerContextFor(owner: CatalogOwnerIdentity): CatalogOwnerContext;
|
|
65
|
+
/**
|
|
66
|
+
* Collect every catalog group carried by one owner in registration-precedence
|
|
67
|
+
* order. This is deliberately not exported from the package root: callers
|
|
68
|
+
* register the owner once through `AccessibilityCatalogResolver.registerOwner`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function collectOwnerCatalogRegistrations(entity: CatalogSourceEntity | null | undefined, owner: CatalogOwnerIdentity): CatalogOwnerRegistrationEntry[];
|
|
71
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity and traversal rules for one mounted accessibility-catalog owner.
|
|
3
|
+
*
|
|
4
|
+
* The resolver is the public lifecycle boundary. This supporting module keeps
|
|
5
|
+
* its owner identity and direct-lookup helper separate from the runtime event
|
|
6
|
+
* adapter, while keeping the entity walk private to the resolver package.
|
|
7
|
+
*/
|
|
8
|
+
const hasCatalogs = (catalogs) => Array.isArray(catalogs) && catalogs.length > 0;
|
|
9
|
+
/**
|
|
10
|
+
* Build the lookup context for a direct resolver client such as inline TTS.
|
|
11
|
+
*
|
|
12
|
+
* Owner registration uses the same function, so direct readers cannot drift
|
|
13
|
+
* from the context the resolver files the entity under.
|
|
14
|
+
*/
|
|
15
|
+
export function catalogOwnerContextFor(owner) {
|
|
16
|
+
if (owner.kind === "passage") {
|
|
17
|
+
return {
|
|
18
|
+
ownerKind: "passage",
|
|
19
|
+
assessmentId: owner.assessmentId,
|
|
20
|
+
sectionId: owner.sectionId,
|
|
21
|
+
passageId: owner.canonicalItemId || owner.itemId,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
ownerKind: "itemModel",
|
|
26
|
+
assessmentId: owner.assessmentId,
|
|
27
|
+
sectionId: owner.sectionId,
|
|
28
|
+
itemId: owner.itemId,
|
|
29
|
+
canonicalItemId: owner.canonicalItemId || owner.itemId,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Collect every catalog group carried by one owner in registration-precedence
|
|
34
|
+
* order. This is deliberately not exported from the package root: callers
|
|
35
|
+
* register the owner once through `AccessibilityCatalogResolver.registerOwner`.
|
|
36
|
+
*/
|
|
37
|
+
export function collectOwnerCatalogRegistrations(entity, owner) {
|
|
38
|
+
if (!entity)
|
|
39
|
+
return [];
|
|
40
|
+
const context = catalogOwnerContextFor(owner);
|
|
41
|
+
const registrations = [];
|
|
42
|
+
if (hasCatalogs(entity.accessibilityCatalogs)) {
|
|
43
|
+
registrations.push({ context, catalogs: entity.accessibilityCatalogs });
|
|
44
|
+
}
|
|
45
|
+
if (hasCatalogs(entity.config?.extractedCatalogs)) {
|
|
46
|
+
registrations.push({
|
|
47
|
+
context,
|
|
48
|
+
catalogs: entity.config.extractedCatalogs,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (owner.kind === "passage")
|
|
52
|
+
return registrations;
|
|
53
|
+
if (context.ownerKind !== "itemModel")
|
|
54
|
+
return registrations;
|
|
55
|
+
for (const model of entity.config?.models ?? []) {
|
|
56
|
+
if (!hasCatalogs(model.accessibilityCatalogs))
|
|
57
|
+
continue;
|
|
58
|
+
registrations.push({
|
|
59
|
+
context: { ...context, modelId: model.id },
|
|
60
|
+
catalogs: model.accessibilityCatalogs,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return registrations;
|
|
64
|
+
}
|
|
@@ -1,86 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Tool Registry Factory
|
|
3
3
|
*
|
|
4
|
-
* Creates
|
|
5
|
-
*
|
|
4
|
+
* Creates an empty `ToolRegistry` and installs whatever component overrides and
|
|
5
|
+
* lazy module loaders the caller supplies.
|
|
6
|
+
*
|
|
7
|
+
* It registers nothing by itself, deliberately. Eleven concrete registrations
|
|
8
|
+
* used to live in this package, which made the policy and registry core know
|
|
9
|
+
* every capability by name and left a host unable to contribute one without a PR
|
|
10
|
+
* against this package. The packaged set now lives in the composition layer:
|
|
11
|
+
* `createPackagedToolRegistry` from `@pie-players/pie-default-tool-loaders`.
|
|
6
12
|
*/
|
|
13
|
+
import type { ToolRegistration, ToolModuleLoader } from "./ToolRegistry.js";
|
|
7
14
|
import { ToolRegistry } from "./ToolRegistry.js";
|
|
8
|
-
import type {
|
|
9
|
-
import
|
|
10
|
-
import { type ToolComponentFactory, type ToolComponentFactoryMap, type ToolTagMap } from "../tools/tool-tag-map.js";
|
|
11
|
-
import { DEFAULT_TOOL_PLACEMENT, PACKAGED_TOOL_PLACEMENT, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT } from "./tool-config-defaults.js";
|
|
15
|
+
import type { ToolComponentFactory, ToolComponentFactoryMap, ToolTagMap } from "../tools/tool-tag-map.js";
|
|
16
|
+
import { DEFAULT_TOOL_PLACEMENT } from "./tool-config-defaults.js";
|
|
12
17
|
export interface DefaultToolRegistryOptions {
|
|
13
18
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
19
|
+
* Registrations to register, keyed by toolId. Nothing is registered when this
|
|
20
|
+
* is absent.
|
|
16
21
|
*/
|
|
17
|
-
|
|
22
|
+
registrations?: Partial<Record<string, ToolRegistration>>;
|
|
18
23
|
/**
|
|
19
|
-
*
|
|
24
|
+
* Element tag mapping for the registrations being installed. There is no
|
|
25
|
+
* built-in default: a tag map names capabilities, so it belongs to whoever
|
|
26
|
+
* decides which capabilities exist.
|
|
20
27
|
*/
|
|
21
28
|
toolTagMap?: Partial<ToolTagMap>;
|
|
22
29
|
/**
|
|
23
|
-
* Override component
|
|
30
|
+
* Override component creation globally (all tools) or per tool.
|
|
24
31
|
*/
|
|
25
32
|
toolComponentFactory?: ToolComponentFactory;
|
|
26
33
|
toolComponentFactories?: Partial<ToolComponentFactoryMap>;
|
|
27
34
|
/**
|
|
28
35
|
* Optional lazy module loaders keyed by toolId.
|
|
29
|
-
* Hosts can inject default loaders from an external package.
|
|
30
36
|
*/
|
|
31
37
|
toolModuleLoaders?: Partial<Record<string, ToolModuleLoader>>;
|
|
32
|
-
/**
|
|
33
|
-
* Register packaged PIE tools by default.
|
|
34
|
-
*
|
|
35
|
-
* @default false
|
|
36
|
-
*/
|
|
37
|
-
includePackagedTools?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Restrict registration to specific packaged tool IDs.
|
|
40
|
-
* Ignored when includePackagedTools is false.
|
|
41
|
-
*/
|
|
42
|
-
toolIds?: string[];
|
|
43
38
|
}
|
|
44
39
|
/**
|
|
45
40
|
* Create a tool registry.
|
|
46
41
|
*
|
|
47
|
-
*
|
|
48
|
-
* For convenience, pass { includePackagedTools: true } to register all packaged tools,
|
|
49
|
-
* or use createPackagedToolRegistry().
|
|
50
|
-
*
|
|
51
|
-
* @returns ToolRegistry with all default tools
|
|
42
|
+
* @returns an empty `ToolRegistry` unless `registrations` is supplied
|
|
52
43
|
*/
|
|
53
44
|
export declare function createDefaultToolRegistry(options?: DefaultToolRegistryOptions): ToolRegistry;
|
|
54
|
-
export interface RegisterPackagedToolsOptions {
|
|
55
|
-
toolIds?: string[];
|
|
56
|
-
applyOverrides?: (registration: ToolRegistration) => ToolRegistration;
|
|
57
|
-
}
|
|
58
45
|
/**
|
|
59
|
-
*
|
|
60
|
-
*/
|
|
61
|
-
export declare function registerPackagedTools(registry: ToolRegistry, options?: RegisterPackagedToolsOptions): void;
|
|
62
|
-
/**
|
|
63
|
-
* Convenience factory that registers all packaged PIE tools.
|
|
64
|
-
*/
|
|
65
|
-
export declare function createPackagedToolRegistry(options?: Omit<DefaultToolRegistryOptions, "includePackagedTools">): ToolRegistry;
|
|
66
|
-
/**
|
|
67
|
-
* Default tool placement configuration
|
|
46
|
+
* Placement configuration with every level empty.
|
|
68
47
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* - Global tools: theme (assessment/section level)
|
|
74
|
-
* - Context-smart: calculator, graph, periodicTable (item/element, auto-detect)
|
|
75
|
-
* - Reading aids: textToSpeech, lineReader, annotationToolbar (where text exists)
|
|
76
|
-
* - Interaction-specific: answerEliminator (choice questions), highlighter (text)
|
|
77
|
-
* - Measurement: ruler, protractor (element level, diagram/geometry)
|
|
48
|
+
* The only placement default this package can hold: a populated one would name
|
|
49
|
+
* capabilities. `PACKAGED_TOOL_PLACEMENT` and
|
|
50
|
+
* `SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT` are in
|
|
51
|
+
* `@pie-players/pie-default-tool-loaders`.
|
|
78
52
|
*/
|
|
79
53
|
export { DEFAULT_TOOL_PLACEMENT };
|
|
80
|
-
export { PACKAGED_TOOL_PLACEMENT };
|
|
81
|
-
export { SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT };
|
|
82
|
-
/**
|
|
83
|
-
* Tool priority order for rendering
|
|
84
|
-
* Tools will be rendered in this order when multiple tools are visible
|
|
85
|
-
*/
|
|
86
|
-
export declare const DEFAULT_TOOL_ORDER: readonly ["theme", "calculator", "textToSpeech", "lineReader", "annotationToolbar", "highlighter", "answerEliminator", "ruler", "protractor", "graph", "periodicTable"];
|
|
@@ -1,125 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Tool Registry Factory
|
|
3
3
|
*
|
|
4
|
-
* Creates
|
|
5
|
-
*
|
|
4
|
+
* Creates an empty `ToolRegistry` and installs whatever component overrides and
|
|
5
|
+
* lazy module loaders the caller supplies.
|
|
6
|
+
*
|
|
7
|
+
* It registers nothing by itself, deliberately. Eleven concrete registrations
|
|
8
|
+
* used to live in this package, which made the policy and registry core know
|
|
9
|
+
* every capability by name and left a host unable to contribute one without a PR
|
|
10
|
+
* against this package. The packaged set now lives in the composition layer:
|
|
11
|
+
* `createPackagedToolRegistry` from `@pie-players/pie-default-tool-loaders`.
|
|
6
12
|
*/
|
|
7
13
|
import { ToolRegistry } from "./ToolRegistry.js";
|
|
8
|
-
import {
|
|
9
|
-
import { ttsToolRegistration } from "../tools/registrations/tts.js";
|
|
10
|
-
import { rulerToolRegistration, protractorToolRegistration, } from "../tools/registrations/measurement-tools.js";
|
|
11
|
-
import { answerEliminatorToolRegistration, highlighterToolRegistration, } from "../tools/registrations/interaction-tools.js";
|
|
12
|
-
import { lineReaderToolRegistration, themeToolRegistration, annotationToolbarRegistration, } from "../tools/registrations/accessibility-tools.js";
|
|
13
|
-
import { graphToolRegistration, periodicTableToolRegistration, } from "../tools/registrations/subject-specific-tools.js";
|
|
14
|
-
import { DEFAULT_TOOL_TAG_MAP, } from "../tools/tool-tag-map.js";
|
|
15
|
-
import { DEFAULT_TOOL_PLACEMENT, PACKAGED_TOOL_PLACEMENT, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, } from "./tool-config-defaults.js";
|
|
16
|
-
const PACKAGED_TOOL_REGISTRATIONS = [
|
|
17
|
-
calculatorToolRegistration,
|
|
18
|
-
ttsToolRegistration,
|
|
19
|
-
rulerToolRegistration,
|
|
20
|
-
protractorToolRegistration,
|
|
21
|
-
answerEliminatorToolRegistration,
|
|
22
|
-
highlighterToolRegistration,
|
|
23
|
-
lineReaderToolRegistration,
|
|
24
|
-
themeToolRegistration,
|
|
25
|
-
annotationToolbarRegistration,
|
|
26
|
-
graphToolRegistration,
|
|
27
|
-
periodicTableToolRegistration,
|
|
28
|
-
];
|
|
14
|
+
import { DEFAULT_TOOL_PLACEMENT } from "./tool-config-defaults.js";
|
|
29
15
|
/**
|
|
30
16
|
* Create a tool registry.
|
|
31
17
|
*
|
|
32
|
-
*
|
|
33
|
-
* For convenience, pass { includePackagedTools: true } to register all packaged tools,
|
|
34
|
-
* or use createPackagedToolRegistry().
|
|
35
|
-
*
|
|
36
|
-
* @returns ToolRegistry with all default tools
|
|
18
|
+
* @returns an empty `ToolRegistry` unless `registrations` is supplied
|
|
37
19
|
*/
|
|
38
20
|
export function createDefaultToolRegistry(options = {}) {
|
|
39
21
|
const registry = new ToolRegistry();
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
...(options.toolTagMap || {}),
|
|
44
|
-
},
|
|
45
|
-
toolComponentFactory: options.toolComponentFactory,
|
|
46
|
-
toolComponentFactories: options.toolComponentFactories,
|
|
47
|
-
};
|
|
48
|
-
const applyOverrides = (registration) => options.overrides?.[registration.toolId] || registration;
|
|
49
|
-
if (options.includePackagedTools) {
|
|
50
|
-
registerPackagedTools(registry, {
|
|
51
|
-
toolIds: options.toolIds,
|
|
52
|
-
applyOverrides,
|
|
53
|
-
});
|
|
22
|
+
for (const registration of Object.values(options.registrations ?? {})) {
|
|
23
|
+
if (registration)
|
|
24
|
+
registry.register(registration);
|
|
54
25
|
}
|
|
55
26
|
if (options.toolModuleLoaders &&
|
|
56
27
|
Object.keys(options.toolModuleLoaders).length > 0) {
|
|
57
28
|
registry.setToolModuleLoaders(options.toolModuleLoaders);
|
|
58
29
|
}
|
|
59
|
-
registry.setComponentOverrides(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
* Register packaged PIE tools onto an existing registry.
|
|
64
|
-
*/
|
|
65
|
-
export function registerPackagedTools(registry, options = {}) {
|
|
66
|
-
const selectedToolIds = options.toolIds && options.toolIds.length > 0
|
|
67
|
-
? new Set(options.toolIds)
|
|
68
|
-
: null;
|
|
69
|
-
const applyOverrides = options.applyOverrides ||
|
|
70
|
-
((registration) => registration);
|
|
71
|
-
for (const registration of PACKAGED_TOOL_REGISTRATIONS) {
|
|
72
|
-
if (selectedToolIds && !selectedToolIds.has(registration.toolId)) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
registry.register(applyOverrides(registration));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Convenience factory that registers all packaged PIE tools.
|
|
80
|
-
*/
|
|
81
|
-
export function createPackagedToolRegistry(options = {}) {
|
|
82
|
-
return createDefaultToolRegistry({
|
|
83
|
-
...options,
|
|
84
|
-
includePackagedTools: true,
|
|
30
|
+
registry.setComponentOverrides({
|
|
31
|
+
toolTagMap: options.toolTagMap,
|
|
32
|
+
toolComponentFactory: options.toolComponentFactory,
|
|
33
|
+
toolComponentFactories: options.toolComponentFactories,
|
|
85
34
|
});
|
|
35
|
+
return registry;
|
|
86
36
|
}
|
|
87
37
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* Defines which tools appear at which levels by default.
|
|
91
|
-
* Integrators can override this configuration.
|
|
38
|
+
* Placement configuration with every level empty.
|
|
92
39
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* -
|
|
97
|
-
* - Interaction-specific: answerEliminator (choice questions), highlighter (text)
|
|
98
|
-
* - Measurement: ruler, protractor (element level, diagram/geometry)
|
|
40
|
+
* The only placement default this package can hold: a populated one would name
|
|
41
|
+
* capabilities. `PACKAGED_TOOL_PLACEMENT` and
|
|
42
|
+
* `SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT` are in
|
|
43
|
+
* `@pie-players/pie-default-tool-loaders`.
|
|
99
44
|
*/
|
|
100
45
|
export { DEFAULT_TOOL_PLACEMENT };
|
|
101
|
-
export { PACKAGED_TOOL_PLACEMENT };
|
|
102
|
-
export { SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT };
|
|
103
|
-
/**
|
|
104
|
-
* Tool priority order for rendering
|
|
105
|
-
* Tools will be rendered in this order when multiple tools are visible
|
|
106
|
-
*/
|
|
107
|
-
export const DEFAULT_TOOL_ORDER = [
|
|
108
|
-
// Global accessibility first
|
|
109
|
-
"theme",
|
|
110
|
-
// Common tools
|
|
111
|
-
"calculator",
|
|
112
|
-
"textToSpeech",
|
|
113
|
-
// Reading aids
|
|
114
|
-
"lineReader",
|
|
115
|
-
"annotationToolbar",
|
|
116
|
-
"highlighter",
|
|
117
|
-
// Interaction tools
|
|
118
|
-
"answerEliminator",
|
|
119
|
-
// Measurement tools
|
|
120
|
-
"ruler",
|
|
121
|
-
"protractor",
|
|
122
|
-
// Subject-specific
|
|
123
|
-
"graph",
|
|
124
|
-
"periodicTable",
|
|
125
|
-
];
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import type { PersonalNeedsProfile } from "@pie-players/pie-players-shared/types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* An empty personal-needs profile: nothing granted, nothing prohibited, nothing
|
|
4
|
+
* activated at init.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* tool's `pnpSupportIds`, which
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
6
|
+
* The core ships no populated default on purpose. It once derived one from every
|
|
7
|
+
* registered tool's `pnpSupportIds`, which read *registry membership* as
|
|
8
|
+
* *eligibility tier* — registration means "policy-addressable", not "universal,
|
|
9
|
+
* on by default" — so an accommodation-tier capability was granted to every
|
|
10
|
+
* student of every host that supplied no profile. The remedy at the time was a
|
|
11
|
+
* compile-time list of ids to exclude, which a host could not extend for its own
|
|
12
|
+
* accommodation.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* Which capabilities a deployment grants by default is a property of the
|
|
15
|
+
* program, not of this package: TTS is a universal feature in one program and a
|
|
16
|
+
* documented accommodation in another. That belongs in policy configuration
|
|
17
|
+
* alongside the district and test-administration levels. A named preset of
|
|
18
|
+
* today's universal set ships as data from
|
|
19
|
+
* `@pie-players/pie-default-tool-loaders`, for hosts that want it.
|
|
16
20
|
*/
|
|
17
|
-
export declare
|
|
18
|
-
export declare const DEFAULT_PERSONAL_NEEDS_PROFILE: PersonalNeedsProfile;
|
|
19
|
-
export declare function createDefaultPersonalNeedsProfile(): PersonalNeedsProfile;
|
|
21
|
+
export declare function createEmptyPersonalNeedsProfile(): PersonalNeedsProfile;
|