@pie-players/pie-assessment-toolkit 0.3.73 → 0.3.75
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 +469 -318
- package/dist/attempt/AssessmentSession.d.ts +1 -5
- package/dist/attempt/AssessmentSession.js +0 -29
- package/dist/attempt/TestSession.d.ts +1 -20
- package/dist/attempt/TestSession.js +8 -99
- package/dist/components/ItemScope.custom-element.d.ts +1 -0
- package/dist/components/ItemScope.custom-element.js +1 -0
- package/dist/components/ItemToolBar.custom-element.d.ts +1 -0
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.d.ts +1 -0
- package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
- package/dist/components/SectionToolBar.custom-element.d.ts +1 -0
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
- package/dist/components/chunks/ItemToolBar-97hx60z4.js +2 -0
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
- package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
- package/dist/components/item-scope-element.d.ts +2 -0
- package/dist/components/item-scope-element.js +2 -0
- package/dist/context/assessment-toolkit-context.d.ts +32 -6
- package/dist/index.d.ts +23 -48
- package/dist/index.js +12 -37
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +85 -34
- package/dist/policy/core/ToolPolicyEngine.js +148 -46
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +75 -54
- package/dist/policy/core/decision-types.d.ts +65 -34
- package/dist/policy/core/feature-decision.d.ts +16 -9
- package/dist/policy/core/feature-decision.js +14 -8
- package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
- package/dist/policy/core/pnp-policy-inputs.js +28 -56
- package/dist/policy/core/provenance.d.ts +9 -4
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
- package/dist/policy/sources/PnpPolicySource.js +117 -118
- package/dist/runtime/SectionControllerBinding.d.ts +279 -0
- package/dist/runtime/SectionControllerBinding.js +450 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
- package/dist/runtime/SectionRuntimeEngine.js +30 -372
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
- package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
- package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
- package/dist/runtime/adapter/dom-event-bridge.js +17 -44
- package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
- package/dist/runtime/adapter/subscriber-fanout.js +1 -2
- package/dist/runtime/catalog-context.d.ts +19 -0
- package/dist/runtime/catalog-context.js +28 -0
- package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
- package/dist/runtime/composition-emit-scheduler.js +9 -15
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +17 -0
- package/dist/runtime/content-region.js +29 -0
- package/dist/runtime/content-registration.d.ts +13 -0
- package/dist/runtime/content-registration.js +25 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
- package/dist/runtime/core/SectionEngineCore.js +2 -2
- package/dist/runtime/core/cohort.d.ts +1 -1
- package/dist/runtime/core/cohort.js +1 -1
- package/dist/runtime/core/engine-input.d.ts +18 -30
- package/dist/runtime/core/engine-input.js +11 -12
- package/dist/runtime/core/engine-output.d.ts +16 -40
- package/dist/runtime/core/engine-output.js +9 -21
- package/dist/runtime/core/engine-readiness.d.ts +5 -37
- package/dist/runtime/core/engine-readiness.js +8 -41
- package/dist/runtime/core/engine-resolver.d.ts +46 -74
- package/dist/runtime/core/engine-resolver.js +18 -43
- package/dist/runtime/core/engine-state.d.ts +28 -36
- package/dist/runtime/core/engine-state.js +18 -21
- package/dist/runtime/core/engine-transition.d.ts +14 -19
- package/dist/runtime/core/engine-transition.js +71 -51
- package/dist/runtime/engine.d.ts +16 -19
- package/dist/runtime/engine.js +12 -19
- package/dist/runtime/page-warnings.d.ts +13 -0
- package/dist/runtime/page-warnings.js +22 -0
- package/dist/runtime/policy-input-forwarding.d.ts +25 -0
- package/dist/runtime/policy-input-forwarding.js +25 -0
- package/dist/runtime/registration-events.d.ts +14 -0
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/shell-event-bridge.d.ts +45 -0
- package/dist/runtime/shell-event-bridge.js +127 -0
- package/dist/runtime/shell-registration.d.ts +73 -0
- package/dist/runtime/shell-registration.js +95 -0
- package/dist/runtime/shell-scope.d.ts +68 -0
- package/dist/runtime/shell-scope.js +188 -0
- package/dist/runtime/tool-host-contract.d.ts +28 -10
- package/dist/runtime/tool-host-contract.js +31 -10
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/ElementToolStateStore.d.ts +14 -10
- package/dist/services/ElementToolStateStore.js +37 -13
- package/dist/services/HighlightCoordinator.d.ts +22 -28
- package/dist/services/HighlightCoordinator.js +431 -327
- package/dist/services/RangeSerializer.d.ts +10 -1
- package/dist/services/RangeSerializer.js +87 -14
- package/dist/services/TTSService.d.ts +130 -69
- package/dist/services/TTSService.js +713 -570
- package/dist/services/ToolCoordinator.d.ts +43 -66
- package/dist/services/ToolCoordinator.js +164 -208
- package/dist/services/ToolRegistry.d.ts +78 -54
- package/dist/services/ToolRegistry.js +107 -105
- package/dist/services/ToolkitCoordinator.d.ts +261 -175
- package/dist/services/ToolkitCoordinator.js +667 -433
- package/dist/services/audio-handoff.d.ts +6 -7
- package/dist/services/audio-handoff.js +20 -14
- package/dist/services/catalog-owner.d.ts +11 -1
- package/dist/services/catalog-owner.js +25 -0
- package/dist/services/create-tools-config.d.ts +2 -2
- package/dist/services/framework-error-bus.d.ts +3 -6
- package/dist/services/framework-error-bus.js +3 -6
- package/dist/services/framework-error.d.ts +30 -8
- package/dist/services/framework-error.js +9 -7
- package/dist/services/interfaces.d.ts +158 -129
- package/dist/services/section-controller-types.d.ts +15 -0
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +82 -0
- package/dist/services/spoken-audio-cards.d.ts +0 -2
- package/dist/services/spoken-audio-cards.js +1 -3
- package/dist/services/tool-config-defaults.d.ts +3 -3
- package/dist/services/tool-config-defaults.js +3 -3
- package/dist/services/tool-config-validation.d.ts +14 -4
- package/dist/services/tool-config-validation.js +63 -71
- package/dist/services/tool-context.d.ts +0 -8
- package/dist/services/tool-context.js +29 -25
- package/dist/services/tool-icons.d.ts +4 -3
- package/dist/services/tool-icons.js +4 -3
- package/dist/services/tool-instance-id.d.ts +0 -1
- package/dist/services/tool-instance-id.js +0 -6
- package/dist/services/tool-providers/TTSToolProvider.d.ts +41 -80
- package/dist/services/tool-providers/TTSToolProvider.js +81 -40
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +32 -28
- package/dist/services/tool-providers/ToolProviderRegistry.js +121 -107
- package/dist/services/tool-providers/index.d.ts +0 -9
- package/dist/services/tool-providers/index.js +2 -4
- package/dist/services/tool-request.d.ts +27 -12
- package/dist/services/tool-request.js +24 -14
- package/dist/services/toolbar-decided-tools.d.ts +15 -0
- package/dist/services/toolbar-decided-tools.js +28 -0
- package/dist/services/tools-config-normalizer.d.ts +37 -23
- package/dist/services/tools-config-normalizer.js +2 -10
- package/dist/services/tts/browser-provider.d.ts +38 -2
- package/dist/services/tts/browser-provider.js +276 -140
- package/dist/services/tts/catalog-span-alignment.d.ts +2 -17
- package/dist/services/tts/catalog-span-alignment.js +17 -142
- package/dist/services/tts/flat-tree.d.ts +71 -0
- package/dist/services/tts/flat-tree.js +269 -0
- package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
- package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
- package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
- package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/generated-speech/types.d.ts +0 -12
- package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +12 -62
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +38 -5
- package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +3 -6
- package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
- package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
- package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
- package/dist/services/tts/math-alignment/index.d.ts +0 -5
- package/dist/services/tts/math-alignment/index.js +5 -25
- package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +9 -1
- package/dist/services/tts/math-alignment/speech-tokenizer.js +38 -36
- package/dist/services/tts/math-alignment/types.d.ts +4 -2
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +74 -18
- package/dist/services/tts/math-control-names.d.ts +21 -0
- package/dist/services/tts/math-control-names.js +142 -0
- package/dist/services/tts/math-speech.d.ts +16 -1
- package/dist/services/tts/math-speech.js +55 -19
- package/dist/services/tts/provider-options.d.ts +41 -0
- package/dist/services/tts/provider-options.js +1 -0
- package/dist/services/tts/sre-engine.d.ts +7 -0
- package/dist/services/tts/sre-engine.js +11 -0
- package/dist/services/tts/sre-locales.d.ts +14 -0
- package/dist/services/tts/sre-locales.js +57 -0
- package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
- package/dist/services/tts/ssml/spoken-text.js +29 -0
- package/dist/services/tts/start-failure.d.ts +11 -0
- package/dist/services/tts/start-failure.js +19 -0
- package/dist/services/tts/text-processing.d.ts +9 -1
- package/dist/services/tts/text-processing.js +46 -34
- package/dist/services/tts/text-segmentation.d.ts +7 -0
- package/dist/services/tts/text-segmentation.js +47 -0
- package/dist/services/tts-runtime-config.d.ts +44 -18
- package/dist/services/tts-runtime-config.js +22 -93
- package/dist/tools/content-capability-resolution.d.ts +7 -9
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +58 -0
- package/dist/tools/registration.js +54 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +44 -42
- package/dist/tools/tool-tag-map.d.ts +5 -15
- package/dist/tools/tool-tag-map.js +6 -20
- package/dist/utils/structural-equality.d.ts +11 -0
- package/dist/utils/structural-equality.js +47 -0
- package/package.json +24 -59
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
- package/dist/components/chunks/ItemToolBar-byq80z42.js +0 -40
- package/dist/components/chunks/ItemToolBar-d36g3aw4.js +0 -49
- package/dist/context/runtime-context-consumer.d.ts +0 -13
- package/dist/context/runtime-context-consumer.js +0 -51
- package/dist/item-loader.d.ts +0 -44
- package/dist/item-loader.js +0 -61
- package/dist/policy/core/engine-context.d.ts +0 -29
- package/dist/policy/core/engine-context.js +0 -27
- package/dist/policy/core/policy-source-tag.d.ts +0 -31
- package/dist/policy/core/policy-source-tag.js +0 -28
- package/dist/policy/internal.d.ts +0 -25
- package/dist/policy/internal.js +0 -25
- package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
- package/dist/runtime/adapter/coordinator-bridge.js +0 -126
- package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
- package/dist/runtime/adapter/framework-error-bridge.js +0 -46
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
- package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
- package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
- package/dist/runtime/core/engine-stage-derivation.js +0 -29
- package/dist/runtime/engine-context.d.ts +0 -39
- package/dist/runtime/engine-context.js +0 -31
- package/dist/runtime/internal.d.ts +0 -43
- package/dist/runtime/internal.js +0 -45
- package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -80
- package/dist/runtime/section-runtime-engine-host-context.js +0 -95
- package/dist/runtime/stage-emit-gate.d.ts +0 -92
- package/dist/runtime/stage-emit-gate.js +0 -82
- package/dist/services/I18nService.d.ts +0 -47
- package/dist/services/I18nService.js +0 -84
- package/dist/services/ThemeProvider.d.ts +0 -95
- package/dist/services/ThemeProvider.js +0 -334
- package/dist/services/ToolConfigResolver.d.ts +0 -161
- package/dist/services/ToolConfigResolver.js +0 -229
- package/dist/services/catalog-media.d.ts +0 -56
- package/dist/services/catalog-media.js +0 -190
- package/dist/services/createDefaultToolRegistry.d.ts +0 -53
- package/dist/services/createDefaultToolRegistry.js +0 -45
- package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
- package/dist/services/defaultPersonalNeedsProfile.js +0 -26
- package/dist/services/pnp-standard-features.d.ts +0 -238
- package/dist/services/pnp-standard-features.js +0 -338
- package/dist/services/tool-providers/CortexToolProvider.d.ts +0 -13
- package/dist/services/tool-providers/CortexToolProvider.js +0 -32
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -14
- package/dist/services/tool-providers/DesmosToolProvider.js +0 -32
- package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +0 -16
- package/dist/services/tool-providers/GeoGebraToolProvider.js +0 -32
- package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +0 -35
- package/dist/services/tool-providers/LazyCalculatorToolProvider.js +0 -95
- package/dist/services/tts/visual-line-ranges.d.ts +0 -18
- package/dist/services/tts/visual-line-ranges.js +0 -226
- package/dist/tools/client.d.ts +0 -12
- package/dist/tools/client.js +0 -14
- package/dist/tools/index.d.ts +0 -8
- package/dist/tools/index.js +0 -10
- package/dist/tools/internal.d.ts +0 -43
- package/dist/tools/internal.js +0 -41
- package/dist/tools/response-discovery.d.ts +0 -61
- package/dist/tools/response-discovery.js +0 -113
- package/dist/tools/types.d.ts +0 -337
- package/dist/tools/types.js +0 -12
- package/dist/tools/variant-resolver.d.ts +0 -41
- package/dist/tools/variant-resolver.js +0 -207
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* Used by both TTS (for timing data) and annotations (for persistence).
|
|
6
6
|
*
|
|
7
7
|
* Uses CSS selector paths and node indices for robust serialization that
|
|
8
|
-
* survives content changes when possible.
|
|
8
|
+
* survives content changes when possible. A path into an open shadow root names
|
|
9
|
+
* its host, then ` >>> `, then the path inside the root, so ranges in content
|
|
10
|
+
* that renders into shadow roots round-trip; paths without one read as before.
|
|
9
11
|
*/
|
|
10
12
|
/**
|
|
11
13
|
* Serialized form of a Range suitable for storage.
|
|
@@ -91,6 +93,13 @@ export declare class RangeSerializer {
|
|
|
91
93
|
* @returns CSS selector path
|
|
92
94
|
*/
|
|
93
95
|
private getElementPath;
|
|
96
|
+
/** The path to `shadowRoot` itself: its host's path and an empty step into it. */
|
|
97
|
+
private getShadowRootPath;
|
|
98
|
+
/**
|
|
99
|
+
* The element, or shadow root, an element path names: each step after a
|
|
100
|
+
* {@link SHADOW_STEP} continues in the shadow root of what the step before named.
|
|
101
|
+
*/
|
|
102
|
+
private resolveElementPath;
|
|
94
103
|
/**
|
|
95
104
|
* Find a node by its path from root.
|
|
96
105
|
*
|
|
@@ -5,8 +5,13 @@
|
|
|
5
5
|
* Used by both TTS (for timing data) and annotations (for persistence).
|
|
6
6
|
*
|
|
7
7
|
* Uses CSS selector paths and node indices for robust serialization that
|
|
8
|
-
* survives content changes when possible.
|
|
8
|
+
* survives content changes when possible. A path into an open shadow root names
|
|
9
|
+
* its host, then ` >>> `, then the path inside the root, so ranges in content
|
|
10
|
+
* that renders into shadow roots round-trip; paths without one read as before.
|
|
9
11
|
*/
|
|
12
|
+
import { isShadowRootNode } from "./tts/flat-tree.js";
|
|
13
|
+
/** Separates a shadow host's path from the path inside its shadow root. */
|
|
14
|
+
const SHADOW_STEP = " >>> ";
|
|
10
15
|
/**
|
|
11
16
|
* RangeSerializer - Serialize and deserialize Range objects.
|
|
12
17
|
*/
|
|
@@ -94,20 +99,25 @@ export class RangeSerializer {
|
|
|
94
99
|
}
|
|
95
100
|
// Handle text nodes
|
|
96
101
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
97
|
-
const parent = node.
|
|
102
|
+
const parent = node.parentNode;
|
|
98
103
|
if (!parent) {
|
|
99
104
|
throw new Error("Text node has no parent");
|
|
100
105
|
}
|
|
101
106
|
// Get index of this text node among its siblings
|
|
102
107
|
const textNodes = Array.from(parent.childNodes).filter((n) => n.nodeType === Node.TEXT_NODE);
|
|
103
108
|
const index = textNodes.indexOf(node);
|
|
104
|
-
const parentPath =
|
|
109
|
+
const parentPath = isShadowRootNode(parent)
|
|
110
|
+
? this.getShadowRootPath(parent, root)
|
|
111
|
+
: this.getElementPath(parent, root);
|
|
105
112
|
return `${parentPath}::text[${index}]`;
|
|
106
113
|
}
|
|
107
114
|
// Handle element nodes
|
|
108
115
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
109
116
|
return this.getElementPath(node, root);
|
|
110
117
|
}
|
|
118
|
+
if (isShadowRootNode(node)) {
|
|
119
|
+
return this.getShadowRootPath(node, root);
|
|
120
|
+
}
|
|
111
121
|
throw new Error(`Unsupported node type: ${node.nodeType}`);
|
|
112
122
|
}
|
|
113
123
|
/**
|
|
@@ -121,27 +131,81 @@ export class RangeSerializer {
|
|
|
121
131
|
if (element === root) {
|
|
122
132
|
return "";
|
|
123
133
|
}
|
|
124
|
-
const
|
|
134
|
+
const rootTree = root.getRootNode?.();
|
|
135
|
+
// One path per tree, outermost first.
|
|
136
|
+
const trees = [];
|
|
137
|
+
let path = [];
|
|
125
138
|
let current = element;
|
|
139
|
+
// Ends `current`'s tree at the shadow root holding it, continuing at the host.
|
|
140
|
+
const leaveShadowRoot = (shadowRoot) => {
|
|
141
|
+
trees.unshift(path.join(" > "));
|
|
142
|
+
path = [];
|
|
143
|
+
current = shadowRoot.host;
|
|
144
|
+
};
|
|
126
145
|
while (current && current !== root) {
|
|
127
|
-
// Use ID if available (more stable)
|
|
146
|
+
// Use ID if available (more stable). An id is unique within its tree, so
|
|
147
|
+
// the path still names the shadow host above it.
|
|
128
148
|
if (current.id) {
|
|
129
149
|
path.unshift(`#${current.id}`);
|
|
150
|
+
const tree = current.getRootNode?.();
|
|
151
|
+
if (isShadowRootNode(tree) && tree !== rootTree) {
|
|
152
|
+
leaveShadowRoot(tree);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
130
155
|
break;
|
|
131
156
|
}
|
|
132
157
|
// Otherwise use tag + nth-of-type
|
|
133
158
|
const parent = current.parentElement;
|
|
134
|
-
|
|
159
|
+
const parentNode = current.parentNode;
|
|
160
|
+
const siblingsParent = parent ?? (isShadowRootNode(parentNode) ? parentNode : null);
|
|
161
|
+
if (!siblingsParent)
|
|
135
162
|
break;
|
|
136
|
-
const
|
|
163
|
+
const tagName = current.tagName;
|
|
164
|
+
const siblings = Array.from(siblingsParent.children).filter((el) => el.tagName === tagName);
|
|
137
165
|
const index = siblings.indexOf(current);
|
|
138
166
|
const selector = siblings.length > 1
|
|
139
|
-
? `${
|
|
140
|
-
:
|
|
167
|
+
? `${tagName.toLowerCase()}:nth-of-type(${index + 1})`
|
|
168
|
+
: tagName.toLowerCase();
|
|
141
169
|
path.unshift(selector);
|
|
142
|
-
|
|
170
|
+
if (parent) {
|
|
171
|
+
current = parent;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
leaveShadowRoot(siblingsParent);
|
|
175
|
+
}
|
|
143
176
|
}
|
|
144
|
-
|
|
177
|
+
trees.unshift(path.join(" > "));
|
|
178
|
+
return trees.join(SHADOW_STEP);
|
|
179
|
+
}
|
|
180
|
+
/** The path to `shadowRoot` itself: its host's path and an empty step into it. */
|
|
181
|
+
getShadowRootPath(shadowRoot, root) {
|
|
182
|
+
return `${this.getElementPath(shadowRoot.host, root)}${SHADOW_STEP}`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The element, or shadow root, an element path names: each step after a
|
|
186
|
+
* {@link SHADOW_STEP} continues in the shadow root of what the step before named.
|
|
187
|
+
*/
|
|
188
|
+
resolveElementPath(path, root) {
|
|
189
|
+
let scope = root;
|
|
190
|
+
const steps = path.split(SHADOW_STEP);
|
|
191
|
+
for (let index = 0; index < steps.length; index++) {
|
|
192
|
+
if (index > 0) {
|
|
193
|
+
const shadowRoot = isShadowRootNode(scope)
|
|
194
|
+
? null
|
|
195
|
+
: scope.shadowRoot;
|
|
196
|
+
if (!shadowRoot)
|
|
197
|
+
return null;
|
|
198
|
+
scope = shadowRoot;
|
|
199
|
+
}
|
|
200
|
+
const selector = steps[index].trim();
|
|
201
|
+
if (!selector)
|
|
202
|
+
continue;
|
|
203
|
+
const found = scope.querySelector(selector);
|
|
204
|
+
if (!found)
|
|
205
|
+
return null;
|
|
206
|
+
scope = found;
|
|
207
|
+
}
|
|
208
|
+
return scope;
|
|
145
209
|
}
|
|
146
210
|
/**
|
|
147
211
|
* Find a node by its path from root.
|
|
@@ -156,10 +220,19 @@ export class RangeSerializer {
|
|
|
156
220
|
}
|
|
157
221
|
// Handle text node paths
|
|
158
222
|
if (path.includes("::text[")) {
|
|
159
|
-
const
|
|
223
|
+
const marker = path.lastIndexOf("::text[");
|
|
224
|
+
const elementPath = path.slice(0, marker);
|
|
225
|
+
const textPart = path.slice(marker + "::text[".length);
|
|
160
226
|
const textIndex = Number.parseInt(textPart.replace("]", ""), 10);
|
|
161
227
|
// Find parent element
|
|
162
|
-
|
|
228
|
+
let parent;
|
|
229
|
+
try {
|
|
230
|
+
parent = this.resolveElementPath(elementPath, root);
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.warn("Invalid selector path:", path, error);
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
163
236
|
if (!parent)
|
|
164
237
|
return null;
|
|
165
238
|
// Find text node by index
|
|
@@ -168,7 +241,7 @@ export class RangeSerializer {
|
|
|
168
241
|
}
|
|
169
242
|
// Handle element paths
|
|
170
243
|
try {
|
|
171
|
-
return
|
|
244
|
+
return this.resolveElementPath(path, root);
|
|
172
245
|
}
|
|
173
246
|
catch (error) {
|
|
174
247
|
console.warn("Invalid selector path:", path, error);
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
* Part of PIE Assessment Toolkit.
|
|
17
17
|
*/
|
|
18
18
|
import type { ITTSProvider, TTSConfig, TTSProviderCapabilities } from "@pie-players/pie-tts";
|
|
19
|
-
import type { AccessibilityCatalogResolver
|
|
20
|
-
import type { HighlightCoordinatorApi } from "./interfaces.js";
|
|
19
|
+
import type { AccessibilityCatalogResolver } from "./AccessibilityCatalogResolver.js";
|
|
20
|
+
import type { HighlightCoordinatorApi, SpeakOptions } from "./interfaces.js";
|
|
21
21
|
import type { TTSHighlightTargetResolverProvider } from "./tts/highlight-target-resolver.js";
|
|
22
|
-
|
|
22
|
+
import { type SREMathSpeechOptions } from "./tts/math-speech.js";
|
|
23
|
+
export type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSProviderCapabilities, } from "@pie-players/pie-tts";
|
|
23
24
|
/**
|
|
24
25
|
* Playback state
|
|
25
26
|
*/
|
|
@@ -30,16 +31,6 @@ export declare enum PlaybackState {
|
|
|
30
31
|
PAUSED = "paused",
|
|
31
32
|
ERROR = "error"
|
|
32
33
|
}
|
|
33
|
-
type HighlightMode = "word" | "sentence";
|
|
34
|
-
interface SpeakOptions {
|
|
35
|
-
catalogId?: string;
|
|
36
|
-
catalogContext?: CatalogLookupContext;
|
|
37
|
-
ignoreCatalogs?: boolean;
|
|
38
|
-
language?: string;
|
|
39
|
-
contentElement?: Element;
|
|
40
|
-
wordBoundaryOffset?: number;
|
|
41
|
-
highlightModeOverride?: HighlightMode;
|
|
42
|
-
}
|
|
43
34
|
/**
|
|
44
35
|
* TTSService
|
|
45
36
|
*
|
|
@@ -53,7 +44,13 @@ export declare class TTSService {
|
|
|
53
44
|
private highlightTargetResolverProvider;
|
|
54
45
|
private catalogResolver;
|
|
55
46
|
private state;
|
|
47
|
+
private resumeState;
|
|
56
48
|
private ttsConfig;
|
|
49
|
+
private hostLocales;
|
|
50
|
+
private readLocale;
|
|
51
|
+
private disposed;
|
|
52
|
+
private readinessGate;
|
|
53
|
+
private mathSpeechSource;
|
|
57
54
|
private currentText;
|
|
58
55
|
private currentContentElement;
|
|
59
56
|
private normalizedToDOM;
|
|
@@ -66,11 +63,12 @@ export declare class TTSService {
|
|
|
66
63
|
private playbackChunks;
|
|
67
64
|
private activeRecordedAudio;
|
|
68
65
|
private sentenceHighlightSegments;
|
|
69
|
-
private currentSeekSegmentIndex;
|
|
70
66
|
private activeSentenceStartOffset;
|
|
71
67
|
private playbackStartDeferredRunId;
|
|
72
68
|
private pendingPlaybackStartHighlights;
|
|
73
69
|
private playbackStartBarrierCleanup;
|
|
70
|
+
private pauseHold;
|
|
71
|
+
private structuralPause;
|
|
74
72
|
private playbackRateWriteQueue;
|
|
75
73
|
private playbackRateRequestId;
|
|
76
74
|
private pendingPlaybackRateRequest;
|
|
@@ -79,13 +77,31 @@ export declare class TTSService {
|
|
|
79
77
|
private lastRenderedRegionTarget;
|
|
80
78
|
private telemetryReporter;
|
|
81
79
|
private readonly generatedMathSpeechResolver;
|
|
82
|
-
private static readonly debugEnabled;
|
|
83
80
|
constructor();
|
|
84
|
-
private debugLog;
|
|
85
81
|
private clearPlaybackStartBarrier;
|
|
86
82
|
private notifyPlaybackStarted;
|
|
87
83
|
private installPlaybackStartBarrier;
|
|
88
84
|
private runWhenPlaybackStarts;
|
|
85
|
+
/** Resolves when run `runId` may start its next part: at once unless paused. */
|
|
86
|
+
private waitWhilePaused;
|
|
87
|
+
private releasePauseHold;
|
|
88
|
+
private waitStructuralPause;
|
|
89
|
+
private cancelStructuralPause;
|
|
90
|
+
/**
|
|
91
|
+
* Release what a superseded run still holds: its start barrier, a recorded
|
|
92
|
+
* clip still playing, a structural gap and a pause hold. Its loops then see
|
|
93
|
+
* the new run id and return.
|
|
94
|
+
*/
|
|
95
|
+
private abandonRun;
|
|
96
|
+
/**
|
|
97
|
+
* Start a run and enter loading. From here a pause or stop applies to the
|
|
98
|
+
* run, whatever it is still waiting for: the provider, its content or the
|
|
99
|
+
* provider's audio.
|
|
100
|
+
*/
|
|
101
|
+
private beginRun;
|
|
102
|
+
/** The run's audio is sounding; under a pause, it sounds again on resume. */
|
|
103
|
+
private markPlaying;
|
|
104
|
+
private assertNotDisposed;
|
|
89
105
|
private emitTelemetry;
|
|
90
106
|
/**
|
|
91
107
|
* Initialize TTS service with a provider
|
|
@@ -95,18 +111,27 @@ export declare class TTSService {
|
|
|
95
111
|
*/
|
|
96
112
|
initialize(provider: ITTSProvider, config?: Partial<TTSConfig>): Promise<void>;
|
|
97
113
|
/**
|
|
98
|
-
* Update
|
|
99
|
-
*
|
|
100
|
-
* This allows changing rate, pitch, and voice on the fly.
|
|
101
|
-
* Note: Some providers may require reinitialization for voice changes.
|
|
102
|
-
*
|
|
103
|
-
* @param settings Partial settings to update (rate, pitch, voice)
|
|
114
|
+
* Update rate, pitch, voice or provider options without reinitializing.
|
|
115
|
+
* `providerOptions` merge over the ones already configured.
|
|
104
116
|
*/
|
|
105
117
|
updateSettings(settings: Partial<TTSConfig>): Promise<void>;
|
|
106
118
|
/**
|
|
107
119
|
* Set highlight coordinator for word highlighting
|
|
108
120
|
*/
|
|
109
121
|
setHighlightCoordinator(coordinator: HighlightCoordinatorApi): void;
|
|
122
|
+
/**
|
|
123
|
+
* Starts the service when a caller speaks before it is initialized; a gate
|
|
124
|
+
* that rejects fails the speak with its error. The coordinator installs one
|
|
125
|
+
* that runs its own text-to-speech start.
|
|
126
|
+
*/
|
|
127
|
+
setReadinessGate(gate: (() => Promise<void>) | null): void;
|
|
128
|
+
/**
|
|
129
|
+
* Where the configured math speech options come from before, and apart from,
|
|
130
|
+
* initialization, so math names do not depend on when speech started.
|
|
131
|
+
*/
|
|
132
|
+
setMathSpeechSource(source: (() => unknown) | null): void;
|
|
133
|
+
/** The start a speak must wait for, or null when it can speak now without yielding. */
|
|
134
|
+
private pendingReadiness;
|
|
110
135
|
/**
|
|
111
136
|
* Set a late-bound provider for optional host TTS highlight target remapping.
|
|
112
137
|
*
|
|
@@ -132,18 +157,6 @@ export declare class TTSService {
|
|
|
132
157
|
* @param resolver AccessibilityCatalogResolver instance
|
|
133
158
|
*/
|
|
134
159
|
setCatalogResolver(resolver: AccessibilityCatalogResolver): void;
|
|
135
|
-
/**
|
|
136
|
-
* Whether a catalog holds spoken content this service could actually speak.
|
|
137
|
-
*
|
|
138
|
-
* Exists because `data-catalog-idref` is one attribute with several readers:
|
|
139
|
-
* a node can be docked to a catalog that carries only a signing card, and the
|
|
140
|
-
* nearest docked ancestor of a selection is therefore not necessarily the one
|
|
141
|
-
* holding its authored SSML. A caller resolving a selection climbs ancestors
|
|
142
|
-
* and asks this before settling on an id — see the TTS tool's
|
|
143
|
-
* `findSpokenCatalogId`. Without it, a signing card docked on an inner node
|
|
144
|
-
* silently shadows authored speech on an outer one.
|
|
145
|
-
*/
|
|
146
|
-
hasSpokenAlternate(catalogId: string, language?: string): boolean;
|
|
147
160
|
private getHighlightResolverRuntime;
|
|
148
161
|
private getNodeElement;
|
|
149
162
|
private isElementWithinScope;
|
|
@@ -151,18 +164,45 @@ export declare class TTSService {
|
|
|
151
164
|
private resolveWordHighlightRange;
|
|
152
165
|
private resolveSentenceHighlightTargets;
|
|
153
166
|
private createTextRange;
|
|
154
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Paint the spoken word, each range offered to the host's resolver. A word
|
|
169
|
+
* split across inline elements is one range over its text nodes; across
|
|
170
|
+
* shadow trees, one range per tree.
|
|
171
|
+
*/
|
|
172
|
+
private paintTTSWord;
|
|
155
173
|
private paintTTSSentenceRanges;
|
|
156
174
|
/**
|
|
157
175
|
* Get provider capabilities
|
|
158
176
|
*/
|
|
159
177
|
getCapabilities(): TTSProviderCapabilities | null;
|
|
178
|
+
private providerOptions;
|
|
179
|
+
/** The longest text the provider accepts in one speak, when it declares one. */
|
|
180
|
+
private maxTextLength;
|
|
181
|
+
/**
|
|
182
|
+
* Speak `text`, in pieces when it exceeds the provider's `maxTextLength`. Word
|
|
183
|
+
* boundaries keep indexing the whole text. An SSML document cannot be cut, so
|
|
184
|
+
* one over the limit fails and the chunk's plain fallback reads instead.
|
|
185
|
+
*/
|
|
186
|
+
private speakWithinLimit;
|
|
187
|
+
/** Segments no longer than the provider's `maxTextLength`, offsets kept. */
|
|
188
|
+
private segmentsWithinLimit;
|
|
160
189
|
/**
|
|
161
190
|
* Build a character-by-character map from normalized text positions to DOM positions
|
|
162
191
|
* This handles the complexity of whitespace normalization
|
|
163
192
|
*/
|
|
164
193
|
private getTextProcessingOptions;
|
|
165
|
-
|
|
194
|
+
/**
|
|
195
|
+
* The language a read of `node` is in. Its content language is the nearest
|
|
196
|
+
* `lang` between it and its shell, else the language the speak names, else a
|
|
197
|
+
* pinned `lang_id`. Its locale is that content language, else the host's
|
|
198
|
+
* configured locale, else en-US.
|
|
199
|
+
*/
|
|
200
|
+
private resolveReadLanguage;
|
|
201
|
+
/**
|
|
202
|
+
* The host's SRE options for math speech: from the installed source, else as
|
|
203
|
+
* this service was initialized with.
|
|
204
|
+
*/
|
|
205
|
+
getMathSpeechOptions(): SREMathSpeechOptions | undefined;
|
|
166
206
|
private buildPositionMap;
|
|
167
207
|
private getStructuralPauseProfile;
|
|
168
208
|
private resolvePauseMsFromUnits;
|
|
@@ -171,6 +211,11 @@ export declare class TTSService {
|
|
|
171
211
|
private isElementHidden;
|
|
172
212
|
private getBoundaryStrength;
|
|
173
213
|
private getBoundaryAnchor;
|
|
214
|
+
/**
|
|
215
|
+
* `textOffset` is where `normalizedText` starts in the element's visible text:
|
|
216
|
+
* boundaries are collected over the whole element, and a selection speaks only
|
|
217
|
+
* part of it.
|
|
218
|
+
*/
|
|
174
219
|
private createSpeechPlan;
|
|
175
220
|
private collectSpeechPlanBoundaries;
|
|
176
221
|
private createNodeStartOffsets;
|
|
@@ -182,26 +227,39 @@ export declare class TTSService {
|
|
|
182
227
|
private createSeekSegmentsFromSpeechChunks;
|
|
183
228
|
private getCurrentSeekSegmentIndex;
|
|
184
229
|
private speakWithPlan;
|
|
230
|
+
/**
|
|
231
|
+
* `startOffset` indexes the spoken text; the position map indexes the whole
|
|
232
|
+
* content element, which for a selection starts `activeWordBoundaryOffset`
|
|
233
|
+
* characters earlier.
|
|
234
|
+
*/
|
|
185
235
|
private highlightSentenceSegment;
|
|
186
236
|
private getSegmentIndexForOffset;
|
|
187
237
|
private highlightSentenceForOffset;
|
|
188
238
|
/**
|
|
189
|
-
*
|
|
239
|
+
* Read `target` aloud: a range reads the text it selects, an element its
|
|
240
|
+
* content. A node with a spoken card that the target holds whole reads its
|
|
241
|
+
* card, `catalogId` names the card of the content root, and math reads as
|
|
242
|
+
* math speech.
|
|
190
243
|
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
244
|
+
* Content marked not-to-be-spoken is never read, a named card included. When
|
|
245
|
+
* the target holds nothing speakable, nothing is spoken and playback already
|
|
246
|
+
* running continues.
|
|
194
247
|
*/
|
|
195
|
-
|
|
248
|
+
speak(target: Range | Element, options?: SpeakOptions): Promise<void>;
|
|
196
249
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
|
|
200
|
-
|
|
250
|
+
* Suppression is read from the live ancestors of what is read, because the
|
|
251
|
+
* element carrying it may sit above the content root.
|
|
252
|
+
*/
|
|
253
|
+
private isSuppressedTarget;
|
|
254
|
+
private resolveElementTarget;
|
|
255
|
+
private resolveRangeTarget;
|
|
256
|
+
private speakContent;
|
|
257
|
+
/**
|
|
258
|
+
* Hand the read's language to the provider. A read in a named content language
|
|
259
|
+
* sets the provider's locales and `contentLanguage` to it, so a browser voice
|
|
260
|
+
* follows it; a read naming none restores the host's locales and clears
|
|
261
|
+
* `contentLanguage`, so the browser voice follows the browser's language.
|
|
201
262
|
*/
|
|
202
|
-
speak(text: string, options?: SpeakOptions): Promise<void>;
|
|
203
|
-
private switchProviderToBrowser;
|
|
204
|
-
private isBrowserSpeechFallbackAvailable;
|
|
205
263
|
private applyLanguageSettings;
|
|
206
264
|
private resolveSpeechContent;
|
|
207
265
|
private resolveCatalogComposedSpeechContent;
|
|
@@ -217,6 +275,10 @@ export declare class TTSService {
|
|
|
217
275
|
* defensive net if a capable provider still rejects a given SSML payload.
|
|
218
276
|
*/
|
|
219
277
|
private resolveGeneratedPlaybackFormat;
|
|
278
|
+
/**
|
|
279
|
+
* With `range`, the selection only: an equation it holds whole reads as math
|
|
280
|
+
* speech, and a selection without one reads the selected text, `normalizedInputText`.
|
|
281
|
+
*/
|
|
220
282
|
private resolveGeneratedSpeechContent;
|
|
221
283
|
private logResolvedSpeechContent;
|
|
222
284
|
private initializeSpeakTracking;
|
|
@@ -224,7 +286,6 @@ export declare class TTSService {
|
|
|
224
286
|
private configureWordBoundaryHighlighting;
|
|
225
287
|
private clearWordBoundaryHighlighting;
|
|
226
288
|
private highlightCatalogRegion;
|
|
227
|
-
private highlightCatalogActiveRange;
|
|
228
289
|
private highlightRenderableRegionTarget;
|
|
229
290
|
private highlightRenderableActiveTarget;
|
|
230
291
|
private renderHighlightDecision;
|
|
@@ -245,22 +306,18 @@ export declare class TTSService {
|
|
|
245
306
|
private executeSpeakPlayback;
|
|
246
307
|
private clearHighlightsAndTracking;
|
|
247
308
|
/**
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
* This calculates the offset of the range within its parent element
|
|
251
|
-
* to ensure word highlighting aligns correctly with the selected text.
|
|
252
|
-
*
|
|
253
|
-
* @param range DOM Range to speak
|
|
309
|
+
* The selected part of `root`'s normalized visible text and where it starts, or
|
|
310
|
+
* null when the map is unavailable or holds no selected character.
|
|
254
311
|
*/
|
|
255
|
-
|
|
256
|
-
contentRoot?: Element | null;
|
|
257
|
-
}): Promise<void>;
|
|
312
|
+
private selectMappedRangeText;
|
|
258
313
|
/**
|
|
259
|
-
* Pause playback
|
|
314
|
+
* Pause playback. A pause while the read is loading holds it: its audio does
|
|
315
|
+
* not start until {@link resume}.
|
|
260
316
|
*/
|
|
261
317
|
pause(): void;
|
|
262
318
|
/**
|
|
263
|
-
* Resume playback
|
|
319
|
+
* Resume playback, back to loading when the pause came before the audio
|
|
320
|
+
* started.
|
|
264
321
|
*/
|
|
265
322
|
resume(): void;
|
|
266
323
|
private normalizePlaybackRate;
|
|
@@ -273,6 +330,16 @@ export declare class TTSService {
|
|
|
273
330
|
* Stop playback
|
|
274
331
|
*/
|
|
275
332
|
stop(): void;
|
|
333
|
+
/**
|
|
334
|
+
* Stop playback and drop the provider, whose owner destroys it. A later speak
|
|
335
|
+
* waits on the readiness gate, as before the first {@link initialize}.
|
|
336
|
+
*/
|
|
337
|
+
releaseProvider(): void;
|
|
338
|
+
/**
|
|
339
|
+
* Stop, release the provider and drop every listener, hook and pending timer.
|
|
340
|
+
* A disposed service cannot speak or be initialized again.
|
|
341
|
+
*/
|
|
342
|
+
dispose(): void;
|
|
276
343
|
/**
|
|
277
344
|
* Request UI-level TTS controls to hand off/deactivate.
|
|
278
345
|
*
|
|
@@ -302,16 +369,10 @@ export declare class TTSService {
|
|
|
302
369
|
*/
|
|
303
370
|
getLastError(): string | null;
|
|
304
371
|
/**
|
|
305
|
-
* Subscribe to state changes
|
|
306
|
-
*
|
|
307
|
-
* @param id Unique listener ID
|
|
308
|
-
* @param callback Function to call on state change
|
|
309
|
-
*/
|
|
310
|
-
onStateChange(id: string, callback: (state: PlaybackState) => void): void;
|
|
311
|
-
/**
|
|
312
|
-
* Unsubscribe from state changes
|
|
372
|
+
* Subscribe to playback state changes. The returned function unsubscribes;
|
|
373
|
+
* each subscription is its own, so the same callback can be subscribed twice.
|
|
313
374
|
*/
|
|
314
|
-
|
|
375
|
+
onStateChange(callback: (state: PlaybackState) => void): () => void;
|
|
315
376
|
/**
|
|
316
377
|
* Set state and notify listeners
|
|
317
378
|
*/
|