@pie-players/pie-assessment-toolkit 0.3.75 → 1.0.0-beta.1
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 +451 -541
- package/custom-elements.json +1315 -0
- package/dist/attempt/TestSession.d.ts +0 -1
- package/dist/attempt/TestSession.js +10 -5
- package/dist/components/ItemScope.custom-element.js +1 -1
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +8 -8
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/{ItemToolBar-7tt7v2xp.js → ItemToolBar-3zrc4p3d.js} +4 -4
- package/dist/components/chunks/{ItemToolBar-jx38w99s.js → ItemToolBar-66hcwmfw.js} +2 -2
- package/dist/components/chunks/ItemToolBar-asenkvx6.js +40 -0
- package/dist/components/chunks/ItemToolBar-hzc5wyjp.js +2 -0
- package/dist/components/chunks/{ItemToolBar-97hx60z4.js → ItemToolBar-kkj69ptr.js} +1 -1
- package/dist/components/chunks/sre-engine-bj997w4b.js +1 -0
- package/dist/context/assessment-toolkit-context.d.ts +6 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +4 -10
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +46 -7
- package/dist/policy/core/ToolPolicyEngine.js +73 -16
- package/dist/policy/core/compose-decision.d.ts +3 -3
- package/dist/policy/core/compose-decision.js +32 -30
- package/dist/policy/core/decision-types.d.ts +51 -34
- package/dist/policy/core/feature-decision.d.ts +17 -15
- package/dist/policy/core/feature-decision.js +11 -13
- package/dist/policy/core/pnp-policy-inputs.d.ts +7 -3
- package/dist/policy/core/pnp-policy-inputs.js +17 -33
- package/dist/policy/core/provenance.d.ts +2 -2
- package/dist/policy/core/tool-parameters.d.ts +12 -0
- package/dist/policy/core/tool-parameters.js +27 -0
- package/dist/policy/engine.d.ts +1 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +18 -24
- package/dist/policy/sources/PnpPolicySource.js +57 -29
- package/dist/runtime/SectionControllerBinding.d.ts +6 -2
- package/dist/runtime/SectionControllerBinding.js +21 -15
- package/dist/runtime/adapter/subscriber-fanout.d.ts +0 -1
- package/dist/runtime/adapter/subscriber-fanout.js +1 -4
- package/dist/runtime/composition-emit-scheduler.d.ts +3 -3
- package/dist/runtime/composition-emit-scheduler.js +1 -1
- package/dist/runtime/content-region.d.ts +0 -4
- package/dist/runtime/content-region.js +2 -2
- package/dist/runtime/core/SectionEngineCore.d.ts +0 -2
- package/dist/runtime/core/SectionEngineCore.js +0 -4
- package/dist/runtime/core/cohort.d.ts +0 -5
- package/dist/runtime/core/cohort.js +0 -9
- package/dist/runtime/core/engine-output.d.ts +3 -2
- package/dist/runtime/core/engine-transition.js +3 -2
- package/dist/runtime/registration-events.d.ts +11 -14
- package/dist/runtime/runtime-id.d.ts +1 -1
- package/dist/runtime/runtime-id.js +1 -1
- package/dist/runtime/shell-scope.d.ts +4 -4
- package/dist/runtime/shell-scope.js +15 -9
- package/dist/runtime/tool-host-contract.d.ts +0 -4
- package/dist/runtime/tool-host-contract.js +1 -1
- package/dist/services/AccessibilityCatalogResolver.d.ts +21 -31
- package/dist/services/AccessibilityCatalogResolver.js +29 -42
- package/dist/services/ElementToolStateStore.d.ts +32 -61
- package/dist/services/ElementToolStateStore.js +37 -67
- package/dist/services/HighlightCoordinator.d.ts +9 -21
- package/dist/services/HighlightCoordinator.js +52 -80
- package/dist/services/RangeSerializer.d.ts +4 -35
- package/dist/services/RangeSerializer.js +4 -48
- package/dist/services/SSMLExtractor.d.ts +8 -31
- package/dist/services/SSMLExtractor.js +18 -40
- package/dist/services/TTSService.d.ts +51 -57
- package/dist/services/TTSService.js +323 -284
- package/dist/services/ToolCoordinator.d.ts +6 -49
- package/dist/services/ToolCoordinator.js +25 -61
- package/dist/services/ToolRegistry.d.ts +83 -80
- package/dist/services/ToolRegistry.js +91 -67
- package/dist/services/ToolkitCoordinator.d.ts +83 -81
- package/dist/services/ToolkitCoordinator.js +186 -174
- package/dist/services/framework-error.d.ts +30 -7
- package/dist/services/framework-error.js +10 -13
- package/dist/services/interfaces.d.ts +51 -71
- package/dist/services/section-controller-types.d.ts +7 -7
- package/dist/services/section-session-assignment.js +6 -8
- package/dist/services/spoken-audio-cards.d.ts +2 -4
- package/dist/services/spoken-audio-cards.js +2 -4
- package/dist/services/tool-config-validation.d.ts +5 -7
- package/dist/services/tool-config-validation.js +11 -26
- package/dist/services/tool-context.d.ts +39 -24
- package/dist/services/tool-context.js +158 -92
- package/dist/services/tool-failure.d.ts +30 -0
- package/dist/services/tool-failure.js +11 -0
- package/dist/services/tool-icons.d.ts +1 -2
- package/dist/services/tool-icons.js +2 -2
- package/dist/services/tool-instance-id.d.ts +8 -6
- package/dist/services/tool-instance-id.js +12 -18
- package/dist/services/tool-providers/TTSToolProvider.d.ts +6 -43
- package/dist/services/tool-providers/TTSToolProvider.js +7 -63
- package/dist/services/tool-providers/ToolProviderApi.d.ts +0 -7
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +7 -42
- package/dist/services/tool-providers/ToolProviderRegistry.js +21 -63
- package/dist/services/tool-request.d.ts +4 -0
- package/dist/services/tool-request.js +7 -2
- package/dist/services/toolbar-decided-tools.d.ts +2 -0
- package/dist/services/toolbar-decided-tools.js +2 -0
- package/dist/services/toolbar-items.js +2 -5
- package/dist/services/tools-config-normalizer.d.ts +18 -9
- package/dist/services/tools-config-normalizer.js +25 -19
- package/dist/services/tts/browser-provider.d.ts +2 -5
- package/dist/services/tts/browser-provider.js +13 -22
- package/dist/services/tts/catalog-span-alignment.js +14 -7
- package/dist/services/tts/flat-tree.d.ts +0 -7
- package/dist/services/tts/flat-tree.js +2 -2
- package/dist/services/tts/generated-speech/dom/to-chunk-inputs.d.ts +2 -2
- package/dist/services/tts/generated-speech/index.d.ts +1 -1
- package/dist/services/tts/generated-speech/index.js +1 -1
- package/dist/services/tts/generated-speech/types.d.ts +1 -1
- package/dist/services/tts/generated-speech/types.js +1 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +10 -12
- package/dist/services/tts/highlight-target-resolver.d.ts +12 -0
- package/dist/services/tts/math-aware-text-processing.js +10 -29
- package/dist/services/tts/math-speech.d.ts +1 -1
- package/dist/services/tts/math-speech.js +3 -0
- package/dist/services/tts/mathml-sanitization.d.ts +7 -0
- package/dist/services/tts/mathml-sanitization.js +9 -1
- package/dist/services/tts/provider-options.d.ts +12 -1
- package/dist/services/tts/ssml/spoken-text.js +1 -1
- package/dist/services/tts/start-failure.d.ts +0 -7
- package/dist/services/tts/start-failure.js +1 -1
- package/dist/services/tts/text-segmentation.d.ts +5 -0
- package/dist/services/tts/text-segmentation.js +13 -10
- package/dist/services/tts-runtime-config.d.ts +32 -12
- package/dist/services/tts-runtime-config.js +14 -20
- package/dist/tools/content-capability-resolution.d.ts +2 -2
- package/dist/tools/registration.d.ts +7 -6
- package/dist/tools/registration.js +10 -9
- package/dist/tools/registrations/toolbar-registration-helpers.d.ts +6 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +6 -0
- package/dist/tools/tool-surface-host.js +1 -8
- package/package.json +8 -6
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +0 -2
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +0 -40
- package/dist/components/chunks/sre-engine-jd8cc08x.js +0 -1
- package/dist/services/ContextVariableStore.d.ts +0 -113
- package/dist/services/ContextVariableStore.js +0 -206
- package/dist/services/tts-control-events.d.ts +0 -13
- package/dist/services/tts-control-events.js +0 -7
- package/dist/utils/logger.d.ts +0 -6
- package/dist/utils/logger.js +0 -10
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolFailurePhase } from "./tool-failure.js";
|
|
2
2
|
export type FrameworkErrorKind = "tool-config" | "runtime-init" | "runtime-dispose" | "coordinator-init" | "provider-init" | "provider-register" | "tts-init" | "tool-state-load" | "tool-state-save" | "section-controller-init" | "section-controller-dispose" | "tool-surface"
|
|
3
3
|
/**
|
|
4
4
|
* A toolbar could not load a tool's module. Recoverable unless policy grants
|
|
5
5
|
* the tool: the toolbar withholds the tool and the assessment goes on.
|
|
6
6
|
*/
|
|
7
7
|
| "tool-module-load"
|
|
8
|
+
/**
|
|
9
|
+
* A toolbar threw opening a requested tool or answering whether it hosts one.
|
|
10
|
+
* Recoverable: the request goes unclaimed or passes the toolbar by.
|
|
11
|
+
*/
|
|
12
|
+
| "tool-request"
|
|
13
|
+
/**
|
|
14
|
+
* A tool registration's relevance check or applicability gate threw.
|
|
15
|
+
* Recoverable: the toolbar applies the answer a missing check would give.
|
|
16
|
+
*/
|
|
17
|
+
| "tool-registration"
|
|
18
|
+
/**
|
|
19
|
+
* A tool could not play, seek or change the rate of speech after it started.
|
|
20
|
+
* Recoverable: the tool stays available and the learner can retry.
|
|
21
|
+
*/
|
|
22
|
+
| "tool-playback"
|
|
8
23
|
/**
|
|
9
24
|
* A timed-media section could not deliver a policy as authored: a media time
|
|
10
25
|
* source missing `canPause` / `canRestrictSeeking` (recoverable — cues still
|
|
@@ -34,6 +49,14 @@ export type FrameworkErrorSeverity = "warning" | "error";
|
|
|
34
49
|
* later section runs on, so readiness stays failed. Set by the report site.
|
|
35
50
|
*/
|
|
36
51
|
export type FrameworkErrorScope = "cohort" | "runtime";
|
|
52
|
+
/**
|
|
53
|
+
* The section a `cohort`-scoped error was reported for. A section can fail after
|
|
54
|
+
* the learner has left it, so a reader holding another section ignores the error.
|
|
55
|
+
*/
|
|
56
|
+
export interface FrameworkErrorCohort {
|
|
57
|
+
sectionId: string;
|
|
58
|
+
attemptId?: string;
|
|
59
|
+
}
|
|
37
60
|
export interface FrameworkErrorModel {
|
|
38
61
|
kind: FrameworkErrorKind;
|
|
39
62
|
severity: FrameworkErrorSeverity;
|
|
@@ -42,6 +65,8 @@ export interface FrameworkErrorModel {
|
|
|
42
65
|
details: string[];
|
|
43
66
|
recoverable: boolean;
|
|
44
67
|
scope: FrameworkErrorScope;
|
|
68
|
+
/** Set on a `cohort`-scoped error whose report site knows its section. */
|
|
69
|
+
cohort?: FrameworkErrorCohort;
|
|
45
70
|
cause?: unknown;
|
|
46
71
|
}
|
|
47
72
|
export declare function toFrameworkErrorModel(args: {
|
|
@@ -53,6 +78,7 @@ export declare function toFrameworkErrorModel(args: {
|
|
|
53
78
|
recoverable?: boolean;
|
|
54
79
|
/** Defaults to `runtime`. */
|
|
55
80
|
scope?: FrameworkErrorScope;
|
|
81
|
+
cohort?: FrameworkErrorCohort;
|
|
56
82
|
cause?: unknown;
|
|
57
83
|
}): FrameworkErrorModel;
|
|
58
84
|
export declare function frameworkErrorFromUnknown(args: {
|
|
@@ -61,6 +87,7 @@ export declare function frameworkErrorFromUnknown(args: {
|
|
|
61
87
|
error: unknown;
|
|
62
88
|
recoverable?: boolean;
|
|
63
89
|
scope?: FrameworkErrorScope;
|
|
90
|
+
cohort?: FrameworkErrorCohort;
|
|
64
91
|
}): FrameworkErrorModel;
|
|
65
92
|
/**
|
|
66
93
|
* Coordinator-side error context shape consumed by
|
|
@@ -73,7 +100,7 @@ export declare function frameworkErrorFromUnknown(args: {
|
|
|
73
100
|
* truth for coordinator code; values of that type satisfy this shape.
|
|
74
101
|
*/
|
|
75
102
|
export interface FrameworkErrorCoordinatorContext {
|
|
76
|
-
phase: "coordinator-ready" | "state-load" | "state-save" | "provider-register" | "provider-init" | "tts-init" | "section-controller-init" | "section-controller-dispose" |
|
|
103
|
+
phase: "coordinator-ready" | "state-load" | "state-save" | "provider-register" | "provider-init" | "tts-init" | "section-controller-init" | "section-controller-dispose" | ToolFailurePhase;
|
|
77
104
|
toolId?: string;
|
|
78
105
|
details?: Record<string, unknown>;
|
|
79
106
|
}
|
|
@@ -95,10 +122,6 @@ export declare function frameworkErrorFromCoordinatorContext(args: {
|
|
|
95
122
|
context: FrameworkErrorCoordinatorContext;
|
|
96
123
|
recoverable?: boolean;
|
|
97
124
|
scope?: FrameworkErrorScope;
|
|
98
|
-
|
|
99
|
-
export declare function frameworkErrorFromToolConfigDiagnostics(args: {
|
|
100
|
-
source: string;
|
|
101
|
-
diagnostics: ToolConfigDiagnostic[];
|
|
102
|
-
recoverable?: boolean;
|
|
125
|
+
cohort?: FrameworkErrorCohort;
|
|
103
126
|
}): FrameworkErrorModel;
|
|
104
127
|
export declare function formatFrameworkErrorForConsole(error: FrameworkErrorModel): string;
|
|
@@ -7,6 +7,7 @@ export function toFrameworkErrorModel(args) {
|
|
|
7
7
|
details: [...(args.details || [])],
|
|
8
8
|
recoverable: args.recoverable === true,
|
|
9
9
|
scope: args.scope ?? "runtime",
|
|
10
|
+
...(args.cohort ? { cohort: { ...args.cohort } } : {}),
|
|
10
11
|
cause: args.cause,
|
|
11
12
|
};
|
|
12
13
|
}
|
|
@@ -20,6 +21,7 @@ export function frameworkErrorFromUnknown(args) {
|
|
|
20
21
|
message,
|
|
21
22
|
recoverable: args.recoverable,
|
|
22
23
|
scope: args.scope,
|
|
24
|
+
cohort: args.cohort,
|
|
23
25
|
cause: args.error,
|
|
24
26
|
});
|
|
25
27
|
}
|
|
@@ -33,6 +35,13 @@ const COORDINATOR_PHASE_TO_KIND = {
|
|
|
33
35
|
"section-controller-init": "section-controller-init",
|
|
34
36
|
"section-controller-dispose": "section-controller-dispose",
|
|
35
37
|
"tool-module-load": "tool-module-load",
|
|
38
|
+
"tool-request-open": "tool-request",
|
|
39
|
+
"tool-request-host-check": "tool-request",
|
|
40
|
+
"tool-visibility": "tool-registration",
|
|
41
|
+
"tool-applicability": "tool-registration",
|
|
42
|
+
"tool-state-load": "tool-state-load",
|
|
43
|
+
"tool-state-save": "tool-state-save",
|
|
44
|
+
"tool-playback": "tool-playback",
|
|
36
45
|
};
|
|
37
46
|
/**
|
|
38
47
|
* Build a {@link FrameworkErrorModel} from a coordinator-side error +
|
|
@@ -58,19 +67,7 @@ export function frameworkErrorFromCoordinatorContext(args) {
|
|
|
58
67
|
error: args.error,
|
|
59
68
|
recoverable: args.recoverable,
|
|
60
69
|
scope: args.scope,
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
export function frameworkErrorFromToolConfigDiagnostics(args) {
|
|
64
|
-
const details = args.diagnostics.map((diagnostic) => `${diagnostic.path}: ${diagnostic.message}`);
|
|
65
|
-
const message = details.length > 0
|
|
66
|
-
? "Invalid tools config."
|
|
67
|
-
: "Invalid tools config (no diagnostics details were provided).";
|
|
68
|
-
return toFrameworkErrorModel({
|
|
69
|
-
kind: "tool-config",
|
|
70
|
-
source: args.source,
|
|
71
|
-
message,
|
|
72
|
-
details,
|
|
73
|
-
recoverable: args.recoverable,
|
|
70
|
+
cohort: args.cohort,
|
|
74
71
|
});
|
|
75
72
|
}
|
|
76
73
|
export function formatFrameworkErrorForConsole(error) {
|
|
@@ -9,22 +9,24 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { I18nServiceApi } from "@pie-players/pie-players-shared/i18n";
|
|
11
11
|
import type { AccessibilityCatalog, SectionControllerSessionState } from "@pie-players/pie-players-shared/types";
|
|
12
|
-
import type {
|
|
12
|
+
import type { CatalogChangeListener, CatalogLookupContext, CatalogLookupOptions, CatalogOwnerRegistration, CatalogOwnerView, CatalogStatistics, CatalogType, ResolvedCatalog } from "./AccessibilityCatalogResolver.js";
|
|
13
13
|
import type { CatalogOwnerContext } from "./catalog-owner.js";
|
|
14
14
|
import type { FrameworkErrorListener } from "./framework-error-bus.js";
|
|
15
15
|
import type { FrameworkErrorModel } from "./framework-error.js";
|
|
16
|
-
import type {
|
|
16
|
+
import type { ToolFailurePhase } from "./tool-failure.js";
|
|
17
|
+
import type { Annotation, HighlightColor } from "./HighlightCoordinator.js";
|
|
17
18
|
import type { SerializedRange } from "./RangeSerializer.js";
|
|
18
19
|
import type { SectionControllerHandle, SectionItemEventSubscriptionArgs, SectionScopedEventSubscriptionArgs, SectionEventSubscriptionArgs, ToolkitCoordinatorHooks } from "./ToolkitCoordinator.js";
|
|
20
|
+
import type { ElementIdComponents } from "./ElementToolStateStore.js";
|
|
19
21
|
import type { ZIndexLayer } from "./ToolCoordinator.js";
|
|
20
|
-
import type { PlaybackState
|
|
22
|
+
import type { PlaybackState } from "./TTSService.js";
|
|
21
23
|
import type { TTSHighlightTargetResolverProvider } from "./tts/highlight-target-resolver.js";
|
|
22
24
|
import type { TextToSpeechToolProviderConfig, ToolPlacementConfig, ToolProviderConfig } from "./tools-config-normalizer.js";
|
|
23
25
|
import type { ToolProviderApi } from "./tool-providers/ToolProviderApi.js";
|
|
24
26
|
import type { ToolProviderRegistry } from "./tool-providers/ToolProviderRegistry.js";
|
|
25
|
-
import type { FeaturePolicyDecision, PolicySource, PnpEnforcementMode, ResolvedEngineInputs, ToolPolicyChangeListener, ToolPolicyDecision, ToolPolicyDecisionRequest, ToolScope } from "../policy/engine.js";
|
|
26
|
-
import type { AssessmentEntity, ItemSettings } from "@pie-players/pie-players-shared/types";
|
|
27
|
-
import type {
|
|
27
|
+
import type { FeaturePolicyDecision, PolicySource, PnpEnforcementMode, ResolvedEngineInputs, ToolPolicyChangeListener, ToolPolicyDecision, ToolPolicyDecisionRequest, ToolPolicyDiagnostic, ToolScope } from "../policy/engine.js";
|
|
28
|
+
import type { AssessmentEntity, ItemSettings, ToolParametersFor } from "@pie-players/pie-players-shared/types";
|
|
29
|
+
import type { TTSConfig } from "@pie-players/pie-tts";
|
|
28
30
|
import type { ResolvedToolContext, ToolContextResolverContext, ToolRegistry } from "./ToolRegistry.js";
|
|
29
31
|
import type { ToolOpenRequest, ToolRequestTarget } from "./tool-request.js";
|
|
30
32
|
export type { I18nServiceApi };
|
|
@@ -34,10 +36,6 @@ export type { I18nServiceApi };
|
|
|
34
36
|
* Manages content highlighting for TTS, annotations, and selections.
|
|
35
37
|
*/
|
|
36
38
|
export interface HighlightCoordinatorApi {
|
|
37
|
-
/**
|
|
38
|
-
* Highlight a text range
|
|
39
|
-
*/
|
|
40
|
-
highlightRange(range: Range, type: HighlightType, color: HighlightColor): void;
|
|
41
39
|
/**
|
|
42
40
|
* Highlight the word being read (temporary): one range per tree the word
|
|
43
41
|
* spans, all painted, so a word split across inline elements highlights
|
|
@@ -68,17 +66,9 @@ export interface HighlightCoordinatorApi {
|
|
|
68
66
|
*/
|
|
69
67
|
clearTTS(): void;
|
|
70
68
|
/**
|
|
71
|
-
* Clear
|
|
72
|
-
*/
|
|
73
|
-
clearHighlights(type: HighlightType): void;
|
|
74
|
-
/**
|
|
75
|
-
* Check if highlighting is supported in current environment
|
|
69
|
+
* Clear the TTS word highlight, keeping the sentence highlight
|
|
76
70
|
*/
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Update TTS highlight style dynamically
|
|
80
|
-
*/
|
|
81
|
-
updateTTSHighlightStyle(color: string, opacity: number): void;
|
|
71
|
+
clearTTSWord(): void;
|
|
82
72
|
/**
|
|
83
73
|
* Record a learner annotation over a range.
|
|
84
74
|
*
|
|
@@ -214,6 +204,17 @@ export interface SpeakOptions {
|
|
|
214
204
|
* element target is its own root.
|
|
215
205
|
*/
|
|
216
206
|
contentRoot?: Element | null;
|
|
207
|
+
/**
|
|
208
|
+
* Who starts the read. The run carries it until the next read starts, a
|
|
209
|
+
* seek's restart included, and {@link TtsServiceApi.getRunOwner} reports it.
|
|
210
|
+
*/
|
|
211
|
+
ownerId?: string;
|
|
212
|
+
/** The rate the read starts at; it stays the service's rate afterwards. */
|
|
213
|
+
rate?: number;
|
|
214
|
+
/** The pitch the read starts at, 0–2 with 1 normal; it stays the service's. */
|
|
215
|
+
pitch?: number;
|
|
216
|
+
/** The volume the read starts at, 0–1; it stays the service's. */
|
|
217
|
+
volume?: number;
|
|
217
218
|
}
|
|
218
219
|
/**
|
|
219
220
|
* TTS service interface
|
|
@@ -222,10 +223,6 @@ export interface SpeakOptions {
|
|
|
222
223
|
* Supports QTI 3.0 accessibility catalogs for pre-authored spoken content.
|
|
223
224
|
*/
|
|
224
225
|
export interface TtsServiceApi {
|
|
225
|
-
/**
|
|
226
|
-
* Initialize TTS with a provider
|
|
227
|
-
*/
|
|
228
|
-
initialize(provider: ITTSProvider, config?: Partial<TTSConfig>): Promise<void>;
|
|
229
226
|
/**
|
|
230
227
|
* Read `target` aloud: a range reads the text it selects, an element its
|
|
231
228
|
* content. A node with a spoken card that the target holds whole reads its
|
|
@@ -243,7 +240,8 @@ export interface TtsServiceApi {
|
|
|
243
240
|
*/
|
|
244
241
|
resume(): void;
|
|
245
242
|
/**
|
|
246
|
-
* Stop playback
|
|
243
|
+
* Stop playback and release the run owner. A read that ends on its own
|
|
244
|
+
* keeps its owner.
|
|
247
245
|
*/
|
|
248
246
|
stop(): void;
|
|
249
247
|
/**
|
|
@@ -251,13 +249,6 @@ export interface TtsServiceApi {
|
|
|
251
249
|
* service cannot speak.
|
|
252
250
|
*/
|
|
253
251
|
dispose(): void;
|
|
254
|
-
/**
|
|
255
|
-
* Request active TTS controls to hand off/deactivate their UI state.
|
|
256
|
-
*
|
|
257
|
-
* This is an orchestration hint for TTS tool chrome and does not replace
|
|
258
|
-
* playback controls such as stop/pause/resume.
|
|
259
|
-
*/
|
|
260
|
-
requestControlHandoff(): void;
|
|
261
252
|
/**
|
|
262
253
|
* Seek forward by sentence units
|
|
263
254
|
*/
|
|
@@ -266,30 +257,21 @@ export interface TtsServiceApi {
|
|
|
266
257
|
* Seek backward by sentence units
|
|
267
258
|
*/
|
|
268
259
|
seekBackward(units?: number): Promise<void>;
|
|
269
|
-
/**
|
|
270
|
-
* Check if currently playing
|
|
271
|
-
*/
|
|
272
|
-
isPlaying(): boolean;
|
|
273
|
-
/**
|
|
274
|
-
* Check if paused
|
|
275
|
-
*/
|
|
276
|
-
isPaused(): boolean;
|
|
277
260
|
/**
|
|
278
261
|
* Get current playback state
|
|
279
262
|
*/
|
|
280
263
|
getState(): PlaybackState;
|
|
281
264
|
/**
|
|
282
|
-
*
|
|
265
|
+
* The `ownerId` the latest read started with, or null when it named none,
|
|
266
|
+
* nothing has been read or {@link stop} released it. A new read announces
|
|
267
|
+
* itself through {@link onStateChange} with `loading`, and a stop that
|
|
268
|
+
* releases an owner announces `idle`, so a listener sees the owner change.
|
|
283
269
|
*/
|
|
284
|
-
|
|
270
|
+
getRunOwner(): string | null;
|
|
285
271
|
/**
|
|
286
272
|
* Subscribe to state changes. Returns the function that unsubscribes.
|
|
287
273
|
*/
|
|
288
274
|
onStateChange(callback: (state: PlaybackState) => void): () => void;
|
|
289
|
-
/**
|
|
290
|
-
* Get capabilities of current provider
|
|
291
|
-
*/
|
|
292
|
-
getCapabilities(): TTSProviderCapabilities | null;
|
|
293
275
|
/**
|
|
294
276
|
* Update TTS settings dynamically (rate, pitch, voice)
|
|
295
277
|
*/
|
|
@@ -298,18 +280,10 @@ export interface TtsServiceApi {
|
|
|
298
280
|
* Update playback speed and apply it to active planned playback.
|
|
299
281
|
*/
|
|
300
282
|
setPlaybackRate(rate: number): Promise<void>;
|
|
301
|
-
/**
|
|
302
|
-
* Set highlight coordinator for word highlighting
|
|
303
|
-
*/
|
|
304
|
-
setHighlightCoordinator(coordinator: HighlightCoordinatorApi): void;
|
|
305
283
|
/**
|
|
306
284
|
* Set a late-bound provider for optional host TTS highlight target remapping.
|
|
307
285
|
*/
|
|
308
|
-
setHighlightTargetResolverProvider
|
|
309
|
-
/**
|
|
310
|
-
* Set accessibility catalog resolver for spoken content
|
|
311
|
-
*/
|
|
312
|
-
setCatalogResolver(resolver: AccessibilityCatalogResolver): void;
|
|
286
|
+
setHighlightTargetResolverProvider(provider: TTSHighlightTargetResolverProvider | null): () => void;
|
|
313
287
|
}
|
|
314
288
|
/**
|
|
315
289
|
* Accessibility catalog resolver interface
|
|
@@ -387,18 +361,15 @@ export interface AccessibilityCatalogResolverApi {
|
|
|
387
361
|
*/
|
|
388
362
|
export interface ElementToolStateStoreApi {
|
|
389
363
|
/**
|
|
390
|
-
* Generate a globally unique element ID from
|
|
364
|
+
* Generate a globally unique element ID from its parts. `attemptId` is `""`
|
|
365
|
+
* when the host names no attempt; a tool keyed by item or section leaves
|
|
366
|
+
* `elementId`, and for a section `itemId`, as `""`.
|
|
391
367
|
*/
|
|
392
|
-
getGlobalElementId(
|
|
368
|
+
getGlobalElementId(parts: ElementIdComponents): string;
|
|
393
369
|
/**
|
|
394
370
|
* Parse a global element ID into its components
|
|
395
371
|
*/
|
|
396
|
-
parseGlobalElementId(globalElementId: string):
|
|
397
|
-
assessmentId: string;
|
|
398
|
-
sectionId: string;
|
|
399
|
-
itemId: string;
|
|
400
|
-
elementId: string;
|
|
401
|
-
} | null;
|
|
372
|
+
parseGlobalElementId(globalElementId: string): ElementIdComponents | null;
|
|
402
373
|
/**
|
|
403
374
|
* Set state for a specific tool on an element
|
|
404
375
|
*/
|
|
@@ -436,7 +407,7 @@ export interface ElementToolStateStoreApi {
|
|
|
436
407
|
*/
|
|
437
408
|
clearTool(toolId: string): void;
|
|
438
409
|
/**
|
|
439
|
-
* Clear all elements in a specific section
|
|
410
|
+
* Clear all elements in a specific section, across its attempts
|
|
440
411
|
*/
|
|
441
412
|
clearSection(assessmentId: string, sectionId: string): void;
|
|
442
413
|
/**
|
|
@@ -480,9 +451,9 @@ export interface ToolkitCoordinatorApi {
|
|
|
480
451
|
*/
|
|
481
452
|
readonly toolProviderRegistry: ToolProviderRegistry;
|
|
482
453
|
/**
|
|
483
|
-
* Ensure TTS service is initialized
|
|
454
|
+
* Ensure the TTS service is initialized from the `textToSpeech` tool config.
|
|
484
455
|
*/
|
|
485
|
-
ensureTTSReady(
|
|
456
|
+
ensureTTSReady(): Promise<void>;
|
|
486
457
|
/**
|
|
487
458
|
* Ensure a tool's provider is initialized and ready. Providers register under
|
|
488
459
|
* their tool's id, so a tool passes its own base tool id. A tool starts its
|
|
@@ -619,11 +590,11 @@ export interface ToolkitCoordinatorApi {
|
|
|
619
590
|
*/
|
|
620
591
|
reportFrameworkError?(model: FrameworkErrorModel): void;
|
|
621
592
|
/**
|
|
622
|
-
* Report that a
|
|
623
|
-
*
|
|
624
|
-
*
|
|
593
|
+
* Report that a tool failed in `phase`, under the tool failure policy
|
|
594
|
+
* {@link ToolFailurePhase} describes. Optional so structural host
|
|
595
|
+
* coordinators remain assignable; a reporter without it logs.
|
|
625
596
|
*/
|
|
626
|
-
|
|
597
|
+
reportToolFailure?(toolId: string, phase: ToolFailurePhase, error: unknown): void;
|
|
627
598
|
/**
|
|
628
599
|
* Resolve the visible tool set for a given placement level + scope.
|
|
629
600
|
* Returns the engine's full decision (visible tools, diagnostics,
|
|
@@ -643,7 +614,7 @@ export interface ToolkitCoordinatorApi {
|
|
|
643
614
|
* Optional so host-supplied coordinator stubs predating this method stay
|
|
644
615
|
* assignable; call sites must feature-detect.
|
|
645
616
|
*/
|
|
646
|
-
decideFeaturePolicy
|
|
617
|
+
decideFeaturePolicy?<K extends string>(featureId: K, scope?: ToolScope): FeaturePolicyDecision<ToolParametersFor<K>>;
|
|
647
618
|
/**
|
|
648
619
|
* Subscribe to policy-engine change events. Fires whenever the
|
|
649
620
|
* coordinator's bound policy inputs change (`updateToolConfig`,
|
|
@@ -653,6 +624,15 @@ export interface ToolkitCoordinatorApi {
|
|
|
653
624
|
* should call `decideToolPolicy(...)` with their level / scope.
|
|
654
625
|
*/
|
|
655
626
|
onPolicyChange(listener: ToolPolicyChangeListener): () => void;
|
|
627
|
+
/**
|
|
628
|
+
* Subscribe to the policy diagnostics the coordinator reports: the ones it
|
|
629
|
+
* logs as console warnings, once per code, tool and item. A new listener is
|
|
630
|
+
* first handed every diagnostic already reported. A change to the bound
|
|
631
|
+
* policy inputs or to PNP enforcement clears the record, and so does a tool
|
|
632
|
+
* registration that makes a named support id known or unknown, so a conflict
|
|
633
|
+
* that survives the change is reported again once.
|
|
634
|
+
*/
|
|
635
|
+
onPolicyDiagnostic(listener: (diagnostic: ToolPolicyDiagnostic) => void): () => void;
|
|
656
636
|
/**
|
|
657
637
|
* Subscribe to accessibility-catalog registrations and removals.
|
|
658
638
|
*
|
|
@@ -27,14 +27,14 @@ export interface SectionSessionPersistenceConfig {
|
|
|
27
27
|
context: SectionControllerContext;
|
|
28
28
|
strategy: SectionSessionPersistenceStrategy;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* applySession contract:
|
|
32
|
+
* - Preferred input is the output of getSession().
|
|
33
|
+
* - itemSessions may contain canonical attempt entries
|
|
34
|
+
* ({ itemIdentifier, session, isCompleted }) or raw session payloads
|
|
35
|
+
* ({ id, data, ... }); controller normalizes these before applying.
|
|
36
|
+
*/
|
|
30
37
|
export interface SectionControllerApplySessionOptions {
|
|
31
|
-
/**
|
|
32
|
-
* applySession contract:
|
|
33
|
-
* - Preferred input is the output of getSession().
|
|
34
|
-
* - itemSessions may contain canonical attempt entries
|
|
35
|
-
* ({ itemIdentifier, session, isCompleted }) or raw session payloads
|
|
36
|
-
* ({ id, data, ... }); controller normalizes these before applying.
|
|
37
|
-
*/
|
|
38
38
|
mode?: "replace" | "merge";
|
|
39
39
|
}
|
|
40
40
|
export interface SectionControllerLoadedRenderable {
|
|
@@ -15,16 +15,14 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { hasResponseField, hasResponseValue, } from "@pie-players/pie-players-shared/pie";
|
|
17
17
|
import { structurallyEqual } from "../utils/structural-equality.js";
|
|
18
|
-
|
|
19
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
20
|
-
}
|
|
18
|
+
import { isPlainRecord } from "@pie-players/pie-players-shared/object";
|
|
21
19
|
/** An entry is canonical (`{ itemIdentifier, session, ... }`) or the raw item session. */
|
|
22
20
|
function itemSessionOf(entry) {
|
|
23
|
-
return
|
|
21
|
+
return isPlainRecord(entry) && isPlainRecord(entry.session) ? entry.session : entry;
|
|
24
22
|
}
|
|
25
23
|
function sameItemSessions(next, current) {
|
|
26
|
-
const nextSessions =
|
|
27
|
-
const currentSessions =
|
|
24
|
+
const nextSessions = isPlainRecord(next) ? next : {};
|
|
25
|
+
const currentSessions = isPlainRecord(current) ? current : {};
|
|
28
26
|
const itemIds = new Set([
|
|
29
27
|
...Object.keys(nextSessions),
|
|
30
28
|
...Object.keys(currentSessions),
|
|
@@ -63,10 +61,10 @@ function sameSessionContent(next, current) {
|
|
|
63
61
|
export function resolveSectionSessionAssignment(current, next) {
|
|
64
62
|
if (!current)
|
|
65
63
|
return next;
|
|
66
|
-
const itemSessions =
|
|
64
|
+
const itemSessions = isPlainRecord(next.itemSessions)
|
|
67
65
|
? { ...next.itemSessions }
|
|
68
66
|
: {};
|
|
69
|
-
const currentItemSessions =
|
|
67
|
+
const currentItemSessions = isPlainRecord(current.itemSessions)
|
|
70
68
|
? current.itemSessions
|
|
71
69
|
: {};
|
|
72
70
|
for (const [itemId, currentEntry] of Object.entries(currentItemSessions)) {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* QTI 3 treats a recording and synthesized speech as the *same* support — both
|
|
5
5
|
* are `spoken`, and a card carries recorded audio through `qti-file-href` plus a
|
|
6
|
-
* MIME type — so
|
|
7
|
-
*
|
|
6
|
+
* MIME type — so a recording is the other form the existing support takes.
|
|
7
|
+
* Some programs prefer a human voice to synthesis; PIE's `spoken`
|
|
8
8
|
* card was string-only, so it had no way to say "play this file for this node".
|
|
9
9
|
*
|
|
10
10
|
* A node commonly carries both forms in the same language: the reading script
|
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
* Validation posture matches sign-language cards: "treat as absent, never as
|
|
18
18
|
* partially valid". A malformed payload must not produce a silent player that
|
|
19
19
|
* looks like read-aloud is working.
|
|
20
|
-
*
|
|
21
|
-
* Part of PIE Assessment Toolkit.
|
|
22
20
|
*/
|
|
23
21
|
import type { CatalogCardPayload, MediaFragmentRange, MediaSource } from "@pie-players/pie-players-shared/types";
|
|
24
22
|
/** A validated recorded spoken alternate, flattened for playback. */
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* QTI 3 treats a recording and synthesized speech as the *same* support — both
|
|
5
5
|
* are `spoken`, and a card carries recorded audio through `qti-file-href` plus a
|
|
6
|
-
* MIME type — so
|
|
7
|
-
*
|
|
6
|
+
* MIME type — so a recording is the other form the existing support takes.
|
|
7
|
+
* Some programs prefer a human voice to synthesis; PIE's `spoken`
|
|
8
8
|
* card was string-only, so it had no way to say "play this file for this node".
|
|
9
9
|
*
|
|
10
10
|
* A node commonly carries both forms in the same language: the reading script
|
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
* Validation posture matches sign-language cards: "treat as absent, never as
|
|
18
18
|
* partially valid". A malformed payload must not produce a silent player that
|
|
19
19
|
* looks like read-aloud is working.
|
|
20
|
-
*
|
|
21
|
-
* Part of PIE Assessment Toolkit.
|
|
22
20
|
*/
|
|
23
21
|
import { isUnsupportedMediaAssetVersion, normalizeMediaFragment, normalizeMediaSources, trimmedOrUndefined, } from "@pie-players/pie-players-shared/media";
|
|
24
22
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type CanonicalToolsConfig, type ToolsConfigInput } from "./tools-config-normalizer.js";
|
|
2
|
-
import { type FrameworkErrorModel } from "./framework-error.js";
|
|
3
2
|
import type { ToolRegistry } from "./ToolRegistry.js";
|
|
4
3
|
export type ToolConfigStrictness = "off" | "warn" | "error";
|
|
5
4
|
export type ToolConfigDiagnosticSeverity = "warning" | "error";
|
|
@@ -19,13 +18,12 @@ export interface ToolConfigValidationResult {
|
|
|
19
18
|
config: CanonicalToolsConfig;
|
|
20
19
|
diagnostics: ToolConfigDiagnostic[];
|
|
21
20
|
}
|
|
22
|
-
export declare function frameworkErrorFromToolConfigValidation(args: {
|
|
23
|
-
source: string;
|
|
24
|
-
diagnostics?: ToolConfigDiagnostic[] | null;
|
|
25
|
-
error?: unknown;
|
|
26
|
-
recoverable?: boolean;
|
|
27
|
-
}): FrameworkErrorModel;
|
|
28
21
|
export declare function normalizeToolConfigStrictness(value: unknown): ToolConfigStrictness;
|
|
22
|
+
/**
|
|
23
|
+
* Normalize a tools config, sanitize and validate each provider entry with its
|
|
24
|
+
* registration's hooks, check ids and levels against `options.toolRegistry`,
|
|
25
|
+
* and report the diagnostics by `options.strictness` (default `"error"`).
|
|
26
|
+
*/
|
|
29
27
|
export declare function normalizeAndValidateToolsConfig(input?: ToolsConfigInput | null, options?: ToolConfigValidationOptions): ToolConfigValidationResult;
|
|
30
28
|
/**
|
|
31
29
|
* The normalization and diagnostics of {@link normalizeAndValidateToolsConfig},
|
|
@@ -1,20 +1,4 @@
|
|
|
1
1
|
import { normalizeToolsConfig, } from "./tools-config-normalizer.js";
|
|
2
|
-
import { frameworkErrorFromToolConfigDiagnostics, frameworkErrorFromUnknown, } from "./framework-error.js";
|
|
3
|
-
export function frameworkErrorFromToolConfigValidation(args) {
|
|
4
|
-
if (Array.isArray(args.diagnostics) && args.diagnostics.length > 0) {
|
|
5
|
-
return frameworkErrorFromToolConfigDiagnostics({
|
|
6
|
-
source: args.source,
|
|
7
|
-
diagnostics: args.diagnostics,
|
|
8
|
-
recoverable: args.recoverable,
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
return frameworkErrorFromUnknown({
|
|
12
|
-
kind: "tool-config",
|
|
13
|
-
source: args.source,
|
|
14
|
-
error: args.error ?? new Error("Invalid tools config"),
|
|
15
|
-
recoverable: args.recoverable,
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
2
|
const DEFAULT_STRICTNESS = "error";
|
|
19
3
|
export function normalizeToolConfigStrictness(value) {
|
|
20
4
|
if (value === "off" || value === "warn" || value === "error") {
|
|
@@ -198,6 +182,11 @@ function throwValidationError(diagnostics, source) {
|
|
|
198
182
|
.join("\n");
|
|
199
183
|
throw new Error(`[tool-config-validation:${source}] Invalid tools config:\n${formatted}`);
|
|
200
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Normalize a tools config, sanitize and validate each provider entry with its
|
|
187
|
+
* registration's hooks, check ids and levels against `options.toolRegistry`,
|
|
188
|
+
* and report the diagnostics by `options.strictness` (default `"error"`).
|
|
189
|
+
*/
|
|
201
190
|
export function normalizeAndValidateToolsConfig(input, options = {}) {
|
|
202
191
|
const result = collectToolConfigDiagnostics(input, options.toolRegistry);
|
|
203
192
|
reportToolConfigDiagnostics(result.diagnostics, options);
|
|
@@ -212,11 +201,9 @@ export function collectToolConfigDiagnostics(input, toolRegistry) {
|
|
|
212
201
|
const normalized = normalizeToolsConfig(input);
|
|
213
202
|
const diagnostics = [];
|
|
214
203
|
// Tool-id and provider checks need a registry to check against, and every
|
|
215
|
-
// collector below returns early without one. Say so
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
// valid" to "nobody looked" is the kind of change that surfaces as a typo
|
|
219
|
-
// reaching a learner.
|
|
204
|
+
// collector below returns early without one. Say so, since there is no
|
|
205
|
+
// packaged fallback registry: silence would read as "your ids are valid" when
|
|
206
|
+
// nobody looked, and a typo would reach a learner.
|
|
220
207
|
const hasConfiguredTools = Object.values(normalized.placement).some((ids) => ids.length > 0) ||
|
|
221
208
|
Object.keys(normalized.providers).length > 0 ||
|
|
222
209
|
(normalized.policy.allowed?.length ?? 0) > 0 ||
|
|
@@ -260,11 +247,9 @@ export function reportToolConfigDiagnostics(diagnostics, options = {}) {
|
|
|
260
247
|
if (strictness === "warn") {
|
|
261
248
|
emitWarnings(diagnostics, source);
|
|
262
249
|
}
|
|
263
|
-
// Severity decides what `strictness: "error"` rejects.
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
// turn "no registry supplied" from a host's existing, working setup into a
|
|
267
|
-
// construction failure.
|
|
250
|
+
// Severity decides what `strictness: "error"` rejects. `tools.registryUnavailable`
|
|
251
|
+
// is a warning: it reports that validation could not run, and throwing on it
|
|
252
|
+
// would fail construction for a host whose setup works without a registry.
|
|
268
253
|
const blocking = diagnostics.filter((entry) => entry.severity === "error");
|
|
269
254
|
if (strictness === "error" && blocking.length > 0) {
|
|
270
255
|
throwValidationError(blocking, source);
|
|
@@ -102,39 +102,54 @@ export interface ElementToolContext extends BaseToolContext {
|
|
|
102
102
|
*/
|
|
103
103
|
export type ToolContext = AssessmentToolContext | SectionToolContext | ItemToolContext | PassageToolContext | RubricToolContext | ElementToolContext;
|
|
104
104
|
/**
|
|
105
|
-
*
|
|
106
|
-
|
|
107
|
-
export declare function isItemContext(context: ToolContext): context is ItemToolContext;
|
|
108
|
-
/**
|
|
109
|
-
* Type guard to check if context is at passage level
|
|
110
|
-
*/
|
|
111
|
-
export declare function isPassageContext(context: ToolContext): context is PassageToolContext;
|
|
112
|
-
/**
|
|
113
|
-
* Type guard to check if context is at rubric level
|
|
114
|
-
*/
|
|
115
|
-
export declare function isRubricContext(context: ToolContext): context is RubricToolContext;
|
|
116
|
-
/**
|
|
117
|
-
* Type guard to check if context is at element level
|
|
105
|
+
* Helper to check if context contains mathematical content
|
|
106
|
+
* (Basic heuristic - can be overridden by tools)
|
|
118
107
|
*/
|
|
119
|
-
export declare function
|
|
120
|
-
/** The plain text a context carries, tags removed. */
|
|
121
|
-
export declare function extractTextContent(context: ToolContext): string;
|
|
108
|
+
export declare function hasMathContent(context: ToolContext): boolean;
|
|
122
109
|
/**
|
|
123
|
-
*
|
|
110
|
+
* What one element of a context declares about the PNP supports it implements.
|
|
124
111
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
112
|
+
* An element declares them on its class, as `static pieSupports`: a list of AfA
|
|
113
|
+
* PNP 3.0 support terms, such as `answer-masking`. The toolkit reads the class
|
|
114
|
+
* `customElements` holds under the element's runtime tag, so the declaration is
|
|
115
|
+
* known before the element renders. What a support needs from the rendered
|
|
116
|
+
* element is between the element and the tool that provides it, and that tool
|
|
117
|
+
* documents it.
|
|
118
|
+
*/
|
|
119
|
+
export interface ElementSupports {
|
|
120
|
+
/** The element's model id. */
|
|
121
|
+
elementId: string | undefined;
|
|
122
|
+
/** The tag the item binds the element to, as authored. */
|
|
123
|
+
tag: string;
|
|
124
|
+
/** The element's package spec in the item's `elements` map, when it has one. */
|
|
125
|
+
packageSpec: string | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* The terms the element's class declares: `undefined` while the class is
|
|
128
|
+
* undefined, and for a class that declares nothing. An empty list is a
|
|
129
|
+
* declaration that the element implements none.
|
|
130
|
+
*/
|
|
131
|
+
supports: readonly string[] | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* The runtime tags the class can still be defined under, empty once it is
|
|
134
|
+
* defined. A definition landing under one of them can change `supports`.
|
|
135
|
+
*/
|
|
136
|
+
pendingTags: readonly string[];
|
|
137
|
+
}
|
|
130
138
|
/**
|
|
131
|
-
*
|
|
139
|
+
* The supports each element of a context declares: the element's own at element
|
|
140
|
+
* level, every element of the item or passage config at those levels, and none
|
|
141
|
+
* elsewhere. A model that names no element renders nothing and is skipped.
|
|
132
142
|
*/
|
|
133
|
-
export declare function
|
|
143
|
+
export declare function elementSupports(context: ToolContext): ElementSupports[];
|
|
134
144
|
/**
|
|
135
145
|
* Helper to check if context contains text that can be read aloud
|
|
136
146
|
*/
|
|
137
147
|
export declare function hasReadableText(context: ToolContext): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Whether read-aloud has something to read: readable text, or markup carrying
|
|
150
|
+
* a catalog idref, whose spoken card reads for content with no text.
|
|
151
|
+
*/
|
|
152
|
+
export declare function hasSpokenContent(context: ToolContext): boolean;
|
|
138
153
|
/**
|
|
139
154
|
* Helper to check if context contains science content
|
|
140
155
|
* (Basic heuristic - can be overridden by tools)
|