@pie-players/pie-assessment-toolkit 0.2.0

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.
Files changed (194) hide show
  1. package/README.md +520 -0
  2. package/dist/attempt/TestSession.d.ts +90 -0
  3. package/dist/attempt/TestSession.d.ts.map +1 -0
  4. package/dist/attempt/TestSession.js +174 -0
  5. package/dist/attempt/TestSession.js.map +1 -0
  6. package/dist/core/TypedEventBus.d.ts +48 -0
  7. package/dist/core/TypedEventBus.d.ts.map +1 -0
  8. package/dist/core/TypedEventBus.js +63 -0
  9. package/dist/core/TypedEventBus.js.map +1 -0
  10. package/dist/index.d.ts +37 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +44 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/item-loader.d.ts +45 -0
  15. package/dist/item-loader.d.ts.map +1 -0
  16. package/dist/item-loader.js +62 -0
  17. package/dist/item-loader.js.map +1 -0
  18. package/dist/player/AssessmentPlayer.d.ts +388 -0
  19. package/dist/player/AssessmentPlayer.d.ts.map +1 -0
  20. package/dist/player/AssessmentPlayer.js +965 -0
  21. package/dist/player/AssessmentPlayer.js.map +1 -0
  22. package/dist/player/index.d.ts +17 -0
  23. package/dist/player/index.d.ts.map +1 -0
  24. package/dist/player/index.js +15 -0
  25. package/dist/player/index.js.map +1 -0
  26. package/dist/player/navigation-types.d.ts +63 -0
  27. package/dist/player/navigation-types.d.ts.map +1 -0
  28. package/dist/player/navigation-types.js +7 -0
  29. package/dist/player/navigation-types.js.map +1 -0
  30. package/dist/player/qti-navigation.d.ts +29 -0
  31. package/dist/player/qti-navigation.d.ts.map +1 -0
  32. package/dist/player/qti-navigation.js +160 -0
  33. package/dist/player/qti-navigation.js.map +1 -0
  34. package/dist/reference-layout/index.d.ts +19 -0
  35. package/dist/reference-layout/index.d.ts.map +1 -0
  36. package/dist/reference-layout/index.js +20 -0
  37. package/dist/reference-layout/index.js.map +1 -0
  38. package/dist/services/AccessibilityCatalogResolver.d.ts +141 -0
  39. package/dist/services/AccessibilityCatalogResolver.d.ts.map +1 -0
  40. package/dist/services/AccessibilityCatalogResolver.js +249 -0
  41. package/dist/services/AccessibilityCatalogResolver.js.map +1 -0
  42. package/dist/services/AssessmentAuthoringService.d.ts +60 -0
  43. package/dist/services/AssessmentAuthoringService.d.ts.map +1 -0
  44. package/dist/services/AssessmentAuthoringService.js +183 -0
  45. package/dist/services/AssessmentAuthoringService.js.map +1 -0
  46. package/dist/services/ContextVariableStore.d.ts +114 -0
  47. package/dist/services/ContextVariableStore.d.ts.map +1 -0
  48. package/dist/services/ContextVariableStore.js +207 -0
  49. package/dist/services/ContextVariableStore.js.map +1 -0
  50. package/dist/services/ElementToolStateStore.d.ts +125 -0
  51. package/dist/services/ElementToolStateStore.d.ts.map +1 -0
  52. package/dist/services/ElementToolStateStore.js +200 -0
  53. package/dist/services/ElementToolStateStore.js.map +1 -0
  54. package/dist/services/HighlightCoordinator.d.ts +179 -0
  55. package/dist/services/HighlightCoordinator.d.ts.map +1 -0
  56. package/dist/services/HighlightCoordinator.js +446 -0
  57. package/dist/services/HighlightCoordinator.js.map +1 -0
  58. package/dist/services/I18nService.d.ts +121 -0
  59. package/dist/services/I18nService.d.ts.map +1 -0
  60. package/dist/services/I18nService.js +276 -0
  61. package/dist/services/I18nService.js.map +1 -0
  62. package/dist/services/PNPMapper.d.ts +71 -0
  63. package/dist/services/PNPMapper.d.ts.map +1 -0
  64. package/dist/services/PNPMapper.js +98 -0
  65. package/dist/services/PNPMapper.js.map +1 -0
  66. package/dist/services/PNPToolResolver.d.ts +127 -0
  67. package/dist/services/PNPToolResolver.d.ts.map +1 -0
  68. package/dist/services/PNPToolResolver.js +222 -0
  69. package/dist/services/PNPToolResolver.js.map +1 -0
  70. package/dist/services/SSMLExtractor.d.ts +61 -0
  71. package/dist/services/SSMLExtractor.d.ts.map +1 -0
  72. package/dist/services/SSMLExtractor.js +181 -0
  73. package/dist/services/SSMLExtractor.js.map +1 -0
  74. package/dist/services/TTSService.d.ts +162 -0
  75. package/dist/services/TTSService.d.ts.map +1 -0
  76. package/dist/services/TTSService.js +465 -0
  77. package/dist/services/TTSService.js.map +1 -0
  78. package/dist/services/ThemeProvider.d.ts +95 -0
  79. package/dist/services/ThemeProvider.d.ts.map +1 -0
  80. package/dist/services/ThemeProvider.js +299 -0
  81. package/dist/services/ThemeProvider.js.map +1 -0
  82. package/dist/services/ToolConfigResolver.d.ts +162 -0
  83. package/dist/services/ToolConfigResolver.d.ts.map +1 -0
  84. package/dist/services/ToolConfigResolver.js +230 -0
  85. package/dist/services/ToolConfigResolver.js.map +1 -0
  86. package/dist/services/ToolCoordinator.d.ts +137 -0
  87. package/dist/services/ToolCoordinator.d.ts.map +1 -0
  88. package/dist/services/ToolCoordinator.js +318 -0
  89. package/dist/services/ToolCoordinator.js.map +1 -0
  90. package/dist/services/ToolkitCoordinator.d.ts +188 -0
  91. package/dist/services/ToolkitCoordinator.d.ts.map +1 -0
  92. package/dist/services/ToolkitCoordinator.js +252 -0
  93. package/dist/services/ToolkitCoordinator.js.map +1 -0
  94. package/dist/services/interfaces.d.ts +391 -0
  95. package/dist/services/interfaces.d.ts.map +1 -0
  96. package/dist/services/interfaces.js +12 -0
  97. package/dist/services/interfaces.js.map +1 -0
  98. package/dist/services/tool-providers/DesmosToolProvider.d.ts +103 -0
  99. package/dist/services/tool-providers/DesmosToolProvider.d.ts.map +1 -0
  100. package/dist/services/tool-providers/DesmosToolProvider.js +127 -0
  101. package/dist/services/tool-providers/DesmosToolProvider.js.map +1 -0
  102. package/dist/services/tool-providers/IToolProvider.d.ts +137 -0
  103. package/dist/services/tool-providers/IToolProvider.d.ts.map +1 -0
  104. package/dist/services/tool-providers/IToolProvider.js +13 -0
  105. package/dist/services/tool-providers/IToolProvider.js.map +1 -0
  106. package/dist/services/tool-providers/TIToolProvider.d.ts +107 -0
  107. package/dist/services/tool-providers/TIToolProvider.d.ts.map +1 -0
  108. package/dist/services/tool-providers/TIToolProvider.js +123 -0
  109. package/dist/services/tool-providers/TIToolProvider.js.map +1 -0
  110. package/dist/services/tool-providers/TTSToolProvider.d.ts +143 -0
  111. package/dist/services/tool-providers/TTSToolProvider.d.ts.map +1 -0
  112. package/dist/services/tool-providers/TTSToolProvider.js +168 -0
  113. package/dist/services/tool-providers/TTSToolProvider.js.map +1 -0
  114. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +165 -0
  115. package/dist/services/tool-providers/ToolProviderRegistry.d.ts.map +1 -0
  116. package/dist/services/tool-providers/ToolProviderRegistry.js +240 -0
  117. package/dist/services/tool-providers/ToolProviderRegistry.js.map +1 -0
  118. package/dist/services/tool-providers/index.d.ts +18 -0
  119. package/dist/services/tool-providers/index.d.ts.map +1 -0
  120. package/dist/services/tool-providers/index.js +15 -0
  121. package/dist/services/tool-providers/index.js.map +1 -0
  122. package/dist/services/tts/browser-provider.d.ts +24 -0
  123. package/dist/services/tts/browser-provider.d.ts.map +1 -0
  124. package/dist/services/tts/browser-provider.js +177 -0
  125. package/dist/services/tts/browser-provider.js.map +1 -0
  126. package/dist/services/tts/provider-interface.d.ts +131 -0
  127. package/dist/services/tts/provider-interface.d.ts.map +1 -0
  128. package/dist/services/tts/provider-interface.js +10 -0
  129. package/dist/services/tts/provider-interface.js.map +1 -0
  130. package/dist/tools/calculators/desmos-provider.d.ts +54 -0
  131. package/dist/tools/calculators/desmos-provider.d.ts.map +1 -0
  132. package/dist/tools/calculators/desmos-provider.js +384 -0
  133. package/dist/tools/calculators/desmos-provider.js.map +1 -0
  134. package/dist/tools/calculators/mathjs-provider.d.ts +50 -0
  135. package/dist/tools/calculators/mathjs-provider.d.ts.map +1 -0
  136. package/dist/tools/calculators/mathjs-provider.js +660 -0
  137. package/dist/tools/calculators/mathjs-provider.js.map +1 -0
  138. package/dist/tools/calculators/ti-provider.d.ts +122 -0
  139. package/dist/tools/calculators/ti-provider.d.ts.map +1 -0
  140. package/dist/tools/calculators/ti-provider.js +587 -0
  141. package/dist/tools/calculators/ti-provider.js.map +1 -0
  142. package/dist/tools/client.d.ts +17 -0
  143. package/dist/tools/client.d.ts.map +1 -0
  144. package/dist/tools/client.js +26 -0
  145. package/dist/tools/client.js.map +1 -0
  146. package/dist/tools/index.d.ts +8 -0
  147. package/dist/tools/index.d.ts.map +1 -0
  148. package/dist/tools/index.js +10 -0
  149. package/dist/tools/index.js.map +1 -0
  150. package/dist/tools/library-loader.d.ts +63 -0
  151. package/dist/tools/library-loader.d.ts.map +1 -0
  152. package/dist/tools/library-loader.js +292 -0
  153. package/dist/tools/library-loader.js.map +1 -0
  154. package/dist/tools/response-discovery.d.ts +72 -0
  155. package/dist/tools/response-discovery.d.ts.map +1 -0
  156. package/dist/tools/response-discovery.js +183 -0
  157. package/dist/tools/response-discovery.js.map +1 -0
  158. package/dist/tools/tool-coordinator.d.ts +76 -0
  159. package/dist/tools/tool-coordinator.d.ts.map +1 -0
  160. package/dist/tools/tool-coordinator.js +197 -0
  161. package/dist/tools/tool-coordinator.js.map +1 -0
  162. package/dist/tools/types.d.ts +427 -0
  163. package/dist/tools/types.d.ts.map +1 -0
  164. package/dist/tools/types.js +13 -0
  165. package/dist/tools/types.js.map +1 -0
  166. package/dist/tools/variant-resolver.d.ts +48 -0
  167. package/dist/tools/variant-resolver.d.ts.map +1 -0
  168. package/dist/tools/variant-resolver.js +214 -0
  169. package/dist/tools/variant-resolver.js.map +1 -0
  170. package/dist/types/events.d.ts +157 -0
  171. package/dist/types/events.d.ts.map +1 -0
  172. package/dist/types/events.js +11 -0
  173. package/dist/types/events.js.map +1 -0
  174. package/dist/utils/logger.d.ts +7 -0
  175. package/dist/utils/logger.d.ts.map +1 -0
  176. package/dist/utils/logger.js +11 -0
  177. package/dist/utils/logger.js.map +1 -0
  178. package/package.json +71 -0
  179. package/src/README.md +626 -0
  180. package/src/components/QuestionToolBar.svelte +406 -0
  181. package/src/player/AssessmentLayout.svelte +68 -0
  182. package/src/player/README.md +154 -0
  183. package/src/reference-layout/README.md +135 -0
  184. package/src/reference-layout/ReferenceLayout.svelte +209 -0
  185. package/src/reference-layout/components/AssessmentContent.svelte +259 -0
  186. package/src/reference-layout/components/AssessmentFooter.svelte +89 -0
  187. package/src/reference-layout/components/AssessmentHeader.svelte +250 -0
  188. package/src/reference-layout/components/AssessmentNavigation.svelte +134 -0
  189. package/src/reference-layout/components/AssessmentToolsBar.svelte +176 -0
  190. package/src/reference-layout/components/ItemPanel.svelte +200 -0
  191. package/src/reference-layout/components/NotesPanel.svelte +179 -0
  192. package/src/reference-layout/components/PassagePanel.svelte +76 -0
  193. package/src/tools/README.md +616 -0
  194. package/src/tools/calculators/README.md +395 -0
@@ -0,0 +1,162 @@
1
+ /**
2
+ * TTSService
3
+ *
4
+ * Text-to-speech service with pluggable provider architecture.
5
+ * Manages playback state, coordinates multiple TTS entry points,
6
+ * and integrates with HighlightCoordinator for word highlighting.
7
+ *
8
+ * Features:
9
+ * - Pluggable TTS providers (browser, AWS Polly, etc.)
10
+ * - QTI 3.0 accessibility catalogs (pre-authored spoken content)
11
+ * - Unified playback state management
12
+ * - Prevents conflicts from simultaneous speech
13
+ * - Word highlighting integration
14
+ * - Playback controls: play, pause, resume, stop
15
+ *
16
+ * Part of PIE Assessment Toolkit.
17
+ */
18
+ import type { ITTSProvider, TTSConfig, TTSProviderCapabilities } from "@pie-players/pie-tts";
19
+ import type { AccessibilityCatalogResolver } from "./AccessibilityCatalogResolver";
20
+ import type { IHighlightCoordinator } from "./interfaces";
21
+ export type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSFeature, TTSProviderCapabilities, } from "@pie-players/pie-tts";
22
+ /**
23
+ * Playback state
24
+ */
25
+ export declare enum PlaybackState {
26
+ IDLE = "idle",
27
+ LOADING = "loading",
28
+ PLAYING = "playing",
29
+ PAUSED = "paused",
30
+ ERROR = "error"
31
+ }
32
+ /**
33
+ * TTSService
34
+ *
35
+ * Instantiable service for text-to-speech functionality.
36
+ * Each instance manages its own playback state.
37
+ */
38
+ export declare class TTSService {
39
+ private currentProvider;
40
+ private provider;
41
+ private highlightCoordinator;
42
+ private catalogResolver;
43
+ private state;
44
+ private currentText;
45
+ private currentContentElement;
46
+ private normalizedToDOM;
47
+ private listeners;
48
+ private lastError;
49
+ constructor();
50
+ /**
51
+ * Initialize TTS service with a provider
52
+ *
53
+ * @param provider TTS provider instance
54
+ * @param config Provider configuration
55
+ */
56
+ initialize(provider: ITTSProvider, config?: Partial<TTSConfig>): Promise<void>;
57
+ /**
58
+ * Update TTS settings dynamically without full reinitialization
59
+ *
60
+ * This allows changing rate, pitch, and voice on the fly.
61
+ * Note: Some providers may require reinitialization for voice changes.
62
+ *
63
+ * @param settings Partial settings to update (rate, pitch, voice)
64
+ */
65
+ updateSettings(settings: Partial<TTSConfig>): Promise<void>;
66
+ /**
67
+ * Set highlight coordinator for word highlighting
68
+ */
69
+ setHighlightCoordinator(coordinator: IHighlightCoordinator): void;
70
+ /**
71
+ * Set accessibility catalog resolver for spoken content
72
+ *
73
+ * When set, the speak() method will check for pre-authored spoken
74
+ * content in catalogs before falling back to generated TTS.
75
+ *
76
+ * @param resolver AccessibilityCatalogResolver instance
77
+ */
78
+ setCatalogResolver(resolver: AccessibilityCatalogResolver): void;
79
+ /**
80
+ * Get provider capabilities
81
+ */
82
+ getCapabilities(): TTSProviderCapabilities | null;
83
+ /**
84
+ * Build a character-by-character map from normalized text positions to DOM positions
85
+ * This handles the complexity of whitespace normalization
86
+ */
87
+ private buildPositionMap;
88
+ /**
89
+ * Find text node and offsets for highlighting a word
90
+ *
91
+ * @param charIndex Character position in normalized/spoken text
92
+ * @param length Length of the word
93
+ * @returns Text node and local offsets, or null if not found
94
+ */
95
+ private findHighlightRange;
96
+ /**
97
+ * Speak text with optional catalog support
98
+ *
99
+ * @param text Text to speak (will be normalized: trimmed and whitespace collapsed)
100
+ * @param options Optional catalog ID, language, and content element for highlighting
101
+ */
102
+ speak(text: string, options?: {
103
+ catalogId?: string;
104
+ language?: string;
105
+ contentElement?: Element;
106
+ }): Promise<void>;
107
+ /**
108
+ * Speak a text range
109
+ *
110
+ * @param range DOM Range to speak
111
+ */
112
+ speakRange(range: Range): Promise<void>;
113
+ /**
114
+ * Pause playback
115
+ */
116
+ pause(): void;
117
+ /**
118
+ * Resume playback
119
+ */
120
+ resume(): void;
121
+ /**
122
+ * Stop playback
123
+ */
124
+ stop(): void;
125
+ /**
126
+ * Check if currently playing
127
+ */
128
+ isPlaying(): boolean;
129
+ /**
130
+ * Check if paused
131
+ */
132
+ isPaused(): boolean;
133
+ /**
134
+ * Get current state
135
+ */
136
+ getState(): PlaybackState;
137
+ /**
138
+ * Get current text being spoken
139
+ */
140
+ getCurrentText(): string | null;
141
+ /**
142
+ * Get the last error message
143
+ * Returns null if no error has occurred
144
+ */
145
+ getLastError(): string | null;
146
+ /**
147
+ * Subscribe to state changes
148
+ *
149
+ * @param id Unique listener ID
150
+ * @param callback Function to call on state change
151
+ */
152
+ onStateChange(id: string, callback: (state: PlaybackState) => void): void;
153
+ /**
154
+ * Unsubscribe from state changes
155
+ */
156
+ offStateChange(id: string, callback: (state: PlaybackState) => void): void;
157
+ /**
158
+ * Set state and notify listeners
159
+ */
160
+ private setState;
161
+ }
162
+ //# sourceMappingURL=TTSService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TTSService.d.ts","sourceRoot":"","sources":["../../src/services/TTSService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACX,YAAY,EAEZ,SAAS,EACT,uBAAuB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,YAAY,EACX,YAAY,EACZ,0BAA0B,EAC1B,SAAS,EACT,UAAU,EACV,uBAAuB,GACvB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,oBAAY,aAAa;IACxB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,KAAK,UAAU;CACf;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,oBAAoB,CAAsC;IAClE,OAAO,CAAC,eAAe,CAA6C;IACpE,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,eAAe,CACZ;IACX,OAAO,CAAC,SAAS,CAA0D;IAC3E,OAAO,CAAC,SAAS,CAAuB;;IAIxC;;;;;OAKG;IACG,UAAU,CACf,QAAQ,EAAE,YAAY,EACtB,MAAM,GAAE,OAAO,CAAC,SAAS,CAAM,GAC7B,OAAO,CAAC,IAAI,CAAC;IAOhB;;;;;;;OAOG;IACG,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjE;;OAEG;IACH,uBAAuB,CAAC,WAAW,EAAE,qBAAqB,GAAG,IAAI;IAIjE;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,4BAA4B,GAAG,IAAI;IAIhE;;OAEG;IACH,eAAe,IAAI,uBAAuB,GAAG,IAAI;IAIjD;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA2HxB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAyD1B;;;;;OAKG;IACG,KAAK,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,OAAO,CAAC;KACzB,GACC,OAAO,CAAC,IAAI,CAAC;IAiHhB;;;;OAIG;IACG,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACH,MAAM,IAAI,IAAI;IASd;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,QAAQ,IAAI,aAAa;IAIzB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;;OAGG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAOzE;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAU1E;;OAEG;IACH,OAAO,CAAC,QAAQ;CAYhB"}
@@ -0,0 +1,465 @@
1
+ /**
2
+ * TTSService
3
+ *
4
+ * Text-to-speech service with pluggable provider architecture.
5
+ * Manages playback state, coordinates multiple TTS entry points,
6
+ * and integrates with HighlightCoordinator for word highlighting.
7
+ *
8
+ * Features:
9
+ * - Pluggable TTS providers (browser, AWS Polly, etc.)
10
+ * - QTI 3.0 accessibility catalogs (pre-authored spoken content)
11
+ * - Unified playback state management
12
+ * - Prevents conflicts from simultaneous speech
13
+ * - Word highlighting integration
14
+ * - Playback controls: play, pause, resume, stop
15
+ *
16
+ * Part of PIE Assessment Toolkit.
17
+ */
18
+ /**
19
+ * Playback state
20
+ */
21
+ export var PlaybackState;
22
+ (function (PlaybackState) {
23
+ PlaybackState["IDLE"] = "idle";
24
+ PlaybackState["LOADING"] = "loading";
25
+ PlaybackState["PLAYING"] = "playing";
26
+ PlaybackState["PAUSED"] = "paused";
27
+ PlaybackState["ERROR"] = "error";
28
+ })(PlaybackState || (PlaybackState = {}));
29
+ /**
30
+ * TTSService
31
+ *
32
+ * Instantiable service for text-to-speech functionality.
33
+ * Each instance manages its own playback state.
34
+ */
35
+ export class TTSService {
36
+ currentProvider = null;
37
+ provider = null;
38
+ highlightCoordinator = null;
39
+ catalogResolver = null;
40
+ state = PlaybackState.IDLE;
41
+ currentText = null;
42
+ currentContentElement = null;
43
+ normalizedToDOM = new Map();
44
+ listeners = new Map();
45
+ lastError = null;
46
+ constructor() { }
47
+ /**
48
+ * Initialize TTS service with a provider
49
+ *
50
+ * @param provider TTS provider instance
51
+ * @param config Provider configuration
52
+ */
53
+ async initialize(provider, config = {}) {
54
+ this.currentProvider = provider;
55
+ // Initialize provider and get implementation
56
+ this.provider = await provider.initialize(config);
57
+ }
58
+ /**
59
+ * Update TTS settings dynamically without full reinitialization
60
+ *
61
+ * This allows changing rate, pitch, and voice on the fly.
62
+ * Note: Some providers may require reinitialization for voice changes.
63
+ *
64
+ * @param settings Partial settings to update (rate, pitch, voice)
65
+ */
66
+ async updateSettings(settings) {
67
+ if (!this.provider) {
68
+ throw new Error("TTSService not initialized. Call initialize() first.");
69
+ }
70
+ // If the provider implementation has an updateSettings method, use it
71
+ if ("updateSettings" in this.provider &&
72
+ typeof this.provider.updateSettings === "function") {
73
+ await this.provider.updateSettings(settings);
74
+ }
75
+ else {
76
+ // Fallback: Reinitialize with merged config
77
+ // This requires storing the original config, which we don't have
78
+ // So for now, just log a warning
79
+ console.warn("[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.");
80
+ }
81
+ }
82
+ /**
83
+ * Set highlight coordinator for word highlighting
84
+ */
85
+ setHighlightCoordinator(coordinator) {
86
+ this.highlightCoordinator = coordinator;
87
+ }
88
+ /**
89
+ * Set accessibility catalog resolver for spoken content
90
+ *
91
+ * When set, the speak() method will check for pre-authored spoken
92
+ * content in catalogs before falling back to generated TTS.
93
+ *
94
+ * @param resolver AccessibilityCatalogResolver instance
95
+ */
96
+ setCatalogResolver(resolver) {
97
+ this.catalogResolver = resolver;
98
+ }
99
+ /**
100
+ * Get provider capabilities
101
+ */
102
+ getCapabilities() {
103
+ return this.currentProvider?.getCapabilities() || null;
104
+ }
105
+ /**
106
+ * Build a character-by-character map from normalized text positions to DOM positions
107
+ * This handles the complexity of whitespace normalization
108
+ */
109
+ buildPositionMap(element, spokenText) {
110
+ this.normalizedToDOM.clear();
111
+ // Get the actual DOM text as it will be rendered
112
+ const range = document.createRange();
113
+ range.selectNodeContents(element);
114
+ const domText = range.toString();
115
+ // Normalize the DOM text the same way the spoken text is normalized
116
+ // (trim + collapse whitespace)
117
+ const normalizedDomText = domText.trim().replace(/\s+/g, " ");
118
+ console.log("[TTSService] Text comparison:", {
119
+ spokenLength: spokenText.length,
120
+ normalizedDomLength: normalizedDomText.length,
121
+ match: spokenText === normalizedDomText,
122
+ spokenPreview: spokenText.substring(0, 150),
123
+ normalizedPreview: normalizedDomText.substring(0, 150),
124
+ differAtIndex: spokenText === normalizedDomText
125
+ ? null
126
+ : (() => {
127
+ for (let i = 0; i < Math.min(spokenText.length, normalizedDomText.length); i++) {
128
+ if (spokenText[i] !== normalizedDomText[i]) {
129
+ return {
130
+ index: i,
131
+ spokenChar: spokenText[i],
132
+ normalizedChar: normalizedDomText[i],
133
+ spokenContext: spokenText.substring(Math.max(0, i - 20), i + 20),
134
+ normalizedContext: normalizedDomText.substring(Math.max(0, i - 20), i + 20),
135
+ };
136
+ }
137
+ }
138
+ return null;
139
+ })(),
140
+ });
141
+ // Build map by walking through nodes and tracking normalized position
142
+ let normalizedPos = 0;
143
+ let inLeadingWhitespace = true;
144
+ let lastCharWasWhitespace = false;
145
+ const walk = (node) => {
146
+ if (node.nodeType === Node.TEXT_NODE) {
147
+ const textNode = node;
148
+ const text = textNode.textContent || "";
149
+ for (let i = 0; i < text.length; i++) {
150
+ const char = text[i];
151
+ const isWhitespace = /\s/.test(char);
152
+ if (inLeadingWhitespace) {
153
+ // Skip leading whitespace entirely - don't map it
154
+ if (!isWhitespace) {
155
+ inLeadingWhitespace = false;
156
+ this.normalizedToDOM.set(normalizedPos, {
157
+ node: textNode,
158
+ offset: i,
159
+ });
160
+ normalizedPos++;
161
+ lastCharWasWhitespace = false;
162
+ }
163
+ }
164
+ else {
165
+ // Past leading whitespace
166
+ if (isWhitespace) {
167
+ // Only map the first whitespace in a sequence (collapse multiple)
168
+ if (!lastCharWasWhitespace) {
169
+ this.normalizedToDOM.set(normalizedPos, {
170
+ node: textNode,
171
+ offset: i,
172
+ });
173
+ normalizedPos++;
174
+ }
175
+ lastCharWasWhitespace = true;
176
+ }
177
+ else {
178
+ // Regular character - always map it
179
+ this.normalizedToDOM.set(normalizedPos, {
180
+ node: textNode,
181
+ offset: i,
182
+ });
183
+ normalizedPos++;
184
+ lastCharWasWhitespace = false;
185
+ }
186
+ }
187
+ }
188
+ }
189
+ else if (node.nodeType === Node.ELEMENT_NODE) {
190
+ const element = node;
191
+ if (element.tagName !== "SCRIPT" && element.tagName !== "STYLE") {
192
+ for (const child of Array.from(node.childNodes)) {
193
+ walk(child);
194
+ }
195
+ }
196
+ }
197
+ };
198
+ walk(element);
199
+ console.log("[TTSService] Position map built:", {
200
+ entries: this.normalizedToDOM.size,
201
+ spokenTextLength: spokenText.length,
202
+ normalizedDomLength: normalizedDomText.length,
203
+ mapLengthMatchesSpoken: this.normalizedToDOM.size === spokenText.length,
204
+ firstFewMappings: Array.from(this.normalizedToDOM.entries())
205
+ .slice(0, 10)
206
+ .map(([pos, { node, offset }]) => ({
207
+ pos,
208
+ offset,
209
+ char: node.textContent?.[offset],
210
+ expected: spokenText[pos],
211
+ })),
212
+ });
213
+ }
214
+ /**
215
+ * Find text node and offsets for highlighting a word
216
+ *
217
+ * @param charIndex Character position in normalized/spoken text
218
+ * @param length Length of the word
219
+ * @returns Text node and local offsets, or null if not found
220
+ */
221
+ findHighlightRange(charIndex, length) {
222
+ const startPos = this.normalizedToDOM.get(charIndex);
223
+ if (!startPos) {
224
+ console.warn(`[TTSService] No mapping found for start position ${charIndex}`, {
225
+ totalMappings: this.normalizedToDOM.size,
226
+ nearbyMappings: Array.from(this.normalizedToDOM.entries())
227
+ .filter(([pos]) => Math.abs(pos - charIndex) < 5)
228
+ .map(([pos, { offset, node }]) => ({
229
+ pos,
230
+ offset,
231
+ char: node.textContent?.[offset],
232
+ })),
233
+ });
234
+ return null;
235
+ }
236
+ // Find the end position (last character of the word)
237
+ const endIndex = charIndex + length - 1;
238
+ const endPos = this.normalizedToDOM.get(endIndex);
239
+ if (!endPos) {
240
+ console.warn(`[TTSService] No mapping found for end position ${endIndex}`, {
241
+ startChar: charIndex,
242
+ length,
243
+ totalMappings: this.normalizedToDOM.size,
244
+ });
245
+ return null;
246
+ }
247
+ // For simplicity, if the word spans multiple nodes, just highlight in the first node
248
+ // (This is a rare edge case and would require creating multiple ranges)
249
+ if (startPos.node !== endPos.node) {
250
+ console.warn(`[TTSService] Word spans multiple nodes, highlighting in first node only`);
251
+ return {
252
+ node: startPos.node,
253
+ start: startPos.offset,
254
+ end: (startPos.node.textContent || "").length,
255
+ };
256
+ }
257
+ return {
258
+ node: startPos.node,
259
+ start: startPos.offset,
260
+ end: endPos.offset + 1, // +1 because we want to include the character at endPos
261
+ };
262
+ }
263
+ /**
264
+ * Speak text with optional catalog support
265
+ *
266
+ * @param text Text to speak (will be normalized: trimmed and whitespace collapsed)
267
+ * @param options Optional catalog ID, language, and content element for highlighting
268
+ */
269
+ async speak(text, options) {
270
+ if (!this.provider) {
271
+ throw new Error("TTS service not initialized");
272
+ }
273
+ // Normalize the input text to ensure consistency
274
+ // This handles cases where the caller didn't normalize
275
+ const normalizedText = text.trim().replace(/\s+/g, " ");
276
+ // Try to resolve from accessibility catalog if catalogId provided
277
+ let contentToSpeak = normalizedText;
278
+ if (options?.catalogId && this.catalogResolver) {
279
+ const catalogContent = this.catalogResolver.getAlternative(options.catalogId, {
280
+ type: "spoken",
281
+ language: options.language || "en-US",
282
+ useFallback: true,
283
+ });
284
+ if (catalogContent) {
285
+ // Use pre-authored spoken content from catalog
286
+ contentToSpeak = catalogContent.content;
287
+ console.debug(`[TTSService] Using catalog content for "${options.catalogId}" (${catalogContent.language})`);
288
+ }
289
+ else {
290
+ console.debug(`[TTSService] No catalog found for "${options.catalogId}", falling back to generated TTS`);
291
+ }
292
+ }
293
+ this.currentText = contentToSpeak;
294
+ this.currentContentElement = options?.contentElement || null;
295
+ this.lastError = null; // Clear previous error
296
+ this.setState(PlaybackState.LOADING);
297
+ // Build position map for highlighting if we have a content element
298
+ if (this.currentContentElement && this.highlightCoordinator) {
299
+ this.buildPositionMap(this.currentContentElement, contentToSpeak);
300
+ // Apply sentence-level highlighting as base layer
301
+ const range = document.createRange();
302
+ range.selectNodeContents(this.currentContentElement);
303
+ this.highlightCoordinator.highlightTTSSentence([range]);
304
+ console.log("[TTSService] Applied sentence-level highlighting");
305
+ }
306
+ try {
307
+ // Setup word boundary highlighting
308
+ if (this.highlightCoordinator && this.currentContentElement) {
309
+ this.provider.onWordBoundary = (word, charIndex, length) => {
310
+ const wordLength = length || word.length;
311
+ const highlightRange = this.findHighlightRange(charIndex, wordLength);
312
+ if (highlightRange && this.highlightCoordinator) {
313
+ const highlightText = highlightRange.node.textContent?.substring(highlightRange.start, highlightRange.end) || "";
314
+ console.log(`[TTSService] Highlighting "${highlightText}" (word: "${word}") at position ${charIndex}`);
315
+ this.highlightCoordinator.highlightTTSWord(highlightRange.node, highlightRange.start, highlightRange.end);
316
+ }
317
+ else {
318
+ console.warn(`[TTSService] Could not find highlight range for position ${charIndex}, length ${wordLength}`);
319
+ }
320
+ };
321
+ }
322
+ this.setState(PlaybackState.PLAYING);
323
+ await this.provider.speak(contentToSpeak);
324
+ this.setState(PlaybackState.IDLE);
325
+ // Clear highlights when done
326
+ if (this.highlightCoordinator) {
327
+ this.highlightCoordinator.clearTTS();
328
+ }
329
+ // Clear tracking
330
+ this.currentContentElement = null;
331
+ this.normalizedToDOM.clear();
332
+ }
333
+ catch (error) {
334
+ console.error("TTS error:", error);
335
+ this.lastError = error instanceof Error ? error.message : String(error);
336
+ this.setState(PlaybackState.ERROR);
337
+ // Clear highlights on error
338
+ if (this.highlightCoordinator) {
339
+ this.highlightCoordinator.clearTTS();
340
+ }
341
+ // Clear tracking
342
+ this.currentContentElement = null;
343
+ this.normalizedToDOM.clear();
344
+ throw error;
345
+ }
346
+ }
347
+ /**
348
+ * Speak a text range
349
+ *
350
+ * @param range DOM Range to speak
351
+ */
352
+ async speakRange(range) {
353
+ const text = range.toString();
354
+ await this.speak(text);
355
+ }
356
+ /**
357
+ * Pause playback
358
+ */
359
+ pause() {
360
+ if (!this.provider)
361
+ return;
362
+ if (this.state === PlaybackState.PLAYING) {
363
+ this.provider.pause();
364
+ this.setState(PlaybackState.PAUSED);
365
+ }
366
+ }
367
+ /**
368
+ * Resume playback
369
+ */
370
+ resume() {
371
+ if (!this.provider)
372
+ return;
373
+ if (this.state === PlaybackState.PAUSED) {
374
+ this.provider.resume();
375
+ this.setState(PlaybackState.PLAYING);
376
+ }
377
+ }
378
+ /**
379
+ * Stop playback
380
+ */
381
+ stop() {
382
+ if (!this.provider)
383
+ return;
384
+ this.provider.stop();
385
+ this.setState(PlaybackState.IDLE);
386
+ this.currentText = null;
387
+ // Clear highlights
388
+ if (this.highlightCoordinator) {
389
+ this.highlightCoordinator.clearTTS();
390
+ }
391
+ // Clear tracking
392
+ this.currentContentElement = null;
393
+ this.normalizedToDOM.clear();
394
+ }
395
+ /**
396
+ * Check if currently playing
397
+ */
398
+ isPlaying() {
399
+ return this.state === PlaybackState.PLAYING;
400
+ }
401
+ /**
402
+ * Check if paused
403
+ */
404
+ isPaused() {
405
+ return this.state === PlaybackState.PAUSED;
406
+ }
407
+ /**
408
+ * Get current state
409
+ */
410
+ getState() {
411
+ return this.state;
412
+ }
413
+ /**
414
+ * Get current text being spoken
415
+ */
416
+ getCurrentText() {
417
+ return this.currentText;
418
+ }
419
+ /**
420
+ * Get the last error message
421
+ * Returns null if no error has occurred
422
+ */
423
+ getLastError() {
424
+ return this.lastError;
425
+ }
426
+ /**
427
+ * Subscribe to state changes
428
+ *
429
+ * @param id Unique listener ID
430
+ * @param callback Function to call on state change
431
+ */
432
+ onStateChange(id, callback) {
433
+ if (!this.listeners.has(id)) {
434
+ this.listeners.set(id, new Set());
435
+ }
436
+ this.listeners.get(id).add(callback);
437
+ }
438
+ /**
439
+ * Unsubscribe from state changes
440
+ */
441
+ offStateChange(id, callback) {
442
+ const callbacks = this.listeners.get(id);
443
+ if (callbacks) {
444
+ callbacks.delete(callback);
445
+ if (callbacks.size === 0) {
446
+ this.listeners.delete(id);
447
+ }
448
+ }
449
+ }
450
+ /**
451
+ * Set state and notify listeners
452
+ */
453
+ setState(newState) {
454
+ if (this.state === newState)
455
+ return;
456
+ this.state = newState;
457
+ // Notify all listeners
458
+ for (const callbacks of this.listeners.values()) {
459
+ for (const callback of callbacks) {
460
+ callback(newState);
461
+ }
462
+ }
463
+ }
464
+ }
465
+ //# sourceMappingURL=TTSService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TTSService.js","sourceRoot":"","sources":["../../src/services/TTSService.ts"],"names":[],"mappings":"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"}