@signalcore/ui 0.1.0 → 1.0.0-beta.1

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 (611) hide show
  1. package/README.md +896 -513
  2. package/dist/AgentAbout.d.ts +186 -0
  3. package/dist/AgentAbout.js +1020 -0
  4. package/dist/AgentAbout.js.map +1 -0
  5. package/dist/AgentCard.d.ts +49 -0
  6. package/dist/AgentCard.js +77 -0
  7. package/dist/AgentCard.js.map +1 -0
  8. package/dist/AgentChat.d.ts +233 -0
  9. package/dist/AgentChat.js +1127 -0
  10. package/dist/AgentChat.js.map +1 -0
  11. package/dist/AgentSpace.d.ts +112 -0
  12. package/dist/AgentSpace.js +339 -0
  13. package/dist/AgentSpace.js.map +1 -0
  14. package/dist/AgentTasks.d.ts +48 -0
  15. package/dist/AgentTasks.js +120 -0
  16. package/dist/AgentTasks.js.map +1 -0
  17. package/dist/BrowserView.d.ts +52 -0
  18. package/dist/BrowserView.js +328 -0
  19. package/dist/BrowserView.js.map +1 -0
  20. package/dist/FileView.d.ts +63 -0
  21. package/dist/FileView.js +449 -0
  22. package/dist/FileView.js.map +1 -0
  23. package/dist/Modes.d.ts +13 -0
  24. package/dist/Modes.js +75 -0
  25. package/dist/Modes.js.map +1 -0
  26. package/dist/VoiceCall.d.ts +91 -0
  27. package/dist/VoiceCall.js +302 -0
  28. package/dist/VoiceCall.js.map +1 -0
  29. package/dist/about.d.ts +212 -0
  30. package/dist/about.js +136 -0
  31. package/dist/about.js.map +1 -0
  32. package/dist/agentIcons.d.ts +33 -0
  33. package/dist/agentIcons.js +36 -0
  34. package/dist/agentIcons.js.map +1 -0
  35. package/dist/automation/Automation.d.ts +35 -0
  36. package/dist/automation/Automation.js +268 -0
  37. package/dist/automation/Automation.js.map +1 -0
  38. package/dist/automation/RunView.d.ts +25 -0
  39. package/dist/automation/RunView.js +187 -0
  40. package/dist/automation/RunView.js.map +1 -0
  41. package/dist/automation/cron.d.ts +41 -0
  42. package/dist/automation/cron.js +169 -0
  43. package/dist/automation/cron.js.map +1 -0
  44. package/dist/automation/marks.js +121 -0
  45. package/dist/automation/marks.js.map +1 -0
  46. package/dist/automation/messages.d.ts +113 -0
  47. package/dist/automation/messages.js +113 -0
  48. package/dist/automation/messages.js.map +1 -0
  49. package/dist/automation/record.d.ts +47 -0
  50. package/dist/automation/record.js +177 -0
  51. package/dist/automation/record.js.map +1 -0
  52. package/dist/automation/types.d.ts +143 -0
  53. package/dist/automation/when.d.ts +36 -0
  54. package/dist/automation/when.js +168 -0
  55. package/dist/automation/when.js.map +1 -0
  56. package/dist/blocks.d.ts +185 -0
  57. package/dist/browser.js +292 -0
  58. package/dist/browser.js.map +1 -0
  59. package/dist/call.d.ts +89 -0
  60. package/dist/call.js +218 -0
  61. package/dist/call.js.map +1 -0
  62. package/dist/channelParts.js +26 -0
  63. package/dist/channelParts.js.map +1 -0
  64. package/dist/classes.js +8 -3
  65. package/dist/classes.js.map +1 -0
  66. package/dist/client.d.ts +146 -54
  67. package/dist/client.js +204 -1
  68. package/dist/client.js.map +1 -0
  69. package/dist/conversationFiles.js +46 -0
  70. package/dist/conversationFiles.js.map +1 -0
  71. package/dist/credentials.d.ts +45 -0
  72. package/dist/credentials.js +98 -0
  73. package/dist/credentials.js.map +1 -0
  74. package/dist/dev.js +17 -0
  75. package/dist/dev.js.map +1 -0
  76. package/dist/es.d.ts +17 -0
  77. package/dist/es.js +382 -0
  78. package/dist/es.js.map +1 -0
  79. package/dist/files.d.ts +21 -0
  80. package/dist/files.js +214 -0
  81. package/dist/files.js.map +1 -0
  82. package/dist/frames.d.ts +115 -0
  83. package/dist/frames.js +219 -0
  84. package/dist/frames.js.map +1 -0
  85. package/dist/icons.js +29 -0
  86. package/dist/icons.js.map +1 -0
  87. package/dist/index.d.ts +63 -60
  88. package/dist/index.js +59 -45
  89. package/dist/kit/AudioPlayer.d.ts +20 -0
  90. package/dist/kit/AudioPlayer.js +116 -0
  91. package/dist/kit/AudioPlayer.js.map +1 -0
  92. package/dist/kit/Button.d.ts +29 -0
  93. package/dist/kit/Button.js +59 -0
  94. package/dist/kit/Button.js.map +1 -0
  95. package/dist/kit/Card.d.ts +16 -0
  96. package/dist/kit/Card.js +36 -0
  97. package/dist/kit/Card.js.map +1 -0
  98. package/dist/kit/Chart.js +152 -0
  99. package/dist/kit/Chart.js.map +1 -0
  100. package/dist/kit/Choices.d.ts +21 -0
  101. package/dist/kit/Choices.js +99 -0
  102. package/dist/kit/Choices.js.map +1 -0
  103. package/dist/kit/Combobox.d.ts +26 -0
  104. package/dist/kit/Combobox.js +190 -0
  105. package/dist/kit/Combobox.js.map +1 -0
  106. package/dist/kit/DateField.d.ts +17 -0
  107. package/dist/kit/DateField.js +133 -0
  108. package/dist/kit/DateField.js.map +1 -0
  109. package/dist/kit/Field.d.ts +40 -0
  110. package/dist/kit/Field.js +98 -0
  111. package/dist/kit/Field.js.map +1 -0
  112. package/dist/kit/FileField.d.ts +113 -0
  113. package/dist/kit/FileField.js +341 -0
  114. package/dist/kit/FileField.js.map +1 -0
  115. package/dist/kit/FileMark.d.ts +15 -0
  116. package/dist/kit/FileMark.js +39 -0
  117. package/dist/kit/FileMark.js.map +1 -0
  118. package/dist/kit/Inputs.d.ts +59 -0
  119. package/dist/kit/Inputs.js +205 -0
  120. package/dist/kit/Inputs.js.map +1 -0
  121. package/dist/kit/List.d.ts +47 -0
  122. package/dist/kit/List.js +85 -0
  123. package/dist/kit/List.js.map +1 -0
  124. package/dist/kit/Mark.d.ts +30 -0
  125. package/dist/kit/Mark.js +27 -0
  126. package/dist/kit/Mark.js.map +1 -0
  127. package/dist/kit/MarkStack.d.ts +15 -0
  128. package/dist/kit/MarkStack.js +26 -0
  129. package/dist/kit/MarkStack.js.map +1 -0
  130. package/dist/kit/Note.d.ts +11 -0
  131. package/dist/kit/Note.js +31 -0
  132. package/dist/kit/Note.js.map +1 -0
  133. package/dist/kit/Popover.js +90 -0
  134. package/dist/kit/Popover.js.map +1 -0
  135. package/dist/kit/RangeField.d.ts +14 -0
  136. package/dist/kit/RangeField.js +47 -0
  137. package/dist/kit/RangeField.js.map +1 -0
  138. package/dist/kit/RatingField.d.ts +14 -0
  139. package/dist/kit/RatingField.js +50 -0
  140. package/dist/kit/RatingField.js.map +1 -0
  141. package/dist/kit/Stat.d.ts +26 -0
  142. package/dist/kit/Stat.js +46 -0
  143. package/dist/kit/Stat.js.map +1 -0
  144. package/dist/kit/Switch.d.ts +14 -0
  145. package/dist/kit/Switch.js +21 -0
  146. package/dist/kit/Switch.js.map +1 -0
  147. package/dist/kit/Tag.d.ts +16 -0
  148. package/dist/kit/Tag.js +20 -0
  149. package/dist/kit/Tag.js.map +1 -0
  150. package/dist/kit/Tile.d.ts +34 -0
  151. package/dist/kit/Tile.js +52 -0
  152. package/dist/kit/Tile.js.map +1 -0
  153. package/dist/kit/TimeField.d.ts +31 -0
  154. package/dist/kit/TimeField.js +109 -0
  155. package/dist/kit/TimeField.js.map +1 -0
  156. package/dist/kit/context.d.ts +22 -0
  157. package/dist/kit/context.js +46 -0
  158. package/dist/kit/context.js.map +1 -0
  159. package/dist/kit/dates.d.ts +14 -0
  160. package/dist/kit/dates.js +129 -0
  161. package/dist/kit/dates.js.map +1 -0
  162. package/dist/kit/messages.d.ts +99 -0
  163. package/dist/kit/messages.js +66 -0
  164. package/dist/kit/messages.js.map +1 -0
  165. package/dist/kit/numbers.d.ts +12 -0
  166. package/dist/kit/numbers.js +40 -0
  167. package/dist/kit/numbers.js.map +1 -0
  168. package/dist/kit/options.d.ts +10 -0
  169. package/dist/kit/options.js +23 -0
  170. package/dist/kit/options.js.map +1 -0
  171. package/dist/kit/uploads.d.ts +42 -0
  172. package/dist/kit/uploads.js +165 -0
  173. package/dist/kit/uploads.js.map +1 -0
  174. package/dist/kit/waveform.js +76 -0
  175. package/dist/kit/waveform.js.map +1 -0
  176. package/dist/locale.d.ts +1 -0
  177. package/dist/locale.js +1 -0
  178. package/dist/markdown.js +84 -0
  179. package/dist/markdown.js.map +1 -0
  180. package/dist/marks.js +217 -0
  181. package/dist/marks.js.map +1 -0
  182. package/dist/reveal.js +48 -0
  183. package/dist/reveal.js.map +1 -0
  184. package/dist/stepGlyphs.js +62 -0
  185. package/dist/stepGlyphs.js.map +1 -0
  186. package/dist/surface/Form.js +264 -0
  187. package/dist/surface/Form.js.map +1 -0
  188. package/dist/surface/Markdown.js +42 -0
  189. package/dist/surface/Markdown.js.map +1 -0
  190. package/dist/surface/Surface.d.ts +31 -17
  191. package/dist/surface/Surface.js +480 -57
  192. package/dist/surface/Surface.js.map +1 -0
  193. package/dist/surface/scope.d.ts +32 -0
  194. package/dist/surface/scope.js +23 -0
  195. package/dist/surface/scope.js.map +1 -0
  196. package/dist/surface/values.d.ts +44 -0
  197. package/dist/surface/values.js +237 -0
  198. package/dist/surface/values.js.map +1 -0
  199. package/dist/tint.d.ts +10 -0
  200. package/dist/tint.js +19 -0
  201. package/dist/tint.js.map +1 -0
  202. package/dist/types.d.ts +541 -0
  203. package/dist/types.js +16 -0
  204. package/dist/types.js.map +1 -0
  205. package/dist/useAgentFace.d.ts +18 -0
  206. package/dist/useAgentFace.js +45 -0
  207. package/dist/useAgentFace.js.map +1 -0
  208. package/dist/useCall.d.ts +39 -0
  209. package/dist/useCall.js +273 -0
  210. package/dist/useCall.js.map +1 -0
  211. package/dist/useConversation.d.ts +77 -0
  212. package/dist/useConversation.js +523 -0
  213. package/dist/useConversation.js.map +1 -0
  214. package/dist/useDictation.d.ts +17 -0
  215. package/dist/useDictation.js +68 -0
  216. package/dist/useDictation.js.map +1 -0
  217. package/dist/useLive.d.ts +26 -0
  218. package/dist/useLive.js +88 -0
  219. package/dist/useLive.js.map +1 -0
  220. package/dist/usePolled.js +68 -0
  221. package/dist/usePolled.js.map +1 -0
  222. package/dist/voice/Orb.d.ts +10 -9
  223. package/dist/voice/Orb.js +43 -39
  224. package/dist/voice/Orb.js.map +1 -0
  225. package/dist/voice/StillOrb.js +33 -0
  226. package/dist/voice/StillOrb.js.map +1 -0
  227. package/dist/voice/WebGLOrb.js +98 -0
  228. package/dist/voice/WebGLOrb.js.map +1 -0
  229. package/dist/voice/fluidDots.js +161 -0
  230. package/dist/voice/fluidDots.js.map +1 -0
  231. package/dist/voice/motion.js +84 -0
  232. package/dist/voice/motion.js.map +1 -0
  233. package/dist/voice/orbs.d.ts +32 -0
  234. package/dist/voice/orbs.js +16 -0
  235. package/dist/voice/orbs.js.map +1 -0
  236. package/dist/voice/useReducedMotion.js +16 -16
  237. package/dist/voice/useReducedMotion.js.map +1 -0
  238. package/dist/voice/wave.js +116 -0
  239. package/dist/voice/wave.js.map +1 -0
  240. package/dist/voice/webgl.js +177 -0
  241. package/dist/voice/webgl.js.map +1 -0
  242. package/dist/widget.js +284 -8
  243. package/package.json +49 -39
  244. package/src/AgentAbout.tsx +1621 -0
  245. package/src/AgentCard.tsx +123 -0
  246. package/src/AgentChat.tsx +1812 -0
  247. package/src/AgentSpace.tsx +540 -0
  248. package/src/AgentTasks.tsx +163 -0
  249. package/src/BrowserView.tsx +442 -0
  250. package/src/FileView.tsx +620 -0
  251. package/src/Modes.tsx +112 -0
  252. package/src/VoiceCall.tsx +411 -0
  253. package/src/about.ts +355 -0
  254. package/src/agentIcons.ts +56 -0
  255. package/src/automation/Automation.tsx +308 -0
  256. package/src/automation/RunView.tsx +213 -0
  257. package/src/automation/cron.ts +196 -0
  258. package/src/automation/marks.tsx +144 -0
  259. package/src/automation/messages.ts +231 -0
  260. package/src/automation/record.ts +206 -0
  261. package/src/automation/types.ts +146 -0
  262. package/src/automation/when.ts +195 -0
  263. package/src/blocks.ts +249 -0
  264. package/src/browser.ts +334 -0
  265. package/src/call.ts +300 -0
  266. package/src/channelParts.ts +17 -0
  267. package/src/classes.ts +10 -0
  268. package/src/client.ts +397 -0
  269. package/src/conversationFiles.ts +54 -0
  270. package/src/credentials.ts +158 -0
  271. package/src/dev.ts +20 -0
  272. package/src/es.ts +423 -0
  273. package/src/files.ts +238 -0
  274. package/src/frames.ts +291 -0
  275. package/src/icons.tsx +49 -0
  276. package/src/index.ts +271 -0
  277. package/src/kit/AudioPlayer.tsx +129 -0
  278. package/src/kit/Button.tsx +97 -0
  279. package/src/kit/Card.tsx +47 -0
  280. package/src/kit/Chart.tsx +129 -0
  281. package/src/kit/Choices.tsx +131 -0
  282. package/src/kit/Combobox.tsx +247 -0
  283. package/src/kit/DateField.tsx +156 -0
  284. package/src/kit/Field.tsx +137 -0
  285. package/src/kit/FileField.tsx +492 -0
  286. package/src/kit/FileMark.tsx +56 -0
  287. package/src/kit/Inputs.tsx +250 -0
  288. package/src/kit/List.tsx +135 -0
  289. package/src/kit/Mark.tsx +64 -0
  290. package/src/kit/MarkStack.tsx +29 -0
  291. package/src/kit/Note.tsx +42 -0
  292. package/src/kit/Popover.tsx +121 -0
  293. package/src/kit/RangeField.tsx +53 -0
  294. package/src/kit/RatingField.tsx +62 -0
  295. package/src/kit/Stat.tsx +60 -0
  296. package/src/kit/Switch.tsx +28 -0
  297. package/src/kit/Tag.tsx +32 -0
  298. package/src/kit/Tile.tsx +74 -0
  299. package/src/kit/TimeField.tsx +157 -0
  300. package/src/kit/context.tsx +246 -0
  301. package/src/kit/dates.ts +150 -0
  302. package/src/kit/messages.ts +160 -0
  303. package/src/kit/numbers.ts +44 -0
  304. package/src/kit/options.ts +30 -0
  305. package/src/kit/uploads.ts +244 -0
  306. package/src/kit/waveform.ts +84 -0
  307. package/src/locale.ts +6 -0
  308. package/src/markdown.ts +69 -0
  309. package/src/marks.tsx +328 -0
  310. package/src/reveal.ts +52 -0
  311. package/src/stepGlyphs.ts +83 -0
  312. package/src/styles.css +6970 -0
  313. package/src/surface/Form.tsx +299 -0
  314. package/src/surface/Markdown.tsx +55 -0
  315. package/src/surface/Surface.tsx +605 -0
  316. package/src/surface/scope.ts +82 -0
  317. package/src/surface/values.ts +361 -0
  318. package/src/tint.ts +14 -0
  319. package/src/types.ts +604 -0
  320. package/src/useAgentFace.ts +47 -0
  321. package/src/useCall.ts +292 -0
  322. package/src/useConversation.ts +627 -0
  323. package/src/useDictation.ts +83 -0
  324. package/src/useLive.ts +115 -0
  325. package/src/usePolled.ts +60 -0
  326. package/src/voice/Orb.tsx +45 -0
  327. package/src/voice/StillOrb.tsx +29 -0
  328. package/src/voice/WebGLOrb.tsx +98 -0
  329. package/src/voice/fluidDots.tsx +171 -0
  330. package/src/voice/motion.ts +112 -0
  331. package/src/voice/orbs.ts +39 -0
  332. package/src/voice/useReducedMotion.ts +24 -0
  333. package/src/voice/wave.tsx +129 -0
  334. package/src/voice/webgl.ts +209 -0
  335. package/src/widget/css.d.ts +5 -0
  336. package/src/widget/element.tsx +535 -0
  337. package/src/widget/index.ts +10 -0
  338. package/src/widget/mount.ts +27 -0
  339. package/src/widget/widget.css +253 -0
  340. package/dist/SignalcoreProvider.d.ts +0 -113
  341. package/dist/SignalcoreProvider.js +0 -84
  342. package/dist/automations/AppMarks.d.ts +0 -11
  343. package/dist/automations/AppMarks.js +0 -18
  344. package/dist/automations/AutomationCard.d.ts +0 -27
  345. package/dist/automations/AutomationCard.js +0 -53
  346. package/dist/automations/AutomationsWindow.d.ts +0 -38
  347. package/dist/automations/AutomationsWindow.js +0 -57
  348. package/dist/automations/Card.d.ts +0 -46
  349. package/dist/automations/Card.js +0 -45
  350. package/dist/automations/ScheduleMarks.d.ts +0 -13
  351. package/dist/automations/ScheduleMarks.js +0 -24
  352. package/dist/automations/presentationIcons.d.ts +0 -7
  353. package/dist/automations/presentationIcons.js +0 -67
  354. package/dist/automations/schedule.d.ts +0 -25
  355. package/dist/automations/schedule.js +0 -59
  356. package/dist/automations/time.d.ts +0 -3
  357. package/dist/automations/time.js +0 -25
  358. package/dist/browser/BrowserView.d.ts +0 -43
  359. package/dist/browser/BrowserView.js +0 -94
  360. package/dist/browser/room.d.ts +0 -21
  361. package/dist/browser/room.js +0 -33
  362. package/dist/browser/useBrowserSession.d.ts +0 -17
  363. package/dist/browser/useBrowserSession.js +0 -67
  364. package/dist/builder/BuilderChat.d.ts +0 -32
  365. package/dist/builder/BuilderChat.js +0 -41
  366. package/dist/builder/BuilderTranscript.d.ts +0 -49
  367. package/dist/builder/BuilderTranscript.js +0 -62
  368. package/dist/builder/StatusLine.d.ts +0 -8
  369. package/dist/builder/StatusLine.js +0 -17
  370. package/dist/builder/answer.d.ts +0 -7
  371. package/dist/builder/answer.js +0 -8
  372. package/dist/builder/blocks.d.ts +0 -31
  373. package/dist/builder/blocks.js +0 -74
  374. package/dist/builder/items.d.ts +0 -15
  375. package/dist/builder/items.js +0 -21
  376. package/dist/builder/steps.d.ts +0 -20
  377. package/dist/builder/steps.js +0 -120
  378. package/dist/builder/time.d.ts +0 -4
  379. package/dist/builder/time.js +0 -24
  380. package/dist/builder/useBuildSession.d.ts +0 -36
  381. package/dist/builder/useBuildSession.js +0 -130
  382. package/dist/builder/workingOn.d.ts +0 -7
  383. package/dist/builder/workingOn.js +0 -15
  384. package/dist/chat/AgentChat.d.ts +0 -37
  385. package/dist/chat/AgentChat.js +0 -21
  386. package/dist/chat/ChatView.d.ts +0 -25
  387. package/dist/chat/ChatView.js +0 -34
  388. package/dist/chat/Composer.d.ts +0 -20
  389. package/dist/chat/Composer.js +0 -22
  390. package/dist/chat/MessageRow.d.ts +0 -22
  391. package/dist/chat/MessageRow.js +0 -32
  392. package/dist/chat/arrival.d.ts +0 -15
  393. package/dist/chat/arrival.js +0 -25
  394. package/dist/chat/history.d.ts +0 -24
  395. package/dist/chat/history.js +0 -45
  396. package/dist/chat/moments.d.ts +0 -25
  397. package/dist/chat/moments.js +0 -72
  398. package/dist/chat/types.d.ts +0 -12
  399. package/dist/chat/types.js +0 -1
  400. package/dist/chat/useComposer.d.ts +0 -46
  401. package/dist/chat/useComposer.js +0 -62
  402. package/dist/chat/useConversation.d.ts +0 -35
  403. package/dist/chat/useConversation.js +0 -71
  404. package/dist/chat/useStickToBottom.d.ts +0 -9
  405. package/dist/chat/useStickToBottom.js +0 -33
  406. package/dist/chat/useTurns.d.ts +0 -49
  407. package/dist/chat/useTurns.js +0 -111
  408. package/dist/classes.d.ts +0 -2
  409. package/dist/development.d.ts +0 -5
  410. package/dist/development.js +0 -8
  411. package/dist/flow/FlowWindow.d.ts +0 -42
  412. package/dist/flow/FlowWindow.js +0 -126
  413. package/dist/flow/index.d.ts +0 -16
  414. package/dist/flow/index.js +0 -16
  415. package/dist/flow/kinds.d.ts +0 -23
  416. package/dist/flow/kinds.js +0 -48
  417. package/dist/flow/map.d.ts +0 -44
  418. package/dist/flow/map.js +0 -225
  419. package/dist/flow/nodePaths.d.ts +0 -7
  420. package/dist/flow/nodePaths.js +0 -17
  421. package/dist/flow/relations.d.ts +0 -42
  422. package/dist/flow/relations.js +0 -174
  423. package/dist/host.d.ts +0 -124
  424. package/dist/host.js +0 -1
  425. package/dist/live/LiveView.d.ts +0 -28
  426. package/dist/live/LiveView.js +0 -55
  427. package/dist/live/capture.d.ts +0 -20
  428. package/dist/live/capture.js +0 -100
  429. package/dist/live/follow.d.ts +0 -26
  430. package/dist/live/follow.js +0 -72
  431. package/dist/live/paint.d.ts +0 -13
  432. package/dist/live/paint.js +0 -77
  433. package/dist/live/useLiveStream.d.ts +0 -16
  434. package/dist/live/useLiveStream.js +0 -57
  435. package/dist/look.d.ts +0 -33
  436. package/dist/look.js +0 -241
  437. package/dist/messages/en.d.ts +0 -3
  438. package/dist/messages/en.js +0 -251
  439. package/dist/messages/es.d.ts +0 -3
  440. package/dist/messages/es.js +0 -251
  441. package/dist/messages/index.d.ts +0 -16
  442. package/dist/messages/index.js +0 -33
  443. package/dist/messages/types.d.ts +0 -246
  444. package/dist/messages/types.js +0 -1
  445. package/dist/parts/Button.d.ts +0 -18
  446. package/dist/parts/Button.js +0 -17
  447. package/dist/parts/Icon.d.ts +0 -39
  448. package/dist/parts/Icon.js +0 -37
  449. package/dist/parts/Input.d.ts +0 -6
  450. package/dist/parts/Input.js +0 -11
  451. package/dist/parts/Spinner.d.ts +0 -2
  452. package/dist/parts/Spinner.js +0 -7
  453. package/dist/patterns.d.ts +0 -15
  454. package/dist/patterns.js +0 -5
  455. package/dist/presets.d.ts +0 -82
  456. package/dist/presets.js +0 -81
  457. package/dist/primitives.d.ts +0 -22
  458. package/dist/primitives.js +0 -58
  459. package/dist/request/RequestCard.d.ts +0 -34
  460. package/dist/request/RequestCard.js +0 -101
  461. package/dist/request/approval/ApprovalPreview.d.ts +0 -5
  462. package/dist/request/approval/ApprovalPreview.js +0 -27
  463. package/dist/request/approval/shapes.d.ts +0 -32
  464. package/dist/request/approval/shapes.js +0 -68
  465. package/dist/request/apps.d.ts +0 -11
  466. package/dist/request/apps.js +0 -27
  467. package/dist/request/cards.d.ts +0 -12
  468. package/dist/request/cards.js +0 -24
  469. package/dist/request/deliver.d.ts +0 -12
  470. package/dist/request/deliver.js +0 -21
  471. package/dist/request/handOver.d.ts +0 -18
  472. package/dist/request/handOver.js +0 -33
  473. package/dist/request/kinds/Approval.d.ts +0 -3
  474. package/dist/request/kinds/Approval.js +0 -9
  475. package/dist/request/kinds/Choice.d.ts +0 -3
  476. package/dist/request/kinds/Choice.js +0 -8
  477. package/dist/request/kinds/Connect.d.ts +0 -9
  478. package/dist/request/kinds/Connect.js +0 -119
  479. package/dist/request/kinds/FreeText.d.ts +0 -3
  480. package/dist/request/kinds/FreeText.js +0 -20
  481. package/dist/request/kinds/HandOver.d.ts +0 -13
  482. package/dist/request/kinds/HandOver.js +0 -20
  483. package/dist/request/kinds/Secret.d.ts +0 -7
  484. package/dist/request/kinds/Secret.js +0 -49
  485. package/dist/request/kinds/Upload.d.ts +0 -6
  486. package/dist/request/kinds/Upload.js +0 -47
  487. package/dist/request/types.d.ts +0 -83
  488. package/dist/request/types.js +0 -1
  489. package/dist/safeUrl.d.ts +0 -6
  490. package/dist/safeUrl.js +0 -8
  491. package/dist/stream/builder.d.ts +0 -176
  492. package/dist/stream/builder.js +0 -202
  493. package/dist/stream/reduce.d.ts +0 -51
  494. package/dist/stream/reduce.js +0 -58
  495. package/dist/stream/untilAborted.d.ts +0 -7
  496. package/dist/stream/untilAborted.js +0 -32
  497. package/dist/stream/useRunStream.d.ts +0 -26
  498. package/dist/stream/useRunStream.js +0 -137
  499. package/dist/styles.css +0 -2318
  500. package/dist/surface/HostNode.d.ts +0 -14
  501. package/dist/surface/HostNode.js +0 -30
  502. package/dist/surface/Node.d.ts +0 -7
  503. package/dist/surface/Node.js +0 -49
  504. package/dist/surface/SurfaceBoundary.d.ts +0 -26
  505. package/dist/surface/SurfaceBoundary.js +0 -20
  506. package/dist/surface/bindings.d.ts +0 -14
  507. package/dist/surface/bindings.js +0 -37
  508. package/dist/surface/check.d.ts +0 -27
  509. package/dist/surface/check.js +0 -102
  510. package/dist/surface/format.d.ts +0 -10
  511. package/dist/surface/format.js +0 -32
  512. package/dist/surface/hosts.d.ts +0 -6
  513. package/dist/surface/hosts.js +0 -11
  514. package/dist/surface/scene.d.ts +0 -21
  515. package/dist/surface/scene.js +0 -8
  516. package/dist/surface/templates/Browser.d.ts +0 -6
  517. package/dist/surface/templates/Browser.js +0 -11
  518. package/dist/surface/templates/Chart.d.ts +0 -6
  519. package/dist/surface/templates/Chart.js +0 -13
  520. package/dist/surface/templates/Choices.d.ts +0 -3
  521. package/dist/surface/templates/Choices.js +0 -12
  522. package/dist/surface/templates/Form.d.ts +0 -3
  523. package/dist/surface/templates/Form.js +0 -44
  524. package/dist/surface/templates/KeyValue.d.ts +0 -3
  525. package/dist/surface/templates/KeyValue.js +0 -7
  526. package/dist/surface/templates/Layout.d.ts +0 -5
  527. package/dist/surface/templates/Layout.js +0 -16
  528. package/dist/surface/templates/Live.d.ts +0 -6
  529. package/dist/surface/templates/Live.js +0 -9
  530. package/dist/surface/templates/Media.d.ts +0 -5
  531. package/dist/surface/templates/Media.js +0 -13
  532. package/dist/surface/templates/Slots.d.ts +0 -3
  533. package/dist/surface/templates/Slots.js +0 -19
  534. package/dist/surface/templates/Table.d.ts +0 -3
  535. package/dist/surface/templates/Table.js +0 -12
  536. package/dist/surface/templates/Text.d.ts +0 -4
  537. package/dist/surface/templates/Text.js +0 -15
  538. package/dist/surface/templates/index.d.ts +0 -7
  539. package/dist/surface/templates/index.js +0 -32
  540. package/dist/surface/types.d.ts +0 -68
  541. package/dist/surface/types.js +0 -6
  542. package/dist/theme.d.ts +0 -62
  543. package/dist/theme.js +0 -9
  544. package/dist/useTokens.d.ts +0 -7
  545. package/dist/useTokens.js +0 -41
  546. package/dist/voice/VoiceWindow.d.ts +0 -18
  547. package/dist/voice/VoiceWindow.js +0 -35
  548. package/dist/voice/index.d.ts +0 -13
  549. package/dist/voice/index.js +0 -12
  550. package/dist/voice/meter.d.ts +0 -16
  551. package/dist/voice/meter.js +0 -52
  552. package/dist/voice/orbColors.d.ts +0 -16
  553. package/dist/voice/orbColors.js +0 -75
  554. package/dist/voice/pushable.d.ts +0 -16
  555. package/dist/voice/pushable.js +0 -56
  556. package/dist/voice/useDictation.d.ts +0 -24
  557. package/dist/voice/useDictation.js +0 -60
  558. package/dist/voice/useReducedMotion.d.ts +0 -5
  559. package/dist/voice/useVoice.d.ts +0 -70
  560. package/dist/voice/useVoice.js +0 -197
  561. package/dist/voice/useVoicePrimitives.d.ts +0 -7
  562. package/dist/voice/useVoicePrimitives.js +0 -11
  563. package/dist/voice/voice.d.ts +0 -55
  564. package/dist/voice/voice.js +0 -9
  565. package/dist/voice/webSpeech.d.ts +0 -33
  566. package/dist/voice/webSpeech.js +0 -258
  567. package/dist/widget.js.map +0 -1
  568. package/dist/windows/AgentSpace.d.ts +0 -78
  569. package/dist/windows/AgentSpace.js +0 -135
  570. package/dist/windows/Captions.d.ts +0 -13
  571. package/dist/windows/Captions.js +0 -22
  572. package/dist/windows/Dock.d.ts +0 -37
  573. package/dist/windows/Dock.js +0 -22
  574. package/dist/windows/Journal.d.ts +0 -15
  575. package/dist/windows/Journal.js +0 -19
  576. package/dist/windows/KindMark.d.ts +0 -7
  577. package/dist/windows/KindMark.js +0 -31
  578. package/dist/windows/Pending.d.ts +0 -8
  579. package/dist/windows/Pending.js +0 -17
  580. package/dist/windows/Stage.d.ts +0 -18
  581. package/dist/windows/Stage.js +0 -21
  582. package/dist/windows/StatusLabel.d.ts +0 -9
  583. package/dist/windows/StatusLabel.js +0 -7
  584. package/dist/windows/Strip.d.ts +0 -17
  585. package/dist/windows/Strip.js +0 -42
  586. package/dist/windows/SurfaceWindow.d.ts +0 -20
  587. package/dist/windows/SurfaceWindow.js +0 -12
  588. package/dist/windows/WindowFrame.d.ts +0 -23
  589. package/dist/windows/WindowFrame.js +0 -22
  590. package/dist/windows/hearing.d.ts +0 -11
  591. package/dist/windows/hearing.js +0 -26
  592. package/dist/windows/kinds.d.ts +0 -47
  593. package/dist/windows/kinds.js +0 -28
  594. package/dist/windows/reduce.d.ts +0 -98
  595. package/dist/windows/reduce.js +0 -151
  596. package/dist/windows/registry.d.ts +0 -18
  597. package/dist/windows/registry.js +0 -61
  598. package/dist/windows/reveal.d.ts +0 -9
  599. package/dist/windows/reveal.js +0 -6
  600. package/dist/windows/space.d.ts +0 -21
  601. package/dist/windows/space.js +0 -6
  602. package/dist/windows/status.d.ts +0 -11
  603. package/dist/windows/status.js +0 -30
  604. package/dist/windows/types.d.ts +0 -15
  605. package/dist/windows/types.js +0 -1
  606. package/dist/windows/useLoaded.d.ts +0 -44
  607. package/dist/windows/useLoaded.js +0 -58
  608. package/dist/windows/useUnread.d.ts +0 -7
  609. package/dist/windows/useUnread.js +0 -21
  610. package/dist/windows/useWindows.d.ts +0 -70
  611. package/dist/windows/useWindows.js +0 -60
@@ -0,0 +1,535 @@
1
+ /// <reference path="./css.d.ts" />
2
+ import { ChatCircleDotsIcon, XIcon } from "@phosphor-icons/react";
3
+ import { useMemo, useState } from "react";
4
+ import { createRoot, type Root } from "react-dom/client";
5
+
6
+ import type { ChatSteps } from "../AgentChat";
7
+ import { AgentSpace, SPACE_MESSAGES } from "../AgentSpace";
8
+ import { createClient } from "../client";
9
+ import type { Credentials } from "../credentials";
10
+ import { SPACE_MESSAGES_ES } from "../es";
11
+ import { es } from "../locale";
12
+ import styles from "../styles.css?inline";
13
+ import type { WidgetConfig, WidgetLook } from "../types";
14
+ import own from "./widget.css?inline";
15
+
16
+ /** The tag the widget registers. */
17
+ export const TAG = "signalcore-chat";
18
+
19
+ /** What the page says on the element; a change to any of them draws it again. */
20
+ const ATTRIBUTES = [
21
+ "base-url",
22
+ "agent",
23
+ "publishable-key",
24
+ "token",
25
+ "theme",
26
+ "locale",
27
+ "mode",
28
+ "header",
29
+ "steps",
30
+ "stylesheet",
31
+ "unstyled",
32
+ "shadow",
33
+ "contained",
34
+ ] as const;
35
+
36
+ type Attribute = (typeof ATTRIBUTES)[number];
37
+
38
+ /** The two languages the widget speaks. */
39
+ type Language = "es" | "en";
40
+
41
+ /** What the widget is drawn from, as its attributes say it. */
42
+ export interface WidgetSettings {
43
+ /** The public API: its origin and `/v1`. */
44
+ baseUrl: string;
45
+ /** The agent; null: the web channel its publishable key belongs to names it. */
46
+ agent: string | null;
47
+ /**
48
+ * Who the page speaks for: a person, by the token the host minted; a visitor of the site; or,
49
+ * with neither, the page's own sign-in (SignalCore's app, previewing the widget).
50
+ */
51
+ credential: Credentials;
52
+ language: Language;
53
+ /** A button at the page's corner that opens a panel; or the panel in the page's flow. */
54
+ mode: "floating" | "inline";
55
+ /** The agent's face over the space (`header`); off unless the page asks. */
56
+ header: boolean;
57
+ /** Whether the agent's steps show (`steps`); as the page speaks (hidden for its people) unless said. */
58
+ steps: ChatSteps | undefined;
59
+ /** Floating within the element's own box (`contained`), not at the page's corner: a preview. */
60
+ contained: boolean;
61
+ }
62
+
63
+ /** The launcher's words, by language. */
64
+ const LAUNCHER: Readonly<Record<Language, { open: string; close: string; chat: string }>> = {
65
+ en: { open: "Open the chat", close: "Close the chat", chat: "Chat" },
66
+ es: { open: "Abrir el chat", close: "Cerrar el chat", chat: "Chat" },
67
+ };
68
+
69
+ /**
70
+ * The language asked for (`locale`), else the page's own (`<html lang>`), else the browser's:
71
+ * Spanish for any `es`, English otherwise.
72
+ */
73
+ export function languageOf(locale: string | null): Language {
74
+ const asked = locale || document.documentElement.lang || navigator.language;
75
+ return asked.toLowerCase().startsWith("es") ? "es" : "en";
76
+ }
77
+
78
+ /** Whether a boolean attribute is on: present, and not `"false"`. */
79
+ const on = (element: Element, name: Attribute): boolean =>
80
+ element.hasAttribute(name) && element.getAttribute(name) !== "false";
81
+
82
+ /**
83
+ * The settings an element's attributes give, or null while one it needs is missing: the API, and
84
+ * the agent, which only a publishable key may leave to its web channel.
85
+ */
86
+ export function settingsOf(element: Element): WidgetSettings | null {
87
+ const read = (name: Attribute) => element.getAttribute(name) || null;
88
+ const baseUrl = read("base-url");
89
+ const agent = read("agent");
90
+ const token = read("token");
91
+ const publishableKey = read("publishable-key");
92
+ const credential: Credentials =
93
+ token !== null
94
+ ? { token }
95
+ : publishableKey !== null
96
+ ? { publishableKey }
97
+ : { credentials: "cookie" };
98
+ if (baseUrl === null || (agent === null && publishableKey === null)) return null;
99
+ const steps = read("steps");
100
+ return {
101
+ baseUrl,
102
+ agent,
103
+ credential,
104
+ language: languageOf(read("locale")),
105
+ mode: read("mode") === "inline" ? "inline" : "floating",
106
+ header: on(element, "header"),
107
+ steps: steps === "shown" || steps === "hidden" ? steps : undefined,
108
+ contained: on(element, "contained"),
109
+ };
110
+ }
111
+
112
+ /**
113
+ * A look as the widget's own stylesheet: its tokens on the host (`:host` in its shadow root, the
114
+ * element itself when drawn into the page), where the page's own rules for the element still
115
+ * win, then its CSS. The font is the face's name; `loadFont` brings the face.
116
+ */
117
+ export function lookCss(look: WidgetLook, host: string): string {
118
+ const px = (value: number | null | undefined) => (value == null ? null : `${String(value)}px`);
119
+ const tokens: [string, string | null | undefined][] = [
120
+ ["--sc-accent", look.accent],
121
+ ["--sc-accent-fg", look.accent_fg],
122
+ ["--sc-font", look.font && `"${look.font}", ui-sans-serif, system-ui, sans-serif`],
123
+ ["--sc-radius", px(look.radius)],
124
+ ["--sc-launcher-size", px(look.launcher_size)],
125
+ ["--sc-panel-width", px(look.panel_width)],
126
+ ["--sc-panel-height", px(look.panel_height)],
127
+ ["color-scheme", look.theme === "light" || look.theme === "dark" ? look.theme : null],
128
+ ];
129
+ const said = tokens.flatMap(([name, value]) => (value ? [`${name}: ${value};`] : []));
130
+ const rule = said.length > 0 ? `${host} { ${said.join(" ")} }` : "";
131
+ return [rule, look.css ?? ""].filter(Boolean).join("\n");
132
+ }
133
+
134
+ /** The face from Google Fonts, in the page's head (where a shadow root's text finds it), once. */
135
+ export function loadFont(font: string) {
136
+ if (document.querySelector(`link[data-signalcore-font="${font}"]`) !== null) return;
137
+ const family = encodeURIComponent(font).replace(/%20/g, "+");
138
+ const link = linkTo(
139
+ `https://fonts.googleapis.com/css2?family=${family}:wght@400;500;600&display=swap`,
140
+ );
141
+ link.setAttribute("data-signalcore-font", font);
142
+ document.head.append(link);
143
+ }
144
+
145
+ /**
146
+ * How light a CSS colour is, from 0 (black) to 1 (white), as a browser gives a computed one:
147
+ * `rgb()`, `rgba()`, `color(srgb …)`, `oklab()`, `oklch()`, `lab()`, `lch()`; null for any other.
148
+ */
149
+ export function lightnessOf(color: string): number | null {
150
+ const open = color.indexOf("(");
151
+ if (open < 0) return null;
152
+ const space = color.slice(0, open).trim().toLowerCase();
153
+ const inside = color.slice(open + 1);
154
+ // `color()` names its space first: only sRGB's channels are read as they are.
155
+ if (space === "color" && !/^\s*srgb\s/i.test(inside)) return null;
156
+ const values = inside
157
+ .replace(/^\s*srgb\s/i, "")
158
+ .match(/-?\d*\.?\d+(?:e-?\d+)?%?/gi)
159
+ ?.map((value) => (value.endsWith("%") ? Number.parseFloat(value) / 100 : Number(value)));
160
+ if (values === undefined) return null;
161
+ const [a, b, c] = values;
162
+ const luminance = (red: number, green: number, blue: number) =>
163
+ 0.2126 * red + 0.7152 * green + 0.0722 * blue;
164
+ if (a === undefined) return null;
165
+ switch (space) {
166
+ case "rgb":
167
+ case "rgba":
168
+ return b === undefined || c === undefined ? null : luminance(a, b, c) / 255;
169
+ case "color":
170
+ return b === undefined || c === undefined ? null : luminance(a, b, c);
171
+ case "oklab":
172
+ case "oklch":
173
+ return a;
174
+ case "lab":
175
+ case "lch":
176
+ return a / 100;
177
+ default:
178
+ return null;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Whether the widget wears its dark palette by the page's text: only where the page names no
184
+ * `color-scheme` (`normal`) and its text is light, as on a page made dark by its own classes.
185
+ */
186
+ export function darkByInk(colorScheme: string, color: string): boolean {
187
+ if (colorScheme !== "" && colorScheme !== "normal") return false;
188
+ const lightness = lightnessOf(color);
189
+ return lightness !== null && lightness > 0.6;
190
+ }
191
+
192
+ /** Whether the page's stylesheet for the widget is CSS itself, or the address of one. */
193
+ const isCss = (stylesheet: string): boolean => stylesheet.includes("{");
194
+
195
+ /** A stylesheet of this CSS. */
196
+ function cssOf(text: string): HTMLStyleElement {
197
+ const style = document.createElement("style");
198
+ style.textContent = text;
199
+ return style;
200
+ }
201
+
202
+ /** The stylesheet at this address. */
203
+ function linkTo(address: string): HTMLLinkElement {
204
+ const link = document.createElement("link");
205
+ link.rel = "stylesheet";
206
+ link.href = address;
207
+ return link;
208
+ }
209
+
210
+ /** Where the page keeps the visitor's conversation with an agent, so a visit goes on with it. */
211
+ const conversationKey = (agent: string): string => `signalcore.conversation.${agent}`;
212
+
213
+ function keptConversation(agent: string): string | undefined {
214
+ try {
215
+ return localStorage.getItem(conversationKey(agent)) ?? undefined;
216
+ } catch {
217
+ return undefined;
218
+ }
219
+ }
220
+
221
+ function keepConversation(agent: string, id: string) {
222
+ try {
223
+ localStorage.setItem(conversationKey(agent), id);
224
+ } catch {
225
+ // A page that can't keep anything starts a new conversation each visit.
226
+ }
227
+ }
228
+
229
+ /** Our stylesheet in the page itself, once, first in its head so the page's own CSS wins. */
230
+ function stylePage() {
231
+ if (document.querySelector("style[data-signalcore-ui]") !== null) return;
232
+ const style = document.createElement("style");
233
+ style.setAttribute("data-signalcore-ui", "");
234
+ style.textContent = `${styles}\n${own}`;
235
+ document.head.prepend(style);
236
+ }
237
+
238
+ /** What the widget draws: its settings with the agent known, and its look, if it has one. */
239
+ export interface WidgetProps {
240
+ settings: WidgetSettings & { agent: string };
241
+ look?: WidgetLook | null | undefined;
242
+ }
243
+
244
+ /**
245
+ * The widget: the agent's space (`AgentSpace`) in a panel, opened from a round button at the
246
+ * page's corner (the left one if its look says so), or (`inline`) in the page's flow at the
247
+ * element's size. The conversation it opens is kept in the page's storage for the next visit.
248
+ */
249
+ export function Widget({ settings, look = null }: WidgetProps) {
250
+ const { baseUrl, agent, credential, language, mode, steps, contained } = settings;
251
+ const signedAs = credential.token ?? credential.publishableKey ?? "cookie";
252
+ // One client while the page says the same; a new token (the host's, renewed) makes another.
253
+ const client = useMemo(() => createClient({ baseUrl, ...credential }), [baseUrl, signedAs]);
254
+ const [open, setOpen] = useState(false);
255
+ const words = LAUNCHER[language];
256
+ const floating = mode === "floating";
257
+ const header = settings.header || look?.header === true;
258
+
259
+ const space = (
260
+ <div part="panel" role="dialog" aria-label={words.chat} className="sc-widget__panel">
261
+ <AgentSpace
262
+ key={agent}
263
+ client={client}
264
+ agentId={agent}
265
+ conversationId={keptConversation(agent)}
266
+ onConversation={(id) => {
267
+ keepConversation(agent, id);
268
+ }}
269
+ layout={floating ? "compact" : "full"}
270
+ header={header}
271
+ steps={steps}
272
+ messages={language === "es" ? SPACE_MESSAGES_ES : SPACE_MESSAGES}
273
+ locale={language === "es" ? es : undefined}
274
+ onClose={
275
+ floating
276
+ ? () => {
277
+ setOpen(false);
278
+ }
279
+ : undefined
280
+ }
281
+ />
282
+ </div>
283
+ );
284
+
285
+ if (!floating) return <div className="sc sc-widget sc-widget--inline">{space}</div>;
286
+ const classes = [
287
+ "sc sc-widget sc-widget--floating",
288
+ open && "sc-widget--open",
289
+ look?.position === "left" && "sc-widget--left",
290
+ contained && "sc-widget--contained",
291
+ ];
292
+ return (
293
+ <div className={classes.filter(Boolean).join(" ")}>
294
+ {open && space}
295
+ <button
296
+ type="button"
297
+ part="launcher"
298
+ aria-label={open ? words.close : words.open}
299
+ aria-expanded={open}
300
+ onClick={() => {
301
+ setOpen(!open);
302
+ }}
303
+ className="sc-widget__launcher"
304
+ >
305
+ {open ? (
306
+ <XIcon aria-hidden weight="bold" />
307
+ ) : (
308
+ <ChatCircleDotsIcon aria-hidden weight="fill" />
309
+ )}
310
+ </button>
311
+ </div>
312
+ );
313
+ }
314
+
315
+ /**
316
+ * `<signalcore-chat>`: the widget as a web component, for a page built without React. It draws
317
+ * into a shadow root holding the package's stylesheet (or, `shadow="none"`, into the page, the
318
+ * stylesheet first in its head), takes the page's type and ink, and lets in its `--sc-*` tokens,
319
+ * `::part()` and its own stylesheet (`stylesheet`: CSS, or its address). Its attributes say where
320
+ * the API is (`base-url`), the agent, who the page speaks for (`publishable-key`, or `token`),
321
+ * `theme` (`light`, `dark`; the page's by default), `locale` (`es`, `en`), `mode` (`inline`;
322
+ * floating by default), `header` (the agent's face), `steps` (`shown`, `hidden`), `unstyled`
323
+ * (our look's defaults dropped, the layout kept) and `contained` (floating in its own box).
324
+ *
325
+ * With a publishable key and no `agent`, it is a web channel's widget: it reads its agent and
326
+ * its look by the key as it loads (`GET /channels/web/widget`), so a change the business makes
327
+ * reaches every site. A look set on it (`look`) stands over its channel's: SignalCore's preview.
328
+ */
329
+ export class SignalCoreChat extends HTMLElement {
330
+ static observedAttributes = [...ATTRIBUTES];
331
+
332
+ #mount: HTMLElement | null = null;
333
+ #root: Root | null = null;
334
+ /** The page's own stylesheet for the widget, and what it was made from. */
335
+ #sheet: { from: string; element: HTMLStyleElement | HTMLLinkElement } | null = null;
336
+ /** The look as a stylesheet, before the page's own. */
337
+ #lookSheet: HTMLStyleElement | null = null;
338
+ /** The look set on the element, over its channel's. */
339
+ #look: WidgetLook | null = null;
340
+ /** The web channel its publishable key belongs to, as read for that key (null while read). */
341
+ #channel: { key: string; config: WidgetConfig | null } | null = null;
342
+ /** The page's type and ink as last given to the widget. */
343
+ #adopted = "";
344
+ #unwatch: (() => void) | null = null;
345
+
346
+ /** The page's own stylesheet for the widget: CSS, or the address of one (`stylesheet`). */
347
+ get stylesheet(): string | null {
348
+ return this.getAttribute("stylesheet");
349
+ }
350
+
351
+ set stylesheet(value: string | null) {
352
+ if (value === null) this.removeAttribute("stylesheet");
353
+ else this.setAttribute("stylesheet", value);
354
+ }
355
+
356
+ /** A look over its channel's (or the only one, with an `agent`); null: its channel's. */
357
+ get look(): WidgetLook | null {
358
+ return this.#look;
359
+ }
360
+
361
+ set look(value: WidgetLook | null) {
362
+ this.#look = value;
363
+ this.#draw();
364
+ }
365
+
366
+ connectedCallback() {
367
+ this.#mount ??= this.#build();
368
+ this.#root = createRoot(this.#mount);
369
+ this.#unwatch = this.#watch();
370
+ this.#draw();
371
+ }
372
+
373
+ disconnectedCallback() {
374
+ this.#unwatch?.();
375
+ this.#unwatch = null;
376
+ this.#root?.unmount();
377
+ this.#root = null;
378
+ }
379
+
380
+ attributeChangedCallback() {
381
+ this.#draw();
382
+ }
383
+
384
+ /**
385
+ * Where the widget draws (and the kit's panels go): in a shadow root after the package's styles,
386
+ * or (`shadow="none"`, read once, as the element first connects) in the element itself.
387
+ */
388
+ #build(): HTMLElement {
389
+ const mount = document.createElement("div");
390
+ mount.setAttribute("data-sc-portal", "");
391
+ mount.setAttribute("data-sc-widget", "");
392
+ if (this.getAttribute("shadow") === "none") {
393
+ stylePage();
394
+ this.append(mount);
395
+ return mount;
396
+ }
397
+ const shadow = this.attachShadow({ mode: "open" });
398
+ const style = document.createElement("style");
399
+ style.textContent = `${styles}\n${own}`;
400
+ shadow.append(style, mount);
401
+ return mount;
402
+ }
403
+
404
+ /**
405
+ * Follows the page: its type and ink again whenever `<html>` or `<body>` change (a class that
406
+ * makes it dark, say) and when the system's scheme does.
407
+ */
408
+ #watch(): () => void {
409
+ const adopt = () => {
410
+ this.#adopt();
411
+ };
412
+ const observer = new MutationObserver(adopt);
413
+ for (const node of [document.documentElement, document.body]) {
414
+ if (node) observer.observe(node, { attributes: true });
415
+ }
416
+ const scheme =
417
+ typeof window.matchMedia === "function"
418
+ ? window.matchMedia("(prefers-color-scheme: dark)")
419
+ : null;
420
+ scheme?.addEventListener("change", adopt);
421
+ return () => {
422
+ observer.disconnect();
423
+ scheme?.removeEventListener("change", adopt);
424
+ };
425
+ }
426
+
427
+ /** The look it wears: the one set on it, else its channel's, else none. */
428
+ get #worn(): WidgetLook | null {
429
+ return this.#look ?? this.#channel?.config?.appearance ?? null;
430
+ }
431
+
432
+ /**
433
+ * The page's type and ink, as the element inherits them, given to the widget for its defaults
434
+ * (`--_host-font`, `--_host-font-size`, `--_host-fg`); and its dark palette where the page
435
+ * names no scheme but its text is light. A theme named (`theme`, or the look's) wears its own
436
+ * ink, not the page's.
437
+ */
438
+ #adopt() {
439
+ const mount = this.#mount;
440
+ if (mount === null) return;
441
+ const page = getComputedStyle(this);
442
+ const themed = this.hasAttribute("theme") || (this.#worn?.theme ?? "auto") !== "auto";
443
+ const dark = !themed && darkByInk(page.colorScheme, page.color);
444
+ const adopted = [page.fontFamily, page.fontSize, page.color, dark, themed].join("|");
445
+ if (adopted === this.#adopted) return;
446
+ this.#adopted = adopted;
447
+ mount.style.setProperty("--_host-font", page.fontFamily);
448
+ mount.style.setProperty("--_host-font-size", page.fontSize);
449
+ if (themed) mount.style.removeProperty("--_host-fg");
450
+ else mount.style.setProperty("--_host-fg", page.color);
451
+ if (dark) mount.setAttribute("data-scheme", "dark");
452
+ else mount.removeAttribute("data-scheme");
453
+ }
454
+
455
+ /**
456
+ * Its look as a stylesheet (and its face loaded), then the page's own stylesheet beside ours
457
+ * (`stylesheet`), and ours bare (`unstyled`).
458
+ */
459
+ #dress() {
460
+ const mount = this.#mount;
461
+ if (mount === null) return;
462
+ mount.toggleAttribute("data-sc-unstyled", on(this, "unstyled"));
463
+ this.#wear(mount, this.#worn);
464
+ const from = this.getAttribute("stylesheet")?.trim() || null;
465
+ if (from === (this.#sheet?.from ?? null)) return;
466
+ this.#sheet?.element.remove();
467
+ this.#sheet = null;
468
+ if (from === null) return;
469
+ const element = isCss(from) ? cssOf(from) : linkTo(from);
470
+ // After ours, so it wins where it says the same as loudly.
471
+ mount.before(element);
472
+ this.#sheet = { from, element };
473
+ }
474
+
475
+ #wear(mount: HTMLElement, look: WidgetLook | null) {
476
+ if (look?.font) loadFont(look.font);
477
+ const css = look === null ? "" : lookCss(look, this.shadowRoot === null ? TAG : ":host");
478
+ if (css === "") {
479
+ this.#lookSheet?.remove();
480
+ this.#lookSheet = null;
481
+ return;
482
+ }
483
+ this.#lookSheet ??= document.createElement("style");
484
+ if (this.#lookSheet.textContent !== css) this.#lookSheet.textContent = css;
485
+ // After ours and before the page's own, which wins over it.
486
+ if (!this.#lookSheet.isConnected) (this.#sheet?.element ?? mount).before(this.#lookSheet);
487
+ }
488
+
489
+ /**
490
+ * Its web channel's agent and look, read once for its key: null while read, and when it has
491
+ * an `agent` of its own (it needs no channel then).
492
+ */
493
+ #channelOf(settings: WidgetSettings): WidgetConfig | null {
494
+ const key = settings.credential.publishableKey;
495
+ if (settings.agent !== null || key === undefined) return null;
496
+ if (this.#channel?.key === key) return this.#channel.config;
497
+ this.#channel = { key, config: null };
498
+ createClient({ baseUrl: settings.baseUrl, publishableKey: key })
499
+ .widget()
500
+ .then(
501
+ (config) => {
502
+ if (this.#channel?.key !== key) return;
503
+ this.#channel = { key, config };
504
+ this.#draw();
505
+ },
506
+ (error: unknown) => {
507
+ console.warn(`<${TAG}> could not read its web channel`, error);
508
+ },
509
+ );
510
+ return null;
511
+ }
512
+
513
+ #draw() {
514
+ if (this.#root === null) return;
515
+ const settings = settingsOf(this);
516
+ const config = settings && this.#channelOf(settings);
517
+ this.#adopt();
518
+ this.#dress();
519
+ if (settings === null) {
520
+ console.warn(`<${TAG}> needs base-url, and an agent or a publishable key`);
521
+ }
522
+ const agent = settings?.agent ?? config?.agent_id ?? null;
523
+ this.#root.render(
524
+ settings && agent && <Widget settings={{ ...settings, agent }} look={this.#worn} />,
525
+ );
526
+ }
527
+ }
528
+
529
+ /** Registers `<signalcore-chat>`, once however often it is asked. */
530
+ export function defineSignalCoreChat(): CustomElementConstructor {
531
+ const known = customElements.get(TAG);
532
+ if (known) return known;
533
+ customElements.define(TAG, SignalCoreChat);
534
+ return SignalCoreChat;
535
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The widget's script (`dist/widget.js`): React and the package in one file, which registers
3
+ * `<signalcore-chat>` as it loads. A page puts the element where it wants it, or, with the one
4
+ * line a web channel gives, lets the script put it (`mountFromScript`).
5
+ */
6
+ import { defineSignalCoreChat } from "./element";
7
+ import { mountFromScript } from "./mount";
8
+
9
+ defineSignalCoreChat();
10
+ mountFromScript(document.currentScript);
@@ -0,0 +1,27 @@
1
+ import { TAG } from "./element";
2
+
3
+ /**
4
+ * The web channel's one line, `<script src="https://signalcore.ai/v1/widget.js" data-key="pk_…"
5
+ * async>`: the script puts the widget on the page itself, speaking to the API it was loaded from
6
+ * with that key, which names the agent and the look. `data-locale` and `data-theme` say what
7
+ * the element's `locale` and `theme` would. Once per key, however often the line is pasted.
8
+ */
9
+ export function mountFromScript(script: HTMLOrSVGScriptElement | null): HTMLElement | null {
10
+ if (!(script instanceof HTMLScriptElement)) return null;
11
+ const key = script.dataset.key;
12
+ if (!key || !script.src) return null;
13
+ if (document.querySelector(`${TAG}[publishable-key="${CSS.escape(key)}"]`) !== null) return null;
14
+ const element = document.createElement(TAG);
15
+ element.setAttribute("base-url", `${new URL(script.src).origin}/v1`);
16
+ element.setAttribute("publishable-key", key);
17
+ for (const name of ["locale", "theme"] as const) {
18
+ const value = script.dataset[name];
19
+ if (value) element.setAttribute(name, value);
20
+ }
21
+ const place = () => {
22
+ document.body.append(element);
23
+ };
24
+ if (document.body === null) document.addEventListener("DOMContentLoaded", place, { once: true });
25
+ else place();
26
+ return element;
27
+ }