@pie-players/pie-section-player 0.3.43 → 0.3.45

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 (90) hide show
  1. package/README.md +11 -23
  2. package/dist/chunks/dist-24a90544.js +198 -173
  3. package/dist/chunks/{dist-DIBQdekL-ec6db34a.js → dist-DfQrc9XY-6d8e61c6.js} +175 -150
  4. package/dist/chunks/{dist-rF11IR1B-adc4857f.js → dist-Dns3leWh-4f7af4d3.js} +1 -1
  5. package/dist/chunks/dist-c4148994.js +1 -1
  6. package/dist/chunks/sre-0162a7a9.js +17534 -0
  7. package/dist/chunks/sre-CXN7ed6H-7db47d5d.js +17532 -0
  8. package/dist/chunks/tool-annotation-toolbar-db5bfbec.js +5303 -2118
  9. package/dist/component-definitions.d.ts +0 -1
  10. package/dist/components/item-shell-element.d.ts +0 -1
  11. package/dist/components/passage-shell-element.d.ts +0 -1
  12. package/dist/components/section-player-base-element.d.ts +0 -1
  13. package/dist/components/section-player-item-card-element.d.ts +0 -1
  14. package/dist/components/section-player-items-pane-element.d.ts +0 -1
  15. package/dist/components/section-player-kernel-host-element.d.ts +0 -1
  16. package/dist/components/section-player-passage-card-element.d.ts +0 -1
  17. package/dist/components/section-player-passages-pane-element.d.ts +0 -1
  18. package/dist/components/section-player-shell-element.d.ts +0 -1
  19. package/dist/components/section-player-splitpane-element.d.ts +0 -1
  20. package/dist/components/section-player-tabbed-element.d.ts +0 -1
  21. package/dist/components/section-player-vertical-element.d.ts +0 -1
  22. package/dist/components/shared/composition.d.ts +0 -1
  23. package/dist/components/shared/player-action.d.ts +0 -1
  24. package/dist/components/shared/player-preload.d.ts +0 -1
  25. package/dist/components/shared/section-player-card-context.d.ts +0 -1
  26. package/dist/components/shared/section-player-host-runtime.d.ts +2 -12
  27. package/dist/components/shared/section-player-props.d.ts +0 -1
  28. package/dist/components/shared/section-player-runtime-callbacks.d.ts +0 -1
  29. package/dist/components/shared/section-player-view-state.d.ts +0 -1
  30. package/dist/contracts/card-title-formatters.d.ts +0 -1
  31. package/dist/contracts/host-hooks.d.ts +0 -1
  32. package/dist/contracts/layout-contract.d.ts +2 -3
  33. package/dist/contracts/layout-parity-metadata.d.ts +0 -1
  34. package/dist/contracts/public-events.d.ts +8 -16
  35. package/dist/contracts/runtime-host-contract.d.ts +0 -1
  36. package/dist/contracts/stages.d.ts +0 -1
  37. package/dist/controllers/SectionContentService.d.ts +0 -1
  38. package/dist/controllers/SectionController.d.ts +0 -1
  39. package/dist/controllers/SectionItemNavigationService.d.ts +0 -1
  40. package/dist/controllers/SectionSessionService.d.ts +0 -1
  41. package/dist/controllers/toolkit-section-contracts.d.ts +0 -1
  42. package/dist/controllers/types.d.ts +0 -1
  43. package/dist/pie-section-player.d.ts +0 -1
  44. package/dist/pie-section-player.js +42872 -19696
  45. package/dist/policies/guards.d.ts +0 -1
  46. package/dist/policies/index.d.ts +0 -1
  47. package/dist/policies/types.d.ts +0 -1
  48. package/dist/utils/z-index.d.ts +0 -1
  49. package/package.json +10 -10
  50. package/dist/component-definitions.d.ts.map +0 -1
  51. package/dist/components/item-shell-element.d.ts.map +0 -1
  52. package/dist/components/passage-shell-element.d.ts.map +0 -1
  53. package/dist/components/section-player-base-element.d.ts.map +0 -1
  54. package/dist/components/section-player-item-card-element.d.ts.map +0 -1
  55. package/dist/components/section-player-items-pane-element.d.ts.map +0 -1
  56. package/dist/components/section-player-kernel-host-element.d.ts.map +0 -1
  57. package/dist/components/section-player-passage-card-element.d.ts.map +0 -1
  58. package/dist/components/section-player-passages-pane-element.d.ts.map +0 -1
  59. package/dist/components/section-player-shell-element.d.ts.map +0 -1
  60. package/dist/components/section-player-splitpane-element.d.ts.map +0 -1
  61. package/dist/components/section-player-tabbed-element.d.ts.map +0 -1
  62. package/dist/components/section-player-vertical-element.d.ts.map +0 -1
  63. package/dist/components/shared/composition.d.ts.map +0 -1
  64. package/dist/components/shared/player-action.d.ts.map +0 -1
  65. package/dist/components/shared/player-preload.d.ts.map +0 -1
  66. package/dist/components/shared/section-player-card-context.d.ts.map +0 -1
  67. package/dist/components/shared/section-player-host-runtime.d.ts.map +0 -1
  68. package/dist/components/shared/section-player-props.d.ts.map +0 -1
  69. package/dist/components/shared/section-player-runtime-callbacks.d.ts.map +0 -1
  70. package/dist/components/shared/section-player-view-state.d.ts.map +0 -1
  71. package/dist/contracts/card-title-formatters.d.ts.map +0 -1
  72. package/dist/contracts/host-hooks.d.ts.map +0 -1
  73. package/dist/contracts/layout-contract.d.ts.map +0 -1
  74. package/dist/contracts/layout-parity-metadata.d.ts.map +0 -1
  75. package/dist/contracts/public-events.d.ts.map +0 -1
  76. package/dist/contracts/runtime-host-contract.d.ts.map +0 -1
  77. package/dist/contracts/stages.d.ts.map +0 -1
  78. package/dist/controllers/SectionContentService.d.ts.map +0 -1
  79. package/dist/controllers/SectionController.d.ts.map +0 -1
  80. package/dist/controllers/SectionItemNavigationService.d.ts.map +0 -1
  81. package/dist/controllers/SectionSessionService.d.ts.map +0 -1
  82. package/dist/controllers/toolkit-section-contracts.d.ts.map +0 -1
  83. package/dist/controllers/types.d.ts.map +0 -1
  84. package/dist/pie-section-player.d.ts.map +0 -1
  85. package/dist/policies/guards.d.ts.map +0 -1
  86. package/dist/policies/index.d.ts.map +0 -1
  87. package/dist/policies/types.d.ts.map +0 -1
  88. package/dist/utils/z-index.d.ts.map +0 -1
  89. /package/dist/chunks/{defineProperty-aab5a8e0.js → defineProperty-8fd4b6d7.js} +0 -0
  90. /package/dist/chunks/{defineProperty-CyepwRr5-3800a70a.js → defineProperty-Dt7ri80W-76aeaed7.js} +0 -0
@@ -1,22 +1,22 @@
1
- import { t as d } from "./defineProperty-CyepwRr5-3800a70a.js";
2
- function w(e, t) {
1
+ import { t as h } from "./defineProperty-Dt7ri80W-76aeaed7.js";
2
+ function T(e, t) {
3
3
  if (typeof e != "string" || e.length === 0) return null;
4
4
  try {
5
- const i = typeof t.apiEndpoint == "string" && /^https?:\/\//i.test(t.apiEndpoint) ? t.apiEndpoint : void 0, r = i ? new URL(e, i) : new URL(e);
6
- return r.protocol !== "http:" && r.protocol !== "https:" ? null : r;
5
+ const r = typeof t.apiEndpoint == "string" && /^https?:\/\//i.test(t.apiEndpoint) ? t.apiEndpoint : void 0, i = r ? new URL(e, r) : new URL(e);
6
+ return i.protocol !== "http:" && i.protocol !== "https:" ? null : i;
7
7
  } catch {
8
8
  return null;
9
9
  }
10
10
  }
11
- function k(e, t) {
12
- const i = Array.isArray(t.assetOrigins) ? t.assetOrigins.filter((r) => typeof r == "string" && r.length > 0).map((r) => {
11
+ function A(e, t) {
12
+ const r = Array.isArray(t.assetOrigins) ? t.assetOrigins.filter((i) => typeof i == "string" && i.length > 0).map((i) => {
13
13
  try {
14
- return new URL(r).origin;
14
+ return new URL(i).origin;
15
15
  } catch {
16
- return r;
16
+ return i;
17
17
  }
18
18
  }) : [];
19
- if (i.length === 0) {
19
+ if (r.length === 0) {
20
20
  if (typeof t.apiEndpoint == "string" && /^https?:\/\//i.test(t.apiEndpoint)) try {
21
21
  return new URL(t.apiEndpoint).origin === e.origin;
22
22
  } catch {
@@ -24,79 +24,83 @@ function k(e, t) {
24
24
  }
25
25
  return typeof window < "u" && typeof window.location?.origin == "string" && window.location.origin === e.origin;
26
26
  }
27
- return i.includes(e.origin);
27
+ return r.includes(e.origin);
28
28
  }
29
- function A(e) {
29
+ function R(e) {
30
30
  const t = {};
31
- for (const [i, r] of Object.entries(e)) {
32
- const o = i.toLowerCase();
33
- o === "authorization" || o === "proxy-authorization" || o === "cookie" || o.startsWith("x-auth-") || (t[i] = r);
31
+ for (const [r, i] of Object.entries(e)) {
32
+ const o = r.toLowerCase();
33
+ o === "authorization" || o === "proxy-authorization" || o === "cookie" || o.startsWith("x-auth-") || (t[r] = i);
34
34
  }
35
35
  return t;
36
36
  }
37
- var R = (e) => {
37
+ var I = (e) => {
38
38
  const t = (e.providerOptions && typeof e.providerOptions == "object" ? e.providerOptions : {}).__pieTelemetry;
39
39
  return typeof t == "function" ? t : void 0;
40
40
  }, E = {
41
41
  pie: 3e3,
42
42
  custom: 3e3
43
- }, T = (e) => e.replace(/\/+$/, ""), M = (e) => {
44
- const t = T(e.apiEndpoint), i = (e.provider || "").toLowerCase();
45
- return i === "polly" || i === "google" ? `${t}/${i}/voices` : `${t}/voices`;
46
- }, b = (e) => e.transportMode === "custom" ? "custom" : e.transportMode === "pie" ? "pie" : e.provider === "custom" ? "custom" : "pie", S = (e, t) => e.endpointMode ? e.endpointMode : t === "custom" ? "rootPost" : "synthesizePath", U = (e, t) => e.endpointValidationMode ? e.endpointValidationMode : t === "custom" ? "none" : "voices", P = (e) => {
43
+ }, P = /* @__PURE__ */ new Set(["polly", "google"]), U = (e) => {
44
+ if (!e || b(e) !== "pie") return !1;
45
+ const t = (e.provider || "polly").toLowerCase();
46
+ return P.has(t);
47
+ }, S = (e) => e.replace(/\/+$/, ""), z = (e) => {
48
+ const t = S(e.apiEndpoint), r = (e.provider || "").toLowerCase();
49
+ return r === "polly" || r === "google" ? `${t}/${r}/voices` : `${t}/voices`;
50
+ }, b = (e) => e.transportMode === "custom" ? "custom" : e.transportMode === "pie" ? "pie" : e.provider === "custom" ? "custom" : "pie", k = (e, t) => e.endpointMode ? e.endpointMode : t === "custom" ? "rootPost" : "synthesizePath", M = (e, t) => e.endpointValidationMode ? e.endpointValidationMode : t === "custom" ? "none" : "voices", O = (e) => {
47
51
  const t = e.providerOptions || {};
48
52
  if (typeof t.speedRate == "string") return t.speedRate;
49
- const i = Number(e.rate ?? 1);
50
- return !Number.isFinite(i) || i <= 0.95 ? "slow" : i >= 1.5 ? "fast" : "medium";
51
- }, z = (e) => {
53
+ const r = Number(e.rate ?? 1);
54
+ return !Number.isFinite(r) || r <= 0.95 ? "slow" : r >= 1.5 ? "fast" : "medium";
55
+ }, C = (e) => {
52
56
  const t = [];
53
- let i = 0;
54
- const r = e.split(`
57
+ let r = 0;
58
+ const i = e.split(`
55
59
  `).map((o) => o.trim()).filter(Boolean);
56
- for (const o of r) try {
57
- const s = JSON.parse(o), a = typeof s.type == "string" ? s.type : "word", h = typeof s.time == "number" && Number.isFinite(s.time) ? s.time : 0, n = typeof s.value == "string" ? s.value : "", c = typeof s.start == "number" && Number.isFinite(s.start) ? s.start : null, u = typeof s.end == "number" && Number.isFinite(s.end) ? s.end : null, p = c ?? i, l = u ?? p + Math.max(1, n.length || String(s.value || "").length);
58
- i = Math.max(l + 1, i), t.push({
59
- time: h,
60
+ for (const o of i) try {
61
+ const s = JSON.parse(o), a = typeof s.type == "string" ? s.type : "word", n = typeof s.time == "number" && Number.isFinite(s.time) ? s.time : 0, l = typeof s.value == "string" ? s.value : "", d = typeof s.start == "number" && Number.isFinite(s.start) ? s.start : null, u = typeof s.end == "number" && Number.isFinite(s.end) ? s.end : null, g = d ?? r, c = u ?? g + Math.max(1, l.length || String(s.value || "").length);
62
+ r = Math.max(c + 1, r), t.push({
63
+ time: n,
60
64
  type: a,
61
- start: p,
62
- end: l,
63
- value: n
65
+ start: g,
66
+ end: c,
67
+ value: l
64
68
  });
65
69
  } catch {
66
70
  }
67
71
  return t;
68
- }, C = (e) => {
72
+ }, L = (e) => {
69
73
  if (!Array.isArray(e)) return [];
70
74
  const t = [];
71
- let i = 0;
72
- for (const r of e) {
73
- if (!r || typeof r != "object") continue;
74
- const o = typeof r.type == "string" ? r.type : "word", s = typeof r.time == "number" && Number.isFinite(r.time) ? r.time : 0, a = typeof r.value == "string" ? r.value : "", h = typeof r.start == "number" && Number.isFinite(r.start) ? r.start : null, n = typeof r.end == "number" && Number.isFinite(r.end) ? r.end : null, c = h ?? i, u = n ?? c + Math.max(1, a.length || 1);
75
- i = Math.max(i, u + 1), t.push({
75
+ let r = 0;
76
+ for (const i of e) {
77
+ if (!i || typeof i != "object") continue;
78
+ const o = typeof i.type == "string" ? i.type : "word", s = typeof i.time == "number" && Number.isFinite(i.time) ? i.time : 0, a = typeof i.value == "string" ? i.value : "", n = typeof i.start == "number" && Number.isFinite(i.start) ? i.start : null, l = typeof i.end == "number" && Number.isFinite(i.end) ? i.end : null, d = n ?? r, u = l ?? d + Math.max(1, a.length || 1);
79
+ r = Math.max(r, u + 1), t.push({
76
80
  time: s,
77
81
  type: o,
78
- start: c,
82
+ start: d,
79
83
  end: u,
80
84
  value: a
81
85
  });
82
86
  }
83
- return t.sort((r, o) => r.time !== o.time ? r.time - o.time : r.start !== o.start ? r.start - o.start : r.end - o.end);
84
- }, O = {
87
+ return t.sort((i, o) => i.time !== o.time ? i.time - o.time : i.start !== o.start ? i.start - o.start : i.end - o.end);
88
+ }, B = {
85
89
  pie: {
86
90
  id: "pie",
87
91
  resolveSynthesisUrl: (e) => {
88
- const t = S(e, "pie"), i = T(e.apiEndpoint);
89
- return t === "rootPost" ? i : `${i}/synthesize`;
92
+ const t = k(e, "pie"), r = S(e.apiEndpoint);
93
+ return t === "rootPost" ? r : `${r}/synthesize`;
90
94
  },
91
95
  buildRequestBody: (e, t) => {
92
- const i = t.providerOptions || {}, r = typeof t.engine == "string" ? t.engine : typeof i.engine == "string" ? i.engine : void 0, o = typeof i.sampleRate == "number" && Number.isFinite(i.sampleRate) ? i.sampleRate : void 0, s = i.format === "mp3" || i.format === "ogg" || i.format === "pcm" ? i.format : void 0, a = Array.isArray(i.speechMarkTypes) ? i.speechMarkTypes.filter((h) => h === "word" || h === "sentence" || h === "ssml") : void 0;
96
+ const r = t.providerOptions || {}, i = typeof t.engine == "string" ? t.engine : typeof r.engine == "string" ? r.engine : void 0, o = typeof r.sampleRate == "number" && Number.isFinite(r.sampleRate) ? r.sampleRate : void 0, s = r.format === "mp3" || r.format === "ogg" || r.format === "pcm" ? r.format : void 0, a = Array.isArray(r.speechMarkTypes) ? r.speechMarkTypes.filter((n) => n === "word" || n === "sentence" || n === "ssml") : void 0;
93
97
  return {
94
98
  text: e,
95
99
  provider: t.provider || "polly",
96
100
  voice: t.voice,
97
101
  language: t.language,
98
102
  rate: t.rate,
99
- engine: r,
103
+ engine: i,
100
104
  sampleRate: o,
101
105
  format: s,
102
106
  speechMarkTypes: a,
@@ -118,85 +122,81 @@ var R = (e) => {
118
122
  custom: {
119
123
  id: "custom",
120
124
  resolveSynthesisUrl: (e) => {
121
- const t = S(e, "custom"), i = T(e.apiEndpoint);
122
- return t === "synthesizePath" ? `${i}/synthesize` : i;
125
+ const t = k(e, "custom"), r = S(e.apiEndpoint);
126
+ return t === "synthesizePath" ? `${r}/synthesize` : r;
123
127
  },
124
128
  buildRequestBody: (e, t) => {
125
- const i = t.providerOptions || {}, r = typeof i.lang_id == "string" ? i.lang_id : t.language || "en-US", o = typeof i.cache == "boolean" ? i.cache : !0;
129
+ const r = t.providerOptions || {}, i = typeof r.lang_id == "string" ? r.lang_id : t.language || "en-US", o = typeof r.cache == "boolean" ? r.cache : !0;
126
130
  return {
127
131
  text: e,
128
- speedRate: P(t),
129
- lang_id: r,
132
+ speedRate: O(t),
133
+ lang_id: i,
130
134
  cache: o
131
135
  };
132
136
  },
133
- parseResponse: async (e, t, i, r) => {
137
+ parseResponse: async (e, t, r, i) => {
134
138
  const o = await e.json(), s = {};
135
- if (t.includeAuthOnAssetFetch) for (const [c, u] of Object.entries(i)) c.toLowerCase() === "authorization" && (s[c] = u);
139
+ if (t.includeAuthOnAssetFetch) for (const [d, u] of Object.entries(r)) d.toLowerCase() === "authorization" && (s[d] = u);
136
140
  let a = [];
137
- const h = C(o.speechMarks);
138
- if (h.length > 0) a = h;
141
+ const n = L(o.speechMarks);
142
+ if (n.length > 0) a = n;
139
143
  else if (typeof o.word == "string" && o.word.length > 0) {
140
- const c = w(o.word, t);
141
- if (c !== null) {
142
- const u = k(c, t) ? s : A(s), p = await fetch(c.toString(), {
144
+ const d = T(o.word, t);
145
+ if (d !== null) {
146
+ const u = A(d, t) ? s : R(s), g = await fetch(d.toString(), {
143
147
  headers: u,
144
- signal: r,
148
+ signal: i,
145
149
  redirect: "error"
146
150
  });
147
- p.ok && (a = z(await p.text()));
151
+ g.ok && (a = C(await g.text()));
148
152
  }
149
153
  }
150
- const n = w(o.audioContent, t);
151
- if (n === null) throw new Error("TTS server returned an invalid audio URL");
154
+ const l = T(o.audioContent, t);
155
+ if (l === null) throw new Error("TTS server returned an invalid audio URL");
152
156
  return {
153
157
  audio: {
154
158
  kind: "url",
155
- url: n.toString()
159
+ url: l.toString()
156
160
  },
157
161
  speechMarks: a
158
162
  };
159
163
  }
160
164
  }
161
- }, L = class {
165
+ }, x = class {
162
166
  constructor(e, t) {
163
- d(this, "config", void 0), d(this, "adapter", void 0), d(this, "currentAudio", null), d(this, "pausedState", !1), d(this, "wordTimings", []), d(this, "highlightInterval", null), d(this, "intentionallyStopped", !1), d(this, "activeSynthesisController", null), d(this, "synthesisRunId", 0), d(this, "telemetryReporter", void 0), d(this, "onWordBoundary", void 0), this.config = e, this.adapter = t, this.telemetryReporter = R(e);
167
+ h(this, "config", void 0), h(this, "adapter", void 0), h(this, "currentAudio", null), h(this, "pausedState", !1), h(this, "wordTimings", []), h(this, "highlightInterval", null), h(this, "intentionallyStopped", !1), h(this, "activeSynthesisController", null), h(this, "synthesisRunId", 0), h(this, "telemetryReporter", void 0), h(this, "onWordBoundary", void 0), this.config = e, this.adapter = t, this.telemetryReporter = I(e);
164
168
  }
165
169
  async emitTelemetry(e, t) {
166
170
  try {
167
171
  await this.telemetryReporter?.(e, t);
168
- } catch (i) {
169
- console.warn("[ServerTTSProvider] telemetry callback failed:", i);
172
+ } catch (r) {
173
+ console.warn("[ServerTTSProvider] telemetry callback failed:", r);
170
174
  }
171
175
  }
172
176
  async speak(e) {
173
177
  this.stop(), this.intentionallyStopped = !1;
174
- const t = ++this.synthesisRunId, i = new AbortController();
175
- this.activeSynthesisController = i;
176
- const { audioUrl: r, wordTimings: o } = await this.synthesizeSpeech(e, i.signal, t);
178
+ const t = ++this.synthesisRunId, r = new AbortController();
179
+ this.activeSynthesisController = r;
180
+ const { audioUrl: i, wordTimings: o } = await this.synthesizeSpeech(e, r.signal, t);
177
181
  if (t !== this.synthesisRunId) {
178
- URL.revokeObjectURL(r);
182
+ URL.revokeObjectURL(i);
179
183
  return;
180
184
  }
181
- const s = this.config.rate || 1;
182
- return this.wordTimings = o.map((a) => ({
183
- ...a,
184
- time: a.time / s
185
- })), new Promise((a, h) => {
186
- const n = new Audio(r);
187
- this.currentAudio = n, this.config.rate && (n.playbackRate = Math.max(0.25, Math.min(4, this.config.rate))), this.config.volume !== void 0 && (n.volume = Math.max(0, Math.min(1, this.config.volume))), n.onplay = () => {
185
+ return this.wordTimings = o, new Promise((s, a) => {
186
+ const n = new Audio(i);
187
+ this.currentAudio = n, this.config.volume !== void 0 && (n.volume = Math.max(0, Math.min(1, this.config.volume))), n.onplay = () => {
188
188
  this.pausedState = !1, this.onWordBoundary && this.wordTimings.length > 0 && this.startWordHighlighting();
189
189
  }, n.onended = () => {
190
- this.stopWordHighlighting(), URL.revokeObjectURL(r), this.currentAudio = null, this.wordTimings = [], a();
191
- }, n.onerror = (c) => {
192
- this.stopWordHighlighting(), URL.revokeObjectURL(r), this.currentAudio = null, this.wordTimings = [], this.intentionallyStopped ? a() : h(/* @__PURE__ */ new Error("Failed to play audio from server"));
190
+ this.stopWordHighlighting(), URL.revokeObjectURL(i), this.currentAudio = null, this.wordTimings = [], s();
191
+ }, n.onerror = (l) => {
192
+ this.stopWordHighlighting(), URL.revokeObjectURL(i), this.currentAudio = null, this.wordTimings = [], this.intentionallyStopped ? s() : a(/* @__PURE__ */ new Error("Failed to play audio from server"));
193
193
  }, n.onpause = () => {
194
194
  this.stopWordHighlighting(), this.pausedState = !0;
195
- }, n.play().catch(h);
195
+ }, n.play().catch(a);
196
196
  });
197
197
  }
198
- async synthesizeSpeech(e, t, i) {
199
- const r = Date.now();
198
+ async synthesizeSpeech(e, t, r) {
199
+ const i = Date.now();
200
200
  await this.emitTelemetry("pie-tool-backend-call-start", {
201
201
  toolId: "tts",
202
202
  backend: this.config.provider || "server",
@@ -207,7 +207,7 @@ var R = (e) => {
207
207
  ...this.config.headers
208
208
  };
209
209
  this.config.authToken && (o.Authorization = `Bearer ${this.config.authToken}`);
210
- const s = this.adapter.resolveSynthesisUrl(this.config), a = this.adapter.buildRequestBody(e, this.config), h = await (async () => {
210
+ const s = this.adapter.resolveSynthesisUrl(this.config), a = this.adapter.buildRequestBody(e, this.config), n = await (async () => {
211
211
  try {
212
212
  return await fetch(s, {
213
213
  method: "POST",
@@ -215,108 +215,131 @@ var R = (e) => {
215
215
  body: JSON.stringify(a),
216
216
  signal: t
217
217
  });
218
- } catch (l) {
218
+ } catch (c) {
219
219
  throw await this.emitTelemetry("pie-tool-backend-call-error", {
220
220
  toolId: "tts",
221
221
  backend: this.config.provider || "server",
222
222
  operation: "synthesize-speech",
223
- duration: Date.now() - r,
223
+ duration: Date.now() - i,
224
224
  errorType: "TTSBackendNetworkError",
225
- message: l instanceof Error ? l.message : String(l)
226
- }), l;
225
+ message: c instanceof Error ? c.message : String(c)
226
+ }), c;
227
227
  }
228
228
  })();
229
- if (!h.ok) {
230
- const l = await h.json().catch(() => ({})), g = l.message || l.error?.message || `Server returned ${h.status}`;
231
- throw await this.emitTelemetry("pie-tool-backend-call-error", {
229
+ if (!n.ok) {
230
+ const c = await n.text().catch(() => "");
231
+ let p = {};
232
+ if (c) try {
233
+ p = JSON.parse(c);
234
+ } catch (f) {
235
+ console.warn("[ServerTTSProvider] non-OK response body was not JSON", {
236
+ status: n.status,
237
+ url: s,
238
+ rawBodyPreview: c.slice(0, 500),
239
+ parseError: f instanceof Error ? f.message : String(f)
240
+ });
241
+ }
242
+ const y = typeof p.message == "string" && p.message || (typeof p.error?.message == "string" ? p.error.message : void 0) || `Server returned ${n.status}`;
243
+ await this.emitTelemetry("pie-tool-backend-call-error", {
232
244
  toolId: "tts",
233
245
  backend: this.config.provider || "server",
234
246
  operation: "synthesize-speech",
235
- duration: Date.now() - r,
236
- statusCode: h.status,
247
+ duration: Date.now() - i,
248
+ statusCode: n.status,
237
249
  errorType: "TTSBackendRequestError",
238
- message: g
239
- }), new Error(g);
250
+ message: y
251
+ });
252
+ const m = e.replace(/\s+/g, " ").trim().slice(0, 120);
253
+ throw console.error("[ServerTTSProvider] synthesize request failed", {
254
+ status: n.status,
255
+ url: s,
256
+ backend: this.config.provider || "server",
257
+ message: y,
258
+ responseBody: p,
259
+ textLength: e.length,
260
+ textPreview: m.length < e.length ? `${m}…` : m
261
+ }), new Error(y);
240
262
  }
241
- const n = await this.adapter.parseResponse(h, this.config, o, t);
242
- if (i !== this.synthesisRunId || t.aborted) throw new Error("Synthesis superseded by a newer request");
243
- let c;
244
- if (n.audio.kind === "base64") c = this.base64ToBlob(n.audio.data, n.audio.contentType);
263
+ const l = await this.adapter.parseResponse(n, this.config, o, t);
264
+ if (r !== this.synthesisRunId || t.aborted) throw new Error("Synthesis superseded by a newer request");
265
+ let d;
266
+ if (l.audio.kind === "base64") d = this.base64ToBlob(l.audio.data, l.audio.contentType);
245
267
  else {
246
- const l = n.audio.url, g = Date.now();
268
+ const c = l.audio.url, p = Date.now();
247
269
  await this.emitTelemetry("pie-tool-backend-call-start", {
248
270
  toolId: "tts",
249
271
  backend: this.config.provider || "server",
250
272
  operation: "fetch-synthesized-audio-asset"
251
273
  });
252
- const f = {};
253
- this.config.includeAuthOnAssetFetch && this.config.authToken && (f.Authorization = `Bearer ${this.config.authToken}`);
254
- const v = w(l, this.config);
255
- if (v === null) throw await this.emitTelemetry("pie-tool-backend-call-error", {
274
+ const y = {};
275
+ this.config.includeAuthOnAssetFetch && this.config.authToken && (y.Authorization = `Bearer ${this.config.authToken}`);
276
+ const m = T(c, this.config);
277
+ if (m === null) throw await this.emitTelemetry("pie-tool-backend-call-error", {
256
278
  toolId: "tts",
257
279
  backend: this.config.provider || "server",
258
280
  operation: "fetch-synthesized-audio-asset",
259
- duration: Date.now() - g,
281
+ duration: Date.now() - p,
260
282
  errorType: "TTSAssetInvalidUrl",
261
283
  message: "TTS asset URL rejected (non-http(s) or malformed)"
262
284
  }), /* @__PURE__ */ new Error("TTS asset URL rejected (non-http(s) or malformed)");
263
- const I = k(v, this.config) ? f : A(f), y = await (async () => {
285
+ const f = A(m, this.config) ? y : R(y), v = await (async () => {
264
286
  try {
265
- return await fetch(v.toString(), {
266
- headers: I,
287
+ return await fetch(m.toString(), {
288
+ headers: f,
267
289
  signal: t,
268
290
  redirect: "error"
269
291
  });
270
- } catch (m) {
292
+ } catch (w) {
271
293
  throw await this.emitTelemetry("pie-tool-backend-call-error", {
272
294
  toolId: "tts",
273
295
  backend: this.config.provider || "server",
274
296
  operation: "fetch-synthesized-audio-asset",
275
- duration: Date.now() - g,
297
+ duration: Date.now() - p,
276
298
  errorType: "TTSAssetNetworkError",
277
- message: m instanceof Error ? m.message : String(m)
278
- }), m;
299
+ message: w instanceof Error ? w.message : String(w)
300
+ }), w;
279
301
  }
280
302
  })();
281
- if (!y.ok) throw await this.emitTelemetry("pie-tool-backend-call-error", {
303
+ if (!v.ok) throw await this.emitTelemetry("pie-tool-backend-call-error", {
282
304
  toolId: "tts",
283
305
  backend: this.config.provider || "server",
284
306
  operation: "fetch-synthesized-audio-asset",
285
- duration: Date.now() - g,
286
- statusCode: y.status,
307
+ duration: Date.now() - p,
308
+ statusCode: v.status,
287
309
  errorType: "TTSAssetFetchError",
288
- message: `Failed to download synthesized audio (${y.status})`
289
- }), /* @__PURE__ */ new Error(`Failed to download synthesized audio (${y.status})`);
290
- c = await y.blob(), await this.emitTelemetry("pie-tool-backend-call-success", {
310
+ message: `Failed to download synthesized audio (${v.status})`
311
+ }), /* @__PURE__ */ new Error(`Failed to download synthesized audio (${v.status})`);
312
+ d = await v.blob(), await this.emitTelemetry("pie-tool-backend-call-success", {
291
313
  toolId: "tts",
292
314
  backend: this.config.provider || "server",
293
315
  operation: "fetch-synthesized-audio-asset",
294
- duration: Date.now() - g
316
+ duration: Date.now() - p
295
317
  });
296
318
  }
297
- const u = URL.createObjectURL(c), p = this.parseSpeechMarks(n.speechMarks);
319
+ const u = URL.createObjectURL(d), g = this.parseSpeechMarks(l.speechMarks);
298
320
  return await this.emitTelemetry("pie-tool-backend-call-success", {
299
321
  toolId: "tts",
300
322
  backend: this.config.provider || "server",
301
323
  operation: "synthesize-speech",
302
- duration: Date.now() - r
324
+ duration: Date.now() - i
303
325
  }), {
304
326
  audioUrl: u,
305
- wordTimings: p
327
+ wordTimings: g
306
328
  };
307
329
  }
308
330
  base64ToBlob(e, t) {
309
- const i = atob(e), r = new Array(i.length);
310
- for (let s = 0; s < i.length; s++) r[s] = i.charCodeAt(s);
311
- const o = new Uint8Array(r);
331
+ const r = atob(e), i = new Array(r.length);
332
+ for (let s = 0; s < r.length; s++) i[s] = r.charCodeAt(s);
333
+ const o = new Uint8Array(i);
312
334
  return new Blob([o], { type: t });
313
335
  }
314
336
  parseSpeechMarks(e) {
315
- return e.filter((t) => t.type === "word").map((t, i) => ({
337
+ return e.filter((t) => t.type === "word").map((t, r) => ({
316
338
  time: t.time,
317
- wordIndex: i,
339
+ wordIndex: r,
318
340
  charIndex: t.start,
319
- length: t.end - t.start
341
+ length: t.end - t.start,
342
+ word: t.value
320
343
  }));
321
344
  }
322
345
  startWordHighlighting() {
@@ -336,10 +359,10 @@ var R = (e) => {
336
359
  return;
337
360
  }
338
361
  const t = this.currentAudio.currentTime * 1e3;
339
- for (let i = 0; i < this.wordTimings.length; i++) {
340
- const r = this.wordTimings[i];
341
- if (t >= r.time && i > e) {
342
- this.onWordBoundary && (console.log("[ServerTTSProvider] Highlighting word at charIndex:", r.charIndex, "length:", r.length, "time:", r.time, "currentTime:", t), this.onWordBoundary("", r.charIndex, r.length)), e = i;
362
+ for (let r = 0; r < this.wordTimings.length; r++) {
363
+ const i = this.wordTimings[r];
364
+ if (t >= i.time && r > e) {
365
+ this.onWordBoundary && (console.log("[ServerTTSProvider] Highlighting word at charIndex:", i.charIndex, "length:", i.length, "time:", i.time, "currentTime:", t), this.onWordBoundary(i.word, i.charIndex, i.length)), e = r;
343
366
  break;
344
367
  }
345
368
  }
@@ -364,26 +387,26 @@ var R = (e) => {
364
387
  return this.pausedState;
365
388
  }
366
389
  updateSettings(e) {
367
- e.rate !== void 0 && (this.config.rate = e.rate, this.currentAudio && (this.currentAudio.playbackRate = Math.max(0.25, Math.min(4, e.rate)))), e.pitch !== void 0 && (this.config.pitch = e.pitch), e.voice !== void 0 && (this.config.voice = e.voice);
390
+ e.rate !== void 0 && (this.config.rate = e.rate), e.pitch !== void 0 && (this.config.pitch = e.pitch), e.voice !== void 0 && (this.config.voice = e.voice);
368
391
  }
369
- }, B = class {
392
+ }, N = class {
370
393
  constructor() {
371
- d(this, "providerId", "server-tts"), d(this, "providerName", "Server TTS"), d(this, "version", "1.0.0"), d(this, "config", null), d(this, "adapter", null), d(this, "telemetryReporter", void 0);
394
+ h(this, "providerId", "server-tts"), h(this, "providerName", "Server TTS"), h(this, "version", "1.0.0"), h(this, "config", null), h(this, "adapter", null), h(this, "telemetryReporter", void 0);
372
395
  }
373
396
  async emitTelemetry(e, t) {
374
397
  try {
375
398
  await this.telemetryReporter?.(e, t);
376
- } catch (i) {
377
- console.warn("[ServerTTSProvider] telemetry callback failed:", i);
399
+ } catch (r) {
400
+ console.warn("[ServerTTSProvider] telemetry callback failed:", r);
378
401
  }
379
402
  }
380
403
  async initialize(e) {
381
404
  const t = e;
382
405
  if (!t.apiEndpoint) throw new Error("apiEndpoint is required for ServerTTSProvider");
383
- this.config = t, this.telemetryReporter = R(t);
384
- const i = b(t);
385
- if (this.adapter = O[i], t.validateEndpoint) {
386
- const r = Date.now();
406
+ this.config = t, this.telemetryReporter = I(t);
407
+ const r = b(t);
408
+ if (this.adapter = B[r], t.validateEndpoint) {
409
+ const i = Date.now();
387
410
  if (await this.emitTelemetry("pie-tool-backend-call-start", {
388
411
  toolId: "tts",
389
412
  backend: t.provider || "server",
@@ -392,7 +415,7 @@ var R = (e) => {
392
415
  toolId: "tts",
393
416
  backend: t.provider || "server",
394
417
  operation: "validate-endpoint",
395
- duration: Date.now() - r,
418
+ duration: Date.now() - i,
396
419
  errorType: "TTSEndpointValidationError",
397
420
  message: `Server TTS API not available at ${t.apiEndpoint}`
398
421
  }), /* @__PURE__ */ new Error(`Server TTS API not available at ${t.apiEndpoint}`);
@@ -400,28 +423,28 @@ var R = (e) => {
400
423
  toolId: "tts",
401
424
  backend: t.provider || "server",
402
425
  operation: "validate-endpoint",
403
- duration: Date.now() - r
426
+ duration: Date.now() - i
404
427
  });
405
428
  }
406
- return new L(t, this.adapter);
429
+ return new x(t, this.adapter);
407
430
  }
408
431
  async testAPIAvailability() {
409
432
  if (!this.config || !this.adapter) return !1;
410
433
  try {
411
434
  const e = { ...this.config.headers };
412
435
  this.config.authToken && (e.Authorization = `Bearer ${this.config.authToken}`);
413
- const t = new AbortController(), i = setTimeout(() => t.abort(), 5e3), r = U(this.config, this.adapter.id);
414
- if (r === "none") return clearTimeout(i), !0;
415
- const o = r === "voices" ? M(this.config) : this.adapter.resolveSynthesisUrl(this.config), s = r === "voices" ? "GET" : "OPTIONS";
436
+ const t = new AbortController(), r = setTimeout(() => t.abort(), 5e3), i = M(this.config, this.adapter.id);
437
+ if (i === "none") return clearTimeout(r), !0;
438
+ const o = i === "voices" ? z(this.config) : this.adapter.resolveSynthesisUrl(this.config), s = i === "voices" ? "GET" : "OPTIONS";
416
439
  try {
417
440
  const a = await fetch(o, {
418
441
  method: s,
419
442
  headers: e,
420
443
  signal: t.signal
421
444
  });
422
- return clearTimeout(i), a.ok || a.status === 405;
445
+ return clearTimeout(r), a.ok || a.status === 405;
423
446
  } catch {
424
- return clearTimeout(i), !1;
447
+ return clearTimeout(r), !1;
425
448
  }
426
449
  } catch {
427
450
  return !1;
@@ -442,6 +465,7 @@ var R = (e) => {
442
465
  }
443
466
  }
444
467
  getCapabilities() {
468
+ const e = this.config ? b(this.config) : "pie";
445
469
  return {
446
470
  supportsPause: !0,
447
471
  supportsResume: !0,
@@ -449,7 +473,8 @@ var R = (e) => {
449
473
  supportsVoiceSelection: !0,
450
474
  supportsRateControl: !0,
451
475
  supportsPitchControl: !1,
452
- maxTextLength: E[this.config ? b(this.config) : "pie"]
476
+ supportsSSML: U(this.config),
477
+ maxTextLength: E[e]
453
478
  };
454
479
  }
455
480
  destroy() {
@@ -457,5 +482,5 @@ var R = (e) => {
457
482
  }
458
483
  };
459
484
  export {
460
- B as ServerTTSProvider
485
+ N as ServerTTSProvider
461
486
  };
@@ -1,4 +1,4 @@
1
- import { t as s } from "./defineProperty-CyepwRr5-3800a70a.js";
1
+ import { t as s } from "./defineProperty-Dt7ri80W-76aeaed7.js";
2
2
  var n = class {
3
3
  constructor() {
4
4
  s(this, "providerId", "desmos"), s(this, "providerName", "Desmos"), s(this, "supportedTypes", [
@@ -1,4 +1,4 @@
1
- import { t as s } from "./defineProperty-aab5a8e0.js";
1
+ import { t as s } from "./defineProperty-8fd4b6d7.js";
2
2
  var n = class {
3
3
  constructor() {
4
4
  s(this, "providerId", "desmos"), s(this, "providerName", "Desmos"), s(this, "supportedTypes", [