@memberjunction/realtime-widget 0.0.0 → 5.45.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 (86) hide show
  1. package/README.md +107 -43
  2. package/dist/embed.d.ts +18 -0
  3. package/dist/embed.d.ts.map +1 -0
  4. package/dist/embed.js +33 -0
  5. package/dist/embed.js.map +1 -0
  6. package/dist/index.d.ts +23 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +37 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/loader.d.ts +32 -0
  11. package/dist/loader.d.ts.map +1 -0
  12. package/dist/loader.js +163 -0
  13. package/dist/loader.js.map +1 -0
  14. package/dist/session/visitor-key-cookie.d.ts +20 -0
  15. package/dist/session/visitor-key-cookie.d.ts.map +1 -0
  16. package/dist/session/visitor-key-cookie.js +60 -0
  17. package/dist/session/visitor-key-cookie.js.map +1 -0
  18. package/dist/session/widget-session-client.d.ts +74 -0
  19. package/dist/session/widget-session-client.d.ts.map +1 -0
  20. package/dist/session/widget-session-client.js +147 -0
  21. package/dist/session/widget-session-client.js.map +1 -0
  22. package/dist/transport/mock-widget-transport.d.ts +26 -0
  23. package/dist/transport/mock-widget-transport.d.ts.map +1 -0
  24. package/dist/transport/mock-widget-transport.js +42 -0
  25. package/dist/transport/mock-widget-transport.js.map +1 -0
  26. package/dist/transport/runtime-widget-transport.d.ts +54 -0
  27. package/dist/transport/runtime-widget-transport.d.ts.map +1 -0
  28. package/dist/transport/runtime-widget-transport.js +203 -0
  29. package/dist/transport/runtime-widget-transport.js.map +1 -0
  30. package/dist/transport/widget-transport.d.ts +41 -0
  31. package/dist/transport/widget-transport.d.ts.map +1 -0
  32. package/dist/transport/widget-transport.js +13 -0
  33. package/dist/transport/widget-transport.js.map +1 -0
  34. package/dist/types.d.ts +104 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +6 -0
  37. package/dist/types.js.map +1 -0
  38. package/dist/ui/browser-capabilities.d.ts +36 -0
  39. package/dist/ui/browser-capabilities.d.ts.map +1 -0
  40. package/dist/ui/browser-capabilities.js +30 -0
  41. package/dist/ui/browser-capabilities.js.map +1 -0
  42. package/dist/ui/support-widget-element.d.ts +149 -0
  43. package/dist/ui/support-widget-element.d.ts.map +1 -0
  44. package/dist/ui/support-widget-element.js +540 -0
  45. package/dist/ui/support-widget-element.js.map +1 -0
  46. package/dist/ui/tokens.d.ts +16 -0
  47. package/dist/ui/tokens.d.ts.map +1 -0
  48. package/dist/ui/tokens.js +135 -0
  49. package/dist/ui/tokens.js.map +1 -0
  50. package/dist/voice/channels/base-widget-channel.d.ts +63 -0
  51. package/dist/voice/channels/base-widget-channel.d.ts.map +1 -0
  52. package/dist/voice/channels/base-widget-channel.js +36 -0
  53. package/dist/voice/channels/base-widget-channel.js.map +1 -0
  54. package/dist/voice/channels/whiteboard-channel.d.ts +38 -0
  55. package/dist/voice/channels/whiteboard-channel.d.ts.map +1 -0
  56. package/dist/voice/channels/whiteboard-channel.js +214 -0
  57. package/dist/voice/channels/whiteboard-channel.js.map +1 -0
  58. package/dist/voice/channels/widget-channel-host.d.ts +68 -0
  59. package/dist/voice/channels/widget-channel-host.d.ts.map +1 -0
  60. package/dist/voice/channels/widget-channel-host.js +111 -0
  61. package/dist/voice/channels/widget-channel-host.js.map +1 -0
  62. package/dist/voice/guest-tool-relay.d.ts +14 -0
  63. package/dist/voice/guest-tool-relay.d.ts.map +1 -0
  64. package/dist/voice/guest-tool-relay.js +28 -0
  65. package/dist/voice/guest-tool-relay.js.map +1 -0
  66. package/dist/voice/guest-voice-mint.d.ts +23 -0
  67. package/dist/voice/guest-voice-mint.d.ts.map +1 -0
  68. package/dist/voice/guest-voice-mint.js +61 -0
  69. package/dist/voice/guest-voice-mint.js.map +1 -0
  70. package/dist/voice/mock-voice-controller.d.ts +22 -0
  71. package/dist/voice/mock-voice-controller.d.ts.map +1 -0
  72. package/dist/voice/mock-voice-controller.js +42 -0
  73. package/dist/voice/mock-voice-controller.js.map +1 -0
  74. package/dist/voice/realtime-voice-controller.d.ts +75 -0
  75. package/dist/voice/realtime-voice-controller.d.ts.map +1 -0
  76. package/dist/voice/realtime-voice-controller.js +182 -0
  77. package/dist/voice/realtime-voice-controller.js.map +1 -0
  78. package/dist/voice/voice-abuse-guard.d.ts +39 -0
  79. package/dist/voice/voice-abuse-guard.d.ts.map +1 -0
  80. package/dist/voice/voice-abuse-guard.js +57 -0
  81. package/dist/voice/voice-abuse-guard.js.map +1 -0
  82. package/dist/voice/voice-controller.d.ts +39 -0
  83. package/dist/voice/voice-controller.d.ts.map +1 -0
  84. package/dist/voice/voice-controller.js +10 -0
  85. package/dist/voice/voice-controller.js.map +1 -0
  86. package/package.json +36 -7
@@ -0,0 +1,540 @@
1
+ /**
2
+ * @fileoverview `<mj-support-widget>` — a self-contained shadow-DOM custom element
3
+ * rendering the text support surface. Host CSS cannot bleed in or out (closed style
4
+ * scope + `all: initial` on :host). It owns NO chat logic — it delegates turns to an
5
+ * injected `IWidgetTransport` (which reuses ConversationsRuntime). Voice is layered on
6
+ * in W4 via the same element.
7
+ *
8
+ * @module @memberjunction/realtime-widget
9
+ */
10
+ import { WIDGET_SHADOW_STYLES } from './tokens.js';
11
+ import { VoiceIsSupported } from './browser-capabilities.js';
12
+ /** The registered custom-element tag name. */
13
+ export const WIDGET_TAG_NAME = 'mj-support-widget';
14
+ /** The droppable support widget element. */
15
+ export class SupportWidgetElement extends HTMLElement {
16
+ constructor() {
17
+ super();
18
+ this.transport = null;
19
+ this.voiceController = null;
20
+ this.session = null;
21
+ this.messages = [];
22
+ this.sending = false;
23
+ this.voiceActive = false;
24
+ this.headerTitle = 'Support';
25
+ this.greeting = 'Hi! How can we help you today?';
26
+ /** The pending retry the connection-lost banner invokes; null when no banner is shown. */
27
+ this.pendingRetry = null;
28
+ this.forgetHandler = null;
29
+ this.forgetting = false;
30
+ /** Capability probe for the voice/mic affordance (overridable for tests). */
31
+ this.voiceSupportedProbe = () => VoiceIsSupported();
32
+ /** Bound key handler for the open panel's focus trap (added/removed on open/close). */
33
+ this.trapHandler = (e) => this.onPanelKeydown(e);
34
+ this.root = this.attachShadow({ mode: 'open' });
35
+ }
36
+ connectedCallback() {
37
+ this.render();
38
+ }
39
+ /** Sets the UI title + greeting (called by the loader before mount). */
40
+ Configure(options) {
41
+ if (options.title)
42
+ this.headerTitle = options.title;
43
+ if (options.greeting)
44
+ this.greeting = options.greeting;
45
+ if (this.isConnected)
46
+ this.render();
47
+ }
48
+ /** Injects the minted session (drives modality/agent pinning). */
49
+ SetSession(session) {
50
+ this.session = session;
51
+ }
52
+ /** Injects the transport the element sends turns through. */
53
+ SetTransport(transport) {
54
+ this.transport = transport;
55
+ }
56
+ /**
57
+ * Wires the RV5 "forget me" action. The loader supplies a handler that archives the visitor's
58
+ * server-side memory and clears the durable cookie. When set (and the widget remembers returning
59
+ * visitors), a privacy notice + "Forget me" control render below the composer.
60
+ */
61
+ SetForgetHandler(handler) {
62
+ this.forgetHandler = handler;
63
+ if (this.isConnected)
64
+ this.render();
65
+ }
66
+ /** Injects the voice controller (enables the mic button when modality allows voice). */
67
+ SetVoiceController(controller) {
68
+ this.voiceController = controller;
69
+ if (this.isConnected)
70
+ this.render();
71
+ }
72
+ /** Overrides the voice capability probe (used by tests to simulate unsupported browsers). */
73
+ SetVoiceSupportedProbe(probe) {
74
+ this.voiceSupportedProbe = probe;
75
+ if (this.isConnected)
76
+ this.render();
77
+ }
78
+ /** Opens the chat panel, traps focus inside it, and focuses the composer. */
79
+ Open() {
80
+ const panel = this.panel();
81
+ if (!panel)
82
+ return;
83
+ panel.removeAttribute('hidden');
84
+ panel.addEventListener('keydown', this.trapHandler);
85
+ this.input()?.focus();
86
+ }
87
+ /** Closes the chat panel, releases the focus trap, and returns focus to the launcher. */
88
+ Close() {
89
+ const panel = this.panel();
90
+ panel?.setAttribute('hidden', '');
91
+ panel?.removeEventListener('keydown', this.trapHandler);
92
+ this.launcher()?.focus();
93
+ }
94
+ // ── rendering ────────────────────────────────────────────────────────────
95
+ render() {
96
+ this.root.innerHTML = '';
97
+ const style = document.createElement('style');
98
+ style.textContent = WIDGET_SHADOW_STYLES;
99
+ this.root.append(style, this.buildLauncher(), this.buildPanel());
100
+ this.renderTranscript();
101
+ }
102
+ buildLauncher() {
103
+ const btn = document.createElement('button');
104
+ btn.className = 'mj-widget-launcher';
105
+ btn.type = 'button';
106
+ btn.textContent = '💬';
107
+ btn.setAttribute('aria-label', 'Open support chat');
108
+ btn.addEventListener('click', () => this.Open());
109
+ return btn;
110
+ }
111
+ buildPanel() {
112
+ const panel = document.createElement('section');
113
+ panel.className = 'mj-widget-panel';
114
+ panel.setAttribute('hidden', '');
115
+ panel.setAttribute('role', 'dialog');
116
+ panel.setAttribute('aria-label', `${this.headerTitle} chat`);
117
+ panel.append(this.buildHeader(), this.buildBanner(), this.buildDemonstrationSurface(), this.buildTranscriptContainer(), this.buildProgress(), this.buildComposer());
118
+ const notice = this.buildMemoryNotice();
119
+ if (notice) {
120
+ panel.append(notice);
121
+ }
122
+ return panel;
123
+ }
124
+ /**
125
+ * RV5 visitor-facing privacy notice + "Forget me" control. Rendered only when this widget remembers
126
+ * returning visitors AND a forget handler is wired — otherwise returns null (no notice, no control),
127
+ * keeping the default (memory-off) widget unchanged.
128
+ */
129
+ buildMemoryNotice() {
130
+ if (!this.session?.rememberReturningVisitors || !this.forgetHandler) {
131
+ return null;
132
+ }
133
+ const notice = document.createElement('div');
134
+ notice.className = 'mj-widget-memory-notice';
135
+ const text = document.createElement('span');
136
+ text.className = 'mj-widget-memory-notice-text';
137
+ text.textContent = 'We remember your past chats to help you faster.';
138
+ const forget = document.createElement('button');
139
+ forget.className = 'mj-widget-forget';
140
+ forget.type = 'button';
141
+ forget.textContent = 'Forget me';
142
+ forget.addEventListener('click', () => void this.onForgetClicked());
143
+ notice.append(text, forget);
144
+ return notice;
145
+ }
146
+ /** Invokes the wired forget handler, then surfaces a confirmation as a system line. */
147
+ async onForgetClicked() {
148
+ if (this.forgetting || !this.forgetHandler) {
149
+ return;
150
+ }
151
+ this.forgetting = true;
152
+ const forget = this.query('.mj-widget-forget');
153
+ if (forget) {
154
+ forget.disabled = true;
155
+ }
156
+ try {
157
+ await this.forgetHandler();
158
+ this.appendMessage('system', 'Your saved chat history has been forgotten.');
159
+ }
160
+ catch {
161
+ this.appendMessage('system', 'Could not forget your history right now. Please try again later.');
162
+ }
163
+ finally {
164
+ this.forgetting = false;
165
+ if (forget) {
166
+ forget.disabled = false;
167
+ }
168
+ }
169
+ }
170
+ /** The connection-lost banner (hidden until a send / token refresh fails). */
171
+ buildBanner() {
172
+ const banner = document.createElement('div');
173
+ banner.className = 'mj-widget-banner';
174
+ banner.setAttribute('hidden', '');
175
+ banner.setAttribute('role', 'alert');
176
+ const text = document.createElement('span');
177
+ text.className = 'mj-widget-banner-text';
178
+ const retry = document.createElement('button');
179
+ retry.className = 'mj-widget-banner-retry';
180
+ retry.type = 'button';
181
+ retry.textContent = 'Retry';
182
+ retry.addEventListener('click', () => this.onRetryClicked());
183
+ banner.append(text, retry);
184
+ return banner;
185
+ }
186
+ buildHeader() {
187
+ const header = document.createElement('header');
188
+ header.className = 'mj-widget-header';
189
+ const title = document.createElement('span');
190
+ title.textContent = this.headerTitle;
191
+ const controls = document.createElement('span');
192
+ if (this.voiceEnabled()) {
193
+ controls.appendChild(this.buildVoiceButton());
194
+ }
195
+ const close = document.createElement('button');
196
+ close.className = 'mj-widget-close';
197
+ close.type = 'button';
198
+ close.textContent = '×';
199
+ close.setAttribute('aria-label', 'Close support chat');
200
+ close.addEventListener('click', () => this.Close());
201
+ controls.appendChild(close);
202
+ header.append(title, controls);
203
+ return header;
204
+ }
205
+ buildTranscriptContainer() {
206
+ const transcript = document.createElement('div');
207
+ transcript.className = 'mj-widget-transcript';
208
+ transcript.setAttribute('role', 'log');
209
+ transcript.setAttribute('aria-live', 'polite');
210
+ return transcript;
211
+ }
212
+ /**
213
+ * The interactive-channel demonstration surface (Phase 2): a titled stage an MJ channel (e.g. the
214
+ * Whiteboard) renders into while voice is active. Hidden until a channel's first tool call reveals it
215
+ * via {@link RevealChannelSurface}; a widget with no enabled channels never shows it.
216
+ */
217
+ buildDemonstrationSurface() {
218
+ const surface = document.createElement('div');
219
+ surface.className = 'mj-widget-surface';
220
+ surface.setAttribute('hidden', '');
221
+ const title = document.createElement('div');
222
+ title.className = 'mj-widget-surface-title';
223
+ const host = document.createElement('div');
224
+ host.className = 'mj-widget-surface-host';
225
+ surface.append(title, host);
226
+ return surface;
227
+ }
228
+ /**
229
+ * Reveals the demonstration surface for an interactive channel and returns the inner host element the
230
+ * channel renders into. Called (via the voice callbacks) the first time the agent engages a channel.
231
+ */
232
+ RevealChannelSurface(_channelName, title) {
233
+ const surface = this.query('.mj-widget-surface');
234
+ const titleEl = this.query('.mj-widget-surface-title');
235
+ const host = this.query('.mj-widget-surface-host');
236
+ if (titleEl)
237
+ titleEl.textContent = title;
238
+ surface?.removeAttribute('hidden');
239
+ return host ?? document.createElement('div');
240
+ }
241
+ /** Hides + clears the demonstration surface (on voice end). */
242
+ hideChannelSurface() {
243
+ const surface = this.query('.mj-widget-surface');
244
+ surface?.setAttribute('hidden', '');
245
+ const host = this.query('.mj-widget-surface-host');
246
+ if (host)
247
+ host.innerHTML = '';
248
+ }
249
+ buildProgress() {
250
+ const progress = document.createElement('div');
251
+ progress.className = 'mj-widget-progress';
252
+ progress.setAttribute('hidden', '');
253
+ return progress;
254
+ }
255
+ buildComposer() {
256
+ const form = document.createElement('form');
257
+ form.className = 'mj-widget-composer';
258
+ const input = document.createElement('textarea');
259
+ input.className = 'mj-widget-input';
260
+ input.rows = 1;
261
+ input.setAttribute('aria-label', 'Type your message');
262
+ input.placeholder = 'Type your message…';
263
+ input.addEventListener('keydown', (e) => this.onComposerKeydown(e));
264
+ const send = document.createElement('button');
265
+ send.className = 'mj-widget-send';
266
+ send.type = 'submit';
267
+ send.textContent = 'Send';
268
+ form.append(input, send);
269
+ form.addEventListener('submit', (e) => {
270
+ e.preventDefault();
271
+ void this.sendCurrent();
272
+ });
273
+ return form;
274
+ }
275
+ renderTranscript() {
276
+ const transcript = this.query('.mj-widget-transcript');
277
+ if (!transcript)
278
+ return;
279
+ transcript.innerHTML = '';
280
+ if (this.messages.length === 0) {
281
+ const empty = document.createElement('div');
282
+ empty.className = 'mj-widget-empty';
283
+ empty.textContent = this.greeting;
284
+ transcript.appendChild(empty);
285
+ return;
286
+ }
287
+ for (const msg of this.messages) {
288
+ const el = document.createElement('div');
289
+ el.className = `mj-widget-msg ${msg.role}`;
290
+ el.textContent = msg.text;
291
+ transcript.appendChild(el);
292
+ }
293
+ transcript.scrollTop = transcript.scrollHeight;
294
+ }
295
+ // ── interaction ──────────────────────────────────────────────────────────
296
+ onComposerKeydown(e) {
297
+ if (e.key === 'Enter' && !e.shiftKey) {
298
+ e.preventDefault();
299
+ void this.sendCurrent();
300
+ }
301
+ else if (e.key === 'Escape') {
302
+ this.Close();
303
+ }
304
+ }
305
+ // ── focus trap (W6 accessibility) ──────────────────────────────────────────
306
+ /** Keeps Tab focus cycling within the open panel; Esc still closes. */
307
+ onPanelKeydown(e) {
308
+ if (e.key === 'Escape') {
309
+ this.Close();
310
+ return;
311
+ }
312
+ if (e.key !== 'Tab')
313
+ return;
314
+ const focusables = this.focusableElements();
315
+ if (focusables.length === 0)
316
+ return;
317
+ const first = focusables[0];
318
+ const last = focusables[focusables.length - 1];
319
+ const active = this.activeWithinPanel();
320
+ if (e.shiftKey && active === first) {
321
+ e.preventDefault();
322
+ last.focus();
323
+ }
324
+ else if (!e.shiftKey && active === last) {
325
+ e.preventDefault();
326
+ first.focus();
327
+ }
328
+ }
329
+ /** The focusable controls inside the panel, in DOM order, excluding hidden subtrees. */
330
+ focusableElements() {
331
+ const panel = this.panel();
332
+ if (!panel)
333
+ return [];
334
+ const selector = 'button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])';
335
+ return Array.from(panel.querySelectorAll(selector)).filter((el) => !this.isInHiddenSubtree(el, panel));
336
+ }
337
+ /** True when the element (or an ancestor up to the panel) carries the `hidden` attribute. */
338
+ isInHiddenSubtree(el, panel) {
339
+ let node = el;
340
+ while (node && node !== panel) {
341
+ if (node.hasAttribute('hidden'))
342
+ return true;
343
+ node = node.parentElement;
344
+ }
345
+ return false;
346
+ }
347
+ /** The currently-focused element, resolved through the shadow root. */
348
+ activeWithinPanel() {
349
+ const active = this.root.activeElement;
350
+ return active instanceof HTMLElement ? active : null;
351
+ }
352
+ /** Reads the composer, appends the user turn, dispatches it, renders the reply. */
353
+ async sendCurrent() {
354
+ const input = this.input();
355
+ const text = input?.value.trim() ?? '';
356
+ if (!text || this.sending)
357
+ return;
358
+ if (!this.transport) {
359
+ this.appendMessage('system', 'Support is not connected yet. Please try again in a moment.');
360
+ return;
361
+ }
362
+ if (input)
363
+ input.value = '';
364
+ this.appendMessage('user', text);
365
+ await this.dispatchTurn(text);
366
+ }
367
+ /** Sends one turn through the transport and renders progress + the reply. */
368
+ async dispatchTurn(text) {
369
+ this.setSending(true);
370
+ try {
371
+ const result = await this.transport.SendMessage(text, (m) => this.showProgress(m));
372
+ if (result.success) {
373
+ this.clearConnectionError();
374
+ this.appendMessage('agent', result.reply || '(no response)');
375
+ }
376
+ else {
377
+ this.ShowConnectionError(result.error ?? 'Message could not be sent.', () => void this.dispatchTurn(text));
378
+ }
379
+ }
380
+ catch (err) {
381
+ const msg = err instanceof Error ? err.message : 'Connection lost.';
382
+ this.ShowConnectionError(msg, () => void this.dispatchTurn(text));
383
+ }
384
+ finally {
385
+ this.hideProgress();
386
+ this.setSending(false);
387
+ }
388
+ }
389
+ appendMessage(role, text) {
390
+ this.messages.push({ role, text, timestampMs: Date.now() });
391
+ this.renderTranscript();
392
+ }
393
+ showProgress(message) {
394
+ const progress = this.query('.mj-widget-progress');
395
+ if (!progress)
396
+ return;
397
+ progress.textContent = message;
398
+ progress.removeAttribute('hidden');
399
+ }
400
+ hideProgress() {
401
+ this.query('.mj-widget-progress')?.setAttribute('hidden', '');
402
+ }
403
+ setSending(sending) {
404
+ this.sending = sending;
405
+ const send = this.query('.mj-widget-send');
406
+ if (send)
407
+ send.disabled = sending;
408
+ }
409
+ // ── voice (W4) ─────────────────────────────────────────────────────────────
410
+ /**
411
+ * Voice is offered only when a controller is wired, the instance enables Voice/Both,
412
+ * AND the browser can actually capture the mic (secure context + getUserMedia). On an
413
+ * insecure origin or an unsupported browser the mic affordance is hidden and the
414
+ * visitor falls back to text (graceful degradation, W6).
415
+ */
416
+ voiceEnabled() {
417
+ const modalityAllows = this.session?.modality === 'Voice' || this.session?.modality === 'Both';
418
+ return this.voiceController !== null && modalityAllows && this.voiceSupportedProbe();
419
+ }
420
+ buildVoiceButton() {
421
+ const btn = document.createElement('button');
422
+ btn.className = 'mj-widget-close mj-widget-voice';
423
+ btn.type = 'button';
424
+ btn.textContent = this.voiceActive ? '⏹' : '🎤';
425
+ btn.setAttribute('aria-label', this.voiceActive ? 'Stop voice' : 'Start voice');
426
+ btn.setAttribute('aria-pressed', String(this.voiceActive));
427
+ btn.addEventListener('click', () => void this.toggleVoice());
428
+ return btn;
429
+ }
430
+ /** Starts or stops a voice session via the injected controller. */
431
+ async toggleVoice() {
432
+ if (!this.voiceController)
433
+ return;
434
+ if (this.voiceActive) {
435
+ await this.voiceController.Stop();
436
+ return;
437
+ }
438
+ try {
439
+ await this.voiceController.Start({
440
+ onState: (s) => this.onVoiceState(s),
441
+ onTranscript: (t) => {
442
+ if (t.isFinal && t.text.trim())
443
+ this.appendMessage(t.role, t.text);
444
+ },
445
+ onEnded: (reason) => this.onVoiceEnded(reason),
446
+ // Phase 2: an MJ interactive channel reveals its surface here on first use.
447
+ getChannelSurface: (name, title) => this.RevealChannelSurface(name, title),
448
+ });
449
+ }
450
+ catch (err) {
451
+ this.appendMessage('system', err instanceof Error ? err.message : 'Could not start voice.');
452
+ this.onVoiceEnded();
453
+ }
454
+ }
455
+ onVoiceState(state) {
456
+ this.voiceActive = state !== 'idle' && state !== 'ended' && state !== 'error';
457
+ this.refreshVoiceButton();
458
+ if (state === 'listening')
459
+ this.showProgress('🎙 Listening…');
460
+ else if (state === 'speaking')
461
+ this.showProgress('🔊 Speaking…');
462
+ else
463
+ this.hideProgress();
464
+ }
465
+ onVoiceEnded(reason) {
466
+ this.voiceActive = false;
467
+ this.refreshVoiceButton();
468
+ this.hideProgress();
469
+ this.hideChannelSurface();
470
+ if (reason)
471
+ this.appendMessage('system', reason);
472
+ }
473
+ refreshVoiceButton() {
474
+ const btn = this.query('.mj-widget-voice');
475
+ if (!btn)
476
+ return;
477
+ btn.textContent = this.voiceActive ? '⏹' : '🎤';
478
+ btn.setAttribute('aria-label', this.voiceActive ? 'Stop voice' : 'Start voice');
479
+ btn.setAttribute('aria-pressed', String(this.voiceActive));
480
+ }
481
+ // ── small DOM accessors (testable) ─────────────────────────────────────────
482
+ /** Surfaces a system/notification line in the transcript (used by the notification adapter). */
483
+ ShowSystemMessage(text) {
484
+ this.appendMessage('system', text);
485
+ }
486
+ /**
487
+ * Shows the connection-lost banner with a retry affordance. Used when a send fails or
488
+ * a token refresh fails (graceful degradation, W6). Invoking the banner's Retry button
489
+ * (or {@link RetryConnection}) runs the supplied action and clears the banner on success.
490
+ *
491
+ * @param message The user-facing reason shown in the banner.
492
+ * @param retry The action to run when the visitor clicks Retry.
493
+ */
494
+ ShowConnectionError(message, retry) {
495
+ this.pendingRetry = retry;
496
+ const banner = this.query('.mj-widget-banner');
497
+ const text = this.query('.mj-widget-banner-text');
498
+ if (text)
499
+ text.textContent = message;
500
+ banner?.removeAttribute('hidden');
501
+ }
502
+ /** Programmatically triggers the pending retry (same effect as clicking Retry). */
503
+ RetryConnection() {
504
+ this.onRetryClicked();
505
+ }
506
+ /** Hides the connection-lost banner and drops the pending retry. */
507
+ clearConnectionError() {
508
+ this.pendingRetry = null;
509
+ this.query('.mj-widget-banner')?.setAttribute('hidden', '');
510
+ }
511
+ /** Runs the pending retry (if any) and hides the banner; the retry re-shows it on a repeat failure. */
512
+ onRetryClicked() {
513
+ const retry = this.pendingRetry;
514
+ this.clearConnectionError();
515
+ retry?.();
516
+ }
517
+ /** Exposes the shadow root for tests + integration code. */
518
+ get ShadowRootRef() {
519
+ return this.root;
520
+ }
521
+ query(selector) {
522
+ return this.root.querySelector(selector);
523
+ }
524
+ panel() {
525
+ return this.query('.mj-widget-panel');
526
+ }
527
+ launcher() {
528
+ return this.query('.mj-widget-launcher');
529
+ }
530
+ input() {
531
+ return this.query('.mj-widget-input');
532
+ }
533
+ }
534
+ /** Registers the custom element once (idempotent). */
535
+ export function defineSupportWidgetElement() {
536
+ if (typeof customElements !== 'undefined' && !customElements.get(WIDGET_TAG_NAME)) {
537
+ customElements.define(WIDGET_TAG_NAME, SupportWidgetElement);
538
+ }
539
+ }
540
+ //# sourceMappingURL=support-widget-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-widget-element.js","sourceRoot":"","sources":["../../src/ui/support-widget-element.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview Design tokens injected into the widget's SHADOW ROOT (not <head>),
3
+ * so the widget is themeable yet fully isolated from — and cannot bleed into — the
4
+ * host page. Mirrors the `--mj-chat-*` token set from
5
+ * `conversations-runtime-bootstrap.service.ts`, plus the minimal base semantic tokens
6
+ * the shadow tree needs (the shadow root does not inherit the host app's `:root`).
7
+ *
8
+ * No hardcoded colors leak into component rules — every rule references a token
9
+ * (CLAUDE design-token rule). Defaults here are the token values; a host can override
10
+ * by setting these custom properties on the mount element.
11
+ *
12
+ * @module @memberjunction/realtime-widget
13
+ */
14
+ /** The `:host`-scoped token defaults + component CSS for the widget shadow root. */
15
+ export declare const WIDGET_SHADOW_STYLES = "\n:host {\n /* base semantic tokens (shadow root needs its own \u2014 it can't see the app :root) */\n --mj-text-primary: #1f2933;\n --mj-text-secondary: #52606d;\n --mj-text-inverse: #ffffff;\n --mj-bg-surface: #ffffff;\n --mj-bg-surface-card: #f5f7fa;\n --mj-bg-surface-sunken: #eef1f5;\n --mj-border-default: #e2e8f0;\n --mj-brand-primary: #264faf;\n --mj-brand-primary-hover: #1d3f8c;\n --mj-status-error: #dc2626;\n --mj-status-error-text: #b91c1c;\n --mj-status-error-bg: #fef2f2;\n\n /* chat tokens (mirror the Angular bootstrap names) */\n --mj-chat-bubble-user-bg: var(--mj-brand-primary);\n --mj-chat-bubble-user-text: var(--mj-text-inverse);\n --mj-chat-bubble-agent-bg: var(--mj-bg-surface-card);\n --mj-chat-bubble-agent-text: var(--mj-text-primary);\n --mj-chat-composer-bg: var(--mj-bg-surface);\n --mj-chat-composer-border: var(--mj-border-default);\n\n all: initial;\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n color: var(--mj-text-primary);\n}\n\n* { box-sizing: border-box; }\n\n.mj-widget-launcher {\n position: fixed; right: 20px; bottom: 20px;\n width: 56px; height: 56px; border-radius: 50%;\n background: var(--mj-brand-primary); color: var(--mj-text-inverse);\n border: none; cursor: pointer; font-size: 24px;\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-text-primary) 25%, transparent);\n}\n.mj-widget-launcher:hover { background: var(--mj-brand-primary-hover); }\n\n.mj-widget-panel {\n position: fixed; right: 20px; bottom: 88px;\n width: 360px; max-width: calc(100vw - 40px); height: 520px; max-height: calc(100vh - 120px);\n display: flex; flex-direction: column;\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 12px; overflow: hidden;\n box-shadow: 0 8px 28px color-mix(in srgb, var(--mj-text-primary) 22%, transparent);\n}\n.mj-widget-panel[hidden] { display: none; }\n\n.mj-widget-header {\n padding: 12px 16px; background: var(--mj-brand-primary); color: var(--mj-text-inverse);\n display: flex; align-items: center; justify-content: space-between; font-weight: 600;\n}\n.mj-widget-close { background: none; border: none; color: var(--mj-text-inverse); cursor: pointer; font-size: 18px; }\n\n.mj-widget-transcript {\n flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px;\n background: var(--mj-bg-surface-sunken);\n}\n.mj-widget-empty { color: var(--mj-text-secondary); text-align: center; margin: auto; padding: 16px; }\n\n.mj-widget-msg { max-width: 80%; padding: 8px 12px; border-radius: 12px; white-space: pre-wrap; word-break: break-word; }\n.mj-widget-msg.user { align-self: flex-end; background: var(--mj-chat-bubble-user-bg); color: var(--mj-chat-bubble-user-text); }\n.mj-widget-msg.agent { align-self: flex-start; background: var(--mj-chat-bubble-agent-bg); color: var(--mj-chat-bubble-agent-text); }\n.mj-widget-msg.system { align-self: center; color: var(--mj-status-error-text); font-size: 0.85em; }\n\n.mj-widget-progress { align-self: flex-start; color: var(--mj-text-secondary); font-size: 0.85em; font-style: italic; }\n.mj-widget-progress[hidden] { display: none; }\n\n/* Interactive-channel demonstration surface (Phase 2 \u2014 e.g. the Whiteboard the agent draws on during voice). */\n.mj-widget-surface { display: flex; flex-direction: column; border-bottom: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); }\n.mj-widget-surface[hidden] { display: none; }\n.mj-widget-surface-title { padding: 6px 12px; font-size: 0.8em; font-weight: 600; color: var(--mj-text-secondary); background: var(--mj-bg-surface-card); }\n.mj-widget-surface-host { height: 200px; width: 100%; background: var(--mj-bg-surface); overflow: hidden; }\n.mj-widget-surface-host svg { display: block; width: 100%; height: 100%; }\n\n.mj-widget-composer {\n display: flex; gap: 8px; padding: 10px; border-top: 1px solid var(--mj-chat-composer-border);\n background: var(--mj-chat-composer-bg);\n}\n.mj-widget-input {\n flex: 1; resize: none; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 8px; font: inherit; color: var(--mj-text-primary); background: var(--mj-bg-surface);\n}\n.mj-widget-send {\n background: var(--mj-brand-primary); color: var(--mj-text-inverse); border: none;\n border-radius: 8px; padding: 0 14px; cursor: pointer; font: inherit;\n}\n.mj-widget-send:disabled { opacity: 0.5; cursor: default; }\n\n/* Connection-lost banner (graceful degradation, W6) */\n.mj-widget-banner {\n display: flex; align-items: center; gap: 8px; padding: 8px 12px;\n background: var(--mj-status-error-bg); color: var(--mj-status-error-text);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-error) 35%, transparent);\n font-size: 0.85em;\n}\n.mj-widget-banner[hidden] { display: none; }\n.mj-widget-banner-text { flex: 1; }\n.mj-widget-banner-retry {\n background: var(--mj-status-error); color: var(--mj-text-inverse); border: none;\n border-radius: 6px; padding: 4px 10px; cursor: pointer; font: inherit; font-size: 0.95em;\n}\n.mj-widget-banner-retry:hover { background: var(--mj-status-error-text); }\n.mj-widget-memory-notice {\n display: flex; align-items: center; gap: 8px; padding: 6px 12px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n border-top: 1px solid var(--mj-border-default);\n font-size: 0.75em;\n}\n.mj-widget-memory-notice-text { flex: 1; }\n.mj-widget-forget {\n background: none; color: var(--mj-text-secondary); border: none;\n padding: 2px 4px; cursor: pointer; font: inherit; font-size: 1em;\n text-decoration: underline; white-space: nowrap;\n}\n.mj-widget-forget:hover { color: var(--mj-text-primary); }\n.mj-widget-forget:disabled { opacity: 0.6; cursor: default; }\n";
16
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/ui/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,gyLAuHhC,CAAC"}