@ringg/react-native 0.0.1-alpha.9 → 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 (118) hide show
  1. package/dist/index.d.mts +964 -0
  2. package/dist/index.d.ts +964 -0
  3. package/dist/index.js +1164 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +1129 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +24 -66
  8. package/LICENSE +0 -21
  9. package/README.md +0 -250
  10. package/app.plugin.js +0 -51
  11. package/lib/module/adapters/index.js +0 -4
  12. package/lib/module/adapters/index.js.map +0 -1
  13. package/lib/module/adapters/livekit-rn-adapter.js +0 -216
  14. package/lib/module/adapters/livekit-rn-adapter.js.map +0 -1
  15. package/lib/module/components/RinggWidget.js +0 -554
  16. package/lib/module/components/RinggWidget.js.map +0 -1
  17. package/lib/module/components/steps/ButtonsStep.js +0 -146
  18. package/lib/module/components/steps/ButtonsStep.js.map +0 -1
  19. package/lib/module/components/steps/CalendarStep.js +0 -190
  20. package/lib/module/components/steps/CalendarStep.js.map +0 -1
  21. package/lib/module/components/steps/ConfirmationStep.js +0 -175
  22. package/lib/module/components/steps/ConfirmationStep.js.map +0 -1
  23. package/lib/module/components/steps/FormStep.js +0 -346
  24. package/lib/module/components/steps/FormStep.js.map +0 -1
  25. package/lib/module/components/steps/InteractiveFlow.js +0 -249
  26. package/lib/module/components/steps/InteractiveFlow.js.map +0 -1
  27. package/lib/module/components/ui/ActionButton.js +0 -92
  28. package/lib/module/components/ui/ActionButton.js.map +0 -1
  29. package/lib/module/components/ui/CallControls.js +0 -168
  30. package/lib/module/components/ui/CallControls.js.map +0 -1
  31. package/lib/module/components/ui/FeedbackScreen.js +0 -180
  32. package/lib/module/components/ui/FeedbackScreen.js.map +0 -1
  33. package/lib/module/components/ui/Icons.js +0 -294
  34. package/lib/module/components/ui/Icons.js.map +0 -1
  35. package/lib/module/components/ui/MessageBubble.js +0 -80
  36. package/lib/module/components/ui/MessageBubble.js.map +0 -1
  37. package/lib/module/components/ui/TabSelector.js +0 -80
  38. package/lib/module/components/ui/TabSelector.js.map +0 -1
  39. package/lib/module/components/ui/WidgetHeader.js +0 -168
  40. package/lib/module/components/ui/WidgetHeader.js.map +0 -1
  41. package/lib/module/context/RinggProvider.js +0 -134
  42. package/lib/module/context/RinggProvider.js.map +0 -1
  43. package/lib/module/context/index.js +0 -4
  44. package/lib/module/context/index.js.map +0 -1
  45. package/lib/module/globals.d.js +0 -2
  46. package/lib/module/globals.d.js.map +0 -1
  47. package/lib/module/hooks/index.js +0 -10
  48. package/lib/module/hooks/index.js.map +0 -1
  49. package/lib/module/hooks/useRinggCall.js +0 -259
  50. package/lib/module/hooks/useRinggCall.js.map +0 -1
  51. package/lib/module/hooks/useRinggChat.js +0 -141
  52. package/lib/module/hooks/useRinggChat.js.map +0 -1
  53. package/lib/module/hooks/useRinggComponents.js +0 -236
  54. package/lib/module/hooks/useRinggComponents.js.map +0 -1
  55. package/lib/module/hooks/useRinggFeedback.js +0 -66
  56. package/lib/module/hooks/useRinggFeedback.js.map +0 -1
  57. package/lib/module/hooks/useRinggTheme.js +0 -39
  58. package/lib/module/hooks/useRinggTheme.js.map +0 -1
  59. package/lib/module/hooks/useRinggTranscripts.js +0 -70
  60. package/lib/module/hooks/useRinggTranscripts.js.map +0 -1
  61. package/lib/module/hooks/useRinggWidgetState.js +0 -51
  62. package/lib/module/hooks/useRinggWidgetState.js.map +0 -1
  63. package/lib/module/index.js +0 -56
  64. package/lib/module/index.js.map +0 -1
  65. package/lib/module/package.json +0 -1
  66. package/lib/typescript/adapters/index.d.ts +0 -2
  67. package/lib/typescript/adapters/index.d.ts.map +0 -1
  68. package/lib/typescript/adapters/livekit-rn-adapter.d.ts +0 -38
  69. package/lib/typescript/adapters/livekit-rn-adapter.d.ts.map +0 -1
  70. package/lib/typescript/components/RinggWidget.d.ts +0 -44
  71. package/lib/typescript/components/RinggWidget.d.ts.map +0 -1
  72. package/lib/typescript/components/steps/ButtonsStep.d.ts +0 -17
  73. package/lib/typescript/components/steps/ButtonsStep.d.ts.map +0 -1
  74. package/lib/typescript/components/steps/CalendarStep.d.ts +0 -16
  75. package/lib/typescript/components/steps/CalendarStep.d.ts.map +0 -1
  76. package/lib/typescript/components/steps/ConfirmationStep.d.ts +0 -16
  77. package/lib/typescript/components/steps/ConfirmationStep.d.ts.map +0 -1
  78. package/lib/typescript/components/steps/FormStep.d.ts +0 -17
  79. package/lib/typescript/components/steps/FormStep.d.ts.map +0 -1
  80. package/lib/typescript/components/steps/InteractiveFlow.d.ts +0 -23
  81. package/lib/typescript/components/steps/InteractiveFlow.d.ts.map +0 -1
  82. package/lib/typescript/components/ui/ActionButton.d.ts +0 -22
  83. package/lib/typescript/components/ui/ActionButton.d.ts.map +0 -1
  84. package/lib/typescript/components/ui/CallControls.d.ts +0 -22
  85. package/lib/typescript/components/ui/CallControls.d.ts.map +0 -1
  86. package/lib/typescript/components/ui/FeedbackScreen.d.ts +0 -24
  87. package/lib/typescript/components/ui/FeedbackScreen.d.ts.map +0 -1
  88. package/lib/typescript/components/ui/Icons.d.ts +0 -28
  89. package/lib/typescript/components/ui/Icons.d.ts.map +0 -1
  90. package/lib/typescript/components/ui/MessageBubble.d.ts +0 -17
  91. package/lib/typescript/components/ui/MessageBubble.d.ts.map +0 -1
  92. package/lib/typescript/components/ui/TabSelector.d.ts +0 -21
  93. package/lib/typescript/components/ui/TabSelector.d.ts.map +0 -1
  94. package/lib/typescript/components/ui/WidgetHeader.d.ts +0 -20
  95. package/lib/typescript/components/ui/WidgetHeader.d.ts.map +0 -1
  96. package/lib/typescript/context/RinggProvider.d.ts +0 -53
  97. package/lib/typescript/context/RinggProvider.d.ts.map +0 -1
  98. package/lib/typescript/context/index.d.ts +0 -3
  99. package/lib/typescript/context/index.d.ts.map +0 -1
  100. package/lib/typescript/hooks/index.d.ts +0 -15
  101. package/lib/typescript/hooks/index.d.ts.map +0 -1
  102. package/lib/typescript/hooks/useRinggCall.d.ts +0 -41
  103. package/lib/typescript/hooks/useRinggCall.d.ts.map +0 -1
  104. package/lib/typescript/hooks/useRinggChat.d.ts +0 -29
  105. package/lib/typescript/hooks/useRinggChat.d.ts.map +0 -1
  106. package/lib/typescript/hooks/useRinggComponents.d.ts +0 -52
  107. package/lib/typescript/hooks/useRinggComponents.d.ts.map +0 -1
  108. package/lib/typescript/hooks/useRinggFeedback.d.ts +0 -23
  109. package/lib/typescript/hooks/useRinggFeedback.d.ts.map +0 -1
  110. package/lib/typescript/hooks/useRinggTheme.d.ts +0 -40
  111. package/lib/typescript/hooks/useRinggTheme.d.ts.map +0 -1
  112. package/lib/typescript/hooks/useRinggTranscripts.d.ts +0 -30
  113. package/lib/typescript/hooks/useRinggTranscripts.d.ts.map +0 -1
  114. package/lib/typescript/hooks/useRinggWidgetState.d.ts +0 -38
  115. package/lib/typescript/hooks/useRinggWidgetState.d.ts.map +0 -1
  116. package/lib/typescript/index.d.ts +0 -44
  117. package/lib/typescript/index.d.ts.map +0 -1
  118. package/lib/typescript/package.json +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../../core/dist/generated/tokens.js","../../core/dist/ports/event-bus.js","../../core/dist/ports/clock.js","../../core/dist/ports/platform.js","../../core/dist/api/client.js","../../core/dist/theme/theme-engine.js","../../core/dist/rpc/formatter.js","../../core/dist/stores/store.js","../../core/dist/stores/shell-store.js","../../core/dist/stores/session-store.js","../../core/dist/stores/message-store.js","../../core/dist/constants.js","../../core/dist/stores/typing-store.js","../../core/dist/stores/component-store.js","../../core/dist/stores/slash-command-store.js","../../core/dist/controller.js","../../core/dist/react/hooks.js"],"sourcesContent":["/**\n * @ringg/react-native — RN widget on the shared @ringg/core brain.\n *\n * Ships the headless hooks now (shared with @ringg/web via\n * \"@ringg/core/react\"); the <RinggWidget /> UI and the\n * @livekit/react-native transport adapter land next.\n *\n * @ringg/core is a devDependency on purpose: it is private and must be\n * bundled into the published output, never resolved from the registry.\n */\n\nexport { createRinggWidgetController, createCallbackEventBus, type RinggWidgetController, type RinggWidgetConfig, type ControllerPorts, type TransportAdapter } from \"@ringg/core\";\nexport * from \"@ringg/core/react\";\n","/**\n * GENERATED FILE — DO NOT EDIT.\n * Source: tokens/tokens.json + tokens/defaults.json\n * Regenerate: node scripts/generate-tokens.mjs\n */\nexport const DEFAULT_WIDGET_THEME = {\n \"primaryColor\": \"#0a0a0b\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#ffffff\",\n \"surfaceColor\": \"#f3f4f6\",\n \"agentBubbleColor\": \"\",\n \"textColor\": \"#0a0a0b\",\n \"mutedTextColor\": \"#6b7280\",\n \"borderColor\": \"#e5e7eb\",\n \"errorColor\": \"#ef4444\",\n \"successColor\": \"#16a34a\",\n \"buttonStyle\": \"pill\",\n \"borderRadius\": \"16px\",\n \"fontFamily\": \"inherit\"\n};\nexport const WIDGET_PRESET_THEMES = {\n \"light\": {\n \"primaryColor\": \"#18181b\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#ffffff\",\n \"surfaceColor\": \"#f4f4f5\",\n \"textColor\": \"#18181b\",\n \"mutedTextColor\": \"#71717a\",\n \"borderColor\": \"#e4e4e7\"\n },\n \"warm\": {\n \"primaryColor\": \"#57534e\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#fefefe\",\n \"surfaceColor\": \"#fafaf9\",\n \"textColor\": \"#1c1917\",\n \"mutedTextColor\": \"#78716c\",\n \"borderColor\": \"#e7e5e4\"\n },\n \"blue\": {\n \"primaryColor\": \"#2563eb\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#fafcff\",\n \"surfaceColor\": \"#f0f7ff\",\n \"textColor\": \"#1e3a8a\",\n \"mutedTextColor\": \"#64748b\",\n \"borderColor\": \"#dbeafe\"\n },\n \"indigo\": {\n \"primaryColor\": \"#6366f1\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#fbfbff\",\n \"surfaceColor\": \"#f5f5ff\",\n \"textColor\": \"#312e81\",\n \"mutedTextColor\": \"#6b7280\",\n \"borderColor\": \"#e0e7ff\"\n },\n \"green\": {\n \"primaryColor\": \"#16a34a\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#fbfefb\",\n \"surfaceColor\": \"#f0fdf4\",\n \"textColor\": \"#14532d\",\n \"mutedTextColor\": \"#6b7280\",\n \"borderColor\": \"#dcfce7\"\n },\n \"orange\": {\n \"primaryColor\": \"#ea580c\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#fffdfb\",\n \"surfaceColor\": \"#fff7ed\",\n \"textColor\": \"#7c2d12\",\n \"mutedTextColor\": \"#78716c\",\n \"borderColor\": \"#ffedd5\"\n },\n \"dark\": {\n \"primaryColor\": \"#fafafa\",\n \"primaryTextColor\": \"#18181b\",\n \"backgroundColor\": \"#18181b\",\n \"surfaceColor\": \"#27272a\",\n \"textColor\": \"#fafafa\",\n \"mutedTextColor\": \"#a1a1aa\",\n \"borderColor\": \"#3f3f46\"\n },\n \"sunset\": {\n \"primaryColor\": \"linear-gradient(135deg, #f97316, #ef4444)\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#fffbf7\",\n \"surfaceColor\": \"#fff3e8\",\n \"textColor\": \"#7c2d12\",\n \"mutedTextColor\": \"#9a3412\",\n \"borderColor\": \"#fed7aa\"\n },\n \"ocean\": {\n \"primaryColor\": \"linear-gradient(135deg, #667eea, #764ba2)\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#faf9ff\",\n \"surfaceColor\": \"#f0edff\",\n \"textColor\": \"#312e81\",\n \"mutedTextColor\": \"#6366f1\",\n \"borderColor\": \"#ddd6fe\"\n },\n \"emerald\": {\n \"primaryColor\": \"linear-gradient(135deg, #10b981, #0ea5e9)\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#f7fdfb\",\n \"surfaceColor\": \"#ecfdf5\",\n \"textColor\": \"#064e3b\",\n \"mutedTextColor\": \"#047857\",\n \"borderColor\": \"#a7f3d0\"\n },\n \"midnight\": {\n \"primaryColor\": \"linear-gradient(135deg, #6366f1, #8b5cf6)\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#18181b\",\n \"surfaceColor\": \"#27272a\",\n \"textColor\": \"#fafafa\",\n \"mutedTextColor\": \"#a1a1aa\",\n \"borderColor\": \"#3f3f46\"\n },\n \"policybazaar\": {\n \"primaryColor\": \"linear-gradient(88deg, #9403fd, #00adfe)\",\n \"primaryTextColor\": \"#ffffff\",\n \"backgroundColor\": \"#ffffff\",\n \"surfaceColor\": \"#f4f2ff\",\n \"agentBubbleColor\": \"linear-gradient(107deg, #f0fff9, #f7eeff)\",\n \"textColor\": \"#18181b\",\n \"mutedTextColor\": \"#64748b\",\n \"borderColor\": \"#e6e2ff\"\n }\n};\nexport const TIMING = {\n \"chatWidgetGraceMs\": 800,\n \"chatWidgetAfterTextMs\": 120,\n \"minTypingIndicatorMs\": 500\n};\nexport const WIDGET_DEFAULTS = {\n \"mode\": \"prod\",\n \"title\": \"Ringg AI Support\",\n \"description\": \"Ringg AI offers 24/7 voice support to handle your business calls efficiently and professionally\",\n \"defaultTab\": \"audio\",\n \"hideTabSelector\": false,\n \"defaultExpanded\": false,\n \"bypassStartScreen\": false,\n \"bypassFeedbackScreen\": false,\n \"voiceCallShowAnimation\": false,\n \"voiceCallShowTranscript\": true,\n \"notificationTuneUrl\": \"https://assets.ringg.ai/audios/misc/widget_notification.mp3\"\n};\n","/**\n * Event bus port — abstraction over platform-specific host-event dispatch.\n *\n * Web: DOM CustomEvents on `window` (existing integrations listen for these)\n * React Native: callback props / in-memory listeners\n */\n/** Web implementation — dispatches/listens via DOM CustomEvents on `window`. */\nexport function createDomEventBus() {\n const listeners = new Map();\n return {\n emit(event, payload) {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(event, { detail: payload }));\n }\n },\n on(event, handler) {\n if (typeof window === \"undefined\")\n return () => { };\n const wrapped = ((e) => handler(e.detail));\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n set.add(wrapped);\n window.addEventListener(event, wrapped);\n return () => {\n window.removeEventListener(event, wrapped);\n listeners.get(event)?.delete(wrapped);\n };\n },\n off(event) {\n const remove = (name, handlers) => {\n handlers.forEach((h) => window.removeEventListener(name, h));\n };\n if (event) {\n const handlers = listeners.get(event);\n if (handlers)\n remove(event, handlers);\n listeners.delete(event);\n }\n else {\n listeners.forEach((handlers, name) => remove(name, handlers));\n listeners.clear();\n }\n },\n };\n}\n/** In-memory event bus — for React Native or testing. */\nexport function createCallbackEventBus() {\n const listeners = new Map();\n return {\n emit(event, payload) {\n listeners.get(event)?.forEach((handler) => handler(payload));\n },\n on(event, handler) {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n const typed = handler;\n set.add(typed);\n return () => {\n listeners.get(event)?.delete(typed);\n };\n },\n off(event) {\n if (event) {\n listeners.delete(event);\n }\n else {\n listeners.clear();\n }\n },\n };\n}\n","/**\n * Clock port — injectable time and timers.\n *\n * The widget's UX-critical logic is timing logic (typing-indicator minimum\n * duration, chat-widget grace buffering). Routing all time access through\n * this port makes that logic deterministic under test.\n */\nexport function createSystemClock() {\n return {\n now() {\n return Date.now();\n },\n setTimeout(fn, ms) {\n return setTimeout(fn, ms);\n },\n clearTimeout(handle) {\n clearTimeout(handle);\n },\n };\n}\n","/**\n * Small platform ports — capabilities core needs but cannot implement\n * portably. Web and React Native each provide implementations.\n */\n/** No-op defaults for platforms/tests that don't wire these up */\nexport const grantedMicPermission = {\n isGranted: async () => true,\n request: async () => true,\n};\nexport const silentNotificationPlayer = {\n play: () => { },\n};\n","/**\n * API client for the Ringg backend.\n * Pure fetch-based — works in any JS runtime (browser, Node, React Native).\n * URLs are always injected by the platform entry point via a UrlResolver;\n * core embeds no endpoints.\n */\nexport function createStaticUrlResolver(urls) {\n return {\n resolve(mode) {\n return urls[mode];\n },\n };\n}\nexport function createRinggApiClient(config) {\n const { backendUrl, livekitUrl } = config.urlResolver.resolve(config.mode);\n const authHeaders = config.authorization\n ? { Authorization: config.authorization }\n : config.xApiKey\n ? { \"X-API-KEY\": config.xApiKey }\n : {};\n const headers = () => ({ \"Content-Type\": \"application/json\", ...authHeaders });\n return {\n backendUrl,\n livekitUrl,\n async startWebcall(params) {\n const response = await fetch(`${backendUrl}/calling/webcall`, {\n method: \"POST\",\n body: JSON.stringify({\n agent_id: params.agentId,\n custom_args_values: params.variables,\n media_type: params.mediaType,\n // Marks this call as coming from the v2 embed so the backend can use\n // the newer endpoint; absent on older embeds, which fall back.\n embed_version: \"v2\",\n }),\n headers: headers(),\n });\n // Read as text first, then parse — a non-JSON error page shouldn't crash\n // the widget with a cryptic JSON parse error.\n const responseText = await response.text();\n let data;\n try {\n data = JSON.parse(responseText);\n }\n catch {\n throw new Error(responseText.slice(0, 200) || `Request failed with status ${response.status}`);\n }\n if (!response.ok) {\n throw new Error(data?.message || \"Failed to make call\");\n }\n return {\n call_id: data.call_id,\n user_token: data.user_token,\n enabled_slash_commands: data.enabled_slash_commands,\n };\n },\n async submitFeedback(callId, feedback) {\n await fetch(`${backendUrl}/calling/${callId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify(feedback),\n headers: headers(),\n });\n },\n async callComponentApi(method, endpoint, payload) {\n const url = endpoint.startsWith(\"http\") ? endpoint : `${backendUrl}${endpoint}`;\n const response = await fetch(url, {\n method,\n body: method === \"GET\" ? undefined : JSON.stringify(payload),\n headers: headers(),\n });\n // Unchecked parse, same as production — the flow renderer validates shape.\n return (await response.json());\n },\n };\n}\n","/**\n * Theme engine — resolves, merges, and provides theme values.\n * Pure functions with no framework dependency.\n *\n * Default and preset theme VALUES live in tokens/tokens.json (shared across\n * all implementations via codegen) — only merging/contrast LOGIC lives here.\n */\nimport { DEFAULT_WIDGET_THEME, WIDGET_PRESET_THEMES } from \"../generated/tokens.js\";\nimport { getDominantColor } from \"./gradient-utils.js\";\nexport { DEFAULT_WIDGET_THEME, WIDGET_PRESET_THEMES };\n// ─── Theme merging ───────────────────────────────────────────────────────────\n/** Merge a partial user theme with the defaults. Returns a fully resolved theme. */\nexport function mergeWidgetTheme(theme) {\n return { ...DEFAULT_WIDGET_THEME, ...theme };\n}\n/** Merge a component-level theme with the widget theme as fallback. */\nexport function mergeComponentTheme(componentTheme, widgetTheme) {\n const base = widgetTheme ?? DEFAULT_WIDGET_THEME;\n return {\n primaryColor: base.primaryColor,\n primaryTextColor: base.primaryTextColor,\n backgroundColor: base.backgroundColor,\n surfaceColor: base.surfaceColor,\n textColor: base.textColor,\n mutedTextColor: base.mutedTextColor,\n borderColor: base.borderColor,\n errorColor: base.errorColor,\n successColor: base.successColor,\n fontFamily: base.fontFamily,\n borderRadius: base.borderRadius,\n buttonStyle: base.buttonStyle,\n ...componentTheme,\n };\n}\n// ─── Button radius ───────────────────────────────────────────────────────────\n/** Get button border radius based on style */\nexport function getButtonRadius(style) {\n switch (style) {\n case \"pill\":\n return \"9999px\";\n case \"square\":\n return \"6px\";\n case \"rounded\":\n default:\n return \"12px\";\n }\n}\n// ─── Color contrast ──────────────────────────────────────────────────────────\n/**\n * Calculate relative luminance of a color.\n * Handles both solid hex colors and gradient strings (uses dominant color).\n */\nfunction getLuminance(hexColor) {\n const solid = getDominantColor(hexColor);\n const hex = solid.replace(\"#\", \"\");\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n const toLinear = (c) => (c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));\n return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n/** Check if a color is considered \"light\" (for auto-contrast) */\nexport function isLightColor(hexColor) {\n try {\n return getLuminance(hexColor) > 0.5;\n }\n catch {\n return true;\n }\n}\n/** Get a contrasting text color (black or white) for a given background */\nexport function getContrastingTextColor(bgColor) {\n return isLightColor(bgColor) ? \"#212121\" : \"#ffffff\";\n}\n","/**\n * RPC message formatting — transforms between backend RPC format and internal\n * component format.\n *\n * The backend sends `send_dynamic_data` RPCs like:\n * { component_type: \"render_component_calendar\", component_config: { ... } }\n * The widget needs them in the internal format:\n * { component_type: \"calendar_booking\", component_id: \"calendar_1234\", data: { ... } }\n *\n * This module handles both directions.\n */\n// ─── Backend -> widget ───────────────────────────────────────────────────────\n/**\n * Transform a backend RPC payload into the internal component format.\n * Returns null if the component type is unknown.\n */\nexport function transformRpcToComponent(componentName, rpcPayload) {\n const componentId = `${componentName}_${Date.now()}`;\n // Legacy senders put the config under component_data — accept both, like production.\n const config = rpcPayload.component_config ?? rpcPayload.component_data;\n switch (componentName) {\n case \"calendar\":\n return transformCalendar(componentId, config, rpcPayload);\n case \"form\":\n return transformForm(componentId, config);\n case \"buttons\":\n return transformButtons(componentId, config, rpcPayload);\n case \"quick_replay\":\n return transformQuickReplay(componentId, config);\n case \"confirmation\":\n return transformConfirmation(componentId, rpcPayload);\n default:\n // Already in the internal format — pass through.\n if (rpcPayload.component_type && rpcPayload.component_id) {\n return rpcPayload;\n }\n return null;\n }\n}\nfunction transformCalendar(componentId, config, rpcPayload) {\n const configObj = config;\n const slots = configObj?.slots || [];\n const timezone = configObj?.timezone || \"UTC\";\n return {\n component_type: \"calendar_booking\",\n component_id: componentId,\n data: {\n available_slots: slots.map((slot) => ({ id: slot.id, datetime: slot.datetime })),\n timezone,\n title: rpcPayload.title || \"Select a time slot\",\n },\n };\n}\nfunction transformForm(componentId, config) {\n const configObj = config;\n const transformedFields = (configObj?.fields || []).map((field) => ({\n name: field.key || field.name || \"\",\n type: mapFieldType(field.type),\n label: field.description || field.label || field.key || field.name || \"\",\n required: field.required,\n placeholder: field.placeholder,\n options: field.options,\n }));\n return {\n component_type: \"form\",\n component_id: componentId,\n data: {\n title: configObj?.title || \"Form\",\n description: configObj?.description,\n fields: transformedFields,\n submit_label: configObj?.cta || configObj?.submit_label || \"Submit\",\n },\n };\n}\nfunction transformButtons(componentId, config, rpcPayload) {\n return {\n component_type: \"buttons\",\n component_id: componentId,\n data: {\n title: rpcPayload.title,\n buttons: Array.isArray(config) ? config : [],\n },\n };\n}\n/**\n * Quick replies render as free-standing chips (no boxed card) and, once picked,\n * show the selection as a user bubble instead of a confirmation card.\n */\nfunction transformQuickReplay(componentId, config) {\n const configObj = config;\n const options = Array.isArray(configObj?.options) ? configObj.options.filter((option) => typeof option === \"string\" && option.trim().length > 0) : [];\n return {\n component_type: \"buttons\",\n component_id: componentId,\n data: {\n presentation: \"free\",\n completionDisplay: \"selected_item\",\n buttons: options.map((option) => ({\n id: option,\n label: option,\n action: { type: \"trigger_component\" },\n })),\n },\n };\n}\nfunction transformConfirmation(componentId, rpcPayload) {\n return {\n component_type: \"confirmation\",\n component_id: componentId,\n data: {\n title: rpcPayload.title || \"Confirmed\",\n message: rpcPayload.message || \"\",\n icon: rpcPayload.icon || \"success\",\n details: rpcPayload.details,\n },\n };\n}\n/** Map backend field type strings to internal FormFieldType */\nfunction mapFieldType(backendType) {\n const typeMap = {\n text: \"text\",\n string: \"text\",\n number: \"number\",\n email: \"email\",\n phone_number: \"tel\",\n single_select: \"select\",\n multiselect: \"multiselect\",\n checkbox: \"boolean\",\n date: \"date\",\n textarea: \"textarea\",\n };\n return typeMap[backendType] || \"text\";\n}\nconst RECEIVE_RPC_METHOD = \"receive_dynamic_data\";\n/**\n * Format a component response payload for sending back to the backend via RPC.\n * Used when the user interacts with a component (selects a slot, submits a\n * form, taps a button).\n */\nexport function formatComponentResponse(componentName, componentId, responseData, originalConfig) {\n let componentData;\n const stepData = responseData.step_data;\n if (componentName === \"calendar\") {\n const slotId = stepData?.slot_id;\n const configObj = originalConfig;\n const slots = configObj?.slots || [];\n const timezone = configObj?.timezone || \"UTC\";\n const selectedSlot = slots.find((slot) => slot.id === slotId);\n componentData = {\n id: selectedSlot?.id || slotId,\n datetime: selectedSlot?.datetime || stepData?.slot_datetime,\n timezone,\n slot_time: stepData?.slot_time,\n slot_date: stepData?.slot_date,\n };\n }\n else if (componentName === \"form\") {\n componentData = responseData.step_data || responseData.all_data;\n }\n else if (componentName === \"buttons\") {\n const buttonId = stepData?.selected_button;\n const buttons = Array.isArray(originalConfig) ? originalConfig : [];\n const selectedButton = buttons.find((btn) => btn.id === buttonId);\n componentData = selectedButton || { id: buttonId };\n }\n else if (componentName === \"quick_replay\") {\n componentData = { text: stepData?.selected_button };\n }\n else {\n componentData = responseData;\n }\n // Echo the render payload's tool_id when present.\n const toolId = originalConfig?.tool_id;\n return {\n method: RECEIVE_RPC_METHOD,\n payload: JSON.stringify({\n component_type: `receive_component_${componentName}`,\n component_id: componentId,\n component_data: componentData,\n ...(toolId && { tool_id: toolId }),\n }),\n };\n}\n/** Format a slash command for sending via RPC. */\nexport function formatSlashCommand(command) {\n return {\n method: RECEIVE_RPC_METHOD,\n payload: JSON.stringify({\n component_type: \"receive_component_slash_command\",\n command: command.replace(/^\\//, \"\"),\n }),\n };\n}\n/**\n * Format a Block Kit interaction for the agent. Envelope mirrors the dashboard\n * test widget the bot bridge was tested against: `component_id` and `values`\n * are always present; `tool_id` is omitted when falsy and `value` when\n * undefined (never sent as null/empty keys).\n */\nexport function formatBlocksAction(toolId, componentId, action) {\n return {\n method: RECEIVE_RPC_METHOD,\n payload: JSON.stringify({\n component_type: \"receive_component_blocks\",\n component_id: componentId,\n ...(toolId && { tool_id: toolId }),\n component_data: {\n action_id: action.action_id,\n ...(action.value !== undefined && { value: action.value }),\n values: action.values,\n },\n }),\n };\n}\n/**\n * Format a raw dynamic-data payload (client packs: disease search/submit).\n * The payload already carries its own `component_type` envelope.\n */\nexport function formatDynamicData(payload) {\n return {\n method: RECEIVE_RPC_METHOD,\n payload: JSON.stringify(payload),\n };\n}\n","/**\n * Base store — the one state-sharing primitive in core.\n *\n * Platform bindings stay thin because they all consume the same shape:\n * web (Lit): subscribe(() => this.host.requestUpdate())\n * RN (React): useSyncExternalStore(store.subscribe, store.getSnapshot)\n *\n * Snapshots must be immutable values — stores rebuild them on change so\n * reference equality is a valid dirty check. `getSnapshot`/`subscribe` are\n * closures, so they stay bound when bindings pass them unbound (React:\n * `useSyncExternalStore(store.subscribe, store.getSnapshot)`).\n */\nexport function createStore(build) {\n const listeners = new Set();\n let snapshot = build();\n return {\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n commit() {\n snapshot = build();\n listeners.forEach((listener) => listener(snapshot));\n },\n dispose() {\n listeners.clear();\n },\n };\n}\n","/**\n * Shell store — widget open/close/feedback lifecycle and the active call id.\n * Ported from the alpha WidgetStateController; emits `ringg:widget_status`\n * host events on visibility transitions.\n */\nimport { createStore } from \"./store.js\";\nexport function createShellStore(eventBus, initialCallMode = \"audio\", \n// Permanently-expanded (embedded) widget: starts open, and minimize/close\n// keep the panel on screen — there is no trigger to reopen it from.\ndefaultExpanded = false) {\n // Two independent flags, exactly like the production useWidgetState hook:\n // minimizing must NOT forget a pending feedback screen — reopening shows it\n // again until it is submitted or skipped (which go through close()).\n let isOpen = defaultExpanded;\n let feedbackPending = false;\n let currentCallId = null;\n let callMode = initialCallMode;\n const buildViewState = () => {\n if (!isOpen)\n return \"closed\";\n return feedbackPending ? \"feedback\" : \"open\";\n };\n const build = () => ({ viewState: buildViewState(), currentCallId, callMode });\n const handle = createStore(build);\n const store = {\n getSnapshot: handle.getSnapshot,\n subscribe: handle.subscribe,\n dispose: handle.dispose,\n get isOpen() {\n return isOpen;\n },\n get isShowingFeedback() {\n return feedbackPending;\n },\n open() {\n // No-op while already visible. A pending feedback flag survives here, so\n // the controller's endCall sequence (showFeedback() then open()) and a\n // minimize → reopen both land on the feedback view.\n if (isOpen)\n return;\n isOpen = true;\n eventBus.emit(\"ringg:widget_status\", { status: \"maximised\", mode: callMode });\n handle.commit();\n },\n minimize() {\n // A permanently-expanded widget has no trigger to reopen from — hiding\n // the panel would strand the user, so minimize is a full no-op (no state\n // change, no \"minimised\" event), matching the production hook.\n if (defaultExpanded)\n return;\n if (!isOpen)\n return;\n // Deliberately keeps feedbackPending: reopening restores the feedback view.\n isOpen = false;\n eventBus.emit(\"ringg:widget_status\", { status: \"minimised\", mode: callMode });\n handle.commit();\n },\n close() {\n feedbackPending = false;\n currentCallId = null;\n // defaultExpanded: the panel stays visible (and no \"minimised\" event) —\n // only the feedback/call state resets, as in the production hook where\n // close() delegates to a no-op minimize().\n if (!defaultExpanded) {\n isOpen = false;\n eventBus.emit(\"ringg:widget_status\", { status: \"minimised\", mode: callMode });\n }\n handle.commit();\n },\n toggle() {\n if (isOpen) {\n store.minimize();\n }\n else {\n store.open();\n }\n },\n showFeedback() {\n feedbackPending = true;\n handle.commit();\n },\n setCallMode(mode) {\n if (callMode === mode)\n return;\n callMode = mode;\n handle.commit();\n },\n setCurrentCallId(callId) {\n currentCallId = callId;\n handle.commit();\n },\n };\n return store;\n}\n","/**\n * Session store — the call lifecycle state machine.\n *\n * idle → starting → live-optimistic → connected → idle\n *\n * \"live-optimistic\" is load-bearing UX (lifted from production): the flag\n * flips the moment /calling/webcall succeeds — before transport.connect()\n * resolves. The call exists server-side at that point, so the calling layout\n * mounts one HTTP round trip after Start instead of waiting out the LiveKit\n * handshake. A connect failure rolls it back so the start screen (with the\n * error) returns instead of a dead calling layout.\n */\nimport { createStore } from \"./store.js\";\nconst NO_ERROR = { hasError: false, message: \"\" };\n/** Verbatim production copy (use-microphone-permission.ts request() denial). */\nconst MIC_DENIED_MESSAGE = \"Microphone access was denied. Please enable it in your browser settings.\";\n/** Verbatim production copy (RoomEvent.MediaDevicesError handler). */\nconst MEDIA_DEVICES_ERROR_MESSAGE = \"Error acquiring microphone permission. Please make sure you grant the necessary permissions in your browser and reload the tab\";\nexport function createSessionStore(api, transport, mic) {\n let phase = \"idle\";\n let isLoading = false;\n let connectionState = \"disconnected\";\n let error = NO_ERROR;\n const computeIsSessionLive = () => phase === \"live-optimistic\" || phase === \"connected\";\n const build = () => ({\n phase,\n isLoading,\n isSessionLive: computeIsSessionLive(),\n connectionState,\n error,\n });\n const handle = createStore(build);\n transport.onConnectionStateChange((state) => {\n connectionState = state;\n if (state === \"connected\" && phase !== \"idle\")\n phase = \"connected\";\n handle.commit();\n });\n // Mic acquisition failing after connect (permission revoked, device gone) —\n // production surfaces this via RoomEvent.MediaDevicesError → setError.\n transport.onMediaDevicesError(() => {\n error = { hasError: true, message: MEDIA_DEVICES_ERROR_MESSAGE };\n handle.commit();\n });\n return {\n getSnapshot: handle.getSnapshot,\n subscribe: handle.subscribe,\n dispose: handle.dispose,\n get isSessionLive() {\n return computeIsSessionLive();\n },\n prewarm() {\n void transport.prepareConnection(api.livekitUrl).catch(() => { });\n },\n async start(params) {\n if (params.mediaType === \"audio\" && !(await mic.isGranted())) {\n if (!(await mic.request())) {\n // Denial must not be silent: production's mic.onError puts this\n // message on the start screen (use-microphone-permission.ts).\n error = { hasError: true, message: MIC_DENIED_MESSAGE };\n handle.commit();\n return null;\n }\n }\n isLoading = true;\n phase = \"starting\";\n handle.commit();\n try {\n const response = await api.startWebcall({\n agentId: params.agentId,\n variables: params.variables,\n mediaType: params.mediaType,\n });\n // Call exists server-side — mount the calling layout now.\n phase = \"live-optimistic\";\n error = NO_ERROR;\n handle.commit();\n await transport.connect(api.livekitUrl, response.user_token);\n if (params.mediaType === \"audio\")\n await transport.setMicrophoneEnabled(true);\n return {\n callId: response.call_id,\n slashCommands: response.enabled_slash_commands ?? [],\n };\n }\n catch (err) {\n // Roll the optimistic flip back — see module docs.\n phase = \"idle\";\n error = { hasError: true, message: err.message };\n handle.commit();\n return null;\n }\n finally {\n isLoading = false;\n handle.commit();\n }\n },\n async end() {\n isLoading = true;\n handle.commit();\n try {\n await transport.disconnect();\n }\n catch {\n // Disconnect failures don't block teardown.\n }\n finally {\n phase = \"idle\";\n isLoading = false;\n handle.commit();\n }\n },\n clearError() {\n error = NO_ERROR;\n handle.commit();\n },\n };\n}\n","/**\n * Message store — the single ordered conversation timeline.\n *\n * Three sources feed it and must interleave correctly:\n * - chat messages (text mode, incl. the local optimistic echo)\n * - transcription segments (audio mode; segments UPDATE in place by id as STT\n * refines, keeping their original position)\n * - component messages (RPC widgets, Block Kit — commit-time stamped so a\n * buffered widget sorts strictly after the agent message that released it)\n *\n * Ordering: entries sort by timestamp. The store hands out strictly\n * monotonically increasing timestamps (sub-ms bumped when the clock hasn't\n * advanced), replacing the production widget's `Date.now() + Math.random()`\n * collision-avoidance hacks with a deterministic policy.\n */\nimport { createStore } from \"./store.js\";\nconst MONOTONIC_BUMP = 0.001;\nexport function createMessageStore(clock) {\n /** Committed messages: chat, components, selection bubbles */\n let entries = [];\n /** Live transcription segments keyed by segment id */\n const transcripts = new Map();\n /** RAG source URL waiting to attach to the next agent reply */\n let pendingSourceUrl = \"\";\n let lastTimestamp = 0;\n const build = () => {\n const merged = [...transcripts.values(), ...entries].sort((a, b) => a.timestamp - b.timestamp);\n return { messages: merged };\n };\n const handle = createStore(build);\n const store = {\n getSnapshot: handle.getSnapshot,\n subscribe: handle.subscribe,\n dispose: handle.dispose,\n nextTimestamp() {\n const now = clock.now();\n lastTimestamp = now > lastTimestamp ? now : lastTimestamp + MONOTONIC_BUMP;\n return lastTimestamp;\n },\n addChatMessage(params) {\n const sourceUrl = !params.isSelf && pendingSourceUrl ? pendingSourceUrl : undefined;\n if (sourceUrl)\n pendingSourceUrl = \"\";\n const msg = {\n name: params.name ?? (params.isSelf ? \"You\" : \"Agent\"),\n message: params.message,\n isSelf: params.isSelf,\n timestamp: params.timestamp ?? store.nextTimestamp(),\n ...(sourceUrl && { sourceUrl }),\n };\n entries.push(msg);\n handle.commit();\n return msg;\n },\n addComponent(component) {\n const msg = {\n name: \"Agent\",\n message: \"\",\n isSelf: false,\n timestamp: store.nextTimestamp(),\n componentType: component.component_type,\n componentData: component,\n };\n entries.push(msg);\n handle.commit();\n return msg;\n },\n addSystemLog(params) {\n entries.push({\n name: \"system\",\n message: params.label,\n isSelf: false,\n timestamp: store.nextTimestamp(),\n kind: \"system\",\n ...(params.meta && { systemMeta: params.meta }),\n systemLevel: params.level,\n });\n handle.commit();\n },\n addLocalSelection(componentId, label) {\n const prompt = entries.find((m) => m.componentData?.component_id === componentId);\n const anchor = prompt ? prompt.timestamp + MONOTONIC_BUMP / 2 : store.nextTimestamp();\n entries.push({ name: \"You\", isSelf: true, message: label, timestamp: anchor });\n handle.commit();\n },\n upsertTranscription(segment) {\n const existing = transcripts.get(segment.id);\n transcripts.set(segment.id, {\n name: segment.participantName ?? (segment.isLocal ? \"You\" : \"Agent\"),\n message: segment.text,\n isSelf: segment.isLocal,\n timestamp: existing?.timestamp ?? store.nextTimestamp(),\n ...(existing?.sourceUrl && { sourceUrl: existing.sourceUrl }),\n });\n // Voice-mode RAG citations (App.tsx:1094-1118): a pending send_source_urls\n // value appends to the LAST transcription when that is an agent segment\n // without a URL yet. Whether it appended or not, the pending value is\n // consumed — production clears the ref on every update that doesn't\n // append, and the append itself is once-only (index guard + !sourceUrl).\n if (pendingSourceUrl) {\n let newestId;\n let newest;\n for (const [id, msg] of transcripts) {\n if (!newest || msg.timestamp >= newest.timestamp) {\n newest = msg;\n newestId = id;\n }\n }\n if (newest && newestId !== undefined && !newest.isSelf && !newest.sourceUrl) {\n transcripts.set(newestId, { ...newest, sourceUrl: pendingSourceUrl });\n }\n pendingSourceUrl = \"\";\n }\n handle.commit();\n },\n setPendingSourceUrl(url) {\n pendingSourceUrl = url;\n },\n clearPendingSourceUrl() {\n pendingSourceUrl = \"\";\n },\n reset() {\n entries = [];\n transcripts.clear();\n pendingSourceUrl = \"\";\n handle.commit();\n },\n };\n return store;\n}\n","/**\n * Timing constants — every value encodes a UX bug that was found and fixed in\n * the production widget. Values live in tokens/defaults.json (shared across\n * all implementations via codegen); change them there, never here.\n */\nimport { TIMING } from \"./generated/tokens.js\";\n/** Chat-widget RPCs land before the agent's text streams in; buffer them this\n * long waiting for the text so the widget sorts below it. */\nexport const CHAT_WIDGET_GRACE_MS = TIMING.chatWidgetGraceMs;\n/** Once the agent text lands, release buffered widgets after this beat so the\n * message paints first. */\nexport const CHAT_WIDGET_AFTER_TEXT_MS = TIMING.chatWidgetAfterTextMs;\n/** Keep the typing dots visible at least this long — instant replies\n * otherwise make the indicator flash. */\nexport const MIN_TYPING_INDICATOR_MS = TIMING.minTypingIndicatorMs;\n","/**\n * Typing store — drives the \"agent is typing\" indicator (text mode).\n *\n * Behavior lifted from the production widget:\n * - Dots appear the moment the user sends (we always expect a reply); the\n * min-duration timer anchors only when they first appear, so back-to-back\n * sends keep one continuous indicator instead of resetting it.\n * - Any landed backend response — text or RPC — answers the pending turn and\n * drops the dots, unconditionally.\n * - Replies that land faster than MIN_TYPING_INDICATOR_MS wait out the\n * remainder before committing, otherwise the indicator just flashes.\n */\nimport { createStore } from \"./store.js\";\nimport { MIN_TYPING_INDICATOR_MS } from \"../constants.js\";\nexport function createTypingStore(clock) {\n let shownAt = null;\n let isTyping = false;\n const build = () => ({ isTyping });\n const handle = createStore(build);\n const set = (next) => {\n if (isTyping === next)\n return;\n isTyping = next;\n handle.commit();\n };\n return {\n getSnapshot: handle.getSnapshot,\n subscribe: handle.subscribe,\n dispose: handle.dispose,\n showOnUserSend() {\n if (shownAt === null)\n shownAt = clock.now();\n set(true);\n },\n clear() {\n shownAt = null;\n set(false);\n },\n waitMinDuration() {\n if (shownAt === null)\n return Promise.resolve();\n const remaining = MIN_TYPING_INDICATOR_MS - (clock.now() - shownAt);\n if (remaining <= 0)\n return Promise.resolve();\n return new Promise((resolve) => clock.setTimeout(resolve, remaining));\n },\n };\n}\n","/**\n * Component store — interactive components pushed by the backend mid-call.\n *\n * Chat-mode anchoring (lifted from production): widget RPCs land instantly\n * while the agent's text streams a beat later. In text mode we buffer the\n * widget until the accompanying message lands, then commit it right after so\n * it sorts below. If no message arrives within CHAT_WIDGET_GRACE_MS, flush\n * anyway. Audio mode commits immediately.\n *\n * Also owns the response side: which components still await a user response\n * (and the original config needed to format it), completed flows, and the\n * extension registry that lets client packs handle domain-specific\n * `send_dynamic_data` component types without polluting core.\n */\nimport { createStore } from \"./store.js\";\nimport { CHAT_WIDGET_GRACE_MS, CHAT_WIDGET_AFTER_TEXT_MS } from \"../constants.js\";\nexport function createComponentStore(clock, \n/** Commits a component to the timeline — wired to MessageStore + host events by the controller */\ncommitComponent) {\n let pendingChatWidgets = [];\n let graceTimer = null;\n const pendingResponses = new Map();\n const completedFlowIds = new Set();\n let extensions = [];\n const build = () => ({ completedFlowIds: new Set(completedFlowIds) });\n const handle = createStore(build);\n const store = {\n getSnapshot: handle.getSnapshot,\n subscribe: handle.subscribe,\n dispose: handle.dispose,\n add(component, mode) {\n if (mode !== \"text\") {\n commitComponent(component);\n return;\n }\n pendingChatWidgets.push(component);\n if (!graceTimer) {\n graceTimer = clock.setTimeout(() => store.flush(), CHAT_WIDGET_GRACE_MS);\n }\n },\n onAgentTextLanded() {\n if (pendingChatWidgets.length > 0) {\n clock.setTimeout(() => store.flush(), CHAT_WIDGET_AFTER_TEXT_MS);\n }\n },\n flush() {\n if (graceTimer) {\n clock.clearTimeout(graceTimer);\n graceTimer = null;\n }\n const queued = pendingChatWidgets;\n pendingChatWidgets = [];\n queued.forEach((component) => commitComponent(component));\n },\n // ─── Response tracking ─────────────────────────────────────────────────────\n trackPendingResponse(componentId, pending) {\n pendingResponses.set(componentId, pending);\n },\n takePendingResponse(componentId) {\n const pending = pendingResponses.get(componentId);\n if (pending)\n pendingResponses.delete(componentId);\n return pending;\n },\n markFlowComplete(componentId) {\n completedFlowIds.add(componentId);\n handle.commit();\n },\n // ─── Extensions ────────────────────────────────────────────────────────────\n registerExtension(extension) {\n extensions.push(extension);\n return () => {\n extensions = extensions.filter((e) => e !== extension);\n };\n },\n runExtensions(componentName, parsed) {\n return extensions.some((extension) => extension(componentName, parsed));\n },\n // ─── Lifecycle ─────────────────────────────────────────────────────────────\n reset() {\n if (graceTimer) {\n clock.clearTimeout(graceTimer);\n graceTimer = null;\n }\n pendingChatWidgets = [];\n pendingResponses.clear();\n completedFlowIds.clear();\n handle.commit();\n },\n };\n return store;\n}\n","/**\n * Slash command store — merges commands declared in config with commands the\n * backend enables at webcall time. Config commands win on collisions.\n */\nimport { createStore } from \"./store.js\";\nexport function createSlashCommandStore(configCommands = []) {\n let runtimeCommands = [];\n const build = () => {\n const seen = new Set(configCommands.map((c) => c.command));\n const merged = [...configCommands];\n for (const cmd of runtimeCommands) {\n if (!seen.has(cmd.command))\n merged.push(cmd);\n }\n return { commands: merged };\n };\n const handle = createStore(build);\n return {\n getSnapshot: handle.getSnapshot,\n subscribe: handle.subscribe,\n dispose: handle.dispose,\n setRuntimeCommands(commands) {\n runtimeCommands = commands;\n handle.commit();\n },\n reset() {\n runtimeCommands = [];\n handle.commit();\n },\n };\n}\n","/**\n * RinggWidgetController — the composition root of the widget brain.\n *\n * Owns every store, wires transport events into them, and exposes the\n * imperative API the platform UIs call. This is the headless replacement for\n * the production widget's App.tsx orchestration: platform bindings render\n * snapshots and forward user intents; ALL behavior lives here or in the\n * stores.\n */\nimport { createRinggApiClient } from \"./api/client.js\";\nimport { createSystemClock } from \"./ports/clock.js\";\nimport { grantedMicPermission, silentNotificationPlayer } from \"./ports/platform.js\";\nimport { createCallbackEventBus } from \"./ports/event-bus.js\";\nimport { createMessageStore } from \"./stores/message-store.js\";\nimport { createTypingStore } from \"./stores/typing-store.js\";\nimport { createComponentStore } from \"./stores/component-store.js\";\nimport { createSlashCommandStore } from \"./stores/slash-command-store.js\";\nimport { createSessionStore } from \"./stores/session-store.js\";\nimport { createShellStore } from \"./stores/shell-store.js\";\nimport { mergeWidgetTheme } from \"./theme/theme-engine.js\";\nimport { transformRpcToComponent, formatComponentResponse, formatSlashCommand, formatBlocksAction, formatDynamicData } from \"./rpc/formatter.js\";\nimport { DEFAULT_CONFIG } from \"./types/config.js\";\nexport function createRinggWidgetController(config, ports) {\n const theme = mergeWidgetTheme(config.theme);\n const eventBus = ports.eventBus ?? createCallbackEventBus();\n const clock = ports.clock ?? createSystemClock();\n const notification = ports.notification ?? silentNotificationPlayer;\n const onDomAction = ports.onDomAction;\n const transport = ports.transport;\n const api = createRinggApiClient({\n urlResolver: ports.urlResolver,\n mode: config.mode ?? DEFAULT_CONFIG.mode,\n xApiKey: config.xApiKey,\n authorization: config.authorization,\n });\n const shell = createShellStore(eventBus, config.defaultTab ?? DEFAULT_CONFIG.defaultTab, config.defaultExpanded ?? DEFAULT_CONFIG.defaultExpanded);\n const session = createSessionStore(api, transport, ports.micPermission ?? grantedMicPermission);\n const messages = createMessageStore(clock);\n const typing = createTypingStore(clock);\n const slashCommands = createSlashCommandStore(config.enabledSlashCommands);\n const components = createComponentStore(clock, (component) => commitComponent(component));\n const unsubscribers = [];\n // ParticipantDisconnected AND Disconnected both funnel into endCall (the\n // transport's onSessionEnded fires for either, and livekit emits Disconnected\n // synchronously inside room.disconnect() while endCall is still awaiting), so\n // the \"ended\" host event needs the same once-per-conversation guard as\n // production's conversationEndedDispatched ref (App.tsx:259-264).\n let conversationEndedDispatched = false;\n // Inline chat pills for DOM-action/system events (App.tsx:945-967). Off by\n // default; `eventLogs.showIds` surfaces the action id next to the meta.\n const eventLogsEnabled = config.eventLogs?.enabled === true;\n const eventLogsShowIds = config.eventLogs?.showIds === true;\n const pushSystemLog = (entry) => {\n if (!eventLogsEnabled)\n return;\n const meta = eventLogsShowIds && entry.id ? (entry.meta ? `${entry.id} · ${entry.meta}` : entry.id) : entry.meta;\n messages.addSystemLog({ label: entry.label, meta, level: entry.level });\n };\n // ─── Internal wiring ───────────────────────────────────────────────────────\n function resetConversation() {\n messages.reset();\n components.reset();\n }\n function commitComponent(component) {\n messages.addComponent(component);\n eventBus.emit(\"ringg:calendar_booking\", { status: \"shown\", componentId: component.component_id });\n // A rendered component *is* the agent's reply — the turn passes to the\n // user, so drop the dots.\n typing.clear();\n if (!shell.isOpen)\n notification.play();\n shell.open();\n }\n async function handleAgentTextStream(stream) {\n // Production registers this handler only while callMode === \"text\" &&\n // isSessionLive (App.tsx:1129). LiveKit Agents backends publish agent/user\n // utterances on BOTH the legacy transcription packets and this topic, so\n // committing these streams during an audio call would render every\n // utterance twice (live upsert + chat bubble).\n if (shell.getSnapshot().callMode !== \"text\" || !session.isSessionLive)\n return;\n try {\n const message = await stream.readAll();\n if (!stream.isAgent) {\n messages.addChatMessage({ message, isSelf: true, name: \"You\" });\n // Any landed text-stream message consumes the pending RAG URL —\n // production clears the ref unconditionally (App.tsx:1159).\n messages.clearPendingSourceUrl();\n return;\n }\n // Hold the dots up for at least the minimum duration even if the reply\n // came back fast — otherwise the indicator just flashes.\n await typing.waitMinDuration();\n if (!shell.isOpen)\n notification.play();\n shell.open();\n messages.addChatMessage({ message, isSelf: false, name: \"Agent\" });\n // Any landed reply clears the dots, unconditionally.\n typing.clear();\n // Release any widget buffered for this turn so it sorts directly below.\n components.onAgentTextLanded();\n }\n catch {\n if (stream.isAgent)\n typing.clear();\n }\n }\n async function handleBlocksStream(stream) {\n try {\n const raw = await stream.readAll();\n typing.clear();\n const parsed = JSON.parse(raw);\n if (parsed.component_type !== \"render_component_blocks\" || !Array.isArray(parsed.component_config?.blocks))\n return;\n components.add({\n component_type: \"blocks\",\n component_id: `blocks_${clock.now()}`,\n data: parsed.component_config,\n }, shell.getSnapshot().callMode);\n }\n catch {\n // Malformed blocks payloads are dropped; the conversation continues.\n }\n }\n async function handleDynamicData(invocation) {\n typing.clear();\n let parsed;\n try {\n parsed = JSON.parse(invocation.payload);\n }\n catch {\n throw new Error(\"Invalid send_dynamic_data payload\");\n }\n const componentType = parsed.component_type;\n if (!componentType) {\n return JSON.stringify({ status: \"error\", message: \"No component_type provided\" });\n }\n // Fire-and-forget host-page action — execute and ack immediately.\n // Backend payload uses { action_id, event_name, detail }; normalize to the\n // internal shape exactly like production (App.tsx:986-995): kind defaults\n // to \"trigger_event\" when absent.\n if (componentType === \"execute_dom_action\") {\n const cfg = (parsed.component_config ?? parsed.component_data ?? {});\n const action = {\n id: cfg.id ?? cfg.action_id ?? \"\",\n kind: cfg.kind ?? \"trigger_event\",\n event_name: cfg.event_name,\n default_payload: cfg.default_payload ?? cfg.detail,\n };\n onDomAction?.(action, pushSystemLog);\n return JSON.stringify({ status: \"received\" });\n }\n const componentName = componentType.replace(\"render_component_\", \"\");\n // Client packs get first refusal (e.g. disease_search_results).\n if (components.runExtensions(componentName, parsed)) {\n return JSON.stringify({ status: \"received\" });\n }\n const component = transformRpcToComponent(componentName, parsed);\n if (!component) {\n return JSON.stringify({ status: \"error\", message: `Unknown component type: ${componentName}` });\n }\n components.trackPendingResponse(component.component_id, {\n name: componentName,\n originalConfig: parsed.component_config ?? parsed.component_data,\n });\n components.add(component, shell.getSnapshot().callMode);\n return JSON.stringify({ status: \"received\", component_id: component.component_id });\n }\n /**\n * Legacy `render_component` RPC (production's componentRpcHandler,\n * App.tsx:789-805): the payload is already in the internal component format\n * — commit it untouched when component_type && component_id are present.\n * No transform, no pending-response tracking, and a bare {status:\"received\"}\n * ack (never a component_id).\n */\n async function handleRenderComponent(invocation) {\n typing.clear();\n let parsed;\n try {\n parsed = JSON.parse(invocation.payload);\n }\n catch {\n throw new Error(\"Invalid component payload\");\n }\n if (parsed.component_type && parsed.component_id) {\n components.add(parsed, shell.getSnapshot().callMode);\n }\n return JSON.stringify({ status: \"received\" });\n }\n function wireTransport() {\n transport.registerRpcMethod(\"send_dynamic_data\", (invocation) => handleDynamicData(invocation));\n // Legacy method name — pre-formatted payloads, committed as-is.\n transport.registerRpcMethod(\"render_component\", (invocation) => handleRenderComponent(invocation));\n // RAG citations (App.tsx:775-786): `source_urls` array → ALL urls joined\n // with \", \"; else the singular `source_url` string. Other keys are ignored\n // (production never sends them) and malformed JSON rejects the RPC.\n transport.registerRpcMethod(\"send_source_urls\", async (invocation) => {\n let parsed;\n try {\n parsed = JSON.parse(invocation.payload);\n }\n catch {\n throw new Error(\"Invalid payload for send_source_urls\");\n }\n if (Array.isArray(parsed.source_urls))\n messages.setPendingSourceUrl(parsed.source_urls.join(\", \"));\n else if (parsed.source_url)\n messages.setPendingSourceUrl(String(parsed.source_url));\n return JSON.stringify({ status: \"received\" });\n });\n // Agent text replies (text mode). Registered up front — text streams\n // aren't replayed, so registering only after \"connected\" can drop the\n // agent's greeting.\n transport.registerTextStreamHandler(\"lk.transcription\", (stream) => {\n void handleAgentTextStream(stream);\n });\n // Block Kit arrives over a text stream (chunked → no RPC size cap).\n transport.registerTextStreamHandler(\"ringg.blocks\", (stream) => {\n void handleBlocksStream(stream);\n });\n unsubscribers.push(transport.onChatMessage((message) => {\n // Local sends are committed optimistically in sendMessage() — an\n // adapter echoing them anyway must not duplicate the bubble.\n if (message.isSelf)\n return;\n // Incoming chat commits only in text mode (production merges\n // `chatMessages` inside the callMode === \"text\" && isSessionLive\n // effect only — App.tsx:1129, 1187-1206).\n if (shell.getSnapshot().callMode !== \"text\" || !session.isSessionLive)\n return;\n messages.addChatMessage({ message: message.message, isSelf: false, name: message.senderName });\n if (message.isAgent)\n typing.clear();\n }), transport.onTranscription((segment) => {\n // Transcription packets merge only during a connected audio call\n // (App.tsx:1074) — text mode renders the lk.transcription streams\n // instead, and both channels carry the same utterances.\n const { callMode } = shell.getSnapshot();\n if (callMode !== \"audio\" || session.getSnapshot().connectionState !== \"connected\")\n return;\n messages.upsertTranscription(segment);\n }), transport.onSessionEnded(() => {\n // Remote hangup / room drop — same path as the user ending the call.\n if (session.isSessionLive)\n void controller.endCall();\n }));\n }\n const controller = {\n config,\n theme,\n eventBus,\n shell,\n session,\n messages,\n typing,\n components,\n slashCommands,\n // ─── Widget shell ──────────────────────────────────────────────────────────\n openWidget() {\n shell.open();\n // Opening is a clear intent signal — warm the connection while the user\n // reads the start screen (never on page views where it's never opened).\n if (!session.isSessionLive)\n session.prewarm();\n },\n minimizeWidget() {\n shell.minimize();\n },\n handleTriggerClick() {\n // defaultExpanded renders no trigger at all — a stray click must never\n // toggle the panel or start a call (the widget is permanently open).\n if (config.defaultExpanded)\n return;\n const { isLoading, connectionState } = session.getSnapshot();\n if (config.bypassStartScreen && !isLoading && connectionState === \"disconnected\" && !session.isSessionLive) {\n controller.openWidget();\n void controller.startCall(shell.getSnapshot().callMode);\n }\n else if (shell.isOpen) {\n shell.minimize();\n }\n else {\n controller.openWidget();\n }\n },\n // ─── Call lifecycle ────────────────────────────────────────────────────────\n async startCall(mediaType) {\n shell.setCallMode(mediaType);\n // Fresh conversation for every new call — old transcript/components never\n // carry over.\n resetConversation();\n const result = await session.start({\n agentId: config.agentId,\n variables: config.variables ?? {},\n mediaType,\n });\n if (!result) {\n typing.clear();\n return;\n }\n shell.setCurrentCallId(result.callId);\n slashCommands.setRuntimeCommands(result.slashCommands);\n // In text mode raise the dots immediately: a greeting is always coming,\n // and they cover both connect and first-reply latency.\n if (mediaType === \"text\")\n typing.showOnUserSend();\n // Re-arm the once-per-conversation \"ended\" guard, then announce the start\n // (production's dispatchConversationStart, App.tsx:254-257).\n conversationEndedDispatched = false;\n eventBus.emit(\"ringg:conversation_status\", { status: \"started\", mode: mediaType, callId: result.callId });\n },\n async endCall() {\n const { currentCallId, callMode } = shell.getSnapshot();\n // Guarded like production's conversationEndedDispatched ref: endCall\n // re-enters via onSessionEnded (livekit emits Disconnected synchronously\n // inside room.disconnect()), and the host must see exactly one \"ended\"\n // per conversation.\n if (currentCallId && !conversationEndedDispatched) {\n conversationEndedDispatched = true;\n eventBus.emit(\"ringg:conversation_status\", { status: \"ended\", mode: callMode, callId: currentCallId });\n }\n slashCommands.reset();\n typing.clear();\n components.reset();\n await session.end();\n if (config.bypassFeedbackScreen) {\n resetConversation();\n shell.close();\n }\n else {\n shell.showFeedback();\n shell.open();\n }\n },\n // ─── Chat ──────────────────────────────────────────────────────────────────\n async sendMessage(text) {\n messages.addChatMessage({ message: text, isSelf: true });\n typing.showOnUserSend();\n await transport.sendChatMessage(text);\n },\n // ─── Components ────────────────────────────────────────────────────────────\n async sendComponentResponse(componentId, responseData) {\n const pending = components.takePendingResponse(componentId);\n if (!pending)\n return;\n const { method, payload } = formatComponentResponse(pending.name, componentId, responseData, pending.originalConfig);\n await transport.performRpcToAgent(method, payload);\n eventBus.emit(\"ringg:component_acknowledgement\", {\n componentName: pending.name,\n componentId,\n status: \"responded\",\n });\n },\n async sendBlocksAction(toolId, componentId, action) {\n const { method, payload } = formatBlocksAction(toolId, componentId, action);\n try {\n await transport.performRpcToAgent(method, payload);\n }\n catch {\n // Production console.errors and never surfaces it — resolving anyway\n // lets the BlocksStep spinner clear.\n }\n },\n callComponentApi(method, endpoint, payload) {\n return api.callComponentApi(method, endpoint, payload);\n },\n async sendDynamicData(payload) {\n const { method, payload: rpcPayload } = formatDynamicData(payload);\n await transport.performRpcToAgent(method, rpcPayload);\n },\n addLocalComponent(component) {\n // Direct commit, like production's local widget messages (slash-command\n // widgets) — NOT the chat buffering path: there's no agent text coming\n // to anchor under, and no typing/notification/open side effects apply.\n messages.addComponent(component);\n },\n displaySelection(componentId, label) {\n messages.addLocalSelection(componentId, label);\n },\n markFlowComplete(componentId) {\n components.markFlowComplete(componentId);\n eventBus.emit(\"ringg:calendar_booking\", { status: \"confirmed\", componentId, message: \"Flow completed\" });\n },\n registerDynamicDataExtension(extension) {\n return components.registerExtension(extension);\n },\n // ─── Slash commands ────────────────────────────────────────────────────────\n async sendSlashCommand(command) {\n // WIDGET_TOOL commands render locally — extensions (client packs) own\n // them; nothing goes over the wire from core.\n if (components.runExtensions(\"slash_command\", { command: command.command, tool_type: command.tool_type }))\n return;\n const { method, payload } = formatSlashCommand(command.command);\n await transport.performRpcToAgent(method, payload);\n },\n // ─── Feedback ──────────────────────────────────────────────────────────────\n async submitFeedback(rating, comment) {\n const { currentCallId } = shell.getSnapshot();\n if (currentCallId) {\n try {\n await api.submitFeedback(currentCallId, { rating, comment });\n eventBus.emit(\"ringg:feedback_status\", { status: \"submitted\", callId: currentCallId, rating });\n }\n catch {\n // Feedback is best-effort — closing the widget must never fail on it.\n }\n }\n resetConversation();\n shell.close();\n },\n skipFeedback() {\n const { currentCallId } = shell.getSnapshot();\n if (currentCallId) {\n eventBus.emit(\"ringg:feedback_status\", { status: \"skipped\", callId: currentCallId });\n }\n resetConversation();\n shell.close();\n },\n // ─── Teardown ──────────────────────────────────────────────────────────────\n destroy() {\n unsubscribers.forEach((unsubscribe) => unsubscribe());\n transport.unregisterRpcMethod(\"send_dynamic_data\");\n transport.unregisterRpcMethod(\"render_component\");\n transport.unregisterRpcMethod(\"send_source_urls\");\n transport.unregisterTextStreamHandler(\"lk.transcription\");\n transport.unregisterTextStreamHandler(\"ringg.blocks\");\n void transport.disconnect();\n [shell, session, messages, typing, components, slashCommands].forEach((store) => store.dispose());\n eventBus.off();\n },\n };\n wireTransport();\n // defaultExpanded seeds the shell store open at creation (no \"maximised\"\n // event on mount, matching production where isOpen starts true), so no\n // explicit open() call is needed here.\n return controller;\n}\n","/**\n * React bindings — shared by @ringg/web (React DOM) and @ringg/react-native.\n *\n * Every hook is a useSyncExternalStore call over a core store; there is no\n * behavior here and there must never be. A fix to typing timing, message\n * ordering, or session lifecycle lands in the stores once and both platforms\n * pick it up.\n *\n * Imported via the \"@ringg/core/react\" subpath so non-React consumers of\n * core never touch the react dependency (it's an optional peer).\n */\nimport { useSyncExternalStore } from \"react\";\nexport function useStoreSnapshot(store) {\n return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n}\nexport const useRinggMessages = (controller) => useStoreSnapshot(controller.messages);\nexport const useRinggTyping = (controller) => useStoreSnapshot(controller.typing);\nexport const useRinggSession = (controller) => useStoreSnapshot(controller.session);\nexport const useRinggShell = (controller) => useStoreSnapshot(controller.shell);\nexport const useRinggComponents = (controller) => useStoreSnapshot(controller.components);\nexport const useRinggSlashCommands = (controller) => useStoreSnapshot(controller.slashCommands);\n"],"mappings":"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","names":[]}