@repzo/widget-react-native 1.0.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 (448) hide show
  1. package/README.md +482 -0
  2. package/lib/commonjs/agent-ui-blocks.js +159 -0
  3. package/lib/commonjs/agent-ui-blocks.js.map +1 -0
  4. package/lib/commonjs/api/client.js +267 -0
  5. package/lib/commonjs/api/client.js.map +1 -0
  6. package/lib/commonjs/api/realtime.js +193 -0
  7. package/lib/commonjs/api/realtime.js.map +1 -0
  8. package/lib/commonjs/api/sse-parser.js +58 -0
  9. package/lib/commonjs/api/sse-parser.js.map +1 -0
  10. package/lib/commonjs/controller.js +23 -0
  11. package/lib/commonjs/controller.js.map +1 -0
  12. package/lib/commonjs/device-id.js +75 -0
  13. package/lib/commonjs/device-id.js.map +1 -0
  14. package/lib/commonjs/events.js +49 -0
  15. package/lib/commonjs/events.js.map +1 -0
  16. package/lib/commonjs/i18n.js +106 -0
  17. package/lib/commonjs/i18n.js.map +1 -0
  18. package/lib/commonjs/index.js +98 -0
  19. package/lib/commonjs/index.js.map +1 -0
  20. package/lib/commonjs/locales.js +85 -0
  21. package/lib/commonjs/locales.js.map +1 -0
  22. package/lib/commonjs/package.json +1 -0
  23. package/lib/commonjs/push/push-notifications.js +208 -0
  24. package/lib/commonjs/push/push-notifications.js.map +1 -0
  25. package/lib/commonjs/state/use-widget-state.js +23 -0
  26. package/lib/commonjs/state/use-widget-state.js.map +1 -0
  27. package/lib/commonjs/state/widget-store.js +1682 -0
  28. package/lib/commonjs/state/widget-store.js.map +1 -0
  29. package/lib/commonjs/storage.js +147 -0
  30. package/lib/commonjs/storage.js.map +1 -0
  31. package/lib/commonjs/types.js +44 -0
  32. package/lib/commonjs/types.js.map +1 -0
  33. package/lib/commonjs/ui/WidgetProvider.js +404 -0
  34. package/lib/commonjs/ui/WidgetProvider.js.map +1 -0
  35. package/lib/commonjs/ui/components/AgentUiBlocks.js +864 -0
  36. package/lib/commonjs/ui/components/AgentUiBlocks.js.map +1 -0
  37. package/lib/commonjs/ui/components/Avatar.js +76 -0
  38. package/lib/commonjs/ui/components/Avatar.js.map +1 -0
  39. package/lib/commonjs/ui/components/ConversationRow.js +155 -0
  40. package/lib/commonjs/ui/components/ConversationRow.js.map +1 -0
  41. package/lib/commonjs/ui/components/ErrorBoundary.js +44 -0
  42. package/lib/commonjs/ui/components/ErrorBoundary.js.map +1 -0
  43. package/lib/commonjs/ui/components/Gradient.js +168 -0
  44. package/lib/commonjs/ui/components/Gradient.js.map +1 -0
  45. package/lib/commonjs/ui/components/Launcher.js +125 -0
  46. package/lib/commonjs/ui/components/Launcher.js.map +1 -0
  47. package/lib/commonjs/ui/components/Markdown.js +257 -0
  48. package/lib/commonjs/ui/components/Markdown.js.map +1 -0
  49. package/lib/commonjs/ui/components/OutboundMessageCard.js +157 -0
  50. package/lib/commonjs/ui/components/OutboundMessageCard.js.map +1 -0
  51. package/lib/commonjs/ui/components/WidgetPanel.js +131 -0
  52. package/lib/commonjs/ui/components/WidgetPanel.js.map +1 -0
  53. package/lib/commonjs/ui/components/icons.js +383 -0
  54. package/lib/commonjs/ui/components/icons.js.map +1 -0
  55. package/lib/commonjs/ui/hooks/use-keyboard-overlap.js +113 -0
  56. package/lib/commonjs/ui/hooks/use-keyboard-overlap.js.map +1 -0
  57. package/lib/commonjs/ui/hooks/use-reduce-motion.js +38 -0
  58. package/lib/commonjs/ui/hooks/use-reduce-motion.js.map +1 -0
  59. package/lib/commonjs/ui/hooks/use-widget-insets.js +41 -0
  60. package/lib/commonjs/ui/hooks/use-widget-insets.js.map +1 -0
  61. package/lib/commonjs/ui/screens/chat/ChatView.js +590 -0
  62. package/lib/commonjs/ui/screens/chat/ChatView.js.map +1 -0
  63. package/lib/commonjs/ui/screens/chat/ChatView.styles.js +362 -0
  64. package/lib/commonjs/ui/screens/chat/ChatView.styles.js.map +1 -0
  65. package/lib/commonjs/ui/screens/chat/ChatView.types.js +6 -0
  66. package/lib/commonjs/ui/screens/chat/ChatView.types.js.map +1 -0
  67. package/lib/commonjs/ui/screens/conversations/ConversationsList.js +150 -0
  68. package/lib/commonjs/ui/screens/conversations/ConversationsList.js.map +1 -0
  69. package/lib/commonjs/ui/screens/conversations/ConversationsList.styles.js +118 -0
  70. package/lib/commonjs/ui/screens/conversations/ConversationsList.styles.js.map +1 -0
  71. package/lib/commonjs/ui/screens/conversations/ConversationsList.types.js +6 -0
  72. package/lib/commonjs/ui/screens/conversations/ConversationsList.types.js.map +1 -0
  73. package/lib/commonjs/ui/screens/home/HomeView.js +336 -0
  74. package/lib/commonjs/ui/screens/home/HomeView.js.map +1 -0
  75. package/lib/commonjs/ui/screens/home/HomeView.styles.js +245 -0
  76. package/lib/commonjs/ui/screens/home/HomeView.styles.js.map +1 -0
  77. package/lib/commonjs/ui/screens/home/HomeView.types.js +6 -0
  78. package/lib/commonjs/ui/screens/home/HomeView.types.js.map +1 -0
  79. package/lib/commonjs/ui/screens/home/greeting.js +49 -0
  80. package/lib/commonjs/ui/screens/home/greeting.js.map +1 -0
  81. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.js +229 -0
  82. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.js.map +1 -0
  83. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.styles.js +125 -0
  84. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.styles.js.map +1 -0
  85. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.types.js +6 -0
  86. package/lib/commonjs/ui/screens/pre-chat/PreChatForm.types.js.map +1 -0
  87. package/lib/commonjs/ui/styles/global.js +55 -0
  88. package/lib/commonjs/ui/styles/global.js.map +1 -0
  89. package/lib/commonjs/ui/styles/theme.js +148 -0
  90. package/lib/commonjs/ui/styles/theme.js.map +1 -0
  91. package/lib/commonjs/ui/utils/conversations.js +125 -0
  92. package/lib/commonjs/ui/utils/conversations.js.map +1 -0
  93. package/lib/commonjs/ui/utils/html.js +44 -0
  94. package/lib/commonjs/ui/utils/html.js.map +1 -0
  95. package/lib/commonjs/ui/utils/native-gradient.js +65 -0
  96. package/lib/commonjs/ui/utils/native-gradient.js.map +1 -0
  97. package/lib/commonjs/ui/utils/rtl.js +56 -0
  98. package/lib/commonjs/ui/utils/rtl.js.map +1 -0
  99. package/lib/commonjs/ui/utils/safe-url.js +67 -0
  100. package/lib/commonjs/ui/utils/safe-url.js.map +1 -0
  101. package/lib/module/agent-ui-blocks.js +152 -0
  102. package/lib/module/agent-ui-blocks.js.map +1 -0
  103. package/lib/module/api/client.js +261 -0
  104. package/lib/module/api/client.js.map +1 -0
  105. package/lib/module/api/realtime.js +189 -0
  106. package/lib/module/api/realtime.js.map +1 -0
  107. package/lib/module/api/sse-parser.js +53 -0
  108. package/lib/module/api/sse-parser.js.map +1 -0
  109. package/lib/module/controller.js +19 -0
  110. package/lib/module/controller.js.map +1 -0
  111. package/lib/module/device-id.js +69 -0
  112. package/lib/module/device-id.js.map +1 -0
  113. package/lib/module/events.js +44 -0
  114. package/lib/module/events.js.map +1 -0
  115. package/lib/module/i18n.js +99 -0
  116. package/lib/module/i18n.js.map +1 -0
  117. package/lib/module/index.js +55 -0
  118. package/lib/module/index.js.map +1 -0
  119. package/lib/module/locales.js +80 -0
  120. package/lib/module/locales.js.map +1 -0
  121. package/lib/module/package.json +1 -0
  122. package/lib/module/push/push-notifications.js +204 -0
  123. package/lib/module/push/push-notifications.js.map +1 -0
  124. package/lib/module/state/use-widget-state.js +18 -0
  125. package/lib/module/state/use-widget-state.js.map +1 -0
  126. package/lib/module/state/widget-store.js +1677 -0
  127. package/lib/module/state/widget-store.js.map +1 -0
  128. package/lib/module/storage.js +141 -0
  129. package/lib/module/storage.js.map +1 -0
  130. package/lib/module/types.js +40 -0
  131. package/lib/module/types.js.map +1 -0
  132. package/lib/module/ui/WidgetProvider.js +400 -0
  133. package/lib/module/ui/WidgetProvider.js.map +1 -0
  134. package/lib/module/ui/components/AgentUiBlocks.js +857 -0
  135. package/lib/module/ui/components/AgentUiBlocks.js.map +1 -0
  136. package/lib/module/ui/components/Avatar.js +71 -0
  137. package/lib/module/ui/components/Avatar.js.map +1 -0
  138. package/lib/module/ui/components/ConversationRow.js +150 -0
  139. package/lib/module/ui/components/ConversationRow.js.map +1 -0
  140. package/lib/module/ui/components/ErrorBoundary.js +39 -0
  141. package/lib/module/ui/components/ErrorBoundary.js.map +1 -0
  142. package/lib/module/ui/components/Gradient.js +165 -0
  143. package/lib/module/ui/components/Gradient.js.map +1 -0
  144. package/lib/module/ui/components/Launcher.js +121 -0
  145. package/lib/module/ui/components/Launcher.js.map +1 -0
  146. package/lib/module/ui/components/Markdown.js +253 -0
  147. package/lib/module/ui/components/Markdown.js.map +1 -0
  148. package/lib/module/ui/components/OutboundMessageCard.js +153 -0
  149. package/lib/module/ui/components/OutboundMessageCard.js.map +1 -0
  150. package/lib/module/ui/components/WidgetPanel.js +127 -0
  151. package/lib/module/ui/components/WidgetPanel.js.map +1 -0
  152. package/lib/module/ui/components/icons.js +370 -0
  153. package/lib/module/ui/components/icons.js.map +1 -0
  154. package/lib/module/ui/hooks/use-keyboard-overlap.js +109 -0
  155. package/lib/module/ui/hooks/use-keyboard-overlap.js.map +1 -0
  156. package/lib/module/ui/hooks/use-reduce-motion.js +34 -0
  157. package/lib/module/ui/hooks/use-reduce-motion.js.map +1 -0
  158. package/lib/module/ui/hooks/use-widget-insets.js +37 -0
  159. package/lib/module/ui/hooks/use-widget-insets.js.map +1 -0
  160. package/lib/module/ui/screens/chat/ChatView.js +586 -0
  161. package/lib/module/ui/screens/chat/ChatView.js.map +1 -0
  162. package/lib/module/ui/screens/chat/ChatView.styles.js +358 -0
  163. package/lib/module/ui/screens/chat/ChatView.styles.js.map +1 -0
  164. package/lib/module/ui/screens/chat/ChatView.types.js +4 -0
  165. package/lib/module/ui/screens/chat/ChatView.types.js.map +1 -0
  166. package/lib/module/ui/screens/conversations/ConversationsList.js +146 -0
  167. package/lib/module/ui/screens/conversations/ConversationsList.js.map +1 -0
  168. package/lib/module/ui/screens/conversations/ConversationsList.styles.js +114 -0
  169. package/lib/module/ui/screens/conversations/ConversationsList.styles.js.map +1 -0
  170. package/lib/module/ui/screens/conversations/ConversationsList.types.js +4 -0
  171. package/lib/module/ui/screens/conversations/ConversationsList.types.js.map +1 -0
  172. package/lib/module/ui/screens/home/HomeView.js +332 -0
  173. package/lib/module/ui/screens/home/HomeView.js.map +1 -0
  174. package/lib/module/ui/screens/home/HomeView.styles.js +242 -0
  175. package/lib/module/ui/screens/home/HomeView.styles.js.map +1 -0
  176. package/lib/module/ui/screens/home/HomeView.types.js +4 -0
  177. package/lib/module/ui/screens/home/HomeView.types.js.map +1 -0
  178. package/lib/module/ui/screens/home/greeting.js +44 -0
  179. package/lib/module/ui/screens/home/greeting.js.map +1 -0
  180. package/lib/module/ui/screens/pre-chat/PreChatForm.js +225 -0
  181. package/lib/module/ui/screens/pre-chat/PreChatForm.js.map +1 -0
  182. package/lib/module/ui/screens/pre-chat/PreChatForm.styles.js +121 -0
  183. package/lib/module/ui/screens/pre-chat/PreChatForm.styles.js.map +1 -0
  184. package/lib/module/ui/screens/pre-chat/PreChatForm.types.js +4 -0
  185. package/lib/module/ui/screens/pre-chat/PreChatForm.types.js.map +1 -0
  186. package/lib/module/ui/styles/global.js +51 -0
  187. package/lib/module/ui/styles/global.js.map +1 -0
  188. package/lib/module/ui/styles/theme.js +137 -0
  189. package/lib/module/ui/styles/theme.js.map +1 -0
  190. package/lib/module/ui/utils/conversations.js +115 -0
  191. package/lib/module/ui/utils/conversations.js.map +1 -0
  192. package/lib/module/ui/utils/html.js +39 -0
  193. package/lib/module/ui/utils/html.js.map +1 -0
  194. package/lib/module/ui/utils/native-gradient.js +60 -0
  195. package/lib/module/ui/utils/native-gradient.js.map +1 -0
  196. package/lib/module/ui/utils/rtl.js +49 -0
  197. package/lib/module/ui/utils/rtl.js.map +1 -0
  198. package/lib/module/ui/utils/safe-url.js +59 -0
  199. package/lib/module/ui/utils/safe-url.js.map +1 -0
  200. package/lib/typescript/commonjs/agent-ui-blocks.d.ts +20 -0
  201. package/lib/typescript/commonjs/agent-ui-blocks.d.ts.map +1 -0
  202. package/lib/typescript/commonjs/api/client.d.ts +115 -0
  203. package/lib/typescript/commonjs/api/client.d.ts.map +1 -0
  204. package/lib/typescript/commonjs/api/realtime.d.ts +39 -0
  205. package/lib/typescript/commonjs/api/realtime.d.ts.map +1 -0
  206. package/lib/typescript/commonjs/api/sse-parser.d.ts +13 -0
  207. package/lib/typescript/commonjs/api/sse-parser.d.ts.map +1 -0
  208. package/lib/typescript/commonjs/controller.d.ts +15 -0
  209. package/lib/typescript/commonjs/controller.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/device-id.d.ts +15 -0
  211. package/lib/typescript/commonjs/device-id.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/events.d.ts +41 -0
  213. package/lib/typescript/commonjs/events.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/i18n.d.ts +78 -0
  215. package/lib/typescript/commonjs/i18n.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/index.d.ts +103 -0
  217. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/locales.d.ts +18 -0
  219. package/lib/typescript/commonjs/locales.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/package.json +1 -0
  221. package/lib/typescript/commonjs/push/push-notifications.d.ts +71 -0
  222. package/lib/typescript/commonjs/push/push-notifications.d.ts.map +1 -0
  223. package/lib/typescript/commonjs/state/use-widget-state.d.ts +10 -0
  224. package/lib/typescript/commonjs/state/use-widget-state.d.ts.map +1 -0
  225. package/lib/typescript/commonjs/state/widget-store.d.ts +227 -0
  226. package/lib/typescript/commonjs/state/widget-store.d.ts.map +1 -0
  227. package/lib/typescript/commonjs/storage.d.ts +42 -0
  228. package/lib/typescript/commonjs/storage.d.ts.map +1 -0
  229. package/lib/typescript/commonjs/types.d.ts +391 -0
  230. package/lib/typescript/commonjs/types.d.ts.map +1 -0
  231. package/lib/typescript/commonjs/ui/WidgetProvider.d.ts +15 -0
  232. package/lib/typescript/commonjs/ui/WidgetProvider.d.ts.map +1 -0
  233. package/lib/typescript/commonjs/ui/components/AgentUiBlocks.d.ts +27 -0
  234. package/lib/typescript/commonjs/ui/components/AgentUiBlocks.d.ts.map +1 -0
  235. package/lib/typescript/commonjs/ui/components/Avatar.d.ts +19 -0
  236. package/lib/typescript/commonjs/ui/components/Avatar.d.ts.map +1 -0
  237. package/lib/typescript/commonjs/ui/components/ConversationRow.d.ts +26 -0
  238. package/lib/typescript/commonjs/ui/components/ConversationRow.d.ts.map +1 -0
  239. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts +27 -0
  240. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts.map +1 -0
  241. package/lib/typescript/commonjs/ui/components/Gradient.d.ts +33 -0
  242. package/lib/typescript/commonjs/ui/components/Gradient.d.ts.map +1 -0
  243. package/lib/typescript/commonjs/ui/components/Launcher.d.ts +18 -0
  244. package/lib/typescript/commonjs/ui/components/Launcher.d.ts.map +1 -0
  245. package/lib/typescript/commonjs/ui/components/Markdown.d.ts +19 -0
  246. package/lib/typescript/commonjs/ui/components/Markdown.d.ts.map +1 -0
  247. package/lib/typescript/commonjs/ui/components/OutboundMessageCard.d.ts +20 -0
  248. package/lib/typescript/commonjs/ui/components/OutboundMessageCard.d.ts.map +1 -0
  249. package/lib/typescript/commonjs/ui/components/WidgetPanel.d.ts +26 -0
  250. package/lib/typescript/commonjs/ui/components/WidgetPanel.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/ui/components/icons.d.ts +38 -0
  252. package/lib/typescript/commonjs/ui/components/icons.d.ts.map +1 -0
  253. package/lib/typescript/commonjs/ui/hooks/use-keyboard-overlap.d.ts +33 -0
  254. package/lib/typescript/commonjs/ui/hooks/use-keyboard-overlap.d.ts.map +1 -0
  255. package/lib/typescript/commonjs/ui/hooks/use-reduce-motion.d.ts +11 -0
  256. package/lib/typescript/commonjs/ui/hooks/use-reduce-motion.d.ts.map +1 -0
  257. package/lib/typescript/commonjs/ui/hooks/use-widget-insets.d.ts +16 -0
  258. package/lib/typescript/commonjs/ui/hooks/use-widget-insets.d.ts.map +1 -0
  259. package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts +11 -0
  260. package/lib/typescript/commonjs/ui/screens/chat/ChatView.d.ts.map +1 -0
  261. package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts +349 -0
  262. package/lib/typescript/commonjs/ui/screens/chat/ChatView.styles.d.ts.map +1 -0
  263. package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts +48 -0
  264. package/lib/typescript/commonjs/ui/screens/chat/ChatView.types.d.ts.map +1 -0
  265. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.d.ts +10 -0
  266. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.d.ts.map +1 -0
  267. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.styles.d.ts +113 -0
  268. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.styles.d.ts.map +1 -0
  269. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.types.d.ts +31 -0
  270. package/lib/typescript/commonjs/ui/screens/conversations/ConversationsList.types.d.ts.map +1 -0
  271. package/lib/typescript/commonjs/ui/screens/home/HomeView.d.ts +17 -0
  272. package/lib/typescript/commonjs/ui/screens/home/HomeView.d.ts.map +1 -0
  273. package/lib/typescript/commonjs/ui/screens/home/HomeView.styles.d.ts +227 -0
  274. package/lib/typescript/commonjs/ui/screens/home/HomeView.styles.d.ts.map +1 -0
  275. package/lib/typescript/commonjs/ui/screens/home/HomeView.types.d.ts +40 -0
  276. package/lib/typescript/commonjs/ui/screens/home/HomeView.types.d.ts.map +1 -0
  277. package/lib/typescript/commonjs/ui/screens/home/greeting.d.ts +19 -0
  278. package/lib/typescript/commonjs/ui/screens/home/greeting.d.ts.map +1 -0
  279. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.d.ts +7 -0
  280. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.d.ts.map +1 -0
  281. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.styles.d.ts +115 -0
  282. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.styles.d.ts.map +1 -0
  283. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.types.d.ts +20 -0
  284. package/lib/typescript/commonjs/ui/screens/pre-chat/PreChatForm.types.d.ts.map +1 -0
  285. package/lib/typescript/commonjs/ui/styles/global.d.ts +46 -0
  286. package/lib/typescript/commonjs/ui/styles/global.d.ts.map +1 -0
  287. package/lib/typescript/commonjs/ui/styles/theme.d.ts +103 -0
  288. package/lib/typescript/commonjs/ui/styles/theme.d.ts.map +1 -0
  289. package/lib/typescript/commonjs/ui/utils/conversations.d.ts +41 -0
  290. package/lib/typescript/commonjs/ui/utils/conversations.d.ts.map +1 -0
  291. package/lib/typescript/commonjs/ui/utils/html.d.ts +10 -0
  292. package/lib/typescript/commonjs/ui/utils/html.d.ts.map +1 -0
  293. package/lib/typescript/commonjs/ui/utils/native-gradient.d.ts +61 -0
  294. package/lib/typescript/commonjs/ui/utils/native-gradient.d.ts.map +1 -0
  295. package/lib/typescript/commonjs/ui/utils/rtl.d.ts +33 -0
  296. package/lib/typescript/commonjs/ui/utils/rtl.d.ts.map +1 -0
  297. package/lib/typescript/commonjs/ui/utils/safe-url.d.ts +21 -0
  298. package/lib/typescript/commonjs/ui/utils/safe-url.d.ts.map +1 -0
  299. package/lib/typescript/module/agent-ui-blocks.d.ts +20 -0
  300. package/lib/typescript/module/agent-ui-blocks.d.ts.map +1 -0
  301. package/lib/typescript/module/api/client.d.ts +115 -0
  302. package/lib/typescript/module/api/client.d.ts.map +1 -0
  303. package/lib/typescript/module/api/realtime.d.ts +39 -0
  304. package/lib/typescript/module/api/realtime.d.ts.map +1 -0
  305. package/lib/typescript/module/api/sse-parser.d.ts +13 -0
  306. package/lib/typescript/module/api/sse-parser.d.ts.map +1 -0
  307. package/lib/typescript/module/controller.d.ts +15 -0
  308. package/lib/typescript/module/controller.d.ts.map +1 -0
  309. package/lib/typescript/module/device-id.d.ts +15 -0
  310. package/lib/typescript/module/device-id.d.ts.map +1 -0
  311. package/lib/typescript/module/events.d.ts +41 -0
  312. package/lib/typescript/module/events.d.ts.map +1 -0
  313. package/lib/typescript/module/i18n.d.ts +78 -0
  314. package/lib/typescript/module/i18n.d.ts.map +1 -0
  315. package/lib/typescript/module/index.d.ts +103 -0
  316. package/lib/typescript/module/index.d.ts.map +1 -0
  317. package/lib/typescript/module/locales.d.ts +18 -0
  318. package/lib/typescript/module/locales.d.ts.map +1 -0
  319. package/lib/typescript/module/package.json +1 -0
  320. package/lib/typescript/module/push/push-notifications.d.ts +71 -0
  321. package/lib/typescript/module/push/push-notifications.d.ts.map +1 -0
  322. package/lib/typescript/module/state/use-widget-state.d.ts +10 -0
  323. package/lib/typescript/module/state/use-widget-state.d.ts.map +1 -0
  324. package/lib/typescript/module/state/widget-store.d.ts +227 -0
  325. package/lib/typescript/module/state/widget-store.d.ts.map +1 -0
  326. package/lib/typescript/module/storage.d.ts +42 -0
  327. package/lib/typescript/module/storage.d.ts.map +1 -0
  328. package/lib/typescript/module/types.d.ts +391 -0
  329. package/lib/typescript/module/types.d.ts.map +1 -0
  330. package/lib/typescript/module/ui/WidgetProvider.d.ts +15 -0
  331. package/lib/typescript/module/ui/WidgetProvider.d.ts.map +1 -0
  332. package/lib/typescript/module/ui/components/AgentUiBlocks.d.ts +27 -0
  333. package/lib/typescript/module/ui/components/AgentUiBlocks.d.ts.map +1 -0
  334. package/lib/typescript/module/ui/components/Avatar.d.ts +19 -0
  335. package/lib/typescript/module/ui/components/Avatar.d.ts.map +1 -0
  336. package/lib/typescript/module/ui/components/ConversationRow.d.ts +26 -0
  337. package/lib/typescript/module/ui/components/ConversationRow.d.ts.map +1 -0
  338. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts +27 -0
  339. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts.map +1 -0
  340. package/lib/typescript/module/ui/components/Gradient.d.ts +33 -0
  341. package/lib/typescript/module/ui/components/Gradient.d.ts.map +1 -0
  342. package/lib/typescript/module/ui/components/Launcher.d.ts +18 -0
  343. package/lib/typescript/module/ui/components/Launcher.d.ts.map +1 -0
  344. package/lib/typescript/module/ui/components/Markdown.d.ts +19 -0
  345. package/lib/typescript/module/ui/components/Markdown.d.ts.map +1 -0
  346. package/lib/typescript/module/ui/components/OutboundMessageCard.d.ts +20 -0
  347. package/lib/typescript/module/ui/components/OutboundMessageCard.d.ts.map +1 -0
  348. package/lib/typescript/module/ui/components/WidgetPanel.d.ts +26 -0
  349. package/lib/typescript/module/ui/components/WidgetPanel.d.ts.map +1 -0
  350. package/lib/typescript/module/ui/components/icons.d.ts +38 -0
  351. package/lib/typescript/module/ui/components/icons.d.ts.map +1 -0
  352. package/lib/typescript/module/ui/hooks/use-keyboard-overlap.d.ts +33 -0
  353. package/lib/typescript/module/ui/hooks/use-keyboard-overlap.d.ts.map +1 -0
  354. package/lib/typescript/module/ui/hooks/use-reduce-motion.d.ts +11 -0
  355. package/lib/typescript/module/ui/hooks/use-reduce-motion.d.ts.map +1 -0
  356. package/lib/typescript/module/ui/hooks/use-widget-insets.d.ts +16 -0
  357. package/lib/typescript/module/ui/hooks/use-widget-insets.d.ts.map +1 -0
  358. package/lib/typescript/module/ui/screens/chat/ChatView.d.ts +11 -0
  359. package/lib/typescript/module/ui/screens/chat/ChatView.d.ts.map +1 -0
  360. package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts +349 -0
  361. package/lib/typescript/module/ui/screens/chat/ChatView.styles.d.ts.map +1 -0
  362. package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts +48 -0
  363. package/lib/typescript/module/ui/screens/chat/ChatView.types.d.ts.map +1 -0
  364. package/lib/typescript/module/ui/screens/conversations/ConversationsList.d.ts +10 -0
  365. package/lib/typescript/module/ui/screens/conversations/ConversationsList.d.ts.map +1 -0
  366. package/lib/typescript/module/ui/screens/conversations/ConversationsList.styles.d.ts +113 -0
  367. package/lib/typescript/module/ui/screens/conversations/ConversationsList.styles.d.ts.map +1 -0
  368. package/lib/typescript/module/ui/screens/conversations/ConversationsList.types.d.ts +31 -0
  369. package/lib/typescript/module/ui/screens/conversations/ConversationsList.types.d.ts.map +1 -0
  370. package/lib/typescript/module/ui/screens/home/HomeView.d.ts +17 -0
  371. package/lib/typescript/module/ui/screens/home/HomeView.d.ts.map +1 -0
  372. package/lib/typescript/module/ui/screens/home/HomeView.styles.d.ts +227 -0
  373. package/lib/typescript/module/ui/screens/home/HomeView.styles.d.ts.map +1 -0
  374. package/lib/typescript/module/ui/screens/home/HomeView.types.d.ts +40 -0
  375. package/lib/typescript/module/ui/screens/home/HomeView.types.d.ts.map +1 -0
  376. package/lib/typescript/module/ui/screens/home/greeting.d.ts +19 -0
  377. package/lib/typescript/module/ui/screens/home/greeting.d.ts.map +1 -0
  378. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.d.ts +7 -0
  379. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.d.ts.map +1 -0
  380. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.styles.d.ts +115 -0
  381. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.styles.d.ts.map +1 -0
  382. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.types.d.ts +20 -0
  383. package/lib/typescript/module/ui/screens/pre-chat/PreChatForm.types.d.ts.map +1 -0
  384. package/lib/typescript/module/ui/styles/global.d.ts +46 -0
  385. package/lib/typescript/module/ui/styles/global.d.ts.map +1 -0
  386. package/lib/typescript/module/ui/styles/theme.d.ts +103 -0
  387. package/lib/typescript/module/ui/styles/theme.d.ts.map +1 -0
  388. package/lib/typescript/module/ui/utils/conversations.d.ts +41 -0
  389. package/lib/typescript/module/ui/utils/conversations.d.ts.map +1 -0
  390. package/lib/typescript/module/ui/utils/html.d.ts +10 -0
  391. package/lib/typescript/module/ui/utils/html.d.ts.map +1 -0
  392. package/lib/typescript/module/ui/utils/native-gradient.d.ts +61 -0
  393. package/lib/typescript/module/ui/utils/native-gradient.d.ts.map +1 -0
  394. package/lib/typescript/module/ui/utils/rtl.d.ts +33 -0
  395. package/lib/typescript/module/ui/utils/rtl.d.ts.map +1 -0
  396. package/lib/typescript/module/ui/utils/safe-url.d.ts +21 -0
  397. package/lib/typescript/module/ui/utils/safe-url.d.ts.map +1 -0
  398. package/metro.js +40 -0
  399. package/package.json +116 -0
  400. package/src/agent-ui-blocks.ts +302 -0
  401. package/src/api/client.ts +332 -0
  402. package/src/api/realtime.ts +225 -0
  403. package/src/api/sse-parser.ts +51 -0
  404. package/src/controller.ts +20 -0
  405. package/src/device-id.ts +71 -0
  406. package/src/events.ts +74 -0
  407. package/src/i18n.ts +114 -0
  408. package/src/index.tsx +199 -0
  409. package/src/locales.ts +80 -0
  410. package/src/push/push-notifications.ts +254 -0
  411. package/src/state/use-widget-state.ts +20 -0
  412. package/src/state/widget-store.ts +1815 -0
  413. package/src/storage.ts +153 -0
  414. package/src/types.ts +445 -0
  415. package/src/ui/WidgetProvider.tsx +434 -0
  416. package/src/ui/components/AgentUiBlocks.tsx +912 -0
  417. package/src/ui/components/Avatar.tsx +86 -0
  418. package/src/ui/components/ConversationRow.tsx +163 -0
  419. package/src/ui/components/ErrorBoundary.tsx +49 -0
  420. package/src/ui/components/Gradient.tsx +165 -0
  421. package/src/ui/components/Launcher.tsx +128 -0
  422. package/src/ui/components/Markdown.tsx +291 -0
  423. package/src/ui/components/OutboundMessageCard.tsx +154 -0
  424. package/src/ui/components/WidgetPanel.tsx +133 -0
  425. package/src/ui/components/icons.tsx +315 -0
  426. package/src/ui/hooks/use-keyboard-overlap.ts +134 -0
  427. package/src/ui/hooks/use-reduce-motion.ts +39 -0
  428. package/src/ui/hooks/use-widget-insets.ts +44 -0
  429. package/src/ui/screens/chat/ChatView.styles.ts +357 -0
  430. package/src/ui/screens/chat/ChatView.tsx +690 -0
  431. package/src/ui/screens/chat/ChatView.types.ts +46 -0
  432. package/src/ui/screens/conversations/ConversationsList.styles.ts +111 -0
  433. package/src/ui/screens/conversations/ConversationsList.tsx +144 -0
  434. package/src/ui/screens/conversations/ConversationsList.types.ts +33 -0
  435. package/src/ui/screens/home/HomeView.styles.ts +246 -0
  436. package/src/ui/screens/home/HomeView.tsx +336 -0
  437. package/src/ui/screens/home/HomeView.types.ts +42 -0
  438. package/src/ui/screens/home/greeting.ts +50 -0
  439. package/src/ui/screens/pre-chat/PreChatForm.styles.ts +120 -0
  440. package/src/ui/screens/pre-chat/PreChatForm.tsx +221 -0
  441. package/src/ui/screens/pre-chat/PreChatForm.types.ts +22 -0
  442. package/src/ui/styles/global.ts +50 -0
  443. package/src/ui/styles/theme.ts +155 -0
  444. package/src/ui/utils/conversations.ts +122 -0
  445. package/src/ui/utils/html.ts +58 -0
  446. package/src/ui/utils/native-gradient.ts +60 -0
  447. package/src/ui/utils/rtl.ts +43 -0
  448. package/src/ui/utils/safe-url.ts +63 -0
@@ -0,0 +1,225 @@
1
+ /**
2
+ * SSE transport over `GET /api/widget/sse`, authenticated with an
3
+ * `Authorization: Bearer` header (never the query string, which ends up in
4
+ * proxy and server access logs).
5
+ *
6
+ * Uses React Native's streaming XMLHttpRequest and handles both network
7
+ * failures and successful stream EOF with exponential reconnect backoff.
8
+ * Auth failures never retry here: 401 hands over to the store's re-init,
9
+ * while 403 is terminal.
10
+ */
11
+
12
+ import type { WidgetRealtimeEvent } from '../types';
13
+ import { RepzoWidgetError } from './client';
14
+ import { SseParser } from './sse-parser';
15
+
16
+ /** Server event names, mapped to the shorter names the store switches on. */
17
+ const SERVER_EVENTS = {
18
+ connected: 'connected',
19
+ 'widget.message.new': 'message.new',
20
+ 'widget.typing.start': 'typing.start',
21
+ 'widget.typing.stop': 'typing.stop',
22
+ 'widget.conversation.updated': 'conversation.updated',
23
+ 'widget.conversation.event': 'conversation.event',
24
+ } as const;
25
+
26
+ type ServerEventName = keyof typeof SERVER_EVENTS;
27
+
28
+ const BASE_RECONNECT_MS = 1_000;
29
+ const MAX_RECONNECT_MS = 60_000;
30
+ /** XHR readyState DONE — the error body is only complete from here. */
31
+ const XHR_DONE = 4;
32
+ /** If DONE never follows a 403 seen mid-body, act on what arrived. */
33
+ const AUTH_ERROR_BODY_WAIT_MS = 3_000;
34
+
35
+ export type RealtimeHandler = (event: WidgetRealtimeEvent, data: any) => void;
36
+
37
+ export interface RealtimeAuthHooks {
38
+ /** 401: the token expired or was revoked. The stream stays closed. */
39
+ onUnauthorized(token: string): void;
40
+ /** 403 (e.g. `messenger_api_disabled`): terminal, the stream stays closed. */
41
+ onForbidden(error: RepzoWidgetError): void;
42
+ }
43
+
44
+ export class WidgetRealtime {
45
+ private source: XMLHttpRequest | null = null;
46
+
47
+ private connected = false;
48
+
49
+ private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
50
+
51
+ private attempt = 0;
52
+
53
+ private closedByUs = false;
54
+
55
+ private url: string | null = null;
56
+
57
+ private token: string | null = null;
58
+
59
+ private handler: RealtimeHandler | null = null;
60
+
61
+ private authHooks: RealtimeAuthHooks | null = null;
62
+
63
+ private authErrorTimer: ReturnType<typeof setTimeout> | null = null;
64
+
65
+ connect(
66
+ baseUrl: string,
67
+ token: string,
68
+ handler: RealtimeHandler,
69
+ authHooks?: RealtimeAuthHooks
70
+ ): void {
71
+ this.close();
72
+ this.url = `${baseUrl.replace(/\/$/, '')}/api/widget/sse`;
73
+ this.token = token;
74
+ this.handler = handler;
75
+ this.authHooks = authHooks ?? null;
76
+ this.closedByUs = false;
77
+ this.open();
78
+ }
79
+
80
+ private open(): void {
81
+ if (!this.url || !this.token || !this.handler) return;
82
+
83
+ const source = new XMLHttpRequest();
84
+ this.source = source;
85
+ let offset = 0;
86
+ const isCurrent = () => this.source === source && !this.closedByUs;
87
+ const parser = new SseParser((name, raw) => {
88
+ if (!isCurrent() || !Object.prototype.hasOwnProperty.call(SERVER_EVENTS, name)) return;
89
+ let payload: unknown = null;
90
+ if (raw) {
91
+ try {
92
+ payload = JSON.parse(raw);
93
+ } catch {
94
+ payload = raw;
95
+ }
96
+ }
97
+ this.handler?.(SERVER_EVENTS[name as ServerEventName], payload);
98
+ });
99
+ const reconnect = () => {
100
+ if (!isCurrent()) return;
101
+ this.handler?.('error', null);
102
+ // A handler may synchronously close or replace this connection.
103
+ if (isCurrent()) this.scheduleReconnect();
104
+ };
105
+ const read = () => {
106
+ if (!isCurrent() || source.readyState < 3) return;
107
+ const complete = source.readyState === XHR_DONE;
108
+ const status = source.status;
109
+ if (status === 401 || status === 403) {
110
+ if (!complete && status === 403) {
111
+ // Wait for the structured error body, but never wait indefinitely.
112
+ this.authErrorTimer ??= setTimeout(() => {
113
+ if (isCurrent()) this.handleAuthError(status, source.responseText);
114
+ }, AUTH_ERROR_BODY_WAIT_MS);
115
+ return;
116
+ }
117
+ this.handleAuthError(status, source.responseText);
118
+ return;
119
+ }
120
+ if (status >= 200 && status < 300) {
121
+ if (!this.connected) {
122
+ this.connected = true;
123
+ this.attempt = 0;
124
+ }
125
+ const text = source.responseText || '';
126
+ const chunk = text.slice(offset);
127
+ offset = text.length;
128
+ parser.push(chunk);
129
+ // A 200 EOF is a disconnected stream too. Tear it down and notify the
130
+ // store so the next `connected` event also triggers history catch-up.
131
+ if (complete) reconnect();
132
+ } else if (complete) {
133
+ reconnect();
134
+ }
135
+ };
136
+ source.onreadystatechange = read;
137
+ source.onprogress = read;
138
+ source.onerror = reconnect;
139
+ source.ontimeout = reconnect;
140
+ source.onabort = reconnect;
141
+ try {
142
+ source.open('GET', this.url, true);
143
+ source.timeout = 0;
144
+ source.setRequestHeader('Accept', 'text/event-stream');
145
+ source.setRequestHeader('Cache-Control', 'no-cache');
146
+ source.setRequestHeader('Authorization', `Bearer ${this.token}`);
147
+ source.send();
148
+ } catch {
149
+ reconnect();
150
+ }
151
+ }
152
+
153
+ private handleAuthError(status: number, rawBody: string | null | undefined): void {
154
+ const token = this.token;
155
+ const hooks = this.authHooks;
156
+ // Backoff cannot fix an auth failure — stop and let the store decide.
157
+ this.close();
158
+ if (!hooks || !token) return;
159
+ if (status === 401) {
160
+ hooks.onUnauthorized(token);
161
+ return;
162
+ }
163
+ let body: unknown = null;
164
+ try {
165
+ body = rawBody ? JSON.parse(rawBody) : null;
166
+ } catch {
167
+ body = null;
168
+ }
169
+ hooks.onForbidden(RepzoWidgetError.fromResponse(403, body));
170
+ }
171
+
172
+ private scheduleReconnect(): void {
173
+ if (this.closedByUs || this.reconnectTimer) return;
174
+
175
+ this.teardownSource();
176
+
177
+ const delay = Math.min(BASE_RECONNECT_MS * 2 ** this.attempt, MAX_RECONNECT_MS);
178
+ // Jitter keeps a fleet of devices from reconnecting in lockstep.
179
+ const jittered = delay * (0.7 + Math.random() * 0.6);
180
+ this.attempt += 1;
181
+
182
+ this.reconnectTimer = setTimeout(() => {
183
+ this.reconnectTimer = null;
184
+ if (this.closedByUs) return;
185
+ this.open();
186
+ }, jittered);
187
+ }
188
+
189
+ private teardownSource(): void {
190
+ const source = this.source;
191
+ this.source = null;
192
+ this.connected = false;
193
+ if (this.authErrorTimer) {
194
+ clearTimeout(this.authErrorTimer);
195
+ this.authErrorTimer = null;
196
+ }
197
+ if (!source) return;
198
+ source.onreadystatechange = null;
199
+ source.onprogress = null;
200
+ source.onerror = null;
201
+ source.ontimeout = null;
202
+ source.onabort = null;
203
+ source.abort();
204
+ }
205
+
206
+ get isConnected(): boolean {
207
+ // Includes a handshake in progress so the store does not replace the
208
+ // connection that a successful re-init just started. EOF clears source.
209
+ return this.source !== null;
210
+ }
211
+
212
+ close(): void {
213
+ this.closedByUs = true;
214
+ this.attempt = 0;
215
+ if (this.reconnectTimer) {
216
+ clearTimeout(this.reconnectTimer);
217
+ this.reconnectTimer = null;
218
+ }
219
+ if (this.authErrorTimer) {
220
+ clearTimeout(this.authErrorTimer);
221
+ this.authErrorTimer = null;
222
+ }
223
+ this.teardownSource();
224
+ }
225
+ }
@@ -0,0 +1,51 @@
1
+ /** Incremental SSE framing. A blank line dispatches an event; EOF alone does not. */
2
+ export class SseParser {
3
+ private line = '';
4
+ private event = '';
5
+ private data: string[] = [];
6
+ private afterCR = false;
7
+ private atStart = true;
8
+
9
+ constructor(private readonly dispatch: (event: string, data: string) => void) {}
10
+
11
+ push(chunk: string): void {
12
+ for (const char of chunk) {
13
+ if (this.atStart) {
14
+ this.atStart = false;
15
+ if (char === '\uFEFF') continue;
16
+ }
17
+ if (this.afterCR) {
18
+ this.afterCR = false;
19
+ if (char === '\n') continue;
20
+ }
21
+ if (char === '\r' || char === '\n') {
22
+ const line = this.line;
23
+ this.line = '';
24
+ this.afterCR = char === '\r';
25
+ this.readLine(line);
26
+ } else {
27
+ this.line += char;
28
+ }
29
+ }
30
+ }
31
+
32
+ private readLine(line: string): void {
33
+ if (!line) {
34
+ const event = this.event || 'message';
35
+ const data = this.data;
36
+ this.event = '';
37
+ this.data = [];
38
+ if (data.length) this.dispatch(event, data.join('\n'));
39
+ return;
40
+ }
41
+ if (line.startsWith(':')) return; // heartbeat/comment
42
+ const colon = line.indexOf(':');
43
+ const field = colon < 0 ? line : line.slice(0, colon);
44
+ let value = colon < 0 ? '' : line.slice(colon + 1);
45
+ if (value.startsWith(' ')) value = value.slice(1);
46
+ if (field === 'event') this.event = value;
47
+ if (field === 'data') this.data.push(value);
48
+ // Reconnect timing belongs to the transport. The store catches up from
49
+ // history on reconnect, so no server retry/id fields are needed here.
50
+ }
51
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Process-wide singleton that owns the store (and therefore the session, the
3
+ * SSE stream and the unread count). Imperative API calls land here whether or
4
+ * not `<RepzoWidgetProvider>` is mounted; the provider is a pure subscriber, so
5
+ * commands issued before boot finishes simply land in state and render once the
6
+ * provider mounts.
7
+ */
8
+
9
+ import { WidgetStore } from './state/widget-store';
10
+
11
+ class RepzoWidgetController {
12
+ readonly store = new WidgetStore();
13
+
14
+ get events() {
15
+ return this.store.events;
16
+ }
17
+ }
18
+
19
+ export const controller = new RepzoWidgetController();
20
+ export type { RepzoWidgetController };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Per-install id sent as `trackingVisitorId`. This is the mobile equivalent of
3
+ * the web widget's `repzo_vid` cookie: it lets the CRM stitch an anonymous
4
+ * visitor back together if the session token is ever lost. Stable until
5
+ * `logout()`, which rotates it.
6
+ */
7
+
8
+ import { DEVICE_ID_KEY, Storage } from './storage';
9
+
10
+ let cached: string | null = null;
11
+
12
+ /**
13
+ * 16 random bytes from `crypto.getRandomValues` when the runtime has it (RN
14
+ * with a polyfill, newer Hermes); otherwise Math.random, which is fine for a
15
+ * correlation id but guessable.
16
+ */
17
+ function randomBytes(): Uint8Array {
18
+ const bytes = new Uint8Array(16);
19
+ const cryptoApi = (globalThis as { crypto?: { getRandomValues?: (array: Uint8Array) => unknown } })
20
+ .crypto;
21
+ if (typeof cryptoApi?.getRandomValues === 'function') {
22
+ try {
23
+ cryptoApi.getRandomValues(bytes);
24
+ return bytes;
25
+ } catch {
26
+ // Present but unusable (some polyfills throw) — fall through.
27
+ }
28
+ }
29
+ for (let index = 0; index < bytes.length; index += 1) {
30
+ bytes[index] = (Math.random() * 256) | 0;
31
+ }
32
+ return bytes;
33
+ }
34
+
35
+ /** RFC-4122 v4. */
36
+ function uuidv4(): string {
37
+ const bytes = randomBytes();
38
+ bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
39
+ bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC-4122 variant
40
+ const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');
41
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
42
+ }
43
+
44
+ export async function getDeviceId(): Promise<string> {
45
+ if (cached) return cached;
46
+
47
+ const stored = await Storage.getItem(DEVICE_ID_KEY);
48
+ if (stored) {
49
+ cached = stored;
50
+ return stored;
51
+ }
52
+
53
+ const created = uuidv4();
54
+ cached = created;
55
+ await Storage.setItem(DEVICE_ID_KEY, created);
56
+ return created;
57
+ }
58
+
59
+ /** Only used by tests and `rotateDeviceId()`. */
60
+ export function resetDeviceIdCache(): void {
61
+ cached = null;
62
+ }
63
+
64
+ /**
65
+ * Called by `logout()`: the id stitches anonymous sessions together, so on a
66
+ * shared device the next visitor must not inherit the previous user's.
67
+ */
68
+ export async function rotateDeviceId(): Promise<void> {
69
+ cached = null;
70
+ await Storage.removeItem(DEVICE_ID_KEY);
71
+ }
package/src/events.ts ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Tiny typed event emitter. Pure JS — no NativeEventEmitter, so listeners work
3
+ * identically on iOS, Android and in tests.
4
+ */
5
+
6
+ import type { Conversation, Message } from './types';
7
+
8
+ export const RepzoWidgetEvents = {
9
+ UnreadCountDidChange: 'repzoWidget.unreadCountDidChange',
10
+ MessageDidArrive: 'repzoWidget.messageDidArrive',
11
+ /** The visitor opened a thread — hosts use it to dismiss that conversation's push notification. */
12
+ ConversationDidRead: 'repzoWidget.conversationDidRead',
13
+ WindowDidShow: 'repzoWidget.windowDidShow',
14
+ WindowDidHide: 'repzoWidget.windowDidHide',
15
+ } as const;
16
+
17
+ export type RepzoWidgetEvent = (typeof RepzoWidgetEvents)[keyof typeof RepzoWidgetEvents];
18
+
19
+ export interface MessageDidArrivePayload {
20
+ conversationId: string;
21
+ message: Message;
22
+ /** Null when the reply lands before this device has listed the thread. */
23
+ conversation: Conversation | null;
24
+ }
25
+
26
+ export interface RepzoWidgetEventPayloads {
27
+ [RepzoWidgetEvents.UnreadCountDidChange]: { count: number };
28
+ [RepzoWidgetEvents.MessageDidArrive]: MessageDidArrivePayload;
29
+ [RepzoWidgetEvents.ConversationDidRead]: { conversationId: string };
30
+ [RepzoWidgetEvents.WindowDidShow]: undefined;
31
+ [RepzoWidgetEvents.WindowDidHide]: undefined;
32
+ }
33
+
34
+ export interface EventSubscription {
35
+ remove(): void;
36
+ }
37
+
38
+ type Listener = (payload: any) => void;
39
+
40
+ export class EventEmitter {
41
+ private listeners = new Map<string, Set<Listener>>();
42
+
43
+ addListener<E extends RepzoWidgetEvent>(
44
+ event: E,
45
+ listener: (payload: RepzoWidgetEventPayloads[E]) => void
46
+ ): EventSubscription {
47
+ const current = this.listeners.get(event) ?? new Set<Listener>();
48
+ current.add(listener as Listener);
49
+ this.listeners.set(event, current);
50
+
51
+ return {
52
+ remove: () => {
53
+ this.listeners.get(event)?.delete(listener as Listener);
54
+ },
55
+ };
56
+ }
57
+
58
+ emit<E extends RepzoWidgetEvent>(event: E, payload: RepzoWidgetEventPayloads[E]): void {
59
+ const current = this.listeners.get(event);
60
+ if (!current) return;
61
+ // Copy first: a listener may remove itself while we iterate.
62
+ for (const listener of Array.from(current)) {
63
+ try {
64
+ listener(payload);
65
+ } catch (error) {
66
+ console.warn('[repzo-widget] event listener threw', error);
67
+ }
68
+ }
69
+ }
70
+
71
+ removeAllListeners(): void {
72
+ this.listeners.clear();
73
+ }
74
+ }
package/src/i18n.ts ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Translations come from the widget config (`translations[locale][key]`), with
3
+ * the widget's default locale as the fallback chain — same lookup as the web
4
+ * widget's `t()` in `client/src/widget/App.tsx`.
5
+ */
6
+
7
+ import { BUNDLED_TRANSLATIONS, baseLanguage } from './locales';
8
+ import type { WidgetConfig } from './types';
9
+
10
+ export type Translator = (key: string, fallback: string) => string;
11
+
12
+ /**
13
+ * Resolution order, most specific first: what the workspace configured for the
14
+ * active locale, what the SDK ships for it, then the same pair for the
15
+ * workspace's default locale, and finally the English built-in. Dashboard
16
+ * copy always outranks a bundled translation.
17
+ */
18
+ export function createTranslator(config: WidgetConfig | null, locale: string): Translator {
19
+ const defaultLocale = config?.defaultLocale || 'en';
20
+ const active = baseLanguage(locale);
21
+ const fallbackLocale = baseLanguage(defaultLocale);
22
+
23
+ return (key, fallback) =>
24
+ config?.translations?.[locale]?.[key] ||
25
+ config?.translations?.[active]?.[key] ||
26
+ BUNDLED_TRANSLATIONS[active]?.[key as keyof typeof DEFAULT_LABELS] ||
27
+ config?.translations?.[defaultLocale]?.[key] ||
28
+ BUNDLED_TRANSLATIONS[fallbackLocale]?.[key as keyof typeof DEFAULT_LABELS] ||
29
+ fallback;
30
+ }
31
+
32
+ export const DEFAULT_LABELS = {
33
+ back: 'Back',
34
+ loading: 'Loading...',
35
+ loadEarlier: 'Load earlier messages',
36
+ emptyConversation: 'Send a message to start the conversation',
37
+ messagePlaceholder: 'Type a message...',
38
+ attachFile: 'Attach file',
39
+ failedToSend: 'Failed to send',
40
+ thinking: 'Typing',
41
+ messages: 'Messages',
42
+ noMessages: 'No messages yet',
43
+ historyHidden: 'Conversation history is hidden',
44
+ startBelow: 'Start a conversation below',
45
+ preChatTitle: 'Before we chat',
46
+ preChatSubtitle: 'Let us know a bit about you so we can help you better.',
47
+ preChatSkip: 'Skip',
48
+ preChatSubmit: 'Start chat',
49
+ viewPreviousConversations: 'View previous conversations',
50
+ homeRecentTitle: 'Recent',
51
+ homeViewAllCount: 'View all ({count})',
52
+ homeNoConversations: 'Your conversations will show up here',
53
+ homeStatusOnline: "We're online",
54
+ homeStatusAway: "We're away",
55
+ unreadBadge: '{count} unread',
56
+ team: 'Team',
57
+ home: 'Home',
58
+ close: 'Close',
59
+ retry: 'Retry',
60
+ connectionError: 'We could not load the chat. Please try again.',
61
+ connecting: 'Connecting you to the team',
62
+ // Terminal errors — no Retry, nothing the visitor can fix from here.
63
+ chatUnavailable: 'Chat is not available right now.',
64
+ identityVerificationError: "We couldn't verify your account. Please sign in again.",
65
+ // Shown if the widget's own UI hits a render error.
66
+ widgetCrashed: 'Something went wrong.',
67
+ // Relative timestamps on the conversation lists.
68
+ timeJustNow: 'Just now',
69
+ timeMinutes: '{count}m',
70
+ timeHours: '{count}h',
71
+ timeDays: '{count}d',
72
+ timeMonths: '{count}mo',
73
+ timeYears: '{count}y',
74
+ // Day separators inside a thread.
75
+ today: 'Today',
76
+ yesterday: 'Yesterday',
77
+ conversationUpdated: 'Conversation updated',
78
+ // Forms.
79
+ procedureSend: 'Send details',
80
+ procedureSent: 'Sent',
81
+ fieldRequired: '{field} is required',
82
+ invalidEmail: 'Enter a valid email address',
83
+ working: 'Working...',
84
+ // Proactive card.
85
+ outboundTitle: 'New update',
86
+ outboundCta: 'Learn more',
87
+ dismiss: 'Dismiss',
88
+ // Rich blocks an agent can send.
89
+ blockService: 'Service',
90
+ blockProduct: 'Product',
91
+ blockChooseTime: 'Choose a time',
92
+ blockProfessional: 'Professional',
93
+ blockPriceOffer: 'Price offer',
94
+ } as const;
95
+
96
+ export type LabelKey = keyof typeof DEFAULT_LABELS;
97
+
98
+ /**
99
+ * Fill `{token}` placeholders in a translated string. Interpolation belongs in
100
+ * the string layer so translators keep control of word order.
101
+ */
102
+ export function formatLabel(template: string, values: Record<string, string | number>): string {
103
+ return template.replace(/\{(\w+)\}/g, (match, key: string) =>
104
+ key in values ? String(values[key]) : match
105
+ );
106
+ }
107
+
108
+ export function buildLabels(translate: Translator): Record<LabelKey, string> {
109
+ const labels = {} as Record<LabelKey, string>;
110
+ (Object.keys(DEFAULT_LABELS) as LabelKey[]).forEach((key) => {
111
+ labels[key] = translate(key, DEFAULT_LABELS[key]);
112
+ });
113
+ return labels;
114
+ }