react-cheminfo 0.64.1 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/README.md +282 -0
  2. package/lib/card/core/cardAddress.d.ts +70 -0
  3. package/lib/card/core/cardAddress.d.ts.map +1 -0
  4. package/lib/card/core/cardAddress.js +59 -0
  5. package/lib/card/core/cardAddress.js.map +1 -0
  6. package/lib/card/core/cardPageUrl.d.ts +49 -0
  7. package/lib/card/core/cardPageUrl.d.ts.map +1 -0
  8. package/lib/card/core/cardPageUrl.js +59 -0
  9. package/lib/card/core/cardPageUrl.js.map +1 -0
  10. package/lib/card/core/index.d.ts +7 -0
  11. package/lib/card/core/index.d.ts.map +1 -0
  12. package/lib/card/core/index.js +4 -0
  13. package/lib/card/core/index.js.map +1 -0
  14. package/lib/card/core/panelRoom.d.ts +40 -0
  15. package/lib/card/core/panelRoom.d.ts.map +1 -0
  16. package/lib/card/core/panelRoom.js +40 -0
  17. package/lib/card/core/panelRoom.js.map +1 -0
  18. package/lib/card/ui/CardDetailsButton.d.ts +38 -0
  19. package/lib/card/ui/CardDetailsButton.d.ts.map +1 -0
  20. package/lib/card/ui/CardDetailsButton.js +50 -0
  21. package/lib/card/ui/CardDetailsButton.js.map +1 -0
  22. package/lib/card/ui/CardFigure.d.ts +51 -0
  23. package/lib/card/ui/CardFigure.d.ts.map +1 -0
  24. package/lib/card/ui/CardFigure.js +27 -0
  25. package/lib/card/ui/CardFigure.js.map +1 -0
  26. package/lib/card/ui/CardFrame.d.ts +30 -0
  27. package/lib/card/ui/CardFrame.d.ts.map +1 -0
  28. package/lib/card/ui/CardFrame.js +20 -0
  29. package/lib/card/ui/CardFrame.js.map +1 -0
  30. package/lib/card/ui/CopyTableButton.d.ts +37 -0
  31. package/lib/card/ui/CopyTableButton.d.ts.map +1 -0
  32. package/lib/card/ui/CopyTableButton.js +19 -0
  33. package/lib/card/ui/CopyTableButton.js.map +1 -0
  34. package/lib/card/ui/cardTooltip.d.ts +14 -0
  35. package/lib/card/ui/cardTooltip.d.ts.map +1 -0
  36. package/lib/card/ui/cardTooltip.js +15 -0
  37. package/lib/card/ui/cardTooltip.js.map +1 -0
  38. package/lib/card/ui/embed.d.ts +15 -0
  39. package/lib/card/ui/embed.d.ts.map +1 -0
  40. package/lib/card/ui/embed.js +24 -0
  41. package/lib/card/ui/embed.js.map +1 -0
  42. package/lib/card/ui/fitCardToFrame.d.ts +31 -0
  43. package/lib/card/ui/fitCardToFrame.d.ts.map +1 -0
  44. package/lib/card/ui/fitCardToFrame.js +66 -0
  45. package/lib/card/ui/fitCardToFrame.js.map +1 -0
  46. package/lib/card/ui/holdRoomForPanels.d.ts +16 -0
  47. package/lib/card/ui/holdRoomForPanels.d.ts.map +1 -0
  48. package/lib/card/ui/holdRoomForPanels.js +76 -0
  49. package/lib/card/ui/holdRoomForPanels.js.map +1 -0
  50. package/lib/card/ui/index.d.ts +11 -0
  51. package/lib/card/ui/index.d.ts.map +1 -0
  52. package/lib/card/ui/index.js +7 -0
  53. package/lib/card/ui/index.js.map +1 -0
  54. package/lib/card/ui/openPanels.d.ts +25 -0
  55. package/lib/card/ui/openPanels.d.ts.map +1 -0
  56. package/lib/card/ui/openPanels.js +85 -0
  57. package/lib/card/ui/openPanels.js.map +1 -0
  58. package/lib/card.d.ts +13 -0
  59. package/lib/card.d.ts.map +1 -0
  60. package/lib/card.js +13 -0
  61. package/lib/card.js.map +1 -0
  62. package/lib/conformers.d.ts +1 -0
  63. package/lib/conformers.d.ts.map +1 -1
  64. package/lib/conformers.js +1 -0
  65. package/lib/conformers.js.map +1 -1
  66. package/lib/core.d.ts +4 -0
  67. package/lib/core.d.ts.map +1 -1
  68. package/lib/core.js +5 -0
  69. package/lib/core.js.map +1 -1
  70. package/lib/fetch/core/apiError.d.ts +56 -0
  71. package/lib/fetch/core/apiError.d.ts.map +1 -0
  72. package/lib/fetch/core/apiError.js +43 -0
  73. package/lib/fetch/core/apiError.js.map +1 -0
  74. package/lib/fetch/core/fetchJson.d.ts +47 -0
  75. package/lib/fetch/core/fetchJson.d.ts.map +1 -0
  76. package/lib/fetch/core/fetchJson.js +109 -0
  77. package/lib/fetch/core/fetchJson.js.map +1 -0
  78. package/lib/fetch/core/index.d.ts +5 -0
  79. package/lib/fetch/core/index.d.ts.map +1 -0
  80. package/lib/fetch/core/index.js +3 -0
  81. package/lib/fetch/core/index.js.map +1 -0
  82. package/lib/formula/core/formulaText.d.ts +46 -0
  83. package/lib/formula/core/formulaText.d.ts.map +1 -0
  84. package/lib/formula/core/formulaText.js +74 -0
  85. package/lib/formula/core/formulaText.js.map +1 -0
  86. package/lib/formula/core/index.d.ts +6 -0
  87. package/lib/formula/core/index.d.ts.map +1 -0
  88. package/lib/formula/core/index.js +4 -0
  89. package/lib/formula/core/index.js.map +1 -0
  90. package/lib/formula/core/normalizeFormula.d.ts +22 -0
  91. package/lib/formula/core/normalizeFormula.d.ts.map +1 -0
  92. package/lib/formula/core/normalizeFormula.js +46 -0
  93. package/lib/formula/core/normalizeFormula.js.map +1 -0
  94. package/lib/formula/core/readFormula.d.ts +73 -0
  95. package/lib/formula/core/readFormula.d.ts.map +1 -0
  96. package/lib/formula/core/readFormula.js +132 -0
  97. package/lib/formula/core/readFormula.js.map +1 -0
  98. package/lib/formula/ui/CopyableFormula.d.ts +31 -0
  99. package/lib/formula/ui/CopyableFormula.d.ts.map +1 -0
  100. package/lib/formula/ui/CopyableFormula.js +19 -0
  101. package/lib/formula/ui/CopyableFormula.js.map +1 -0
  102. package/lib/formula/ui/FormulaInput.d.ts +29 -0
  103. package/lib/formula/ui/FormulaInput.d.ts.map +1 -0
  104. package/lib/formula/ui/FormulaInput.js +16 -0
  105. package/lib/formula/ui/FormulaInput.js.map +1 -0
  106. package/lib/formula/ui/QuestionFormula.d.ts +14 -0
  107. package/lib/formula/ui/QuestionFormula.d.ts.map +1 -0
  108. package/lib/formula/ui/QuestionFormula.js +13 -0
  109. package/lib/formula/ui/QuestionFormula.js.map +1 -0
  110. package/lib/formula/ui/index.d.ts +7 -0
  111. package/lib/formula/ui/index.d.ts.map +1 -0
  112. package/lib/formula/ui/index.js +4 -0
  113. package/lib/formula/ui/index.js.map +1 -0
  114. package/lib/formula.d.ts +11 -0
  115. package/lib/formula.d.ts.map +1 -0
  116. package/lib/formula.js +11 -0
  117. package/lib/formula.js.map +1 -0
  118. package/lib/hooks/ui/index.d.ts +1 -0
  119. package/lib/hooks/ui/index.d.ts.map +1 -1
  120. package/lib/hooks/ui/index.js.map +1 -1
  121. package/lib/hooks/ui/keyTargets.d.ts +4 -2
  122. package/lib/hooks/ui/keyTargets.d.ts.map +1 -1
  123. package/lib/hooks/ui/keyTargets.js +5 -3
  124. package/lib/hooks/ui/keyTargets.js.map +1 -1
  125. package/lib/hooks/ui/useAsync.d.ts +20 -5
  126. package/lib/hooks/ui/useAsync.d.ts.map +1 -1
  127. package/lib/hooks/ui/useAsync.js +29 -14
  128. package/lib/hooks/ui/useAsync.js.map +1 -1
  129. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  130. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  131. package/lib/locales/de.json +37 -0
  132. package/lib/locales/en.json +37 -0
  133. package/lib/locales/es.json +37 -0
  134. package/lib/locales/fr.json +37 -0
  135. package/lib/locales/it.json +37 -0
  136. package/lib/moleculesClient/core/index.d.ts +5 -0
  137. package/lib/moleculesClient/core/index.d.ts.map +1 -0
  138. package/lib/moleculesClient/core/index.js +3 -0
  139. package/lib/moleculesClient/core/index.js.map +1 -0
  140. package/lib/moleculesClient/core/moleculesClient.d.ts +12 -0
  141. package/lib/moleculesClient/core/moleculesClient.d.ts.map +1 -0
  142. package/lib/moleculesClient/core/moleculesClient.js +105 -0
  143. package/lib/moleculesClient/core/moleculesClient.js.map +1 -0
  144. package/lib/moleculesClient/core/moleculesClientApi.d.ts +100 -0
  145. package/lib/moleculesClient/core/moleculesClientApi.d.ts.map +1 -0
  146. package/lib/moleculesClient/core/moleculesClientApi.js +20 -0
  147. package/lib/moleculesClient/core/moleculesClientApi.js.map +1 -0
  148. package/lib/moleculesClient/core/moleculesTypes.d.ts +154 -0
  149. package/lib/moleculesClient/core/moleculesTypes.d.ts.map +1 -0
  150. package/lib/moleculesClient/core/moleculesTypes.js +2 -0
  151. package/lib/moleculesClient/core/moleculesTypes.js.map +1 -0
  152. package/lib/moleculesClient/core/requestRetry.d.ts +50 -0
  153. package/lib/moleculesClient/core/requestRetry.d.ts.map +1 -0
  154. package/lib/moleculesClient/core/requestRetry.js +108 -0
  155. package/lib/moleculesClient/core/requestRetry.js.map +1 -0
  156. package/lib/molstar/core/camera.d.ts +2 -1
  157. package/lib/molstar/core/camera.d.ts.map +1 -1
  158. package/lib/molstar/core/camera.js +3 -2
  159. package/lib/molstar/core/camera.js.map +1 -1
  160. package/lib/molstar/core/framing.d.ts +102 -0
  161. package/lib/molstar/core/framing.d.ts.map +1 -0
  162. package/lib/molstar/core/framing.js +120 -0
  163. package/lib/molstar/core/framing.js.map +1 -0
  164. package/lib/molstar/core/hover.d.ts +16 -0
  165. package/lib/molstar/core/hover.d.ts.map +1 -1
  166. package/lib/molstar/core/hover.js +14 -0
  167. package/lib/molstar/core/hover.js.map +1 -1
  168. package/lib/molstar/core/index.d.ts +4 -1
  169. package/lib/molstar/core/index.d.ts.map +1 -1
  170. package/lib/molstar/core/index.js +2 -1
  171. package/lib/molstar/core/index.js.map +1 -1
  172. package/lib/pedagogy/core/answers.d.ts +46 -0
  173. package/lib/pedagogy/core/answers.d.ts.map +1 -0
  174. package/lib/pedagogy/core/answers.js +77 -0
  175. package/lib/pedagogy/core/answers.js.map +1 -0
  176. package/lib/pedagogy/core/attempts.d.ts +86 -0
  177. package/lib/pedagogy/core/attempts.d.ts.map +1 -0
  178. package/lib/pedagogy/core/attempts.js +117 -0
  179. package/lib/pedagogy/core/attempts.js.map +1 -0
  180. package/lib/pedagogy/core/index.d.ts +8 -0
  181. package/lib/pedagogy/core/index.d.ts.map +1 -1
  182. package/lib/pedagogy/core/index.js +4 -0
  183. package/lib/pedagogy/core/index.js.map +1 -1
  184. package/lib/pedagogy/core/progressController.d.ts +64 -0
  185. package/lib/pedagogy/core/progressController.d.ts.map +1 -0
  186. package/lib/pedagogy/core/progressController.js +56 -0
  187. package/lib/pedagogy/core/progressController.js.map +1 -0
  188. package/lib/pedagogy/core/seed.d.ts +96 -0
  189. package/lib/pedagogy/core/seed.d.ts.map +1 -0
  190. package/lib/pedagogy/core/seed.js +128 -0
  191. package/lib/pedagogy/core/seed.js.map +1 -0
  192. package/lib/pedagogy/core/series.d.ts +77 -0
  193. package/lib/pedagogy/core/series.d.ts.map +1 -0
  194. package/lib/pedagogy/core/series.js +10 -0
  195. package/lib/pedagogy/core/series.js.map +1 -0
  196. package/lib/pedagogy/ui/AnswerFields.d.ts +21 -0
  197. package/lib/pedagogy/ui/AnswerFields.d.ts.map +1 -0
  198. package/lib/pedagogy/ui/AnswerFields.js +24 -0
  199. package/lib/pedagogy/ui/AnswerFields.js.map +1 -0
  200. package/lib/pedagogy/ui/ExerciseList.d.ts +82 -0
  201. package/lib/pedagogy/ui/ExerciseList.d.ts.map +1 -0
  202. package/lib/pedagogy/ui/ExerciseList.js +53 -0
  203. package/lib/pedagogy/ui/ExerciseList.js.map +1 -0
  204. package/lib/pedagogy/ui/ExerciseSeries.d.ts +95 -0
  205. package/lib/pedagogy/ui/ExerciseSeries.d.ts.map +1 -0
  206. package/lib/pedagogy/ui/ExerciseSeries.js +74 -0
  207. package/lib/pedagogy/ui/ExerciseSeries.js.map +1 -0
  208. package/lib/pedagogy/ui/QuestionCard.d.ts +64 -0
  209. package/lib/pedagogy/ui/QuestionCard.d.ts.map +1 -0
  210. package/lib/pedagogy/ui/QuestionCard.js +73 -0
  211. package/lib/pedagogy/ui/QuestionCard.js.map +1 -0
  212. package/lib/pedagogy/ui/index.d.ts +10 -0
  213. package/lib/pedagogy/ui/index.d.ts.map +1 -1
  214. package/lib/pedagogy/ui/index.js +6 -0
  215. package/lib/pedagogy/ui/index.js.map +1 -1
  216. package/lib/pedagogy/ui/seriesCounts.d.ts +17 -0
  217. package/lib/pedagogy/ui/seriesCounts.d.ts.map +1 -0
  218. package/lib/pedagogy/ui/seriesCounts.js +27 -0
  219. package/lib/pedagogy/ui/seriesCounts.js.map +1 -0
  220. package/lib/pedagogy/ui/seriesParts.d.ts +55 -0
  221. package/lib/pedagogy/ui/seriesParts.d.ts.map +1 -0
  222. package/lib/pedagogy/ui/seriesParts.js +38 -0
  223. package/lib/pedagogy/ui/seriesParts.js.map +1 -0
  224. package/lib/pedagogy/ui/useAttemptRecords.d.ts +10 -0
  225. package/lib/pedagogy/ui/useAttemptRecords.d.ts.map +1 -0
  226. package/lib/pedagogy/ui/useAttemptRecords.js +11 -0
  227. package/lib/pedagogy/ui/useAttemptRecords.js.map +1 -0
  228. package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
  229. package/lib/periodic/ui/PeriodicTable.js +6 -3
  230. package/lib/periodic/ui/PeriodicTable.js.map +1 -1
  231. package/lib/property/core/copyableText.d.ts +14 -0
  232. package/lib/property/core/copyableText.d.ts.map +1 -0
  233. package/lib/property/core/copyableText.js +21 -0
  234. package/lib/property/core/copyableText.js.map +1 -0
  235. package/lib/property/core/index.d.ts +2 -0
  236. package/lib/property/core/index.d.ts.map +1 -0
  237. package/lib/property/core/index.js +2 -0
  238. package/lib/property/core/index.js.map +1 -0
  239. package/lib/property/ui/PropertyTable.d.ts +43 -0
  240. package/lib/property/ui/PropertyTable.d.ts.map +1 -0
  241. package/lib/property/ui/PropertyTable.js +19 -0
  242. package/lib/property/ui/PropertyTable.js.map +1 -0
  243. package/lib/property/ui/index.d.ts +3 -0
  244. package/lib/property/ui/index.d.ts.map +1 -0
  245. package/lib/property/ui/index.js +2 -0
  246. package/lib/property/ui/index.js.map +1 -0
  247. package/lib/router/core/history.d.ts +24 -3
  248. package/lib/router/core/history.d.ts.map +1 -1
  249. package/lib/router/core/history.js +55 -7
  250. package/lib/router/core/history.js.map +1 -1
  251. package/lib/router/core/index.d.ts +3 -3
  252. package/lib/router/core/index.d.ts.map +1 -1
  253. package/lib/router/core/index.js +2 -2
  254. package/lib/router/core/index.js.map +1 -1
  255. package/lib/router/core/languageRoute.d.ts +61 -0
  256. package/lib/router/core/languageRoute.d.ts.map +1 -0
  257. package/lib/router/core/languageRoute.js +96 -0
  258. package/lib/router/core/languageRoute.js.map +1 -0
  259. package/lib/router/core/siteAddresses.d.ts +23 -0
  260. package/lib/router/core/siteAddresses.d.ts.map +1 -1
  261. package/lib/router/core/siteAddresses.js +26 -0
  262. package/lib/router/core/siteAddresses.js.map +1 -1
  263. package/lib/router/core/tabRouter.d.ts +2 -108
  264. package/lib/router/core/tabRouter.d.ts.map +1 -1
  265. package/lib/router/core/tabRouter.js +38 -5
  266. package/lib/router/core/tabRouter.js.map +1 -1
  267. package/lib/router/core/tabRouterTypes.d.ts +154 -0
  268. package/lib/router/core/tabRouterTypes.d.ts.map +1 -0
  269. package/lib/router/core/tabRouterTypes.js +2 -0
  270. package/lib/router/core/tabRouterTypes.js.map +1 -0
  271. package/lib/seo/core/fitDescription.d.ts +40 -0
  272. package/lib/seo/core/fitDescription.d.ts.map +1 -0
  273. package/lib/seo/core/fitDescription.js +45 -0
  274. package/lib/seo/core/fitDescription.js.map +1 -0
  275. package/lib/seo/core/index.d.ts +7 -0
  276. package/lib/seo/core/index.d.ts.map +1 -1
  277. package/lib/seo/core/index.js +4 -0
  278. package/lib/seo/core/index.js.map +1 -1
  279. package/lib/seo/core/limits.d.ts +24 -0
  280. package/lib/seo/core/limits.d.ts.map +1 -0
  281. package/lib/seo/core/limits.js +24 -0
  282. package/lib/seo/core/limits.js.map +1 -0
  283. package/lib/seo/core/pageContent.d.ts +25 -0
  284. package/lib/seo/core/pageContent.d.ts.map +1 -0
  285. package/lib/seo/core/pageContent.js +25 -0
  286. package/lib/seo/core/pageContent.js.map +1 -0
  287. package/lib/seo/core/plainDescription.d.ts.map +1 -1
  288. package/lib/seo/core/plainDescription.js +3 -2
  289. package/lib/seo/core/plainDescription.js.map +1 -1
  290. package/lib/seo/core/routeProblems.d.ts.map +1 -1
  291. package/lib/seo/core/routeProblems.js +1 -6
  292. package/lib/seo/core/routeProblems.js.map +1 -1
  293. package/lib/seo/core/routeTable.d.ts +31 -0
  294. package/lib/seo/core/routeTable.d.ts.map +1 -0
  295. package/lib/seo/core/routeTable.js +96 -0
  296. package/lib/seo/core/routeTable.js.map +1 -0
  297. package/lib/seo/vite/index.d.ts +2 -0
  298. package/lib/seo/vite/index.d.ts.map +1 -1
  299. package/lib/seo/vite/index.js +1 -0
  300. package/lib/seo/vite/index.js.map +1 -1
  301. package/lib/seo/vite/prerender.d.ts +10 -0
  302. package/lib/seo/vite/prerender.d.ts.map +1 -1
  303. package/lib/seo/vite/prerender.js +12 -1
  304. package/lib/seo/vite/prerender.js.map +1 -1
  305. package/lib/seo/vite/routeTable.d.ts +40 -0
  306. package/lib/seo/vite/routeTable.d.ts.map +1 -0
  307. package/lib/seo/vite/routeTable.js +44 -0
  308. package/lib/seo/vite/routeTable.js.map +1 -0
  309. package/lib/server/answerAddresses.d.ts +51 -0
  310. package/lib/server/answerAddresses.d.ts.map +1 -0
  311. package/lib/server/answerAddresses.js +72 -0
  312. package/lib/server/answerAddresses.js.map +1 -0
  313. package/lib/server/cardMeta.d.ts +57 -0
  314. package/lib/server/cardMeta.d.ts.map +1 -0
  315. package/lib/server/cardMeta.js +52 -0
  316. package/lib/server/cardMeta.js.map +1 -0
  317. package/lib/server/config.d.ts +72 -0
  318. package/lib/server/config.d.ts.map +1 -0
  319. package/lib/server/config.js +67 -0
  320. package/lib/server/config.js.map +1 -0
  321. package/lib/server/envNumber.d.ts +35 -0
  322. package/lib/server/envNumber.d.ts.map +1 -0
  323. package/lib/server/envNumber.js +42 -0
  324. package/lib/server/envNumber.js.map +1 -0
  325. package/lib/server/healthRoute.d.ts +26 -0
  326. package/lib/server/healthRoute.d.ts.map +1 -0
  327. package/lib/server/healthRoute.js +22 -0
  328. package/lib/server/healthRoute.js.map +1 -0
  329. package/lib/server/listenSite.d.ts +38 -0
  330. package/lib/server/listenSite.d.ts.map +1 -0
  331. package/lib/server/listenSite.js +60 -0
  332. package/lib/server/listenSite.js.map +1 -0
  333. package/lib/server/mcpServer.d.ts +8 -0
  334. package/lib/server/mcpServer.d.ts.map +1 -0
  335. package/lib/server/mcpServer.js +11 -0
  336. package/lib/server/mcpServer.js.map +1 -0
  337. package/lib/server/repositoryVersion.d.ts +16 -0
  338. package/lib/server/repositoryVersion.d.ts.map +1 -0
  339. package/lib/server/repositoryVersion.js +33 -0
  340. package/lib/server/repositoryVersion.js.map +1 -0
  341. package/lib/server/routeOptions.d.ts +23 -0
  342. package/lib/server/routeOptions.d.ts.map +1 -0
  343. package/lib/server/routeOptions.js +20 -0
  344. package/lib/server/routeOptions.js.map +1 -0
  345. package/lib/server/routeTable.d.ts +14 -0
  346. package/lib/server/routeTable.d.ts.map +1 -0
  347. package/lib/server/routeTable.js +32 -0
  348. package/lib/server/routeTable.js.map +1 -0
  349. package/lib/server/siteView.d.ts +29 -0
  350. package/lib/server/siteView.d.ts.map +1 -0
  351. package/lib/server/siteView.js +21 -0
  352. package/lib/server/siteView.js.map +1 -0
  353. package/lib/server/spaPages.d.ts +32 -0
  354. package/lib/server/spaPages.d.ts.map +1 -0
  355. package/lib/server/spaPages.js +126 -0
  356. package/lib/server/spaPages.js.map +1 -0
  357. package/lib/server/spaSite.d.ts +30 -0
  358. package/lib/server/spaSite.d.ts.map +1 -0
  359. package/lib/server/spaSite.js +170 -0
  360. package/lib/server/spaSite.js.map +1 -0
  361. package/lib/server/spaSiteOptions.d.ts +126 -0
  362. package/lib/server/spaSiteOptions.d.ts.map +1 -0
  363. package/lib/server/spaSiteOptions.js +2 -0
  364. package/lib/server/spaSiteOptions.js.map +1 -0
  365. package/lib/server/staticSite.d.ts +9 -0
  366. package/lib/server/staticSite.d.ts.map +1 -1
  367. package/lib/server/staticSite.js +41 -19
  368. package/lib/server/staticSite.js.map +1 -1
  369. package/lib/server/toolSiteServer.d.ts +77 -0
  370. package/lib/server/toolSiteServer.d.ts.map +1 -0
  371. package/lib/server/toolSiteServer.js +58 -0
  372. package/lib/server/toolSiteServer.js.map +1 -0
  373. package/lib/server/trustProxy.d.ts +20 -0
  374. package/lib/server/trustProxy.d.ts.map +1 -0
  375. package/lib/server/trustProxy.js +32 -0
  376. package/lib/server/trustProxy.js.map +1 -0
  377. package/lib/server/types.d.ts +13 -0
  378. package/lib/server/types.d.ts.map +1 -0
  379. package/lib/server/types.js +2 -0
  380. package/lib/server/types.js.map +1 -0
  381. package/lib/server.d.ts +22 -0
  382. package/lib/server.d.ts.map +1 -1
  383. package/lib/server.js +12 -0
  384. package/lib/server.js.map +1 -1
  385. package/lib/share/core/config.d.ts +18 -0
  386. package/lib/share/core/config.d.ts.map +1 -1
  387. package/lib/share/core/config.js +33 -2
  388. package/lib/share/core/config.js.map +1 -1
  389. package/lib/share/core/index.d.ts +3 -1
  390. package/lib/share/core/index.d.ts.map +1 -1
  391. package/lib/share/core/index.js +2 -1
  392. package/lib/share/core/index.js.map +1 -1
  393. package/lib/share/core/keySetParam.d.ts +40 -0
  394. package/lib/share/core/keySetParam.d.ts.map +1 -0
  395. package/lib/share/core/keySetParam.js +60 -0
  396. package/lib/share/core/keySetParam.js.map +1 -0
  397. package/lib/share/core/vocabulary.d.ts +8 -0
  398. package/lib/share/core/vocabulary.d.ts.map +1 -1
  399. package/lib/shell/ui/ShareControl.d.ts +75 -0
  400. package/lib/shell/ui/ShareControl.d.ts.map +1 -0
  401. package/lib/shell/ui/ShareControl.js +40 -0
  402. package/lib/shell/ui/ShareControl.js.map +1 -0
  403. package/lib/shell/ui/ShellFrame.d.ts +14 -0
  404. package/lib/shell/ui/ShellFrame.d.ts.map +1 -0
  405. package/lib/shell/ui/ShellFrame.js +45 -0
  406. package/lib/shell/ui/ShellFrame.js.map +1 -0
  407. package/lib/shell/ui/SiteShell.d.ts +251 -0
  408. package/lib/shell/ui/SiteShell.d.ts.map +1 -0
  409. package/lib/shell/ui/SiteShell.js +39 -0
  410. package/lib/shell/ui/SiteShell.js.map +1 -0
  411. package/lib/shell/ui/index.d.ts +5 -0
  412. package/lib/shell/ui/index.d.ts.map +1 -0
  413. package/lib/shell/ui/index.js +3 -0
  414. package/lib/shell/ui/index.js.map +1 -0
  415. package/lib/state/core/index.d.ts +1 -0
  416. package/lib/state/core/index.d.ts.map +1 -1
  417. package/lib/state/core/index.js.map +1 -1
  418. package/lib/state/core/legacyEntries.d.ts +30 -0
  419. package/lib/state/core/legacyEntries.d.ts.map +1 -0
  420. package/lib/state/core/legacyEntries.js +51 -0
  421. package/lib/state/core/legacyEntries.js.map +1 -0
  422. package/lib/state/core/persistBucket.d.ts +26 -2
  423. package/lib/state/core/persistBucket.d.ts.map +1 -1
  424. package/lib/state/core/persistBucket.js +26 -9
  425. package/lib/state/core/persistBucket.js.map +1 -1
  426. package/lib/state/core/persistSignalBucket.d.ts +26 -0
  427. package/lib/state/core/persistSignalBucket.d.ts.map +1 -1
  428. package/lib/state/core/persistSignalBucket.js +31 -0
  429. package/lib/state/core/persistSignalBucket.js.map +1 -1
  430. package/lib/state/core/storageEntry.d.ts +15 -0
  431. package/lib/state/core/storageEntry.d.ts.map +1 -1
  432. package/lib/state/core/storageEntry.js +33 -0
  433. package/lib/state/core/storageEntry.js.map +1 -1
  434. package/lib/structure/ui/StructureExportButton.d.ts +27 -0
  435. package/lib/structure/ui/StructureExportButton.d.ts.map +1 -0
  436. package/lib/structure/ui/StructureExportButton.js +21 -0
  437. package/lib/structure/ui/StructureExportButton.js.map +1 -0
  438. package/lib/structure/ui/index.d.ts +4 -0
  439. package/lib/structure/ui/index.d.ts.map +1 -1
  440. package/lib/structure/ui/index.js +2 -0
  441. package/lib/structure/ui/index.js.map +1 -1
  442. package/lib/structure/ui/useStructureDraft.d.ts +32 -0
  443. package/lib/structure/ui/useStructureDraft.d.ts.map +1 -0
  444. package/lib/structure/ui/useStructureDraft.js +20 -0
  445. package/lib/structure/ui/useStructureDraft.js.map +1 -0
  446. package/lib/ui.d.ts +2 -0
  447. package/lib/ui.d.ts.map +1 -1
  448. package/lib/ui.js +2 -0
  449. package/lib/ui.js.map +1 -1
  450. package/lib/worker/core/index.d.ts +1 -1
  451. package/lib/worker/core/index.d.ts.map +1 -1
  452. package/lib/worker/core/messages.d.ts +4 -2
  453. package/lib/worker/core/messages.d.ts.map +1 -1
  454. package/lib/worker/core/messages.js.map +1 -1
  455. package/lib/worker/core/oclResourcesUrl.d.ts +16 -0
  456. package/lib/worker/core/oclResourcesUrl.d.ts.map +1 -0
  457. package/lib/worker/core/oclResourcesUrl.js +19 -0
  458. package/lib/worker/core/oclResourcesUrl.js.map +1 -0
  459. package/lib/worker/core/serveWorkerRequests.d.ts +8 -0
  460. package/lib/worker/core/serveWorkerRequests.d.ts.map +1 -1
  461. package/lib/worker/core/serveWorkerRequests.js +15 -2
  462. package/lib/worker/core/serveWorkerRequests.js.map +1 -1
  463. package/lib/worker/core/workerChannel.d.ts +3 -4
  464. package/lib/worker/core/workerChannel.d.ts.map +1 -1
  465. package/lib/worker/core/workerChannel.js +72 -67
  466. package/lib/worker/core/workerChannel.js.map +1 -1
  467. package/lib/worker/core/workerChannelParts.d.ts +17 -6
  468. package/lib/worker/core/workerChannelParts.d.ts.map +1 -1
  469. package/lib/worker/core/workerChannelParts.js +20 -4
  470. package/lib/worker/core/workerChannelParts.js.map +1 -1
  471. package/lib/worker/core/workerChannelTypes.d.ts +46 -2
  472. package/lib/worker/core/workerChannelTypes.d.ts.map +1 -1
  473. package/lib/worker/core/workerSlot.d.ts +66 -0
  474. package/lib/worker/core/workerSlot.d.ts.map +1 -0
  475. package/lib/worker/core/workerSlot.js +107 -0
  476. package/lib/worker/core/workerSlot.js.map +1 -0
  477. package/package.json +16 -1
  478. package/src/card/core/cardAddress.ts +100 -0
  479. package/src/card/core/cardPageUrl.ts +97 -0
  480. package/src/card/core/index.ts +6 -0
  481. package/src/card/core/panelRoom.ts +66 -0
  482. package/src/card/ui/CardDetailsButton.tsx +104 -0
  483. package/src/card/ui/CardFigure.tsx +86 -0
  484. package/src/card/ui/CardFrame.tsx +46 -0
  485. package/src/card/ui/CopyTableButton.tsx +81 -0
  486. package/src/card/ui/cardTooltip.ts +18 -0
  487. package/src/card/ui/embed.ts +27 -0
  488. package/src/card/ui/fitCardToFrame.ts +76 -0
  489. package/src/card/ui/holdRoomForPanels.ts +83 -0
  490. package/src/card/ui/index.ts +14 -0
  491. package/src/card/ui/openPanels.ts +106 -0
  492. package/src/card.ts +13 -0
  493. package/src/conformers.ts +4 -0
  494. package/src/core.ts +5 -0
  495. package/src/fetch/core/apiError.ts +65 -0
  496. package/src/fetch/core/fetchJson.ts +129 -0
  497. package/src/fetch/core/index.ts +4 -0
  498. package/src/formula/core/formulaText.ts +96 -0
  499. package/src/formula/core/index.ts +20 -0
  500. package/src/formula/core/normalizeFormula.ts +50 -0
  501. package/src/formula/core/readFormula.ts +211 -0
  502. package/src/formula/ui/CopyableFormula.tsx +51 -0
  503. package/src/formula/ui/FormulaInput.tsx +50 -0
  504. package/src/formula/ui/QuestionFormula.tsx +20 -0
  505. package/src/formula/ui/index.ts +6 -0
  506. package/src/formula.ts +11 -0
  507. package/src/hooks/ui/index.ts +1 -0
  508. package/src/hooks/ui/keyTargets.ts +5 -3
  509. package/src/hooks/ui/useAsync.ts +50 -14
  510. package/src/locales/de.json +37 -0
  511. package/src/locales/en.json +37 -0
  512. package/src/locales/es.json +37 -0
  513. package/src/locales/fr.json +37 -0
  514. package/src/locales/it.json +37 -0
  515. package/src/moleculesClient/core/index.ts +19 -0
  516. package/src/moleculesClient/core/moleculesClient.ts +175 -0
  517. package/src/moleculesClient/core/moleculesClientApi.ts +120 -0
  518. package/src/moleculesClient/core/moleculesTypes.ts +163 -0
  519. package/src/moleculesClient/core/requestRetry.ts +118 -0
  520. package/src/molstar/core/camera.ts +3 -2
  521. package/src/molstar/core/framing.ts +200 -0
  522. package/src/molstar/core/hover.ts +26 -0
  523. package/src/molstar/core/index.ts +21 -1
  524. package/src/pedagogy/core/answers.ts +94 -0
  525. package/src/pedagogy/core/attempts.ts +205 -0
  526. package/src/pedagogy/core/index.ts +36 -0
  527. package/src/pedagogy/core/progressController.ts +116 -0
  528. package/src/pedagogy/core/seed.ts +177 -0
  529. package/src/pedagogy/core/series.ts +82 -0
  530. package/src/pedagogy/ui/AnswerFields.tsx +63 -0
  531. package/src/pedagogy/ui/ExerciseList.tsx +202 -0
  532. package/src/pedagogy/ui/ExerciseSeries.tsx +250 -0
  533. package/src/pedagogy/ui/QuestionCard.tsx +231 -0
  534. package/src/pedagogy/ui/index.ts +18 -0
  535. package/src/pedagogy/ui/seriesCounts.ts +34 -0
  536. package/src/pedagogy/ui/seriesParts.tsx +127 -0
  537. package/src/pedagogy/ui/useAttemptRecords.ts +16 -0
  538. package/src/periodic/ui/PeriodicTable.tsx +6 -3
  539. package/src/property/core/copyableText.ts +20 -0
  540. package/src/property/core/index.ts +1 -0
  541. package/src/property/ui/PropertyTable.tsx +83 -0
  542. package/src/property/ui/index.ts +2 -0
  543. package/src/router/core/history.ts +61 -7
  544. package/src/router/core/index.ts +3 -2
  545. package/src/router/core/languageRoute.ts +136 -0
  546. package/src/router/core/siteAddresses.ts +38 -0
  547. package/src/router/core/tabRouter.ts +59 -117
  548. package/src/router/core/tabRouterTypes.ts +158 -0
  549. package/src/seo/core/fitDescription.ts +74 -0
  550. package/src/seo/core/index.ts +17 -0
  551. package/src/seo/core/limits.ts +27 -0
  552. package/src/seo/core/pageContent.ts +42 -0
  553. package/src/seo/core/plainDescription.ts +4 -2
  554. package/src/seo/core/routeProblems.ts +1 -7
  555. package/src/seo/core/routeTable.ts +103 -0
  556. package/src/seo/vite/index.ts +2 -0
  557. package/src/seo/vite/prerender.ts +26 -1
  558. package/src/seo/vite/routeTable.ts +79 -0
  559. package/src/server/answerAddresses.ts +92 -0
  560. package/src/server/cardMeta.ts +88 -0
  561. package/src/server/config.ts +125 -0
  562. package/src/server/envNumber.ts +65 -0
  563. package/src/server/healthRoute.ts +42 -0
  564. package/src/server/listenSite.ts +90 -0
  565. package/src/server/mcpServer.ts +14 -0
  566. package/src/server/repositoryVersion.ts +33 -0
  567. package/src/server/routeOptions.ts +26 -0
  568. package/src/server/routeTable.ts +35 -0
  569. package/src/server/siteView.ts +42 -0
  570. package/src/server/spaPages.ts +179 -0
  571. package/src/server/spaSite.ts +216 -0
  572. package/src/server/spaSiteOptions.ts +133 -0
  573. package/src/server/staticSite.ts +65 -35
  574. package/src/server/toolSiteServer.ts +127 -0
  575. package/src/server/trustProxy.ts +32 -0
  576. package/src/server/types.ts +25 -0
  577. package/src/server.ts +40 -0
  578. package/src/share/core/config.ts +45 -2
  579. package/src/share/core/index.ts +4 -0
  580. package/src/share/core/keySetParam.ts +92 -0
  581. package/src/share/core/vocabulary.ts +8 -0
  582. package/src/shell/ui/ShareControl.tsx +150 -0
  583. package/src/shell/ui/ShellFrame.tsx +180 -0
  584. package/src/shell/ui/SiteShell.tsx +297 -0
  585. package/src/shell/ui/index.ts +9 -0
  586. package/src/state/core/index.ts +1 -0
  587. package/src/state/core/legacyEntries.ts +76 -0
  588. package/src/state/core/persistBucket.ts +50 -10
  589. package/src/state/core/persistSignalBucket.ts +52 -0
  590. package/src/state/core/storageEntry.ts +32 -0
  591. package/src/structure/ui/StructureExportButton.tsx +57 -0
  592. package/src/structure/ui/index.ts +4 -0
  593. package/src/structure/ui/useStructureDraft.ts +47 -0
  594. package/src/ui.ts +2 -0
  595. package/src/worker/core/index.ts +1 -0
  596. package/src/worker/core/messages.ts +4 -3
  597. package/src/worker/core/oclResourcesUrl.ts +21 -0
  598. package/src/worker/core/serveWorkerRequests.ts +30 -2
  599. package/src/worker/core/workerChannel.ts +74 -74
  600. package/src/worker/core/workerChannelParts.ts +33 -13
  601. package/src/worker/core/workerChannelTypes.ts +47 -2
  602. package/src/worker/core/workerSlot.ts +181 -0
  603. package/styles/card.css +145 -0
  604. package/styles/chrome.css +248 -0
@@ -0,0 +1,175 @@
1
+ import { XSadd } from 'ml-xsadd';
2
+
3
+ import { trimTrailingSlash } from '../../router/core/address.ts';
4
+
5
+ import type {
6
+ MoleculesClient,
7
+ MoleculesClientOptions,
8
+ } from './moleculesClientApi.ts';
9
+ import { MoleculesError } from './moleculesClientApi.ts';
10
+ import type {
11
+ ImportStarted,
12
+ ImportState,
13
+ LookupResponse,
14
+ PurgeResponse,
15
+ SubmitResponse,
16
+ } from './moleculesTypes.ts';
17
+ import {
18
+ causeOf,
19
+ gzipBody,
20
+ messageOf,
21
+ pause,
22
+ requestSignal,
23
+ retryAfter,
24
+ } from './requestRetry.ts';
25
+
26
+ /** Statuses a request is tried again on: the server is busy or in between. */
27
+ const RETRIED_STATUSES = new Set([429, 502, 503, 504]);
28
+
29
+ /** The doublings of the pause, after which it stays where it is. */
30
+ const MAX_DOUBLINGS = 20;
31
+
32
+ /** One request, as it is tried again. */
33
+ interface Call {
34
+ method: 'GET' | 'POST';
35
+ path: string;
36
+ payload: Uint8Array<ArrayBuffer> | undefined;
37
+ started: number;
38
+ }
39
+
40
+ /** What one attempt came to: the answer, or why another is worth it. */
41
+ type Outcome<T> =
42
+ | { answered: true; value: T }
43
+ | {
44
+ answered: false;
45
+ status: number | undefined;
46
+ reason: string;
47
+ retryAfterMs: number | undefined;
48
+ };
49
+
50
+ /**
51
+ * A client of the routes a source writes through on molecules.cheminfo.org,
52
+ * retrying while the server is busy (503), throttling (429), being restarted
53
+ * (502, 504) or out of reach. Each attempt has its own deadline, the pauses
54
+ * double with a spread and honour `Retry-After`, and bodies travel gzipped.
55
+ * Browser-safe: it reads no Node module.
56
+ * @param options - Where it answers, the token, and how hard to insist.
57
+ * @returns The client.
58
+ */
59
+ export function createMoleculesClient(
60
+ options: MoleculesClientOptions,
61
+ ): MoleculesClient {
62
+ const {
63
+ token,
64
+ maxRetryMs = 1_800_000,
65
+ initialDelayMs = 1000,
66
+ maxDelayMs = 60_000,
67
+ requestTimeoutMs = 600_000,
68
+ signal,
69
+ onRetry,
70
+ fetch: fetchImplementation = globalThis.fetch,
71
+ random = new XSadd().random,
72
+ } = options;
73
+ const baseUrl = trimTrailingSlash(options.baseUrl);
74
+
75
+ async function attemptOnce<T>(call: Call): Promise<Outcome<T>> {
76
+ let response: Response;
77
+ try {
78
+ response = await fetchImplementation(`${baseUrl}${call.path}`, {
79
+ method: call.method,
80
+ headers: {
81
+ authorization: `Bearer ${token}`,
82
+ ...(call.payload === undefined
83
+ ? {}
84
+ : {
85
+ 'content-type': 'application/json',
86
+ 'content-encoding': 'gzip',
87
+ }),
88
+ },
89
+ body: call.payload,
90
+ signal: requestSignal(signal, requestTimeoutMs),
91
+ });
92
+ if (response.ok) {
93
+ return { answered: true, value: (await response.json()) as T };
94
+ }
95
+ } catch (error: unknown) {
96
+ if (signal?.aborted) throw signal.reason;
97
+ return {
98
+ answered: false,
99
+ status: undefined,
100
+ reason: causeOf(error),
101
+ retryAfterMs: undefined,
102
+ };
103
+ }
104
+ const text = await response.text();
105
+ const reason = messageOf(text) ?? response.statusText;
106
+ if (!RETRIED_STATUSES.has(response.status)) {
107
+ throw new MoleculesError(
108
+ `${call.method} ${call.path} answered ${response.status}: ${reason}`,
109
+ response.status,
110
+ text,
111
+ );
112
+ }
113
+ const asked = retryAfter(response.headers.get('retry-after'), Date.now());
114
+ return {
115
+ answered: false,
116
+ status: response.status,
117
+ reason,
118
+ retryAfterMs: asked,
119
+ };
120
+ }
121
+
122
+ async function attempt<T>(call: Call, number: number): Promise<T> {
123
+ signal?.throwIfAborted();
124
+ const outcome = await attemptOnce<T>(call);
125
+ if (outcome.answered) return outcome.value;
126
+ const backoff =
127
+ initialDelayMs *
128
+ 2 ** Math.min(number - 1, MAX_DOUBLINGS) *
129
+ (0.5 + random() * 0.5);
130
+ const delayMs = Math.min(maxDelayMs, outcome.retryAfterMs ?? backoff);
131
+ const elapsed = Date.now() - call.started;
132
+ if (elapsed + delayMs > maxRetryMs) {
133
+ throw new MoleculesError(
134
+ `${call.method} ${call.path} kept failing for ${Math.round(elapsed / 1000)} s: ${outcome.reason}`,
135
+ outcome.status ?? 0,
136
+ outcome.reason,
137
+ );
138
+ }
139
+ onRetry?.({
140
+ method: call.method,
141
+ path: call.path,
142
+ attempt: number,
143
+ status: outcome.status,
144
+ reason: outcome.reason,
145
+ delayMs,
146
+ });
147
+ await pause(delayMs, signal);
148
+ return attempt<T>(call, number + 1);
149
+ }
150
+
151
+ async function request<T>(
152
+ method: 'GET' | 'POST',
153
+ path: string,
154
+ body?: unknown,
155
+ ): Promise<T> {
156
+ const started = Date.now();
157
+ const payload =
158
+ body === undefined ? undefined : await gzipBody(JSON.stringify(body));
159
+ return attempt<T>({ method, path, payload, started }, 1);
160
+ }
161
+
162
+ return {
163
+ startImport: () => request<ImportStarted>('POST', '/v1/imports'),
164
+ importState: () => request<ImportState>('GET', '/v1/imports'),
165
+ submit: (molecules, { returnInfo = false } = {}) =>
166
+ request<SubmitResponse>('POST', '/v1/submit', { molecules, returnInfo }),
167
+ lookup: (queries, kind) =>
168
+ request<LookupResponse>('POST', '/v1/batch', { queries, kind }),
169
+ purge: (importKey, { dryRun = false, force = false } = {}) =>
170
+ request<PurgeResponse>('POST', `/v1/imports/${importKey}/purge`, {
171
+ dryRun,
172
+ force,
173
+ }),
174
+ };
175
+ }
@@ -0,0 +1,120 @@
1
+ import type {
2
+ ImportStarted,
3
+ ImportState,
4
+ LookupResponse,
5
+ MoleculeInput,
6
+ PurgeResponse,
7
+ RetryDetails,
8
+ SubmitResponse,
9
+ } from './moleculesTypes.ts';
10
+
11
+ /** How a client reaches molecules.cheminfo.org, and how hard it insists. */
12
+ export interface MoleculesClientOptions {
13
+ /** Where molecules.cheminfo.org answers, e.g. `https://molecules.cheminfo.org`. */
14
+ baseUrl: string;
15
+ /** The token issued for the source the client writes for. */
16
+ token: string;
17
+ /**
18
+ * How long one request may keep being retried while the server is busy or
19
+ * unreachable, in milliseconds.
20
+ * @default 1_800_000 - half an hour
21
+ */
22
+ maxRetryMs?: number;
23
+ /**
24
+ * The first pause before a retry; each next one doubles, up to `maxDelayMs`.
25
+ * @default 1000
26
+ */
27
+ initialDelayMs?: number;
28
+ /**
29
+ * The longest pause between two attempts, a `Retry-After` included.
30
+ * @default 60_000
31
+ */
32
+ maxDelayMs?: number;
33
+ /**
34
+ * How long one attempt may take before it is given up and retried.
35
+ * @default 600_000
36
+ */
37
+ requestTimeoutMs?: number;
38
+ /**
39
+ * Stops every request, and every pause between two attempts.
40
+ * @default undefined - nothing stops them
41
+ */
42
+ signal?: AbortSignal;
43
+ /**
44
+ * Told about every retry, e.g. to log it.
45
+ * @default undefined - retries are silent
46
+ */
47
+ onRetry?: (details: RetryDetails) => void;
48
+ /**
49
+ * The fetch to use, for tests.
50
+ * @default globalThis.fetch
51
+ */
52
+ fetch?: typeof fetch;
53
+ /**
54
+ * A number from 0 to 1 that spreads the pauses, so clients that failed
55
+ * together do not all come back at the same instant.
56
+ * @default an unseeded `XSadd`
57
+ */
58
+ random?: () => number;
59
+ }
60
+
61
+ /** The routes a source writes through on molecules.cheminfo.org. */
62
+ export interface MoleculesClient {
63
+ /** Take the source's next import key: the start of a full import. */
64
+ startImport: () => Promise<ImportStarted>;
65
+ /** Where the source's import stands. */
66
+ importState: () => Promise<ImportState>;
67
+ /**
68
+ * Send up to 1000 molecules for the source, under its current import key.
69
+ * @param molecules - Each with its identifier and exactly one notation.
70
+ * @param options - Whether every answer carries the molecule's properties.
71
+ * @param options.returnInfo - Ask for them; `false` by default.
72
+ */
73
+ submit: (
74
+ molecules: MoleculeInput[],
75
+ options?: { returnInfo?: boolean },
76
+ ) => Promise<SubmitResponse>;
77
+ /**
78
+ * Compute up to 1000 molecules without storing anything, for a source
79
+ * molecules.cheminfo.org imports itself.
80
+ * @param queries - The structures, all in one notation.
81
+ * @param kind - The notation.
82
+ */
83
+ lookup: (
84
+ queries: string[],
85
+ kind: 'smiles' | 'molfile' | 'idCode',
86
+ ) => Promise<LookupResponse>;
87
+ /**
88
+ * Remove the entries an import did not send again.
89
+ * @param importKey - The key the import took.
90
+ * @param options - Only count, or remove even more than half.
91
+ * @param options.dryRun - Only count; `false` by default.
92
+ * @param options.force - Remove even when that is more than half; `false` by
93
+ * default.
94
+ */
95
+ purge: (
96
+ importKey: number,
97
+ options?: { dryRun?: boolean; force?: boolean },
98
+ ) => Promise<PurgeResponse>;
99
+ }
100
+
101
+ /** A request molecules.cheminfo.org refused, or that kept failing. */
102
+ export class MoleculesError extends Error {
103
+ /** The status answered, or 0 when nothing was. */
104
+ readonly status: number;
105
+ /** What the server said, as text. */
106
+ readonly body: string;
107
+
108
+ /**
109
+ * A failed request, with what the server answered.
110
+ * @param message - What failed, and why.
111
+ * @param status - The status answered, or 0 when nothing was.
112
+ * @param body - What the server said.
113
+ */
114
+ constructor(message: string, status: number, body: string) {
115
+ super(message);
116
+ this.name = 'MoleculesError';
117
+ this.status = status;
118
+ this.body = body;
119
+ }
120
+ }
@@ -0,0 +1,163 @@
1
+ /** One molecule a source sends: its identifier, and exactly one notation. */
2
+ export interface MoleculeInput {
3
+ /** The source's identifier for it, which its address is written with. */
4
+ id: string;
5
+ /**
6
+ * The structure as SMILES.
7
+ * @default undefined - another notation is given
8
+ */
9
+ smiles?: string;
10
+ /**
11
+ * The structure as a molfile.
12
+ * @default undefined - another notation is given
13
+ */
14
+ molfile?: string;
15
+ /**
16
+ * The structure as an OpenChemLib idCode.
17
+ * @default undefined - another notation is given
18
+ */
19
+ idCode?: string;
20
+ }
21
+
22
+ /** What molecules.cheminfo.org computed for a structure. */
23
+ export interface MoleculeInfo {
24
+ mf: string;
25
+ mw: number;
26
+ em: number;
27
+ charge: number;
28
+ idCode: string;
29
+ noStereoID: string;
30
+ noStereoTautomerID: string;
31
+ failedTautomerID: number;
32
+ /** The 512-bit FragFp, sixteen signed 32-bit words. */
33
+ ssIndex: number[];
34
+ logS: number;
35
+ logP: number;
36
+ acceptorCount: number;
37
+ donorCount: number;
38
+ stereoCenterCount: number;
39
+ rotatableBondCount: number;
40
+ polarSurfaceArea: number;
41
+ nbFragments: number;
42
+ /**
43
+ * The degree of unsaturation, when the formula has one.
44
+ * @default undefined
45
+ */
46
+ unsaturation?: number;
47
+ atoms: Record<string, number>;
48
+ /** The hashes, as 16 hex digits: never JSON numbers, which would round them. */
49
+ idCodeHash: string;
50
+ noStereoHash: string;
51
+ noStereoTautomerHash: string;
52
+ createdAt: number | null;
53
+ }
54
+
55
+ /** What became of one molecule a source sent. */
56
+ export interface SubmitResult {
57
+ id: string | null;
58
+ /**
59
+ * The structure it was read as.
60
+ * @default undefined - it could not be read
61
+ */
62
+ idCode?: string;
63
+ /**
64
+ * Whether molecules.cheminfo.org held the structure already.
65
+ * @default undefined - it could not be read
66
+ */
67
+ molecule?: 'created' | 'existing';
68
+ /**
69
+ * What became of the source's entry.
70
+ * @default undefined - it could not be read
71
+ */
72
+ link?: 'added' | 'unchanged' | 'moved';
73
+ /**
74
+ * The computed properties, when they were asked for.
75
+ * @default undefined
76
+ */
77
+ info?: MoleculeInfo;
78
+ /**
79
+ * Why the molecule was refused.
80
+ * @default undefined - it was taken
81
+ */
82
+ error?: string;
83
+ }
84
+
85
+ /** How a batch was taken. */
86
+ export interface SubmitSummary {
87
+ total: number;
88
+ /** Molecules new to molecules.cheminfo.org. */
89
+ created: number;
90
+ /** Entries new to the source. */
91
+ added: number;
92
+ /** Identifiers moved to another structure. */
93
+ moved: number;
94
+ unchanged: number;
95
+ failed: number;
96
+ }
97
+
98
+ /** What `POST /v1/submit` answers: one result per molecule, in their order. */
99
+ export interface SubmitResponse {
100
+ source: string;
101
+ results: SubmitResult[];
102
+ summary: SubmitSummary;
103
+ }
104
+
105
+ /** What `POST /v1/imports` answers: the start of a full import. */
106
+ export interface ImportStarted {
107
+ source: string;
108
+ importKey: number;
109
+ importStartedAt: number;
110
+ }
111
+
112
+ /** What `GET /v1/imports` answers: where the source's import stands. */
113
+ export interface ImportState {
114
+ source: string;
115
+ importKey: number;
116
+ importStartedAt: number | null;
117
+ updatedAt: number | null;
118
+ entries: number;
119
+ stale: number;
120
+ }
121
+
122
+ /** What a purge answers. */
123
+ export interface PurgeResponse {
124
+ source: string;
125
+ importKey: number;
126
+ dryRun: boolean;
127
+ /** The entries the import did not send again, removed or to be removed. */
128
+ removed: number;
129
+ /** The entries the source holds after. */
130
+ remaining: number;
131
+ }
132
+
133
+ /** One answer of `POST /v1/batch`: the molecule a query reads as, or why not. */
134
+ export interface LookupResult {
135
+ query: string;
136
+ result: MoleculeInfo | null;
137
+ /** Whether molecules.cheminfo.org lists it, rather than computing it now. */
138
+ cached: boolean;
139
+ /**
140
+ * Why the query could not be read.
141
+ * @default undefined - it was read
142
+ */
143
+ error?: string;
144
+ }
145
+
146
+ /** What `POST /v1/batch` answers: one result per query, in their order. */
147
+ export interface LookupResponse {
148
+ results: LookupResult[];
149
+ }
150
+
151
+ /** Why a request is tried again, and when. */
152
+ export interface RetryDetails {
153
+ method: string;
154
+ path: string;
155
+ attempt: number;
156
+ /**
157
+ * The status that was answered.
158
+ * @default undefined - nothing was answered
159
+ */
160
+ status?: number;
161
+ reason: string;
162
+ delayMs: number;
163
+ }
@@ -0,0 +1,118 @@
1
+ import { toError } from '../../error/core/toError.ts';
2
+
3
+ /**
4
+ * The pieces of a request that is tried again: its deadline, the pause the
5
+ * server asks for, what an error answer says, and what a failed fetch says.
6
+ * Browser-safe: no Node module is read.
7
+ */
8
+
9
+ /**
10
+ * The signal one attempt runs under: the caller's, and its own deadline.
11
+ * @param signal - The caller's, if any.
12
+ * @param timeoutMs - How long the attempt may take.
13
+ * @returns The signal.
14
+ */
15
+ export function requestSignal(
16
+ signal: AbortSignal | undefined,
17
+ timeoutMs: number,
18
+ ): AbortSignal {
19
+ const timeout = AbortSignal.timeout(timeoutMs);
20
+ return signal === undefined ? timeout : AbortSignal.any([signal, timeout]);
21
+ }
22
+
23
+ /**
24
+ * How long a `Retry-After` header asks to wait.
25
+ * @param header - Its value: seconds, or an HTTP date.
26
+ * @param now - The current instant, in epoch milliseconds.
27
+ * @returns The pause in milliseconds, or `undefined` when there is none to read.
28
+ */
29
+ export function retryAfter(
30
+ header: string | null,
31
+ now: number,
32
+ ): number | undefined {
33
+ if (header === null || header.trim() === '') return undefined;
34
+ const seconds = Number(header);
35
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);
36
+ const date = Date.parse(header);
37
+ return Number.isNaN(date) ? undefined : Math.max(0, date - now);
38
+ }
39
+
40
+ /**
41
+ * The message of an error body Fastify wrote, or the body itself.
42
+ * @param text - The body.
43
+ * @returns The message, or `undefined` when the body is empty.
44
+ */
45
+ export function messageOf(text: string): string | undefined {
46
+ if (text.trim() === '') return undefined;
47
+ try {
48
+ const body = JSON.parse(text) as { message?: unknown } | null;
49
+ if (typeof body?.message === 'string') return body.message;
50
+ } catch {
51
+ return text.slice(0, 500);
52
+ }
53
+ return text.slice(0, 500);
54
+ }
55
+
56
+ /**
57
+ * What a failed fetch says, its cause included: undici reports a refused
58
+ * connection as `fetch failed` with the reason in `cause` — and when several
59
+ * addresses were tried, in the first error of an AggregateError whose own
60
+ * message is empty.
61
+ * @param error - What was thrown.
62
+ * @returns The message, e.g. `fetch failed: connect ECONNREFUSED 127.0.0.1:11980`.
63
+ */
64
+ export function causeOf(error: unknown): string {
65
+ if (!(error instanceof Error)) return String(error);
66
+ const { cause, message } = error;
67
+ if (!(cause instanceof Error)) return message;
68
+ const first: unknown =
69
+ cause instanceof AggregateError ? cause.errors[0] : undefined;
70
+ const code = (cause as { code?: unknown }).code;
71
+ const detail =
72
+ cause.message ||
73
+ (first instanceof Error ? first.message : '') ||
74
+ (typeof code === 'string' ? code : '') ||
75
+ cause.name;
76
+ return `${message}: ${detail}`;
77
+ }
78
+
79
+ /**
80
+ * A request body gzipped, as HTTP's `Content-Encoding: gzip` carries it: a
81
+ * batch of molfiles shrinks several times over.
82
+ * @param text - The body, written out.
83
+ * @returns The gzipped bytes.
84
+ */
85
+ export async function gzipBody(text: string): Promise<Uint8Array<ArrayBuffer>> {
86
+ const stream = new Blob([text])
87
+ .stream()
88
+ .pipeThrough(new CompressionStream('gzip'));
89
+ return new Uint8Array(await new Response(stream).arrayBuffer());
90
+ }
91
+
92
+ /**
93
+ * Wait, unless the signal stops the wait first.
94
+ * @param milliseconds - How long.
95
+ * @param signal - What stops it, if anything.
96
+ * @returns When the time has passed.
97
+ * @throws {unknown} The signal's reason, when it aborts first.
98
+ */
99
+ export function pause(
100
+ milliseconds: number,
101
+ signal: AbortSignal | undefined,
102
+ ): Promise<void> {
103
+ return new Promise((done, fail) => {
104
+ if (signal?.aborted) {
105
+ fail(toError(signal.reason));
106
+ return;
107
+ }
108
+ const abort = () => {
109
+ clearTimeout(timer);
110
+ fail(toError(signal?.reason));
111
+ };
112
+ const timer = setTimeout(() => {
113
+ signal?.removeEventListener('abort', abort);
114
+ done();
115
+ }, milliseconds);
116
+ signal?.addEventListener('abort', abort, { once: true });
117
+ });
118
+ }
@@ -34,10 +34,11 @@ const SPIN_AXIS = Vec3.create(0, 1, 0);
34
34
  * measured against — so reading a camera and applying it are the same move in
35
35
  * opposite directions.
36
36
  * @param radius - Radius of the scene's visible bounding sphere.
37
+ * @param margin - Fraction of the radius kept as breathing room.
37
38
  * @returns The framed radius.
38
39
  */
39
- export function framedRadius(radius: number): number {
40
- return Math.max(radius * (1 + FRAMING_MARGIN), MINIMUM_FRAMING_RADIUS);
40
+ export function framedRadius(radius: number, margin = FRAMING_MARGIN): number {
41
+ return Math.max(radius * (1 + margin), MINIMUM_FRAMING_RADIUS);
41
42
  }
42
43
 
43
44
  /**