@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,292 @@
1
+ //#region src/browser.ts
2
+ /** The action that hands the person the browser; the turn waits on it until they give it back. */
3
+ const HAND_OVER = "browser_hand_over";
4
+ function createScreen() {
5
+ let latest = null;
6
+ const listeners = /* @__PURE__ */ new Set();
7
+ return {
8
+ show: (frame) => {
9
+ latest = frame;
10
+ for (const listener of listeners) listener(frame);
11
+ },
12
+ clear: () => {
13
+ latest = null;
14
+ },
15
+ watch: (listener) => {
16
+ listeners.add(listener);
17
+ if (latest) listener(latest);
18
+ return () => {
19
+ listeners.delete(listener);
20
+ };
21
+ }
22
+ };
23
+ }
24
+ /**
25
+ * The hand-over the turn waits on (its step's id) when the browser it handed over is no longer
26
+ * there to give back: the person can still go on.
27
+ */
28
+ function handOverWaiting(messages, awaiting) {
29
+ if (awaiting === null) return null;
30
+ return messages.flatMap((message) => message.steps).find((one) => one.id === awaiting)?.action === "browser_hand_over" ? awaiting : null;
31
+ }
32
+ /** "es.wikipedia.org" and the rest of the address apart, for an address bar; nothing for a blank page. */
33
+ function siteOf(url) {
34
+ try {
35
+ const { protocol, host, pathname, search } = new URL(url);
36
+ if (!protocol.startsWith("http")) return {
37
+ host: "",
38
+ rest: ""
39
+ };
40
+ return {
41
+ host,
42
+ rest: pathname === "/" && !search ? "" : `${pathname}${search}`
43
+ };
44
+ } catch {
45
+ return {
46
+ host: "",
47
+ rest: ""
48
+ };
49
+ }
50
+ }
51
+ /** Where a pointer event is on the page: scaled from the element as shown, kept inside it. */
52
+ function pointOf(event, box, size) {
53
+ const along = (at, from, shown, real) => shown > 0 ? Math.round(Math.min(Math.max((at - from) / shown, 0), 1) * real) : 0;
54
+ return {
55
+ x: along(event.clientX, box.left, box.width, size.width),
56
+ y: along(event.clientY, box.top, box.height, size.height)
57
+ };
58
+ }
59
+ /** DevTools' mask of the keys held with another: Alt 1, Ctrl 2, Meta 4, Shift 8. */
60
+ function modifiersOf(event) {
61
+ return (event.altKey ? 1 : 0) | (event.ctrlKey ? 2 : 0) | (event.metaKey ? 4 : 0) | (event.shiftKey ? 8 : 0);
62
+ }
63
+ /**
64
+ * A key as the browser takes it; nothing for a key that stays here: Tab (the focus leaves the
65
+ * screen) and paste (the text comes in its own event, from this computer's clipboard).
66
+ */
67
+ function keyOf(event, action) {
68
+ if (event.key === "Tab") return null;
69
+ if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "v") return null;
70
+ return {
71
+ kind: "key",
72
+ action,
73
+ key: event.key.slice(0, 32),
74
+ code: event.code.slice(0, 32),
75
+ keyCode: Math.min(Math.max(event.keyCode, 0), 255),
76
+ modifiers: modifiersOf(event)
77
+ };
78
+ }
79
+ const BUTTONS = {
80
+ 0: "left",
81
+ 1: "middle",
82
+ 2: "right"
83
+ };
84
+ const MOVE_EVERY_MS = 40;
85
+ const WHEEL_EVERY_MS = 50;
86
+ const LINE_PX = 16;
87
+ const MAX_DELTA = 1e4;
88
+ const MAX_PASTE = 4e3;
89
+ const clamp = (value, limit) => Math.min(Math.max(value, -limit), limit);
90
+ /**
91
+ * Sends what the person does on `element` (the screen) to `send`, in the page's pixels; the
92
+ * returned function stops it. The pointer goes as down, move and up (drags and double clicks
93
+ * work as on the page; a drag that leaves the screen still ends), the wheel as wheel (the page
94
+ * around does not scroll; the turns of `WHEEL_EVERY_MS` summed into one), keys while the screen
95
+ * has the focus, and text pasted there as text. A key still held when the focus goes is let go.
96
+ * The context menu is the page's.
97
+ */
98
+ function capture(element, size, send) {
99
+ const held = /* @__PURE__ */ new Map();
100
+ let lastMove = Number.NEGATIVE_INFINITY;
101
+ const at = (event) => pointOf(event, element.getBoundingClientRect(), size);
102
+ const turned = {
103
+ x: 0,
104
+ y: 0,
105
+ dx: 0,
106
+ dy: 0
107
+ };
108
+ let lastWheel = Number.NEGATIVE_INFINITY;
109
+ let wheelTimer;
110
+ const flushWheel = () => {
111
+ wheelTimer = void 0;
112
+ lastWheel = performance.now();
113
+ const { x, y, dx, dy } = turned;
114
+ turned.dx = 0;
115
+ turned.dy = 0;
116
+ if (dx !== 0 || dy !== 0) send({
117
+ kind: "wheel",
118
+ x,
119
+ y,
120
+ dx: clamp(dx, MAX_DELTA),
121
+ dy: clamp(dy, MAX_DELTA)
122
+ });
123
+ };
124
+ const down = (event) => {
125
+ const button = BUTTONS[event.button];
126
+ if (!button) return;
127
+ event.preventDefault();
128
+ element.focus({ preventScroll: true });
129
+ element.setPointerCapture(event.pointerId);
130
+ const clicks = Math.min(Math.max(event.detail, 1), 3);
131
+ send({
132
+ kind: "mouse",
133
+ action: "down",
134
+ ...at(event),
135
+ button,
136
+ clicks
137
+ });
138
+ };
139
+ const up = (event) => {
140
+ const button = BUTTONS[event.button];
141
+ if (!button) return;
142
+ const clicks = Math.min(Math.max(event.detail, 1), 3);
143
+ send({
144
+ kind: "mouse",
145
+ action: "up",
146
+ ...at(event),
147
+ button,
148
+ clicks
149
+ });
150
+ };
151
+ const move = (event) => {
152
+ if (event.timeStamp - lastMove < MOVE_EVERY_MS) return;
153
+ lastMove = event.timeStamp;
154
+ send({
155
+ kind: "mouse",
156
+ action: "move",
157
+ ...at(event)
158
+ });
159
+ };
160
+ const wheel = (event) => {
161
+ event.preventDefault();
162
+ const unit = event.deltaMode === 1 ? LINE_PX : event.deltaMode === 2 ? size.height : 1;
163
+ Object.assign(turned, at(event));
164
+ turned.dx += event.deltaX * unit;
165
+ turned.dy += event.deltaY * unit;
166
+ if (wheelTimer !== void 0) return;
167
+ const wait = lastWheel + WHEEL_EVERY_MS - performance.now();
168
+ if (wait <= 0) flushWheel();
169
+ else wheelTimer = setTimeout(flushWheel, wait);
170
+ };
171
+ const keyed = (action) => (event) => {
172
+ if (event.isComposing) return;
173
+ const key = keyOf(event, action);
174
+ if (!key) return;
175
+ event.preventDefault();
176
+ if (action === "down") held.set(event.code || event.key, {
177
+ ...key,
178
+ action: "up"
179
+ });
180
+ else held.delete(event.code || event.key);
181
+ send(key);
182
+ };
183
+ const paste = (event) => {
184
+ const text = event.clipboardData?.getData("text/plain") ?? "";
185
+ if (text === "") return;
186
+ event.preventDefault();
187
+ send({
188
+ kind: "paste",
189
+ text: text.slice(0, MAX_PASTE)
190
+ });
191
+ };
192
+ const letGo = () => {
193
+ for (const key of held.values()) send(key);
194
+ held.clear();
195
+ };
196
+ const noMenu = (event) => {
197
+ event.preventDefault();
198
+ };
199
+ const keyDown = keyed("down");
200
+ const keyUp = keyed("up");
201
+ element.addEventListener("pointerdown", down);
202
+ element.addEventListener("pointerup", up);
203
+ element.addEventListener("pointermove", move);
204
+ element.addEventListener("wheel", wheel, { passive: false });
205
+ element.addEventListener("keydown", keyDown);
206
+ element.addEventListener("keyup", keyUp);
207
+ element.addEventListener("paste", paste);
208
+ element.addEventListener("blur", letGo);
209
+ element.addEventListener("contextmenu", noMenu);
210
+ return () => {
211
+ clearTimeout(wheelTimer);
212
+ element.removeEventListener("pointerdown", down);
213
+ element.removeEventListener("pointerup", up);
214
+ element.removeEventListener("pointermove", move);
215
+ element.removeEventListener("wheel", wheel);
216
+ element.removeEventListener("keydown", keyDown);
217
+ element.removeEventListener("keyup", keyUp);
218
+ element.removeEventListener("paste", paste);
219
+ element.removeEventListener("blur", letGo);
220
+ element.removeEventListener("contextmenu", noMenu);
221
+ };
222
+ }
223
+ /**
224
+ * The bytes in a base64 string: the platform's own decoder where it has one, else a plain loop
225
+ * (`Uint8Array.from` with a mapper walks a frame's 100,000 characters through an iterator, a
226
+ * callback each, on the main thread, as the next picture is due).
227
+ */
228
+ function bytesOf(base64) {
229
+ const native = Uint8Array.fromBase64;
230
+ if (native) return native(base64);
231
+ const text = atob(base64);
232
+ const bytes = new Uint8Array(text.length);
233
+ for (let at = 0; at < text.length; at += 1) bytes[at] = text.charCodeAt(at);
234
+ return bytes;
235
+ }
236
+ /**
237
+ * Paints JPEGs (base64) on `canvas`, stretched to its size, v2's way: decoded off the main thread
238
+ * (`createImageBitmap`), one at a time, and drawn on the screen's next frame, so a picture never
239
+ * lands mid-paint. A picture that comes while another is being decoded waits, and a newer one
240
+ * replaces it, as a newer decoded one replaces one not drawn yet: a slow device skips to the
241
+ * present instead of falling behind. The canvas keeps the last picture until the next is ready,
242
+ * so it never flickers; one that does not decode is skipped. `onPaint` hears each one drawn.
243
+ */
244
+ function painterOn(canvas, onPaint) {
245
+ let decoding = false;
246
+ let waiting;
247
+ let ready;
248
+ let frame = 0;
249
+ let disposed = false;
250
+ const draw = () => {
251
+ frame = 0;
252
+ const bitmap = ready;
253
+ ready = void 0;
254
+ if (!bitmap) return;
255
+ canvas.getContext("2d")?.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
256
+ bitmap.close();
257
+ onPaint?.();
258
+ };
259
+ const decode = async (jpeg) => {
260
+ decoding = true;
261
+ try {
262
+ const bitmap = await createImageBitmap(new Blob([bytesOf(jpeg)], { type: "image/jpeg" }));
263
+ if (disposed) bitmap.close();
264
+ else {
265
+ ready?.close();
266
+ ready = bitmap;
267
+ if (frame === 0) frame = requestAnimationFrame(draw);
268
+ }
269
+ } catch {}
270
+ decoding = false;
271
+ const next = waiting;
272
+ waiting = void 0;
273
+ if (next !== void 0 && !disposed) await decode(next);
274
+ };
275
+ return {
276
+ paint: (jpeg) => {
277
+ if (decoding) waiting = jpeg;
278
+ else decode(jpeg);
279
+ },
280
+ dispose: () => {
281
+ disposed = true;
282
+ waiting = void 0;
283
+ if (frame !== 0) cancelAnimationFrame(frame);
284
+ ready?.close();
285
+ ready = void 0;
286
+ }
287
+ };
288
+ }
289
+ //#endregion
290
+ export { HAND_OVER, bytesOf, capture, createScreen, handOverWaiting, keyOf, modifiersOf, painterOn, pointOf, siteOf };
291
+
292
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","names":[],"sources":["../src/browser.ts"],"sourcesContent":["/**\n * The conversation's browser, apart from how it is drawn: its screen as pictures to watch, the\n * person's pointer and keys as the input it takes, and where it is in a few words.\n */\n\nimport type { BrowserFrame, BrowserInput, Message } from \"./types\";\n\n/** The action that hands the person the browser; the turn waits on it until they give it back. */\nexport const HAND_OVER = \"browser_hand_over\";\n\n/**\n * The browser's screen as it comes: the latest picture, and whoever watches. Kept out of the\n * conversation's state, so a picture repaints a canvas and nothing else.\n */\nexport interface Screen {\n /** A new picture: each watcher hears it. */\n show: (frame: BrowserFrame) => void;\n /** The browser closed: no picture any more. */\n clear: () => void;\n /** Hears each picture from now on, the latest at once; returns how to stop. */\n watch: (listener: (frame: BrowserFrame) => void) => () => void;\n}\n\nexport function createScreen(): Screen {\n let latest: BrowserFrame | null = null;\n const listeners = new Set<(frame: BrowserFrame) => void>();\n return {\n show: (frame) => {\n latest = frame;\n for (const listener of listeners) listener(frame);\n },\n clear: () => {\n latest = null;\n },\n watch: (listener) => {\n listeners.add(listener);\n if (latest) listener(latest);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\n/**\n * The hand-over the turn waits on (its step's id) when the browser it handed over is no longer\n * there to give back: the person can still go on.\n */\nexport function handOverWaiting(\n messages: readonly Message[],\n awaiting: string | null,\n): string | null {\n if (awaiting === null) return null;\n const step = messages.flatMap((message) => message.steps).find((one) => one.id === awaiting);\n return step?.action === HAND_OVER ? awaiting : null;\n}\n\n/** \"es.wikipedia.org\" and the rest of the address apart, for an address bar; nothing for a blank page. */\nexport function siteOf(url: string): { host: string; rest: string } {\n try {\n const { protocol, host, pathname, search } = new URL(url);\n if (!protocol.startsWith(\"http\")) return { host: \"\", rest: \"\" };\n return { host, rest: pathname === \"/\" && !search ? \"\" : `${pathname}${search}` };\n } catch {\n return { host: \"\", rest: \"\" };\n }\n}\n\nexport interface Size {\n width: number;\n height: number;\n}\n\n/** Where a pointer event is on the page: scaled from the element as shown, kept inside it. */\nexport function pointOf(\n event: { clientX: number; clientY: number },\n box: { left: number; top: number; width: number; height: number },\n size: Size,\n): { x: number; y: number } {\n const along = (at: number, from: number, shown: number, real: number) =>\n shown > 0 ? Math.round(Math.min(Math.max((at - from) / shown, 0), 1) * real) : 0;\n return {\n x: along(event.clientX, box.left, box.width, size.width),\n y: along(event.clientY, box.top, box.height, size.height),\n };\n}\n\n/** DevTools' mask of the keys held with another: Alt 1, Ctrl 2, Meta 4, Shift 8. */\nexport function modifiersOf(event: {\n altKey: boolean;\n ctrlKey: boolean;\n metaKey: boolean;\n shiftKey: boolean;\n}): number {\n return (\n (event.altKey ? 1 : 0) |\n (event.ctrlKey ? 2 : 0) |\n (event.metaKey ? 4 : 0) |\n (event.shiftKey ? 8 : 0)\n );\n}\n\ntype KeyInput = Extract<BrowserInput, { kind: \"key\" }>;\n\n/**\n * A key as the browser takes it; nothing for a key that stays here: Tab (the focus leaves the\n * screen) and paste (the text comes in its own event, from this computer's clipboard).\n */\nexport function keyOf(\n event: Pick<\n KeyboardEvent,\n \"key\" | \"code\" | \"keyCode\" | \"altKey\" | \"ctrlKey\" | \"metaKey\" | \"shiftKey\"\n >,\n action: \"down\" | \"up\",\n): KeyInput | null {\n if (event.key === \"Tab\") return null;\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === \"v\") return null;\n return {\n kind: \"key\",\n action,\n key: event.key.slice(0, 32),\n code: event.code.slice(0, 32),\n keyCode: Math.min(Math.max(event.keyCode, 0), 255),\n modifiers: modifiersOf(event),\n };\n}\n\nconst BUTTONS: Readonly<Record<number, \"left\" | \"middle\" | \"right\">> = {\n 0: \"left\",\n 1: \"middle\",\n 2: \"right\",\n};\nconst MOVE_EVERY_MS = 40; // where the pointer is, 25 times a second at most\n// A trackpad fires the wheel 60 times a second, and each one waits on the hosted browser: what\n// turns within this long goes as one, so the page keeps up with the hand instead of trailing it.\nconst WHEEL_EVERY_MS = 50;\nconst LINE_PX = 16; // a wheel that scrolls by lines, in pixels\nconst MAX_DELTA = 10_000;\nconst MAX_PASTE = 4_000;\n\nconst clamp = (value: number, limit: number) => Math.min(Math.max(value, -limit), limit);\n\n/**\n * Sends what the person does on `element` (the screen) to `send`, in the page's pixels; the\n * returned function stops it. The pointer goes as down, move and up (drags and double clicks\n * work as on the page; a drag that leaves the screen still ends), the wheel as wheel (the page\n * around does not scroll; the turns of `WHEEL_EVERY_MS` summed into one), keys while the screen\n * has the focus, and text pasted there as text. A key still held when the focus goes is let go.\n * The context menu is the page's.\n */\nexport function capture(\n element: HTMLElement,\n size: Size,\n send: (input: BrowserInput) => void,\n): () => void {\n const held = new Map<string, KeyInput>();\n let lastMove = Number.NEGATIVE_INFINITY;\n const at = (event: { clientX: number; clientY: number }) =>\n pointOf(event, element.getBoundingClientRect(), size);\n // The wheel's turns not sent yet, where the pointer was, and when the last went.\n const turned = { x: 0, y: 0, dx: 0, dy: 0 };\n let lastWheel = Number.NEGATIVE_INFINITY;\n let wheelTimer: ReturnType<typeof setTimeout> | undefined;\n const flushWheel = () => {\n wheelTimer = undefined;\n lastWheel = performance.now();\n const { x, y, dx, dy } = turned;\n turned.dx = 0;\n turned.dy = 0;\n if (dx !== 0 || dy !== 0) {\n send({ kind: \"wheel\", x, y, dx: clamp(dx, MAX_DELTA), dy: clamp(dy, MAX_DELTA) });\n }\n };\n\n const down = (event: PointerEvent) => {\n const button = BUTTONS[event.button];\n if (!button) return;\n event.preventDefault(); // the page would select the screen, and keep the focus where it was\n element.focus({ preventScroll: true });\n element.setPointerCapture(event.pointerId);\n const clicks = Math.min(Math.max(event.detail, 1), 3);\n send({ kind: \"mouse\", action: \"down\", ...at(event), button, clicks });\n };\n const up = (event: PointerEvent) => {\n const button = BUTTONS[event.button];\n if (!button) return;\n const clicks = Math.min(Math.max(event.detail, 1), 3);\n send({ kind: \"mouse\", action: \"up\", ...at(event), button, clicks });\n };\n const move = (event: PointerEvent) => {\n if (event.timeStamp - lastMove < MOVE_EVERY_MS) return;\n lastMove = event.timeStamp;\n send({ kind: \"mouse\", action: \"move\", ...at(event) });\n };\n const wheel = (event: WheelEvent) => {\n event.preventDefault();\n const unit = event.deltaMode === 1 ? LINE_PX : event.deltaMode === 2 ? size.height : 1;\n Object.assign(turned, at(event));\n turned.dx += event.deltaX * unit;\n turned.dy += event.deltaY * unit;\n if (wheelTimer !== undefined) return;\n // The first turn goes at once; what follows it within the window, together at its end.\n const wait = lastWheel + WHEEL_EVERY_MS - performance.now();\n if (wait <= 0) flushWheel();\n else wheelTimer = setTimeout(flushWheel, wait);\n };\n const keyed = (action: \"down\" | \"up\") => (event: KeyboardEvent) => {\n if (event.isComposing) return;\n const key = keyOf(event, action);\n if (!key) return;\n event.preventDefault();\n if (action === \"down\") held.set(event.code || event.key, { ...key, action: \"up\" });\n else held.delete(event.code || event.key);\n send(key);\n };\n const paste = (event: ClipboardEvent) => {\n const text = event.clipboardData?.getData(\"text/plain\") ?? \"\";\n if (text === \"\") return;\n event.preventDefault();\n send({ kind: \"paste\", text: text.slice(0, MAX_PASTE) });\n };\n const letGo = () => {\n for (const key of held.values()) send(key);\n held.clear();\n };\n const noMenu = (event: Event) => {\n event.preventDefault();\n };\n const keyDown = keyed(\"down\");\n const keyUp = keyed(\"up\");\n\n element.addEventListener(\"pointerdown\", down);\n element.addEventListener(\"pointerup\", up);\n element.addEventListener(\"pointermove\", move);\n element.addEventListener(\"wheel\", wheel, { passive: false });\n element.addEventListener(\"keydown\", keyDown);\n element.addEventListener(\"keyup\", keyUp);\n element.addEventListener(\"paste\", paste);\n element.addEventListener(\"blur\", letGo);\n element.addEventListener(\"contextmenu\", noMenu);\n return () => {\n clearTimeout(wheelTimer);\n element.removeEventListener(\"pointerdown\", down);\n element.removeEventListener(\"pointerup\", up);\n element.removeEventListener(\"pointermove\", move);\n element.removeEventListener(\"wheel\", wheel);\n element.removeEventListener(\"keydown\", keyDown);\n element.removeEventListener(\"keyup\", keyUp);\n element.removeEventListener(\"paste\", paste);\n element.removeEventListener(\"blur\", letGo);\n element.removeEventListener(\"contextmenu\", noMenu);\n };\n}\n\n/**\n * The bytes in a base64 string: the platform's own decoder where it has one, else a plain loop\n * (`Uint8Array.from` with a mapper walks a frame's 100,000 characters through an iterator, a\n * callback each, on the main thread, as the next picture is due).\n */\nexport function bytesOf(base64: string): Uint8Array<ArrayBuffer> {\n const native = (Uint8Array as { fromBase64?: (text: string) => Uint8Array<ArrayBuffer> })\n .fromBase64;\n if (native) return native(base64);\n const text = atob(base64);\n const bytes = new Uint8Array(text.length);\n for (let at = 0; at < text.length; at += 1) bytes[at] = text.charCodeAt(at);\n return bytes;\n}\n\n/** Draws a picture on a canvas, unless a newer one comes while it is still being decoded. */\nexport interface Painter {\n paint: (jpeg: string) => void;\n dispose: () => void;\n}\n\n/**\n * Paints JPEGs (base64) on `canvas`, stretched to its size, v2's way: decoded off the main thread\n * (`createImageBitmap`), one at a time, and drawn on the screen's next frame, so a picture never\n * lands mid-paint. A picture that comes while another is being decoded waits, and a newer one\n * replaces it, as a newer decoded one replaces one not drawn yet: a slow device skips to the\n * present instead of falling behind. The canvas keeps the last picture until the next is ready,\n * so it never flickers; one that does not decode is skipped. `onPaint` hears each one drawn.\n */\nexport function painterOn(canvas: HTMLCanvasElement, onPaint?: () => void): Painter {\n let decoding = false;\n let waiting: string | undefined;\n let ready: ImageBitmap | undefined; // decoded, for the next frame\n let frame = 0; // the animation frame asked for, if one is\n let disposed = false;\n\n const draw = () => {\n frame = 0;\n const bitmap = ready;\n ready = undefined;\n if (!bitmap) return;\n canvas.getContext(\"2d\")?.drawImage(bitmap, 0, 0, canvas.width, canvas.height);\n bitmap.close();\n onPaint?.();\n };\n\n const decode = async (jpeg: string): Promise<void> => {\n decoding = true;\n try {\n const bitmap = await createImageBitmap(new Blob([bytesOf(jpeg)], { type: \"image/jpeg\" }));\n if (disposed) {\n bitmap.close();\n } else {\n ready?.close();\n ready = bitmap;\n if (frame === 0) frame = requestAnimationFrame(draw);\n }\n } catch {\n // Cut off or damaged: the next picture replaces it.\n }\n decoding = false;\n const next = waiting;\n waiting = undefined;\n if (next !== undefined && !disposed) await decode(next);\n };\n\n return {\n paint: (jpeg) => {\n if (decoding) waiting = jpeg;\n else void decode(jpeg);\n },\n dispose: () => {\n disposed = true;\n waiting = undefined;\n if (frame !== 0) cancelAnimationFrame(frame);\n ready?.close();\n ready = undefined;\n },\n };\n}\n"],"mappings":"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"}
package/dist/call.d.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { CallReason } from "./types.js";
2
+ import { OrbState } from "./voice/orbs.js";
3
+ //#region src/call.d.ts
4
+ /** What the agent is doing, as LiveKit's agents publish it (`lk.agent.state`). */
5
+ export type AgentActivity = "initializing" | "idle" | "listening" | "thinking" | "speaking";
6
+ /** Why a call that began is over. */
7
+ export type CallEndedBy =
8
+ /** The person hung up. */
9
+ "person" |
10
+ /** The agent did: it said one of its goodbyes. */
11
+ "agent" |
12
+ /** It reached its longest time. */
13
+ "limit" |
14
+ /** The line went: the network, or the agent's side fell. */
15
+ "dropped";
16
+ /** Why a call never began. */
17
+ export type CallProblem =
18
+ /** The person, or the browser, said no to the microphone. */
19
+ "denied" |
20
+ /** There is no microphone to use. */
21
+ "nomic" |
22
+ /** Another application holds the microphone. */
23
+ "inuse" |
24
+ /** This browser can't call: no microphone access at all (an old one, or a page not on https). */
25
+ "unsupported" |
26
+ /** Calls aren't set up where the agent works (the API refused with `no_calls`). */
27
+ "off" |
28
+ /** The agent takes no calls: a squad's builder (`builder`). */
29
+ "builder" |
30
+ /** The API wouldn't make the call, for any other reason it named. */
31
+ "refused" |
32
+ /** The call couldn't be made or joined. */
33
+ "failed" |
34
+ /** The room was there, but no agent came to it. */
35
+ "unanswered";
36
+ /** How a call ended: why, and how long it lasted from when the agent picked up. */
37
+ export interface CallEnd {
38
+ /**
39
+ * Why, as far as the room knows: null when the agent's side closed it (its goodbye, or its
40
+ * longest time), which only the API says (`endedByReason`).
41
+ */
42
+ by: CallEndedBy | null;
43
+ seconds: number;
44
+ }
45
+ /** Where a call stands. */
46
+ export interface CallState {
47
+ /** Opening the microphone and the room; ringing until the agent joins; on; over. */
48
+ stage: "opening" | "ringing" | "on" | "over";
49
+ /** When the agent joined, in ms; the call's time counts from it. */
50
+ answeredAt: number | null;
51
+ /** What the agent says it is doing; null while it says nothing. */
52
+ agent: AgentActivity | null;
53
+ /** Whether the agent's voice is coming, for an agent that doesn't say what it is doing. */
54
+ speaking: boolean;
55
+ /** The line is being found again; the call goes on once it is. */
56
+ reconnecting: boolean;
57
+ muted: boolean;
58
+ /** The browser holds the agent's voice until the person presses something. */
59
+ silenced: boolean;
60
+ end: CallEnd | null;
61
+ problem: CallProblem | null;
62
+ }
63
+ /** What the call shows, in one word: each has its words, its look and its orb. */
64
+ export type CallLook = "connecting" | "listening" | "thinking" | "speaking" | "reconnecting" | "ended" | "problem";
65
+ /**
66
+ * What the call shows now. Before the agent picks up, and while it starts, it is connecting;
67
+ * then what the agent says it is doing (an agent that says nothing is speaking while its voice
68
+ * comes, listening otherwise).
69
+ */
70
+ export declare function lookOf(state: CallState): CallLook;
71
+ /**
72
+ * What the orb shows of a call: what the agent is doing once the call is on, moved by whoever is
73
+ * speaking (the agent's voice while it speaks, the person's microphone while it listens); at rest
74
+ * while the line is found (connecting, reconnecting) and once the call is over.
75
+ */
76
+ export declare function orbOf(look: CallLook): {
77
+ state: OrbState;
78
+ follows: "agent" | "person" | null;
79
+ };
80
+ /**
81
+ * Why a call ended as the API keeps it (`CallGlance.reason`), as the call says it: the person hung
82
+ * up, the agent said goodbye, it reached its longest time; anything else (it failed, its end never
83
+ * came) is a line that dropped. Null while the API has no end for it yet.
84
+ */
85
+ export declare function endedByReason(reason: CallReason | null | undefined): CallEndedBy | null;
86
+ /** A call's time as a phone shows it: 0:07, 12:34, 1:02:03. */
87
+ export declare function durationOf(seconds: number): string;
88
+ //#endregion
89
+ //# sourceMappingURL=call.d.ts.map
package/dist/call.js ADDED
@@ -0,0 +1,218 @@
1
+ import { ApiError } from "./client.js";
2
+ //#region src/call.ts
3
+ /**
4
+ * A voice call with an agent, as the person on it sees it: where it stands, why it ended or
5
+ * never began, and how long it lasted. Pure, so it is tested without a room; `useCall` feeds it
6
+ * what LiveKit says.
7
+ */
8
+ const CALL_START = {
9
+ stage: "opening",
10
+ answeredAt: null,
11
+ agent: null,
12
+ speaking: false,
13
+ reconnecting: false,
14
+ muted: false,
15
+ silenced: false,
16
+ end: null,
17
+ problem: null
18
+ };
19
+ /**
20
+ * The call, one event at a time. Once over (ended, or never begun) nothing moves it again: the
21
+ * room's last words after a hang-up (its disconnect, a track going) are not news.
22
+ */
23
+ function callReducer(state, event) {
24
+ if (state.stage === "over") return state;
25
+ switch (event.type) {
26
+ case "ringing": return state.stage === "opening" ? {
27
+ ...state,
28
+ stage: "ringing"
29
+ } : state;
30
+ case "answered": return state.answeredAt === null ? {
31
+ ...state,
32
+ stage: "on",
33
+ answeredAt: event.at
34
+ } : state;
35
+ case "agent": return {
36
+ ...state,
37
+ agent: event.activity
38
+ };
39
+ case "speaking": return {
40
+ ...state,
41
+ speaking: event.speaking
42
+ };
43
+ case "reconnecting": return {
44
+ ...state,
45
+ reconnecting: event.reconnecting
46
+ };
47
+ case "muted": return {
48
+ ...state,
49
+ muted: event.muted
50
+ };
51
+ case "silenced": return {
52
+ ...state,
53
+ silenced: event.silenced
54
+ };
55
+ case "ended": {
56
+ const seconds = state.answeredAt === null ? 0 : secondsBetween(state.answeredAt, event.at);
57
+ return {
58
+ ...state,
59
+ stage: "over",
60
+ reconnecting: false,
61
+ end: {
62
+ by: event.by,
63
+ seconds
64
+ }
65
+ };
66
+ }
67
+ case "failed": return {
68
+ ...state,
69
+ stage: "over",
70
+ reconnecting: false,
71
+ problem: event.problem
72
+ };
73
+ }
74
+ }
75
+ const secondsBetween = (from, to) => Math.max(0, Math.floor((to - from) / 1e3));
76
+ /**
77
+ * What the call shows now. Before the agent picks up, and while it starts, it is connecting;
78
+ * then what the agent says it is doing (an agent that says nothing is speaking while its voice
79
+ * comes, listening otherwise).
80
+ */
81
+ function lookOf(state) {
82
+ if (state.problem !== null) return "problem";
83
+ if (state.end !== null) return "ended";
84
+ if (state.answeredAt === null || state.agent === "initializing") return "connecting";
85
+ if (state.reconnecting) return "reconnecting";
86
+ if (state.agent === "thinking" || state.agent === "speaking") return state.agent;
87
+ if (state.agent === null && state.speaking) return "speaking";
88
+ return "listening";
89
+ }
90
+ /**
91
+ * What the orb shows of a call: what the agent is doing once the call is on, moved by whoever is
92
+ * speaking (the agent's voice while it speaks, the person's microphone while it listens); at rest
93
+ * while the line is found (connecting, reconnecting) and once the call is over.
94
+ */
95
+ function orbOf(look) {
96
+ switch (look) {
97
+ case "speaking": return {
98
+ state: look,
99
+ follows: "agent"
100
+ };
101
+ case "listening": return {
102
+ state: look,
103
+ follows: "person"
104
+ };
105
+ case "thinking": return {
106
+ state: look,
107
+ follows: null
108
+ };
109
+ default: return {
110
+ state: "idle",
111
+ follows: null
112
+ };
113
+ }
114
+ }
115
+ /** The agent's state as LiveKit's agents publish it, or null for anything else. */
116
+ function activityOf(value) {
117
+ switch (value) {
118
+ case "initializing":
119
+ case "idle":
120
+ case "listening":
121
+ case "thinking":
122
+ case "speaking": return value;
123
+ default: return null;
124
+ }
125
+ }
126
+ /**
127
+ * Why the room let the person go, as LiveKit says it (`DisconnectReason`'s names): they hung up;
128
+ * the room was closed under them, which is the agent's side ending the call (its goodbye, or its
129
+ * longest time: null, the API says which); anything else, the line went.
130
+ */
131
+ function endedBy(reason, hungUp) {
132
+ if (hungUp || reason === "CLIENT_INITIATED") return "person";
133
+ if (reason === "ROOM_DELETED" || reason === "ROOM_CLOSED" || reason === "PARTICIPANT_REMOVED") return null;
134
+ return "dropped";
135
+ }
136
+ /**
137
+ * Why a call ended as the API keeps it (`CallGlance.reason`), as the call says it: the person hung
138
+ * up, the agent said goodbye, it reached its longest time; anything else (it failed, its end never
139
+ * came) is a line that dropped. Null while the API has no end for it yet.
140
+ */
141
+ function endedByReason(reason) {
142
+ switch (reason) {
143
+ case "caller": return "person";
144
+ case "agent": return "agent";
145
+ case "max_duration": return "limit";
146
+ case null:
147
+ case void 0: return null;
148
+ default: return "dropped";
149
+ }
150
+ }
151
+ /**
152
+ * Why a call couldn't be made, from what asking for it threw: the API's refusal, by its code
153
+ * (calls not set up where the agent works, an agent that takes none, any other it named);
154
+ * anything else (no answer, or one that named nothing) is a call that failed.
155
+ */
156
+ function refusalOf(error) {
157
+ if (!(error instanceof ApiError) || error.code === null) return "failed";
158
+ switch (error.code) {
159
+ case "no_calls": return "off";
160
+ case "builder": return "builder";
161
+ default: return "refused";
162
+ }
163
+ }
164
+ /**
165
+ * Why the microphone couldn't be opened, from the browser's error (`DOMException` names, as
166
+ * LiveKit reads them too); one the browser doesn't name is a call that failed.
167
+ */
168
+ function callProblemOf(error) {
169
+ switch (error instanceof Error || isNamed(error) ? error.name : "") {
170
+ case "NotAllowedError":
171
+ case "PermissionDeniedError":
172
+ case "SecurityError": return "denied";
173
+ case "NotFoundError":
174
+ case "DevicesNotFoundError":
175
+ case "OverconstrainedError": return "nomic";
176
+ case "NotReadableError":
177
+ case "TrackStartError":
178
+ case "AbortError": return "inuse";
179
+ default: return "failed";
180
+ }
181
+ }
182
+ const isNamed = (value) => typeof value === "object" && value !== null && "name" in value && typeof value.name === "string";
183
+ /** A call's time as a phone shows it: 0:07, 12:34, 1:02:03. */
184
+ function durationOf(seconds) {
185
+ const whole = Math.max(0, Math.floor(seconds));
186
+ const hours = Math.floor(whole / 3600);
187
+ const minutes = Math.floor(whole % 3600 / 60);
188
+ const rest = String(whole % 60).padStart(2, "0");
189
+ return hours > 0 ? `${hours}:${String(minutes).padStart(2, "0")}:${rest}` : `${minutes}:${rest}`;
190
+ }
191
+ /**
192
+ * A loudness read off a track (0 to 1, the root mean square of its spectrum as LiveKit measures
193
+ * it) as the orb shows it: speech sits low on that scale, so it is lifted and the floor of a quiet
194
+ * room cut away.
195
+ */
196
+ function loudness(volume) {
197
+ const lifted = (volume - FLOOR) / (1 - FLOOR);
198
+ return Math.min(1, Math.max(0, Math.sqrt(Math.max(0, lifted)) * GAIN));
199
+ }
200
+ const FLOOR = .04;
201
+ const GAIN = 1.25;
202
+ /**
203
+ * Whether a key belongs to what it was pressed on, not to the call: a field being typed in, or a
204
+ * control of the page's own (outside the call) that Space presses. Elsewhere (the call itself,
205
+ * the page, a dialog it sits in) Space mutes and unmutes.
206
+ */
207
+ function keyBelongsElsewhere(target, call) {
208
+ if (!(target instanceof Element)) return false;
209
+ if (target.matches(EDITABLE)) return true;
210
+ if (call?.contains(target)) return false;
211
+ return target.matches(PRESSABLE);
212
+ }
213
+ const EDITABLE = "input, textarea, select, [contenteditable]:not([contenteditable=\"false\"])";
214
+ const PRESSABLE = "button, a[href], summary, [role=\"button\"], [role=\"checkbox\"], [role=\"switch\"], [role=\"radio\"], [role=\"tab\"], [role=\"menuitem\"], [role=\"option\"], [role=\"slider\"]";
215
+ //#endregion
216
+ export { CALL_START, activityOf, callProblemOf, callReducer, durationOf, endedBy, endedByReason, keyBelongsElsewhere, lookOf, loudness, orbOf, refusalOf };
217
+
218
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","names":[],"sources":["../src/call.ts"],"sourcesContent":["/**\n * A voice call with an agent, as the person on it sees it: where it stands, why it ended or\n * never began, and how long it lasted. Pure, so it is tested without a room; `useCall` feeds it\n * what LiveKit says.\n */\n\nimport { ApiError } from \"./client\";\nimport type { CallReason } from \"./types\";\nimport type { OrbState } from \"./voice/orbs\";\n\n/** What the agent is doing, as LiveKit's agents publish it (`lk.agent.state`). */\nexport type AgentActivity = \"initializing\" | \"idle\" | \"listening\" | \"thinking\" | \"speaking\";\n\n/** Why a call that began is over. */\nexport type CallEndedBy =\n /** The person hung up. */\n | \"person\"\n /** The agent did: it said one of its goodbyes. */\n | \"agent\"\n /** It reached its longest time. */\n | \"limit\"\n /** The line went: the network, or the agent's side fell. */\n | \"dropped\";\n\n/** Why a call never began. */\nexport type CallProblem =\n /** The person, or the browser, said no to the microphone. */\n | \"denied\"\n /** There is no microphone to use. */\n | \"nomic\"\n /** Another application holds the microphone. */\n | \"inuse\"\n /** This browser can't call: no microphone access at all (an old one, or a page not on https). */\n | \"unsupported\"\n /** Calls aren't set up where the agent works (the API refused with `no_calls`). */\n | \"off\"\n /** The agent takes no calls: a squad's builder (`builder`). */\n | \"builder\"\n /** The API wouldn't make the call, for any other reason it named. */\n | \"refused\"\n /** The call couldn't be made or joined. */\n | \"failed\"\n /** The room was there, but no agent came to it. */\n | \"unanswered\";\n\n/** How a call ended: why, and how long it lasted from when the agent picked up. */\nexport interface CallEnd {\n /**\n * Why, as far as the room knows: null when the agent's side closed it (its goodbye, or its\n * longest time), which only the API says (`endedByReason`).\n */\n by: CallEndedBy | null;\n seconds: number;\n}\n\n/** Where a call stands. */\nexport interface CallState {\n /** Opening the microphone and the room; ringing until the agent joins; on; over. */\n stage: \"opening\" | \"ringing\" | \"on\" | \"over\";\n /** When the agent joined, in ms; the call's time counts from it. */\n answeredAt: number | null;\n /** What the agent says it is doing; null while it says nothing. */\n agent: AgentActivity | null;\n /** Whether the agent's voice is coming, for an agent that doesn't say what it is doing. */\n speaking: boolean;\n /** The line is being found again; the call goes on once it is. */\n reconnecting: boolean;\n muted: boolean;\n /** The browser holds the agent's voice until the person presses something. */\n silenced: boolean;\n end: CallEnd | null;\n problem: CallProblem | null;\n}\n\nexport const CALL_START: CallState = {\n stage: \"opening\",\n answeredAt: null,\n agent: null,\n speaking: false,\n reconnecting: false,\n muted: false,\n silenced: false,\n end: null,\n problem: null,\n};\n\n/** What moves a call, from the room. */\nexport type CallEvent =\n | { type: \"ringing\" }\n | { type: \"answered\"; at: number }\n | { type: \"agent\"; activity: AgentActivity | null }\n | { type: \"speaking\"; speaking: boolean }\n | { type: \"reconnecting\"; reconnecting: boolean }\n | { type: \"muted\"; muted: boolean }\n | { type: \"silenced\"; silenced: boolean }\n | { type: \"ended\"; by: CallEndedBy | null; at: number }\n | { type: \"failed\"; problem: CallProblem };\n\n/**\n * The call, one event at a time. Once over (ended, or never begun) nothing moves it again: the\n * room's last words after a hang-up (its disconnect, a track going) are not news.\n */\nexport function callReducer(state: CallState, event: CallEvent): CallState {\n if (state.stage === \"over\") return state;\n switch (event.type) {\n case \"ringing\":\n return state.stage === \"opening\" ? { ...state, stage: \"ringing\" } : state;\n case \"answered\":\n return state.answeredAt === null ? { ...state, stage: \"on\", answeredAt: event.at } : state;\n case \"agent\":\n return { ...state, agent: event.activity };\n case \"speaking\":\n return { ...state, speaking: event.speaking };\n case \"reconnecting\":\n return { ...state, reconnecting: event.reconnecting };\n case \"muted\":\n return { ...state, muted: event.muted };\n case \"silenced\":\n return { ...state, silenced: event.silenced };\n case \"ended\": {\n const seconds = state.answeredAt === null ? 0 : secondsBetween(state.answeredAt, event.at);\n return { ...state, stage: \"over\", reconnecting: false, end: { by: event.by, seconds } };\n }\n case \"failed\":\n return { ...state, stage: \"over\", reconnecting: false, problem: event.problem };\n }\n}\n\nconst secondsBetween = (from: number, to: number): number =>\n Math.max(0, Math.floor((to - from) / 1000));\n\n/** What the call shows, in one word: each has its words, its look and its orb. */\nexport type CallLook =\n \"connecting\" | \"listening\" | \"thinking\" | \"speaking\" | \"reconnecting\" | \"ended\" | \"problem\";\n\n/**\n * What the call shows now. Before the agent picks up, and while it starts, it is connecting;\n * then what the agent says it is doing (an agent that says nothing is speaking while its voice\n * comes, listening otherwise).\n */\nexport function lookOf(state: CallState): CallLook {\n if (state.problem !== null) return \"problem\";\n if (state.end !== null) return \"ended\";\n if (state.answeredAt === null || state.agent === \"initializing\") return \"connecting\";\n if (state.reconnecting) return \"reconnecting\";\n if (state.agent === \"thinking\" || state.agent === \"speaking\") return state.agent;\n if (state.agent === null && state.speaking) return \"speaking\";\n return \"listening\";\n}\n\n/**\n * What the orb shows of a call: what the agent is doing once the call is on, moved by whoever is\n * speaking (the agent's voice while it speaks, the person's microphone while it listens); at rest\n * while the line is found (connecting, reconnecting) and once the call is over.\n */\nexport function orbOf(look: CallLook): { state: OrbState; follows: \"agent\" | \"person\" | null } {\n switch (look) {\n case \"speaking\":\n return { state: look, follows: \"agent\" };\n case \"listening\":\n return { state: look, follows: \"person\" };\n case \"thinking\":\n return { state: look, follows: null };\n default:\n return { state: \"idle\", follows: null };\n }\n}\n\n/** The agent's state as LiveKit's agents publish it, or null for anything else. */\nexport function activityOf(value: string | undefined): AgentActivity | null {\n switch (value) {\n case \"initializing\":\n case \"idle\":\n case \"listening\":\n case \"thinking\":\n case \"speaking\":\n return value;\n default:\n return null;\n }\n}\n\n/**\n * Why the room let the person go, as LiveKit says it (`DisconnectReason`'s names): they hung up;\n * the room was closed under them, which is the agent's side ending the call (its goodbye, or its\n * longest time: null, the API says which); anything else, the line went.\n */\nexport function endedBy(reason: string | undefined, hungUp: boolean): CallEndedBy | null {\n if (hungUp || reason === \"CLIENT_INITIATED\") return \"person\";\n if (reason === \"ROOM_DELETED\" || reason === \"ROOM_CLOSED\" || reason === \"PARTICIPANT_REMOVED\") {\n return null;\n }\n return \"dropped\";\n}\n\n/**\n * Why a call ended as the API keeps it (`CallGlance.reason`), as the call says it: the person hung\n * up, the agent said goodbye, it reached its longest time; anything else (it failed, its end never\n * came) is a line that dropped. Null while the API has no end for it yet.\n */\nexport function endedByReason(reason: CallReason | null | undefined): CallEndedBy | null {\n switch (reason) {\n case \"caller\":\n return \"person\";\n case \"agent\":\n return \"agent\";\n case \"max_duration\":\n return \"limit\";\n case null:\n case undefined:\n return null;\n default:\n return \"dropped\";\n }\n}\n\n/**\n * Why a call couldn't be made, from what asking for it threw: the API's refusal, by its code\n * (calls not set up where the agent works, an agent that takes none, any other it named);\n * anything else (no answer, or one that named nothing) is a call that failed.\n */\nexport function refusalOf(error: unknown): CallProblem {\n if (!(error instanceof ApiError) || error.code === null) return \"failed\";\n switch (error.code) {\n case \"no_calls\":\n return \"off\";\n case \"builder\":\n return \"builder\";\n default:\n return \"refused\";\n }\n}\n\n/**\n * Why the microphone couldn't be opened, from the browser's error (`DOMException` names, as\n * LiveKit reads them too); one the browser doesn't name is a call that failed.\n */\nexport function callProblemOf(error: unknown): CallProblem {\n const name = error instanceof Error || isNamed(error) ? error.name : \"\";\n switch (name) {\n case \"NotAllowedError\":\n case \"PermissionDeniedError\":\n case \"SecurityError\":\n return \"denied\";\n case \"NotFoundError\":\n case \"DevicesNotFoundError\":\n case \"OverconstrainedError\":\n return \"nomic\";\n case \"NotReadableError\":\n case \"TrackStartError\":\n case \"AbortError\":\n return \"inuse\";\n default:\n return \"failed\";\n }\n}\n\nconst isNamed = (value: unknown): value is { name: string } =>\n typeof value === \"object\" &&\n value !== null &&\n \"name\" in value &&\n typeof (value as { name: unknown }).name === \"string\";\n\n/** A call's time as a phone shows it: 0:07, 12:34, 1:02:03. */\nexport function durationOf(seconds: number): string {\n const whole = Math.max(0, Math.floor(seconds));\n const hours = Math.floor(whole / 3600);\n const minutes = Math.floor((whole % 3600) / 60);\n const rest = String(whole % 60).padStart(2, \"0\");\n return hours > 0 ? `${hours}:${String(minutes).padStart(2, \"0\")}:${rest}` : `${minutes}:${rest}`;\n}\n\n/**\n * A loudness read off a track (0 to 1, the root mean square of its spectrum as LiveKit measures\n * it) as the orb shows it: speech sits low on that scale, so it is lifted and the floor of a quiet\n * room cut away.\n */\nexport function loudness(volume: number): number {\n const lifted = (volume - FLOOR) / (1 - FLOOR);\n return Math.min(1, Math.max(0, Math.sqrt(Math.max(0, lifted)) * GAIN));\n}\n\nconst FLOOR = 0.04;\nconst GAIN = 1.25;\n\n/**\n * Whether a key belongs to what it was pressed on, not to the call: a field being typed in, or a\n * control of the page's own (outside the call) that Space presses. Elsewhere (the call itself,\n * the page, a dialog it sits in) Space mutes and unmutes.\n */\nexport function keyBelongsElsewhere(target: EventTarget | null, call: Element | null): boolean {\n if (!(target instanceof Element)) return false;\n if (target.matches(EDITABLE)) return true;\n if (call?.contains(target)) return false;\n return target.matches(PRESSABLE);\n}\n\nconst EDITABLE = 'input, textarea, select, [contenteditable]:not([contenteditable=\"false\"])';\nconst PRESSABLE =\n 'button, a[href], summary, [role=\"button\"], [role=\"checkbox\"], [role=\"switch\"], [role=\"radio\"], [role=\"tab\"], [role=\"menuitem\"], [role=\"option\"], [role=\"slider\"]';\n"],"mappings":"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"}