tempest-react-sdk 0.24.0 → 0.26.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 (403) hide show
  1. package/README.md +25 -4
  2. package/bin/lib/alias/collect.mjs +94 -0
  3. package/bin/lib/alias/collect.test.mjs +95 -0
  4. package/bin/lib/alias/discover.mjs +77 -0
  5. package/bin/lib/alias/discover.test.mjs +189 -0
  6. package/bin/lib/alias/index.mjs +88 -0
  7. package/bin/lib/alias/index.test.mjs +138 -0
  8. package/bin/lib/alias/rewrite-css.mjs +76 -0
  9. package/bin/lib/alias/rewrite-css.test.mjs +85 -0
  10. package/bin/lib/alias/rewrite.mjs +141 -0
  11. package/bin/lib/alias/rewrite.test.mjs +148 -0
  12. package/bin/lib/alias/specifier.mjs +49 -0
  13. package/bin/lib/alias/specifier.test.mjs +85 -0
  14. package/bin/lib/alias/tsconfig.mjs +116 -0
  15. package/bin/lib/alias/typescript.mjs +23 -0
  16. package/bin/lib/icons/generate.mjs +156 -0
  17. package/bin/lib/icons/generate.test.mjs +125 -0
  18. package/bin/tempest.mjs +158 -13
  19. package/dist/audio/use-audio.cjs +1 -1
  20. package/dist/audio/use-audio.cjs.map +1 -1
  21. package/dist/audio/use-audio.js +12 -12
  22. package/dist/audio/use-audio.js.map +1 -1
  23. package/dist/charts/AreaChart.cjs +1 -1
  24. package/dist/charts/AreaChart.cjs.map +1 -1
  25. package/dist/charts/AreaChart.js +7 -7
  26. package/dist/charts/AreaChart.js.map +1 -1
  27. package/dist/charts/BarChart.cjs +1 -1
  28. package/dist/charts/BarChart.cjs.map +1 -1
  29. package/dist/charts/BarChart.js +7 -7
  30. package/dist/charts/BarChart.js.map +1 -1
  31. package/dist/charts/LineChart.cjs +1 -1
  32. package/dist/charts/LineChart.cjs.map +1 -1
  33. package/dist/charts/LineChart.js +6 -6
  34. package/dist/charts/LineChart.js.map +1 -1
  35. package/dist/charts/PieChart.cjs +1 -1
  36. package/dist/charts/PieChart.cjs.map +1 -1
  37. package/dist/charts/PieChart.js +6 -6
  38. package/dist/charts/PieChart.js.map +1 -1
  39. package/dist/charts/RadarChart.cjs +1 -1
  40. package/dist/charts/RadarChart.cjs.map +1 -1
  41. package/dist/charts/RadarChart.js +6 -6
  42. package/dist/charts/RadarChart.js.map +1 -1
  43. package/dist/charts/palette.cjs +1 -1
  44. package/dist/charts/palette.cjs.map +1 -1
  45. package/dist/charts/palette.js +19 -2
  46. package/dist/charts/palette.js.map +1 -1
  47. package/dist/charts/use-chart-colors.cjs +2 -0
  48. package/dist/charts/use-chart-colors.cjs.map +1 -0
  49. package/dist/charts/use-chart-colors.js +29 -0
  50. package/dist/charts/use-chart-colors.js.map +1 -0
  51. package/dist/charts.cjs +1 -1
  52. package/dist/charts.d.ts +61 -10
  53. package/dist/charts.js +8 -7
  54. package/dist/components/AvatarGroup/AvatarGroup.cjs +2 -0
  55. package/dist/components/AvatarGroup/AvatarGroup.cjs.map +1 -0
  56. package/dist/components/AvatarGroup/AvatarGroup.js +39 -0
  57. package/dist/components/AvatarGroup/AvatarGroup.js.map +1 -0
  58. package/dist/components/AvatarGroup/AvatarGroup.module.cjs +2 -0
  59. package/dist/components/AvatarGroup/AvatarGroup.module.cjs.map +1 -0
  60. package/dist/components/AvatarGroup/AvatarGroup.module.js +16 -0
  61. package/dist/components/AvatarGroup/AvatarGroup.module.js.map +1 -0
  62. package/dist/components/ClickOutside/ClickOutside.cjs +1 -1
  63. package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
  64. package/dist/components/ClickOutside/ClickOutside.js +3 -1
  65. package/dist/components/ClickOutside/ClickOutside.js.map +1 -1
  66. package/dist/components/DataTable/DataTable.cjs +1 -1
  67. package/dist/components/DataTable/DataTable.cjs.map +1 -1
  68. package/dist/components/DataTable/DataTable.js +21 -23
  69. package/dist/components/DataTable/DataTable.js.map +1 -1
  70. package/dist/components/Kanban/Kanban.cjs +2 -0
  71. package/dist/components/Kanban/Kanban.cjs.map +1 -0
  72. package/dist/components/Kanban/Kanban.js +102 -0
  73. package/dist/components/Kanban/Kanban.js.map +1 -0
  74. package/dist/components/Kanban/Kanban.module.cjs +2 -0
  75. package/dist/components/Kanban/Kanban.module.cjs.map +1 -0
  76. package/dist/components/Kanban/Kanban.module.js +19 -0
  77. package/dist/components/Kanban/Kanban.module.js.map +1 -0
  78. package/dist/components/Lightbox/Lightbox.cjs +2 -0
  79. package/dist/components/Lightbox/Lightbox.cjs.map +1 -0
  80. package/dist/components/Lightbox/Lightbox.js +148 -0
  81. package/dist/components/Lightbox/Lightbox.js.map +1 -0
  82. package/dist/components/Lightbox/Lightbox.module.cjs +2 -0
  83. package/dist/components/Lightbox/Lightbox.module.cjs.map +1 -0
  84. package/dist/components/Lightbox/Lightbox.module.js +21 -0
  85. package/dist/components/Lightbox/Lightbox.module.js.map +1 -0
  86. package/dist/components/NotificationCenter/NotificationCenter.cjs +2 -0
  87. package/dist/components/NotificationCenter/NotificationCenter.cjs.map +1 -0
  88. package/dist/components/NotificationCenter/NotificationCenter.js +83 -0
  89. package/dist/components/NotificationCenter/NotificationCenter.js.map +1 -0
  90. package/dist/components/NotificationCenter/NotificationCenter.module.cjs +2 -0
  91. package/dist/components/NotificationCenter/NotificationCenter.module.cjs.map +1 -0
  92. package/dist/components/NotificationCenter/NotificationCenter.module.js +21 -0
  93. package/dist/components/NotificationCenter/NotificationCenter.module.js.map +1 -0
  94. package/dist/components/NotificationCenter/use-notification-inbox.cjs +2 -0
  95. package/dist/components/NotificationCenter/use-notification-inbox.cjs.map +1 -0
  96. package/dist/components/NotificationCenter/use-notification-inbox.js +63 -0
  97. package/dist/components/NotificationCenter/use-notification-inbox.js.map +1 -0
  98. package/dist/components/RefreshIndicator/RefreshIndicator.cjs +1 -1
  99. package/dist/components/RefreshIndicator/RefreshIndicator.cjs.map +1 -1
  100. package/dist/components/RefreshIndicator/RefreshIndicator.js +17 -17
  101. package/dist/components/RefreshIndicator/RefreshIndicator.js.map +1 -1
  102. package/dist/components/SignaturePad/SignaturePad.cjs +2 -0
  103. package/dist/components/SignaturePad/SignaturePad.cjs.map +1 -0
  104. package/dist/components/SignaturePad/SignaturePad.js +115 -0
  105. package/dist/components/SignaturePad/SignaturePad.js.map +1 -0
  106. package/dist/components/SignaturePad/SignaturePad.module.cjs +2 -0
  107. package/dist/components/SignaturePad/SignaturePad.module.cjs.map +1 -0
  108. package/dist/components/SignaturePad/SignaturePad.module.js +11 -0
  109. package/dist/components/SignaturePad/SignaturePad.module.js.map +1 -0
  110. package/dist/components/Stepper/Stepper.cjs +1 -1
  111. package/dist/components/Stepper/Stepper.cjs.map +1 -1
  112. package/dist/components/Stepper/Stepper.js +43 -19
  113. package/dist/components/Stepper/Stepper.js.map +1 -1
  114. package/dist/components/Stepper/Stepper.module.cjs +1 -1
  115. package/dist/components/Stepper/Stepper.module.cjs.map +1 -1
  116. package/dist/components/Stepper/Stepper.module.js +6 -3
  117. package/dist/components/Stepper/Stepper.module.js.map +1 -1
  118. package/dist/components/Tooltip/Tooltip.cjs +1 -1
  119. package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
  120. package/dist/components/Tooltip/Tooltip.js +26 -20
  121. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  122. package/dist/components/TreeView/TreeView.cjs +2 -0
  123. package/dist/components/TreeView/TreeView.cjs.map +1 -0
  124. package/dist/components/TreeView/TreeView.js +124 -0
  125. package/dist/components/TreeView/TreeView.js.map +1 -0
  126. package/dist/components/TreeView/TreeView.module.cjs +2 -0
  127. package/dist/components/TreeView/TreeView.module.cjs.map +1 -0
  128. package/dist/components/TreeView/TreeView.module.js +17 -0
  129. package/dist/components/TreeView/TreeView.module.js.map +1 -0
  130. package/dist/components/VirtualTable/VirtualTable.cjs +2 -0
  131. package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -0
  132. package/dist/components/VirtualTable/VirtualTable.js +116 -0
  133. package/dist/components/VirtualTable/VirtualTable.js.map +1 -0
  134. package/dist/components/VirtualTable/VirtualTable.module.cjs +2 -0
  135. package/dist/components/VirtualTable/VirtualTable.module.cjs.map +1 -0
  136. package/dist/components/VirtualTable/VirtualTable.module.js +20 -0
  137. package/dist/components/VirtualTable/VirtualTable.module.js.map +1 -0
  138. package/dist/components/Wizard/Wizard.cjs +2 -0
  139. package/dist/components/Wizard/Wizard.cjs.map +1 -0
  140. package/dist/components/Wizard/Wizard.js +111 -0
  141. package/dist/components/Wizard/Wizard.js.map +1 -0
  142. package/dist/components/Wizard/Wizard.module.cjs +2 -0
  143. package/dist/components/Wizard/Wizard.module.cjs.map +1 -0
  144. package/dist/components/Wizard/Wizard.module.js +10 -0
  145. package/dist/components/Wizard/Wizard.module.js.map +1 -0
  146. package/dist/geo/use-position-tracker.cjs +1 -1
  147. package/dist/geo/use-position-tracker.cjs.map +1 -1
  148. package/dist/geo/use-position-tracker.js +3 -1
  149. package/dist/geo/use-position-tracker.js.map +1 -1
  150. package/dist/hooks/use-async.cjs +1 -1
  151. package/dist/hooks/use-async.cjs.map +1 -1
  152. package/dist/hooks/use-async.js +3 -1
  153. package/dist/hooks/use-async.js.map +1 -1
  154. package/dist/hooks/use-click-outside.cjs +1 -1
  155. package/dist/hooks/use-click-outside.cjs.map +1 -1
  156. package/dist/hooks/use-click-outside.js +3 -1
  157. package/dist/hooks/use-click-outside.js.map +1 -1
  158. package/dist/hooks/use-deep-memo.cjs.map +1 -1
  159. package/dist/hooks/use-deep-memo.js.map +1 -1
  160. package/dist/hooks/use-event-listener.cjs +1 -1
  161. package/dist/hooks/use-event-listener.cjs.map +1 -1
  162. package/dist/hooks/use-event-listener.js +3 -1
  163. package/dist/hooks/use-event-listener.js.map +1 -1
  164. package/dist/hooks/use-interval.cjs +1 -1
  165. package/dist/hooks/use-interval.cjs.map +1 -1
  166. package/dist/hooks/use-interval.js +3 -1
  167. package/dist/hooks/use-interval.js.map +1 -1
  168. package/dist/hooks/use-is-first-render.cjs.map +1 -1
  169. package/dist/hooks/use-is-first-render.js.map +1 -1
  170. package/dist/hooks/use-long-press-handlers.cjs +1 -1
  171. package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
  172. package/dist/hooks/use-long-press-handlers.js +25 -23
  173. package/dist/hooks/use-long-press-handlers.js.map +1 -1
  174. package/dist/hooks/use-long-press.cjs +1 -1
  175. package/dist/hooks/use-long-press.cjs.map +1 -1
  176. package/dist/hooks/use-long-press.js +3 -1
  177. package/dist/hooks/use-long-press.js.map +1 -1
  178. package/dist/hooks/use-online.cjs +1 -1
  179. package/dist/hooks/use-online.cjs.map +1 -1
  180. package/dist/hooks/use-online.js +6 -4
  181. package/dist/hooks/use-online.js.map +1 -1
  182. package/dist/hooks/use-previous.cjs.map +1 -1
  183. package/dist/hooks/use-previous.js.map +1 -1
  184. package/dist/hooks/use-service-worker-update.cjs +1 -1
  185. package/dist/hooks/use-service-worker-update.cjs.map +1 -1
  186. package/dist/hooks/use-service-worker-update.js +3 -1
  187. package/dist/hooks/use-service-worker-update.js.map +1 -1
  188. package/dist/hooks/use-sortable.cjs +2 -0
  189. package/dist/hooks/use-sortable.cjs.map +1 -0
  190. package/dist/hooks/use-sortable.js +169 -0
  191. package/dist/hooks/use-sortable.js.map +1 -0
  192. package/dist/hooks/use-stable-callback.cjs.map +1 -1
  193. package/dist/hooks/use-stable-callback.js.map +1 -1
  194. package/dist/hooks/use-timeout.cjs +1 -1
  195. package/dist/hooks/use-timeout.cjs.map +1 -1
  196. package/dist/hooks/use-timeout.js +3 -1
  197. package/dist/hooks/use-timeout.js.map +1 -1
  198. package/dist/icons/Icon.cjs +2 -0
  199. package/dist/icons/Icon.cjs.map +1 -0
  200. package/dist/icons/Icon.js +24 -0
  201. package/dist/icons/Icon.js.map +1 -0
  202. package/dist/icons/IconProvider.cjs +2 -0
  203. package/dist/icons/IconProvider.cjs.map +1 -0
  204. package/dist/icons/IconProvider.js +24 -0
  205. package/dist/icons/IconProvider.js.map +1 -0
  206. package/dist/icons/generated/aliases.cjs +2 -0
  207. package/dist/icons/generated/aliases.cjs.map +1 -0
  208. package/dist/icons/generated/aliases.js +255 -0
  209. package/dist/icons/generated/aliases.js.map +1 -0
  210. package/dist/icons/generated/icon-names.cjs +2 -0
  211. package/dist/icons/generated/icon-names.cjs.map +1 -0
  212. package/dist/icons/generated/icon-names.js +6 -0
  213. package/dist/icons/generated/icon-names.js.map +1 -0
  214. package/dist/icons/generated/loaders.cjs +2 -0
  215. package/dist/icons/generated/loaders.cjs.map +1 -0
  216. package/dist/icons/generated/loaders.js +32 -0
  217. package/dist/icons/generated/loaders.js.map +1 -0
  218. package/dist/icons/generated/shard-a.cjs +2 -0
  219. package/dist/icons/generated/shard-a.cjs.map +1 -0
  220. package/dist/icons/generated/shard-a.js +114 -0
  221. package/dist/icons/generated/shard-a.js.map +1 -0
  222. package/dist/icons/generated/shard-b.cjs +2 -0
  223. package/dist/icons/generated/shard-b.cjs.map +1 -0
  224. package/dist/icons/generated/shard-b.js +156 -0
  225. package/dist/icons/generated/shard-b.js.map +1 -0
  226. package/dist/icons/generated/shard-c.cjs +2 -0
  227. package/dist/icons/generated/shard-c.cjs.map +1 -0
  228. package/dist/icons/generated/shard-c.js +269 -0
  229. package/dist/icons/generated/shard-c.js.map +1 -0
  230. package/dist/icons/generated/shard-d.cjs +2 -0
  231. package/dist/icons/generated/shard-d.cjs.map +1 -0
  232. package/dist/icons/generated/shard-d.js +62 -0
  233. package/dist/icons/generated/shard-d.js.map +1 -0
  234. package/dist/icons/generated/shard-e.cjs +2 -0
  235. package/dist/icons/generated/shard-e.cjs.map +1 -0
  236. package/dist/icons/generated/shard-e.js +32 -0
  237. package/dist/icons/generated/shard-e.js.map +1 -0
  238. package/dist/icons/generated/shard-f.cjs +2 -0
  239. package/dist/icons/generated/shard-f.cjs.map +1 -0
  240. package/dist/icons/generated/shard-f.js +139 -0
  241. package/dist/icons/generated/shard-f.js.map +1 -0
  242. package/dist/icons/generated/shard-g.cjs +2 -0
  243. package/dist/icons/generated/shard-g.cjs.map +1 -0
  244. package/dist/icons/generated/shard-g.js +61 -0
  245. package/dist/icons/generated/shard-g.js.map +1 -0
  246. package/dist/icons/generated/shard-h.cjs +2 -0
  247. package/dist/icons/generated/shard-h.cjs.map +1 -0
  248. package/dist/icons/generated/shard-h.js +63 -0
  249. package/dist/icons/generated/shard-h.js.map +1 -0
  250. package/dist/icons/generated/shard-i.cjs +2 -0
  251. package/dist/icons/generated/shard-i.cjs.map +1 -0
  252. package/dist/icons/generated/shard-i.js +30 -0
  253. package/dist/icons/generated/shard-i.js.map +1 -0
  254. package/dist/icons/generated/shard-j.cjs +2 -0
  255. package/dist/icons/generated/shard-j.cjs.map +1 -0
  256. package/dist/icons/generated/shard-j.js +10 -0
  257. package/dist/icons/generated/shard-j.js.map +1 -0
  258. package/dist/icons/generated/shard-k.cjs +2 -0
  259. package/dist/icons/generated/shard-k.cjs.map +1 -0
  260. package/dist/icons/generated/shard-k.js +16 -0
  261. package/dist/icons/generated/shard-k.js.map +1 -0
  262. package/dist/icons/generated/shard-l.cjs +2 -0
  263. package/dist/icons/generated/shard-l.cjs.map +1 -0
  264. package/dist/icons/generated/shard-l.js +88 -0
  265. package/dist/icons/generated/shard-l.js.map +1 -0
  266. package/dist/icons/generated/shard-m.cjs +2 -0
  267. package/dist/icons/generated/shard-m.cjs.map +1 -0
  268. package/dist/icons/generated/shard-m.js +140 -0
  269. package/dist/icons/generated/shard-m.js.map +1 -0
  270. package/dist/icons/generated/shard-n.cjs +2 -0
  271. package/dist/icons/generated/shard-n.cjs.map +1 -0
  272. package/dist/icons/generated/shard-n.js +24 -0
  273. package/dist/icons/generated/shard-n.js.map +1 -0
  274. package/dist/icons/generated/shard-o.cjs +2 -0
  275. package/dist/icons/generated/shard-o.cjs.map +1 -0
  276. package/dist/icons/generated/shard-o.js +17 -0
  277. package/dist/icons/generated/shard-o.js.map +1 -0
  278. package/dist/icons/generated/shard-p.cjs +2 -0
  279. package/dist/icons/generated/shard-p.cjs.map +1 -0
  280. package/dist/icons/generated/shard-p.js +115 -0
  281. package/dist/icons/generated/shard-p.js.map +1 -0
  282. package/dist/icons/generated/shard-q.cjs +2 -0
  283. package/dist/icons/generated/shard-q.cjs.map +1 -0
  284. package/dist/icons/generated/shard-q.js +10 -0
  285. package/dist/icons/generated/shard-q.js.map +1 -0
  286. package/dist/icons/generated/shard-r.cjs +2 -0
  287. package/dist/icons/generated/shard-r.cjs.map +1 -0
  288. package/dist/icons/generated/shard-r.js +77 -0
  289. package/dist/icons/generated/shard-r.js.map +1 -0
  290. package/dist/icons/generated/shard-s.cjs +2 -0
  291. package/dist/icons/generated/shard-s.cjs.map +1 -0
  292. package/dist/icons/generated/shard-s.js +255 -0
  293. package/dist/icons/generated/shard-s.js.map +1 -0
  294. package/dist/icons/generated/shard-t.cjs +2 -0
  295. package/dist/icons/generated/shard-t.cjs.map +1 -0
  296. package/dist/icons/generated/shard-t.js +109 -0
  297. package/dist/icons/generated/shard-t.js.map +1 -0
  298. package/dist/icons/generated/shard-u.cjs +2 -0
  299. package/dist/icons/generated/shard-u.cjs.map +1 -0
  300. package/dist/icons/generated/shard-u.js +49 -0
  301. package/dist/icons/generated/shard-u.js.map +1 -0
  302. package/dist/icons/generated/shard-v.cjs +2 -0
  303. package/dist/icons/generated/shard-v.cjs.map +1 -0
  304. package/dist/icons/generated/shard-v.js +30 -0
  305. package/dist/icons/generated/shard-v.js.map +1 -0
  306. package/dist/icons/generated/shard-w.cjs +2 -0
  307. package/dist/icons/generated/shard-w.cjs.map +1 -0
  308. package/dist/icons/generated/shard-w.js +48 -0
  309. package/dist/icons/generated/shard-w.js.map +1 -0
  310. package/dist/icons/generated/shard-x.cjs +2 -0
  311. package/dist/icons/generated/shard-x.cjs.map +1 -0
  312. package/dist/icons/generated/shard-x.js +10 -0
  313. package/dist/icons/generated/shard-x.js.map +1 -0
  314. package/dist/icons/generated/shard-z.cjs +2 -0
  315. package/dist/icons/generated/shard-z.cjs.map +1 -0
  316. package/dist/icons/generated/shard-z.js +25 -0
  317. package/dist/icons/generated/shard-z.js.map +1 -0
  318. package/dist/icons/icon-context.cjs +2 -0
  319. package/dist/icons/icon-context.cjs.map +1 -0
  320. package/dist/icons/icon-context.js +13 -0
  321. package/dist/icons/icon-context.js.map +1 -0
  322. package/dist/icons/is-icon-name.cjs +2 -0
  323. package/dist/icons/is-icon-name.cjs.map +1 -0
  324. package/dist/icons/is-icon-name.js +10 -0
  325. package/dist/icons/is-icon-name.js.map +1 -0
  326. package/dist/icons/shard-cache.cjs +2 -0
  327. package/dist/icons/shard-cache.cjs.map +1 -0
  328. package/dist/icons/shard-cache.js +41 -0
  329. package/dist/icons/shard-cache.js.map +1 -0
  330. package/dist/icons/use-icon.cjs +2 -0
  331. package/dist/icons/use-icon.cjs.map +1 -0
  332. package/dist/icons/use-icon.js +20 -0
  333. package/dist/icons/use-icon.js.map +1 -0
  334. package/dist/icons-virtual.d.ts +22 -0
  335. package/dist/icons.cjs +1 -0
  336. package/dist/icons.d.ts +220 -0
  337. package/dist/icons.js +9 -0
  338. package/dist/offline/create-offline-sync.cjs +1 -1
  339. package/dist/offline/create-offline-sync.cjs.map +1 -1
  340. package/dist/offline/create-offline-sync.js +8 -2
  341. package/dist/offline/create-offline-sync.js.map +1 -1
  342. package/dist/offline/use-offline-sync.cjs +1 -1
  343. package/dist/offline/use-offline-sync.cjs.map +1 -1
  344. package/dist/offline/use-offline-sync.js +3 -1
  345. package/dist/offline/use-offline-sync.js.map +1 -1
  346. package/dist/push/use-push-subscription.cjs +1 -1
  347. package/dist/push/use-push-subscription.cjs.map +1 -1
  348. package/dist/push/use-push-subscription.js +3 -1
  349. package/dist/push/use-push-subscription.js.map +1 -1
  350. package/dist/sse/use-event-stream.cjs +1 -1
  351. package/dist/sse/use-event-stream.cjs.map +1 -1
  352. package/dist/sse/use-event-stream.js +3 -1
  353. package/dist/sse/use-event-stream.js.map +1 -1
  354. package/dist/styles.css +1 -1
  355. package/dist/tempest-react-sdk.cjs +1 -1
  356. package/dist/tempest-react-sdk.d.ts +1187 -2
  357. package/dist/tempest-react-sdk.js +261 -246
  358. package/dist/theme/ThemeProvider.cjs +1 -1
  359. package/dist/theme/ThemeProvider.cjs.map +1 -1
  360. package/dist/theme/ThemeProvider.js +6 -2
  361. package/dist/theme/ThemeProvider.js.map +1 -1
  362. package/dist/theme/apply-theme.cjs +2 -0
  363. package/dist/theme/apply-theme.cjs.map +1 -0
  364. package/dist/theme/apply-theme.js +24 -0
  365. package/dist/theme/apply-theme.js.map +1 -0
  366. package/dist/theme/color.cjs +2 -0
  367. package/dist/theme/color.cjs.map +1 -0
  368. package/dist/theme/color.js +161 -0
  369. package/dist/theme/color.js.map +1 -0
  370. package/dist/theme/create-theme.cjs +5 -0
  371. package/dist/theme/create-theme.cjs.map +1 -0
  372. package/dist/theme/create-theme.js +141 -0
  373. package/dist/theme/create-theme.js.map +1 -0
  374. package/dist/theme/theme-presets.cjs +2 -0
  375. package/dist/theme/theme-presets.cjs.map +1 -0
  376. package/dist/theme/theme-presets.js +82 -0
  377. package/dist/theme/theme-presets.js.map +1 -0
  378. package/dist/utilities.css +432 -0
  379. package/dist/utils/compare-values.cjs +2 -0
  380. package/dist/utils/compare-values.cjs.map +1 -0
  381. package/dist/utils/compare-values.js +8 -0
  382. package/dist/utils/compare-values.js.map +1 -0
  383. package/dist/vision/use-camera-stream.cjs +1 -1
  384. package/dist/vision/use-camera-stream.cjs.map +1 -1
  385. package/dist/vision/use-camera-stream.js +3 -1
  386. package/dist/vision/use-camera-stream.js.map +1 -1
  387. package/dist/vite/create-vite-config.cjs +1 -1
  388. package/dist/vite/create-vite-config.cjs.map +1 -1
  389. package/dist/vite/create-vite-config.js +30 -22
  390. package/dist/vite/create-vite-config.js.map +1 -1
  391. package/dist/vite/tempest-icons.cjs +9 -0
  392. package/dist/vite/tempest-icons.cjs.map +1 -0
  393. package/dist/vite/tempest-icons.js +99 -0
  394. package/dist/vite/tempest-icons.js.map +1 -0
  395. package/dist/vite.cjs +1 -1
  396. package/dist/vite.d.ts +79 -0
  397. package/dist/vite.js +6 -5
  398. package/dist/ws/use-web-socket.cjs +1 -1
  399. package/dist/ws/use-web-socket.cjs.map +1 -1
  400. package/dist/ws/use-web-socket.js +3 -1
  401. package/dist/ws/use-web-socket.js.map +1 -1
  402. package/package.json +14 -4
  403. package/template/package.json +1 -1
@@ -1,8 +1,9 @@
1
- import { resolve as e } from "node:path";
2
- import { defineConfig as t } from "vite";
3
- import n from "@vitejs/plugin-react";
1
+ import { tempestIcons as e } from "./tempest-icons.js";
2
+ import { resolve as t } from "node:path";
3
+ import { defineConfig as n } from "vite";
4
+ import r from "@vitejs/plugin-react";
4
5
  //#region src/vite/create-vite-config.ts
5
- function r(e) {
6
+ function i(e) {
6
7
  let t = {};
7
8
  for (let [n, r] of Object.entries(e)) t[n] = typeof r == "string" ? {
8
9
  target: r,
@@ -10,35 +11,42 @@ function r(e) {
10
11
  } : r;
11
12
  return t;
12
13
  }
13
- function i(i = {}) {
14
- let { srcDir: a = "src", port: o = 5173, host: s = "127.0.0.1", open: c = !1, proxy: l, alias: u = {}, plugins: d = [], overrides: f = {} } = i, p = f, m = {
15
- plugins: [n(), ...d],
14
+ function a(a = {}) {
15
+ let { srcDir: o = "src", port: s = 5173, host: c = "127.0.0.1", open: l = !1, proxy: u, alias: d = {}, plugins: f = [], icons: p = !0, overrides: m = {} } = a, h = m, g = p ? [e({
16
+ dir: o,
17
+ ...typeof p == "object" ? p : {}
18
+ })] : [], _ = {
19
+ plugins: [
20
+ r(),
21
+ ...g,
22
+ ...f
23
+ ],
16
24
  resolve: { alias: {
17
- "@": e(process.cwd(), a),
18
- ...u
25
+ "@": t(process.cwd(), o),
26
+ ...d
19
27
  } },
20
28
  server: {
21
- port: o,
22
- host: s,
23
- open: c,
24
- ...l ? { proxy: r(l) } : {}
29
+ port: s,
30
+ host: c,
31
+ open: l,
32
+ ...u ? { proxy: i(u) } : {}
25
33
  }
26
34
  };
27
- return t({
28
- ...m,
29
- ...p,
30
- plugins: [...m.plugins ?? [], ...p.plugins ?? []],
35
+ return n({
36
+ ..._,
37
+ ...h,
38
+ plugins: [..._.plugins ?? [], ...h.plugins ?? []],
31
39
  resolve: {
32
- ...m.resolve,
33
- ...p.resolve
40
+ ..._.resolve,
41
+ ...h.resolve
34
42
  },
35
43
  server: {
36
- ...m.server,
37
- ...p.server
44
+ ..._.server,
45
+ ...h.server
38
46
  }
39
47
  });
40
48
  }
41
49
  //#endregion
42
- export { i as createViteConfig };
50
+ export { a as createViteConfig };
43
51
 
44
52
  //# sourceMappingURL=create-vite-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-vite-config.js","names":[],"sources":["../../src/vite/create-vite-config.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { defineConfig } from \"vite\";\nimport type { ProxyOptions, UserConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\n/**\n * A Vite proxy entry: either a target URL string (expanded to\n * `{ target, changeOrigin: true }`) or a raw Vite `ProxyOptions` object.\n */\nexport type ProxyEntry = string | Record<string, unknown>;\n\nexport interface CreateViteConfigOptions {\n /**\n * Source directory aliased to `@`, relative to the project root.\n * Default: `\"src\"` (so `@/components/Button` → `<root>/src/components/Button`).\n */\n srcDir?: string;\n /** Dev server port. Default: `5173`. */\n port?: number;\n /** Dev server host. Default: `\"127.0.0.1\"`. */\n host?: string | boolean;\n /** Open the browser on `dev` start. Default: `false`. */\n open?: boolean;\n /**\n * Dev proxy table. String values are expanded to\n * `{ target, changeOrigin: true }`; objects are passed through untouched.\n *\n * @example { \"/api\": \"http://127.0.0.1:8000\" }\n */\n proxy?: Record<string, ProxyEntry>;\n /** Extra path aliases merged on top of the default `@` → src alias. */\n alias?: Record<string, string>;\n /** Vite plugins appended after `@vitejs/plugin-react`. */\n plugins?: unknown[];\n /**\n * Arbitrary Vite config (a `UserConfig` object) deep-merged last, for\n * escape-hatch overrides (build target, define, extra `server` keys, …).\n */\n overrides?: Record<string, unknown>;\n}\n\n/**\n * The resulting Vite config object. Typed loosely so the SDK's published\n * declarations stay free of `vite`'s internal types; assign it straight to a\n * `vite.config.ts` default export.\n */\nexport type TempestViteConfig = Record<string, unknown>;\n\nfunction normalizeProxy(proxy: Record<string, ProxyEntry>): Record<string, ProxyOptions> {\n const out: Record<string, ProxyOptions> = {};\n for (const [path, value] of Object.entries(proxy)) {\n out[path] =\n typeof value === \"string\"\n ? { target: value, changeOrigin: true }\n : (value as ProxyOptions);\n }\n return out;\n}\n\n/**\n * Build a Tempest-flavored Vite config for a React app: the `@vitejs/plugin-react`\n * plugin, the `@` → `src` import alias, and sane dev-server defaults — so a\n * consuming app's `vite.config.ts` is a single call instead of repeated\n * boilerplate. Everything is overridable.\n *\n * Import it from the dedicated Node entry point:\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({\n * proxy: { \"/api\": \"http://127.0.0.1:8000\" },\n * });\n */\nexport function createViteConfig(options: CreateViteConfigOptions = {}): TempestViteConfig {\n const {\n srcDir = \"src\",\n port = 5173,\n host = \"127.0.0.1\",\n open = false,\n proxy,\n alias = {},\n plugins = [],\n overrides = {},\n } = options;\n\n const overridesConfig = overrides as UserConfig;\n\n const base: UserConfig = {\n plugins: [react(), ...plugins] as UserConfig[\"plugins\"],\n resolve: {\n alias: {\n \"@\": resolve(process.cwd(), srcDir),\n ...alias,\n },\n },\n server: {\n port,\n host,\n open,\n ...(proxy ? { proxy: normalizeProxy(proxy) } : {}),\n },\n };\n\n const merged: UserConfig = {\n ...base,\n ...overridesConfig,\n plugins: [...(base.plugins ?? []), ...(overridesConfig.plugins ?? [])],\n resolve: { ...base.resolve, ...overridesConfig.resolve },\n server: { ...base.server, ...overridesConfig.server },\n };\n\n return defineConfig(merged) as TempestViteConfig;\n}\n"],"mappings":";;;;AAgDA,SAAS,EAAe,GAAiE;CACrF,IAAM,IAAoC,CAAC;CAC3C,KAAK,IAAM,CAAC,GAAM,MAAU,OAAO,QAAQ,CAAK,GAC5C,EAAI,KACA,OAAO,KAAU,WACX;EAAE,QAAQ;EAAO,cAAc;CAAK,IACnC;CAEf,OAAO;AACX;AAkBA,SAAgB,EAAiB,IAAmC,CAAC,GAAsB;CACvF,IAAM,EACF,YAAS,OACT,UAAO,MACP,UAAO,aACP,UAAO,IACP,UACA,WAAQ,CAAC,GACT,aAAU,CAAC,GACX,eAAY,CAAC,MACb,GAEE,IAAkB,GAElB,IAAmB;EACrB,SAAS,CAAC,EAAM,GAAG,GAAG,CAAO;EAC7B,SAAS,EACL,OAAO;GACH,KAAK,EAAQ,QAAQ,IAAI,GAAG,CAAM;GAClC,GAAG;EACP,EACJ;EACA,QAAQ;GACJ;GACA;GACA;GACA,GAAI,IAAQ,EAAE,OAAO,EAAe,CAAK,EAAE,IAAI,CAAC;EACpD;CACJ;CAUA,OAAO,EAAa;EAPhB,GAAG;EACH,GAAG;EACH,SAAS,CAAC,GAAI,EAAK,WAAW,CAAC,GAAI,GAAI,EAAgB,WAAW,CAAC,CAAE;EACrE,SAAS;GAAE,GAAG,EAAK;GAAS,GAAG,EAAgB;EAAQ;EACvD,QAAQ;GAAE,GAAG,EAAK;GAAQ,GAAG,EAAgB;EAAO;CAGpC,CAAM;AAC9B"}
1
+ {"version":3,"file":"create-vite-config.js","names":[],"sources":["../../src/vite/create-vite-config.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { defineConfig } from \"vite\";\nimport type { ProxyOptions, UserConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\n\nimport { tempestIcons, type TempestIconsOptions } from \"./tempest-icons\";\n\n/**\n * A Vite proxy entry: either a target URL string (expanded to\n * `{ target, changeOrigin: true }`) or a raw Vite `ProxyOptions` object.\n */\nexport type ProxyEntry = string | Record<string, unknown>;\n\nexport interface CreateViteConfigOptions {\n /**\n * Source directory aliased to `@`, relative to the project root.\n * Default: `\"src\"` (so `@/components/Button` → `<root>/src/components/Button`).\n */\n srcDir?: string;\n /** Dev server port. Default: `5173`. */\n port?: number;\n /** Dev server host. Default: `\"127.0.0.1\"`. */\n host?: string | boolean;\n /** Open the browser on `dev` start. Default: `false`. */\n open?: boolean;\n /**\n * Dev proxy table. String values are expanded to\n * `{ target, changeOrigin: true }`; objects are passed through untouched.\n *\n * @example { \"/api\": \"http://127.0.0.1:8000\" }\n */\n proxy?: Record<string, ProxyEntry>;\n /** Extra path aliases merged on top of the default `@` → src alias. */\n alias?: Record<string, string>;\n /** Vite plugins appended after `@vitejs/plugin-react`. */\n plugins?: unknown[];\n /**\n * The `tempestIcons()` plugin, which generates `virtual:tempest-icons` from the\n * icon slugs your source mentions. On by default — it only ever removes\n * requests. Pass `false` to leave it out, or an options object to configure the\n * scan.\n */\n icons?: boolean | TempestIconsOptions;\n /**\n * Arbitrary Vite config (a `UserConfig` object) deep-merged last, for\n * escape-hatch overrides (build target, define, extra `server` keys, …).\n */\n overrides?: Record<string, unknown>;\n}\n\n/**\n * The resulting Vite config object. Typed loosely so the SDK's published\n * declarations stay free of `vite`'s internal types; assign it straight to a\n * `vite.config.ts` default export.\n */\nexport type TempestViteConfig = Record<string, unknown>;\n\nfunction normalizeProxy(proxy: Record<string, ProxyEntry>): Record<string, ProxyOptions> {\n const out: Record<string, ProxyOptions> = {};\n for (const [path, value] of Object.entries(proxy)) {\n out[path] =\n typeof value === \"string\"\n ? { target: value, changeOrigin: true }\n : (value as ProxyOptions);\n }\n return out;\n}\n\n/**\n * Build a Tempest-flavored Vite config for a React app: the `@vitejs/plugin-react`\n * plugin, the `@` → `src` import alias, and sane dev-server defaults — so a\n * consuming app's `vite.config.ts` is a single call instead of repeated\n * boilerplate. Everything is overridable.\n *\n * Import it from the dedicated Node entry point:\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({\n * proxy: { \"/api\": \"http://127.0.0.1:8000\" },\n * });\n */\nexport function createViteConfig(options: CreateViteConfigOptions = {}): TempestViteConfig {\n const {\n srcDir = \"src\",\n port = 5173,\n host = \"127.0.0.1\",\n open = false,\n proxy,\n alias = {},\n plugins = [],\n icons = true,\n overrides = {},\n } = options;\n\n const overridesConfig = overrides as UserConfig;\n const iconsPlugin = icons\n ? [tempestIcons({ dir: srcDir, ...(typeof icons === \"object\" ? icons : {}) })]\n : [];\n\n const base: UserConfig = {\n plugins: [react(), ...iconsPlugin, ...plugins] as UserConfig[\"plugins\"],\n resolve: {\n alias: {\n \"@\": resolve(process.cwd(), srcDir),\n ...alias,\n },\n },\n server: {\n port,\n host,\n open,\n ...(proxy ? { proxy: normalizeProxy(proxy) } : {}),\n },\n };\n\n const merged: UserConfig = {\n ...base,\n ...overridesConfig,\n plugins: [...(base.plugins ?? []), ...(overridesConfig.plugins ?? [])],\n resolve: { ...base.resolve, ...overridesConfig.resolve },\n server: { ...base.server, ...overridesConfig.server },\n };\n\n return defineConfig(merged) as TempestViteConfig;\n}\n"],"mappings":";;;;;AAyDA,SAAS,EAAe,GAAiE;CACrF,IAAM,IAAoC,CAAC;CAC3C,KAAK,IAAM,CAAC,GAAM,MAAU,OAAO,QAAQ,CAAK,GAC5C,EAAI,KACA,OAAO,KAAU,WACX;EAAE,QAAQ;EAAO,cAAc;CAAK,IACnC;CAEf,OAAO;AACX;AAkBA,SAAgB,EAAiB,IAAmC,CAAC,GAAsB;CACvF,IAAM,EACF,YAAS,OACT,UAAO,MACP,UAAO,aACP,UAAO,IACP,UACA,WAAQ,CAAC,GACT,aAAU,CAAC,GACX,WAAQ,IACR,eAAY,CAAC,MACb,GAEE,IAAkB,GAClB,IAAc,IACd,CAAC,EAAa;EAAE,KAAK;EAAQ,GAAI,OAAO,KAAU,WAAW,IAAQ,CAAC;CAAG,CAAC,CAAC,IAC3E,CAAC,GAED,IAAmB;EACrB,SAAS;GAAC,EAAM;GAAG,GAAG;GAAa,GAAG;EAAO;EAC7C,SAAS,EACL,OAAO;GACH,KAAK,EAAQ,QAAQ,IAAI,GAAG,CAAM;GAClC,GAAG;EACP,EACJ;EACA,QAAQ;GACJ;GACA;GACA;GACA,GAAI,IAAQ,EAAE,OAAO,EAAe,CAAK,EAAE,IAAI,CAAC;EACpD;CACJ;CAUA,OAAO,EAAa;EAPhB,GAAG;EACH,GAAG;EACH,SAAS,CAAC,GAAI,EAAK,WAAW,CAAC,GAAI,GAAI,EAAgB,WAAW,CAAC,CAAE;EACrE,SAAS;GAAE,GAAG,EAAK;GAAS,GAAG,EAAgB;EAAQ;EACvD,QAAQ;GAAE,GAAG,EAAK;GAAQ,GAAG,EAAgB;EAAO;CAGpC,CAAM;AAC9B"}
@@ -0,0 +1,9 @@
1
+ const e=require("../icons/generated/aliases.cjs"),t=require("../icons/generated/icon-names.cjs");let n=require("node:path"),r=require("node:fs/promises");var i=`virtual:tempest-icons`,a=`\0${i}`,o=[/\bname\s*=\s*["']([a-z0-9-]+)["']/g,/\bname\s*=\s*\{\s*["']([a-z0-9-]+)["']\s*\}/g,/\bname\s*:\s*["']([a-z0-9-]+)["']/g],s=/\.[cm]?[jt]sx?$/,c=new Set([`node_modules`,`dist`,`build`,`coverage`]);function l(e,t){let n=new Set;for(let r of o){r.lastIndex=0;let i;for(;(i=r.exec(e))!==null;)t.has(i[1])&&n.add(i[1])}return[...n]}function u(e,t){let n=[...new Set(e)].sort();if(!n.length)return`export const staticIcons = {};
2
+ `;let r=new Map;for(let e of n)r.set(e,d(t[e]??e));return`import { ${[...new Set(r.values())].sort().map(e=>p(e)===e?e:`${e} as ${p(e)}`).join(`, `)} } from "lucide-react";
3
+
4
+ export const staticIcons = {
5
+ ${n.map(e=>` "${e}": ${p(r.get(e))},`).join(`
6
+ `)}
7
+ };
8
+ `}function d(e){return e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)}var f=new Set([`Infinity`,`NaN`,`undefined`,`eval`,`arguments`]);function p(e){return f.has(e)?`${e}Icon`:e}async function m(e,t){let i=[],a;try{a=await(0,r.readdir)(e,{withFileTypes:!0})}catch{return i}for(let r of a)if(r.isDirectory()){if(t.has(r.name)||r.name.startsWith(`.`))continue;i.push(...await m((0,n.join)(e,r.name),t))}else r.isFile()&&s.test(r.name)&&i.push((0,n.join)(e,r.name));return i}function h(i={}){let{dir:o=`src`,include:d=[],skipDirs:f}=i,p=new Set(t.iconNames),h=new Set(f??c),g=new Set(d.filter(e=>p.has(e))),_=process.cwd(),v=async()=>{let e=await m((0,n.resolve)(_,o),h);for(let t of e)try{let e=await(0,r.readFile)(t,`utf8`);for(let t of l(e,p))g.add(t)}catch{}};return{name:`tempest-icons`,enforce:`pre`,configResolved(e){_=e.root??_},async buildStart(){await v()},resolveId(e){return e===`virtual:tempest-icons`?a:null},load(t){return t===a?u([...g],e.iconAliases):null},async handleHotUpdate(e){if(!s.test(e.file))return;let t=g.size;for(let t of l(await e.read(),p))g.add(t);if(g.size===t)return;let n=e.server.moduleGraph.getModuleById(a);if(n)return[n]}}}exports.TEMPEST_ICONS_ID=i,exports.buildIconsModule=u,exports.scanIconSlugs=l,exports.tempestIcons=h;
9
+ //# sourceMappingURL=tempest-icons.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tempest-icons.cjs","names":[],"sources":["../../src/vite/tempest-icons.ts"],"sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nimport { iconAliases } from \"@/icons/generated/aliases\";\nimport { iconNames } from \"@/icons/generated/icon-names\";\n\nimport type { TempestVitePlugin } from \"./tempest-pwa-manifest\";\n\n/** The module id an app imports to get its static registry. */\nexport const TEMPEST_ICONS_ID = \"virtual:tempest-icons\";\n\nconst RESOLVED_ID = `\\0${TEMPEST_ICONS_ID}`;\n\n/**\n * Slugs written as a literal `name` prop or a literal `name:` field.\n *\n * Matching the *attribute* rather than any kebab-case string is what keeps the\n * scan from sweeping in unrelated text — a CSS class, a translation key and a\n * route segment all look like slugs otherwise. Everything matched is still\n * validated against lucide's real slug list before it reaches the module.\n */\nconst NAME_PATTERNS = [\n /\\bname\\s*=\\s*[\"']([a-z0-9-]+)[\"']/g,\n /\\bname\\s*=\\s*\\{\\s*[\"']([a-z0-9-]+)[\"']\\s*\\}/g,\n /\\bname\\s*:\\s*[\"']([a-z0-9-]+)[\"']/g,\n];\n\nconst SOURCE_FILE = /\\.[cm]?[jt]sx?$/;\nconst SKIP_DIRS = new Set([\"node_modules\", \"dist\", \"build\", \"coverage\"]);\n\nexport interface TempestIconsOptions {\n /**\n * Directory to scan, relative to the Vite root. Default: `\"src\"`.\n */\n dir?: string;\n /**\n * Extra slugs to include even when the scan cannot see them — a name built by\n * concatenation, or one that only ever arrives from the API but is worth\n * paying for statically because it is on the first screen.\n */\n include?: readonly string[];\n /** Directory names to skip. Default: `node_modules`, `dist`, `build`, `coverage`. */\n skipDirs?: readonly string[];\n}\n\n/**\n * Collect the icon slugs a source file references literally.\n *\n * @param code - File contents.\n * @param known - The set of real lucide slugs, aliases included.\n * @returns The slugs found, validated against `known`.\n */\nexport function scanIconSlugs(code: string, known: ReadonlySet<string>): string[] {\n const found = new Set<string>();\n for (const pattern of NAME_PATTERNS) {\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(code)) !== null) {\n if (known.has(match[1])) found.add(match[1]);\n }\n }\n return [...found];\n}\n\n/**\n * Build the virtual module source for a set of slugs.\n *\n * Aliases resolve to their canonical slug before importing, because only the\n * canonical name is a real lucide export — but the alias key still points at the\n * component, so `<Icon name=\"alert-circle\" />` stays a zero-request lookup.\n *\n * @param slugs - Validated slugs to include.\n * @param aliases - Alias slug → canonical slug.\n * @returns ES module source.\n */\nexport function buildIconsModule(\n slugs: readonly string[],\n aliases: Record<string, string>,\n): string {\n const sorted = [...new Set(slugs)].sort();\n if (!sorted.length) return \"export const staticIcons = {};\\n\";\n\n const componentOf = new Map<string, string>();\n for (const slug of sorted) componentOf.set(slug, pascalCase(aliases[slug] ?? slug));\n\n const named = [...new Set(componentOf.values())]\n .sort()\n .map((name) => (localName(name) === name ? name : `${name} as ${localName(name)}`))\n .join(\", \");\n const entries = sorted\n .map((slug) => ` \"${slug}\": ${localName(componentOf.get(slug) as string)},`)\n .join(\"\\n\");\n return `import { ${named} } from \"lucide-react\";\n\nexport const staticIcons = {\n${entries}\n};\n`;\n}\n\n/** `circle-alert` → `CircleAlert`; `a-arrow-down` → `AArrowDown`. */\nfunction pascalCase(slug: string): string {\n return slug\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n}\n\n/**\n * Export names that would shadow a restricted global if bound directly.\n *\n * Lucide ships an icon literally called `infinity`, whose export is `Infinity`.\n * Binding that at module scope shadows the global, so the import is aliased.\n */\nconst RESERVED_NAMES = new Set([\"Infinity\", \"NaN\", \"undefined\", \"eval\", \"arguments\"]);\n\n/** The local binding to use for a lucide export name. */\nfunction localName(name: string): string {\n return RESERVED_NAMES.has(name) ? `${name}Icon` : name;\n}\n\n/**\n * Walk a directory and collect every source file path.\n *\n * @param dir - Absolute directory to walk.\n * @param skip - Directory names to skip.\n * @returns Absolute file paths.\n */\nasync function collectSourceFiles(dir: string, skip: ReadonlySet<string>): Promise<string[]> {\n const out: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return out;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (skip.has(entry.name) || entry.name.startsWith(\".\")) continue;\n out.push(...(await collectSourceFiles(join(dir, entry.name), skip)));\n } else if (entry.isFile() && SOURCE_FILE.test(entry.name)) {\n out.push(join(dir, entry.name));\n }\n }\n return out;\n}\n\n/**\n * Generate a static icon registry from the slugs your source mentions.\n *\n * Removes the reason to reach for `lucide-react`'s `DynamicIcon`: the slugs an app\n * writes as literals become ordinary static imports, so the bundler keeps exactly\n * those icons and the browser makes **no** extra request for them. A slug that only\n * exists at runtime still works — `<Icon>` falls back to fetching one shard per\n * initial letter.\n *\n * The scan reads the source tree directly at `buildStart` rather than harvesting\n * modules as they pass through `transform`: relying on transform order would let\n * the virtual module load before every consumer had been seen, and the registry\n * would come out short on a cold dev start — silently, since the missing slugs\n * would still render via the lazy path.\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig, tempestIcons } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({ plugins: [tempestIcons()] });\n *\n * @example\n * // src/main.tsx\n * import { IconProvider } from \"tempest-react-sdk/icons\";\n * import { staticIcons } from \"virtual:tempest-icons\";\n *\n * <IconProvider registry={staticIcons}>\n * <App />\n * </IconProvider>\n */\nexport function tempestIcons(options: TempestIconsOptions = {}): TempestVitePlugin {\n const { dir = \"src\", include = [], skipDirs } = options;\n const known = new Set<string>(iconNames);\n const skip = new Set<string>(skipDirs ?? SKIP_DIRS);\n const slugs = new Set<string>(include.filter((slug) => known.has(slug)));\n let root = process.cwd();\n\n /** Rescan the source tree, keeping the explicitly included slugs. */\n const rescan = async (): Promise<void> => {\n const files = await collectSourceFiles(resolve(root, dir), skip);\n for (const file of files) {\n try {\n const code = await readFile(file, \"utf8\");\n for (const slug of scanIconSlugs(code, known)) slugs.add(slug);\n } catch {\n /* an unreadable file just contributes nothing */\n }\n }\n };\n\n return {\n name: \"tempest-icons\",\n enforce: \"pre\",\n\n configResolved(config: { root?: string }) {\n root = config.root ?? root;\n },\n\n async buildStart() {\n await rescan();\n },\n\n resolveId(id: string) {\n return id === TEMPEST_ICONS_ID ? RESOLVED_ID : null;\n },\n\n load(id: string) {\n return id === RESOLVED_ID ? buildIconsModule([...slugs], iconAliases) : null;\n },\n\n /**\n * Pick up a slug added while the dev server is running.\n *\n * A newly written `<Icon name=\"save\" />` would otherwise only render via\n * the lazy path until the next restart. Rescanning the changed file and\n * invalidating the virtual module keeps dev and build agreeing on what the\n * static registry contains.\n */\n async handleHotUpdate(ctx: {\n file: string;\n read: () => Promise<string>;\n server: { moduleGraph: { getModuleById: (id: string) => unknown } };\n }) {\n if (!SOURCE_FILE.test(ctx.file)) return;\n const before = slugs.size;\n for (const slug of scanIconSlugs(await ctx.read(), known)) slugs.add(slug);\n if (slugs.size === before) return;\n const mod = ctx.server.moduleGraph.getModuleById(RESOLVED_ID);\n if (mod) return [mod];\n },\n } as TempestVitePlugin;\n}\n"],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { iconAliases as e } from "../icons/generated/aliases.js";
2
+ import { iconNames as t } from "../icons/generated/icon-names.js";
3
+ import { join as n, resolve as r } from "node:path";
4
+ import { readFile as i, readdir as a } from "node:fs/promises";
5
+ //#region src/vite/tempest-icons.ts
6
+ var o = "virtual:tempest-icons", s = `\0${o}`, c = [
7
+ /\bname\s*=\s*["']([a-z0-9-]+)["']/g,
8
+ /\bname\s*=\s*\{\s*["']([a-z0-9-]+)["']\s*\}/g,
9
+ /\bname\s*:\s*["']([a-z0-9-]+)["']/g
10
+ ], l = /\.[cm]?[jt]sx?$/, u = /* @__PURE__ */ new Set([
11
+ "node_modules",
12
+ "dist",
13
+ "build",
14
+ "coverage"
15
+ ]);
16
+ function d(e, t) {
17
+ let n = /* @__PURE__ */ new Set();
18
+ for (let r of c) {
19
+ r.lastIndex = 0;
20
+ let i;
21
+ for (; (i = r.exec(e)) !== null;) t.has(i[1]) && n.add(i[1]);
22
+ }
23
+ return [...n];
24
+ }
25
+ function f(e, t) {
26
+ let n = [...new Set(e)].sort();
27
+ if (!n.length) return "export const staticIcons = {};\n";
28
+ let r = /* @__PURE__ */ new Map();
29
+ for (let e of n) r.set(e, p(t[e] ?? e));
30
+ return `import { ${[...new Set(r.values())].sort().map((e) => h(e) === e ? e : `${e} as ${h(e)}`).join(", ")} } from "lucide-react";
31
+
32
+ export const staticIcons = {
33
+ ${n.map((e) => ` "${e}": ${h(r.get(e))},`).join("\n")}
34
+ };
35
+ `;
36
+ }
37
+ function p(e) {
38
+ return e.split("-").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("");
39
+ }
40
+ var m = /* @__PURE__ */ new Set([
41
+ "Infinity",
42
+ "NaN",
43
+ "undefined",
44
+ "eval",
45
+ "arguments"
46
+ ]);
47
+ function h(e) {
48
+ return m.has(e) ? `${e}Icon` : e;
49
+ }
50
+ async function g(e, t) {
51
+ let r = [], i;
52
+ try {
53
+ i = await a(e, { withFileTypes: !0 });
54
+ } catch {
55
+ return r;
56
+ }
57
+ for (let a of i) if (a.isDirectory()) {
58
+ if (t.has(a.name) || a.name.startsWith(".")) continue;
59
+ r.push(...await g(n(e, a.name), t));
60
+ } else a.isFile() && l.test(a.name) && r.push(n(e, a.name));
61
+ return r;
62
+ }
63
+ function _(n = {}) {
64
+ let { dir: a = "src", include: o = [], skipDirs: c } = n, p = new Set(t), m = new Set(c ?? u), h = new Set(o.filter((e) => p.has(e))), _ = process.cwd(), v = async () => {
65
+ let e = await g(r(_, a), m);
66
+ for (let t of e) try {
67
+ let e = await i(t, "utf8");
68
+ for (let t of d(e, p)) h.add(t);
69
+ } catch {}
70
+ };
71
+ return {
72
+ name: "tempest-icons",
73
+ enforce: "pre",
74
+ configResolved(e) {
75
+ _ = e.root ?? _;
76
+ },
77
+ async buildStart() {
78
+ await v();
79
+ },
80
+ resolveId(e) {
81
+ return e === "virtual:tempest-icons" ? s : null;
82
+ },
83
+ load(t) {
84
+ return t === s ? f([...h], e) : null;
85
+ },
86
+ async handleHotUpdate(e) {
87
+ if (!l.test(e.file)) return;
88
+ let t = h.size;
89
+ for (let t of d(await e.read(), p)) h.add(t);
90
+ if (h.size === t) return;
91
+ let n = e.server.moduleGraph.getModuleById(s);
92
+ if (n) return [n];
93
+ }
94
+ };
95
+ }
96
+ //#endregion
97
+ export { o as TEMPEST_ICONS_ID, f as buildIconsModule, d as scanIconSlugs, _ as tempestIcons };
98
+
99
+ //# sourceMappingURL=tempest-icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tempest-icons.js","names":[],"sources":["../../src/vite/tempest-icons.ts"],"sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nimport { iconAliases } from \"@/icons/generated/aliases\";\nimport { iconNames } from \"@/icons/generated/icon-names\";\n\nimport type { TempestVitePlugin } from \"./tempest-pwa-manifest\";\n\n/** The module id an app imports to get its static registry. */\nexport const TEMPEST_ICONS_ID = \"virtual:tempest-icons\";\n\nconst RESOLVED_ID = `\\0${TEMPEST_ICONS_ID}`;\n\n/**\n * Slugs written as a literal `name` prop or a literal `name:` field.\n *\n * Matching the *attribute* rather than any kebab-case string is what keeps the\n * scan from sweeping in unrelated text — a CSS class, a translation key and a\n * route segment all look like slugs otherwise. Everything matched is still\n * validated against lucide's real slug list before it reaches the module.\n */\nconst NAME_PATTERNS = [\n /\\bname\\s*=\\s*[\"']([a-z0-9-]+)[\"']/g,\n /\\bname\\s*=\\s*\\{\\s*[\"']([a-z0-9-]+)[\"']\\s*\\}/g,\n /\\bname\\s*:\\s*[\"']([a-z0-9-]+)[\"']/g,\n];\n\nconst SOURCE_FILE = /\\.[cm]?[jt]sx?$/;\nconst SKIP_DIRS = new Set([\"node_modules\", \"dist\", \"build\", \"coverage\"]);\n\nexport interface TempestIconsOptions {\n /**\n * Directory to scan, relative to the Vite root. Default: `\"src\"`.\n */\n dir?: string;\n /**\n * Extra slugs to include even when the scan cannot see them — a name built by\n * concatenation, or one that only ever arrives from the API but is worth\n * paying for statically because it is on the first screen.\n */\n include?: readonly string[];\n /** Directory names to skip. Default: `node_modules`, `dist`, `build`, `coverage`. */\n skipDirs?: readonly string[];\n}\n\n/**\n * Collect the icon slugs a source file references literally.\n *\n * @param code - File contents.\n * @param known - The set of real lucide slugs, aliases included.\n * @returns The slugs found, validated against `known`.\n */\nexport function scanIconSlugs(code: string, known: ReadonlySet<string>): string[] {\n const found = new Set<string>();\n for (const pattern of NAME_PATTERNS) {\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(code)) !== null) {\n if (known.has(match[1])) found.add(match[1]);\n }\n }\n return [...found];\n}\n\n/**\n * Build the virtual module source for a set of slugs.\n *\n * Aliases resolve to their canonical slug before importing, because only the\n * canonical name is a real lucide export — but the alias key still points at the\n * component, so `<Icon name=\"alert-circle\" />` stays a zero-request lookup.\n *\n * @param slugs - Validated slugs to include.\n * @param aliases - Alias slug → canonical slug.\n * @returns ES module source.\n */\nexport function buildIconsModule(\n slugs: readonly string[],\n aliases: Record<string, string>,\n): string {\n const sorted = [...new Set(slugs)].sort();\n if (!sorted.length) return \"export const staticIcons = {};\\n\";\n\n const componentOf = new Map<string, string>();\n for (const slug of sorted) componentOf.set(slug, pascalCase(aliases[slug] ?? slug));\n\n const named = [...new Set(componentOf.values())]\n .sort()\n .map((name) => (localName(name) === name ? name : `${name} as ${localName(name)}`))\n .join(\", \");\n const entries = sorted\n .map((slug) => ` \"${slug}\": ${localName(componentOf.get(slug) as string)},`)\n .join(\"\\n\");\n return `import { ${named} } from \"lucide-react\";\n\nexport const staticIcons = {\n${entries}\n};\n`;\n}\n\n/** `circle-alert` → `CircleAlert`; `a-arrow-down` → `AArrowDown`. */\nfunction pascalCase(slug: string): string {\n return slug\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n}\n\n/**\n * Export names that would shadow a restricted global if bound directly.\n *\n * Lucide ships an icon literally called `infinity`, whose export is `Infinity`.\n * Binding that at module scope shadows the global, so the import is aliased.\n */\nconst RESERVED_NAMES = new Set([\"Infinity\", \"NaN\", \"undefined\", \"eval\", \"arguments\"]);\n\n/** The local binding to use for a lucide export name. */\nfunction localName(name: string): string {\n return RESERVED_NAMES.has(name) ? `${name}Icon` : name;\n}\n\n/**\n * Walk a directory and collect every source file path.\n *\n * @param dir - Absolute directory to walk.\n * @param skip - Directory names to skip.\n * @returns Absolute file paths.\n */\nasync function collectSourceFiles(dir: string, skip: ReadonlySet<string>): Promise<string[]> {\n const out: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return out;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (skip.has(entry.name) || entry.name.startsWith(\".\")) continue;\n out.push(...(await collectSourceFiles(join(dir, entry.name), skip)));\n } else if (entry.isFile() && SOURCE_FILE.test(entry.name)) {\n out.push(join(dir, entry.name));\n }\n }\n return out;\n}\n\n/**\n * Generate a static icon registry from the slugs your source mentions.\n *\n * Removes the reason to reach for `lucide-react`'s `DynamicIcon`: the slugs an app\n * writes as literals become ordinary static imports, so the bundler keeps exactly\n * those icons and the browser makes **no** extra request for them. A slug that only\n * exists at runtime still works — `<Icon>` falls back to fetching one shard per\n * initial letter.\n *\n * The scan reads the source tree directly at `buildStart` rather than harvesting\n * modules as they pass through `transform`: relying on transform order would let\n * the virtual module load before every consumer had been seen, and the registry\n * would come out short on a cold dev start — silently, since the missing slugs\n * would still render via the lazy path.\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig, tempestIcons } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({ plugins: [tempestIcons()] });\n *\n * @example\n * // src/main.tsx\n * import { IconProvider } from \"tempest-react-sdk/icons\";\n * import { staticIcons } from \"virtual:tempest-icons\";\n *\n * <IconProvider registry={staticIcons}>\n * <App />\n * </IconProvider>\n */\nexport function tempestIcons(options: TempestIconsOptions = {}): TempestVitePlugin {\n const { dir = \"src\", include = [], skipDirs } = options;\n const known = new Set<string>(iconNames);\n const skip = new Set<string>(skipDirs ?? SKIP_DIRS);\n const slugs = new Set<string>(include.filter((slug) => known.has(slug)));\n let root = process.cwd();\n\n /** Rescan the source tree, keeping the explicitly included slugs. */\n const rescan = async (): Promise<void> => {\n const files = await collectSourceFiles(resolve(root, dir), skip);\n for (const file of files) {\n try {\n const code = await readFile(file, \"utf8\");\n for (const slug of scanIconSlugs(code, known)) slugs.add(slug);\n } catch {\n /* an unreadable file just contributes nothing */\n }\n }\n };\n\n return {\n name: \"tempest-icons\",\n enforce: \"pre\",\n\n configResolved(config: { root?: string }) {\n root = config.root ?? root;\n },\n\n async buildStart() {\n await rescan();\n },\n\n resolveId(id: string) {\n return id === TEMPEST_ICONS_ID ? RESOLVED_ID : null;\n },\n\n load(id: string) {\n return id === RESOLVED_ID ? buildIconsModule([...slugs], iconAliases) : null;\n },\n\n /**\n * Pick up a slug added while the dev server is running.\n *\n * A newly written `<Icon name=\"save\" />` would otherwise only render via\n * the lazy path until the next restart. Rescanning the changed file and\n * invalidating the virtual module keeps dev and build agreeing on what the\n * static registry contains.\n */\n async handleHotUpdate(ctx: {\n file: string;\n read: () => Promise<string>;\n server: { moduleGraph: { getModuleById: (id: string) => unknown } };\n }) {\n if (!SOURCE_FILE.test(ctx.file)) return;\n const before = slugs.size;\n for (const slug of scanIconSlugs(await ctx.read(), known)) slugs.add(slug);\n if (slugs.size === before) return;\n const mod = ctx.server.moduleGraph.getModuleById(RESOLVED_ID);\n if (mod) return [mod];\n },\n } as TempestVitePlugin;\n}\n"],"mappings":"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"}
package/dist/vite.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./vite/create-vite-config.cjs"),t=require("./vite/tempest-pwa-manifest.cjs"),n=require("./vite/tempest-pwa-icons.cjs"),r=require("./vite/tempest-pwa-dev-sw.cjs");exports.createViteConfig=e.createViteConfig,exports.tempestPwaDevSw=r.tempestPwaDevSw,exports.tempestPwaIcons=n.tempestPwaIcons,exports.tempestPwaManifest=t.tempestPwaManifest;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./vite/tempest-icons.cjs"),t=require("./vite/create-vite-config.cjs"),n=require("./vite/tempest-pwa-manifest.cjs"),r=require("./vite/tempest-pwa-icons.cjs"),i=require("./vite/tempest-pwa-dev-sw.cjs");exports.TEMPEST_ICONS_ID=e.TEMPEST_ICONS_ID,exports.buildIconsModule=e.buildIconsModule,exports.createViteConfig=t.createViteConfig,exports.scanIconSlugs=e.scanIconSlugs,exports.tempestIcons=e.tempestIcons,exports.tempestPwaDevSw=i.tempestPwaDevSw,exports.tempestPwaIcons=r.tempestPwaIcons,exports.tempestPwaManifest=n.tempestPwaManifest;
package/dist/vite.d.ts CHANGED
@@ -8,6 +8,19 @@ export declare interface AppleSplashSpec {
8
8
  ratio: number;
9
9
  }
10
10
 
11
+ /**
12
+ * Build the virtual module source for a set of slugs.
13
+ *
14
+ * Aliases resolve to their canonical slug before importing, because only the
15
+ * canonical name is a real lucide export — but the alias key still points at the
16
+ * component, so `<Icon name="alert-circle" />` stays a zero-request lookup.
17
+ *
18
+ * @param slugs - Validated slugs to include.
19
+ * @param aliases - Alias slug → canonical slug.
20
+ * @returns ES module source.
21
+ */
22
+ export declare function buildIconsModule(slugs: readonly string[], aliases: Record<string, string>): string;
23
+
11
24
  /**
12
25
  * Build a Tempest-flavored Vite config for a React app: the `@vitejs/plugin-react`
13
26
  * plugin, the `@` → `src` import alias, and sane dev-server defaults — so a
@@ -49,6 +62,13 @@ export declare interface CreateViteConfigOptions {
49
62
  alias?: Record<string, string>;
50
63
  /** Vite plugins appended after `@vitejs/plugin-react`. */
51
64
  plugins?: unknown[];
65
+ /**
66
+ * The `tempestIcons()` plugin, which generates `virtual:tempest-icons` from the
67
+ * icon slugs your source mentions. On by default — it only ever removes
68
+ * requests. Pass `false` to leave it out, or an options object to configure the
69
+ * scan.
70
+ */
71
+ icons?: boolean | TempestIconsOptions;
52
72
  /**
53
73
  * Arbitrary Vite config (a `UserConfig` object) deep-merged last, for
54
74
  * escape-hatch overrides (build target, define, extra `server` keys, …).
@@ -62,6 +82,65 @@ export declare interface CreateViteConfigOptions {
62
82
  */
63
83
  export declare type ProxyEntry = string | Record<string, unknown>;
64
84
 
85
+ /**
86
+ * Collect the icon slugs a source file references literally.
87
+ *
88
+ * @param code - File contents.
89
+ * @param known - The set of real lucide slugs, aliases included.
90
+ * @returns The slugs found, validated against `known`.
91
+ */
92
+ export declare function scanIconSlugs(code: string, known: ReadonlySet<string>): string[];
93
+
94
+ /** The module id an app imports to get its static registry. */
95
+ export declare const TEMPEST_ICONS_ID = "virtual:tempest-icons";
96
+
97
+ /**
98
+ * Generate a static icon registry from the slugs your source mentions.
99
+ *
100
+ * Removes the reason to reach for `lucide-react`'s `DynamicIcon`: the slugs an app
101
+ * writes as literals become ordinary static imports, so the bundler keeps exactly
102
+ * those icons and the browser makes **no** extra request for them. A slug that only
103
+ * exists at runtime still works — `<Icon>` falls back to fetching one shard per
104
+ * initial letter.
105
+ *
106
+ * The scan reads the source tree directly at `buildStart` rather than harvesting
107
+ * modules as they pass through `transform`: relying on transform order would let
108
+ * the virtual module load before every consumer had been seen, and the registry
109
+ * would come out short on a cold dev start — silently, since the missing slugs
110
+ * would still render via the lazy path.
111
+ *
112
+ * @example
113
+ * // vite.config.ts
114
+ * import { createViteConfig, tempestIcons } from "tempest-react-sdk/vite";
115
+ *
116
+ * export default createViteConfig({ plugins: [tempestIcons()] });
117
+ *
118
+ * @example
119
+ * // src/main.tsx
120
+ * import { IconProvider } from "tempest-react-sdk/icons";
121
+ * import { staticIcons } from "virtual:tempest-icons";
122
+ *
123
+ * <IconProvider registry={staticIcons}>
124
+ * <App />
125
+ * </IconProvider>
126
+ */
127
+ export declare function tempestIcons(options?: TempestIconsOptions): TempestVitePlugin;
128
+
129
+ export declare interface TempestIconsOptions {
130
+ /**
131
+ * Directory to scan, relative to the Vite root. Default: `"src"`.
132
+ */
133
+ dir?: string;
134
+ /**
135
+ * Extra slugs to include even when the scan cannot see them — a name built by
136
+ * concatenation, or one that only ever arrives from the API but is worth
137
+ * paying for statically because it is on the first screen.
138
+ */
139
+ include?: readonly string[];
140
+ /** Directory names to skip. Default: `node_modules`, `dist`, `build`, `coverage`. */
141
+ skipDirs?: readonly string[];
142
+ }
143
+
65
144
  /**
66
145
  * Dev-server plugin that makes the service worker available under `npm run dev`.
67
146
  *
package/dist/vite.js CHANGED
@@ -1,5 +1,6 @@
1
- import { createViteConfig as e } from "./vite/create-vite-config.js";
2
- import { tempestPwaManifest as t } from "./vite/tempest-pwa-manifest.js";
3
- import { tempestPwaIcons as n } from "./vite/tempest-pwa-icons.js";
4
- import { tempestPwaDevSw as r } from "./vite/tempest-pwa-dev-sw.js";
5
- export { e as createViteConfig, r as tempestPwaDevSw, n as tempestPwaIcons, t as tempestPwaManifest };
1
+ import { TEMPEST_ICONS_ID as e, buildIconsModule as t, scanIconSlugs as n, tempestIcons as r } from "./vite/tempest-icons.js";
2
+ import { createViteConfig as i } from "./vite/create-vite-config.js";
3
+ import { tempestPwaManifest as a } from "./vite/tempest-pwa-manifest.js";
4
+ import { tempestPwaIcons as o } from "./vite/tempest-pwa-icons.js";
5
+ import { tempestPwaDevSw as s } from "./vite/tempest-pwa-dev-sw.js";
6
+ export { e as TEMPEST_ICONS_ID, t as buildIconsModule, i as createViteConfig, n as scanIconSlugs, r as tempestIcons, s as tempestPwaDevSw, o as tempestPwaIcons, a as tempestPwaManifest };
@@ -1,2 +1,2 @@
1
- const e=require("./create-web-socket.cjs");let t=require("react");function n(n,r={}){let{enabled:i=!0,onMessage:a,...o}=r,[s,c]=(0,t.useState)(`idle`),[l,u]=(0,t.useState)(null),d=(0,t.useRef)(null),f=(0,t.useRef)(a);return f.current=a,(0,t.useEffect)(()=>{if(!i||!n){c(`idle`);return}let t=e.createWebSocket(n,{...o,onStatusChange:c,onMessage:e=>{u(e),f.current?.(e)}});return d.current=t,()=>{t.close(),d.current=null}},[n,i]),{status:s,lastMessage:l,send:(0,t.useCallback)(e=>d.current?.send(e)??!1,[]),reconnect:(0,t.useCallback)(()=>{d.current?.reconnect()},[])}}exports.useWebSocket=n;
1
+ const e=require("./create-web-socket.cjs");let t=require("react");function n(n,r={}){let{enabled:i=!0,onMessage:a,...o}=r,[s,c]=(0,t.useState)(`idle`),[l,u]=(0,t.useState)(null),d=(0,t.useRef)(null),f=(0,t.useRef)(a);return(0,t.useEffect)(()=>{f.current=a},[a]),(0,t.useEffect)(()=>{if(!i||!n){c(`idle`);return}let t=e.createWebSocket(n,{...o,onStatusChange:c,onMessage:e=>{u(e),f.current?.(e)}});return d.current=t,()=>{t.close(),d.current=null}},[n,i]),{status:s,lastMessage:l,send:(0,t.useCallback)(e=>d.current?.send(e)??!1,[]),reconnect:(0,t.useCallback)(()=>{d.current?.reconnect()},[])}}exports.useWebSocket=n;
2
2
  //# sourceMappingURL=use-web-socket.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-web-socket.cjs","names":[],"sources":["../../src/ws/use-web-socket.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n createWebSocket,\n type CreateWebSocketOptions,\n type WebSocketController,\n type WebSocketMessage,\n type WebSocketStatus,\n} from \"./create-web-socket\";\n\nexport interface UseWebSocketOptions<T> extends Omit<CreateWebSocketOptions<T>, \"onStatusChange\"> {\n /** When false, the socket is not opened. Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseWebSocketResult<T> {\n status: WebSocketStatus;\n /** Last decoded frame received. */\n lastMessage: WebSocketMessage<T> | null;\n /** Send a payload through the active connection. Returns false when not open. */\n send: (payload: string | Blob | BufferSource) => boolean;\n /** Force a reconnect, resetting the retry counter. */\n reconnect: () => void;\n}\n\n/**\n * React hook around {@link createWebSocket}. Manages the connection lifecycle\n * for the host component and tears it down on unmount.\n */\nexport function useWebSocket<T = unknown>(\n url: string,\n options: UseWebSocketOptions<T> = {},\n): UseWebSocketResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<WebSocketStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<WebSocketMessage<T> | null>(null);\n const controllerRef = useRef<WebSocketController | null>(null);\n\n const onMessageRef = useRef(onMessage);\n onMessageRef.current = onMessage;\n\n useEffect(() => {\n if (!enabled || !url) {\n setStatus(\"idle\");\n return;\n }\n\n const controller = createWebSocket<T>(url, {\n ...rest,\n onStatusChange: setStatus,\n onMessage: (message) => {\n setLastMessage(message);\n onMessageRef.current?.(message);\n },\n });\n controllerRef.current = controller;\n\n return () => {\n controller.close();\n controllerRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, enabled]);\n\n const send = useCallback((payload: string | Blob | BufferSource): boolean => {\n return controllerRef.current?.send(payload) ?? false;\n }, []);\n\n const reconnect = useCallback((): void => {\n controllerRef.current?.reconnect();\n }, []);\n\n return { status, lastMessage, send, reconnect };\n}\n"],"mappings":"kEA4BA,SAAgB,EACZ,EACA,EAAkC,CAAC,EACd,CACrB,GAAM,CAAE,UAAU,GAAM,YAAW,GAAG,GAAS,EACzC,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAuC,MAAM,EACtD,CAAC,EAAa,IAAA,EAAA,EAAA,SAAA,CAAuD,IAAI,EACzE,GAAA,EAAA,EAAA,OAAA,CAAmD,IAAI,EAEvD,GAAA,EAAA,EAAA,OAAA,CAAsB,CAAS,EAkCrC,MAjCA,GAAa,QAAU,GAEvB,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,GAAW,CAAC,EAAK,CAClB,EAAU,MAAM,EAChB,MACJ,CAEA,IAAM,EAAa,EAAA,gBAAmB,EAAK,CACvC,GAAG,EACH,eAAgB,EAChB,UAAY,GAAY,CACpB,EAAe,CAAO,EACtB,EAAa,UAAU,CAAO,CAClC,CACJ,CAAC,EAGD,MAFA,GAAc,QAAU,MAEX,CACT,EAAW,MAAM,EACjB,EAAc,QAAU,IAC5B,CAEJ,EAAG,CAAC,EAAK,CAAO,CAAC,EAUV,CAAE,SAAQ,cAAa,MAAA,EAAA,EAAA,YAAA,CARJ,GACf,EAAc,SAAS,KAAK,CAAO,GAAK,GAChD,CAAC,CAM0B,EAAM,WAAA,EAAA,EAAA,YAAA,KAJM,CACtC,EAAc,SAAS,UAAU,CACrC,EAAG,CAAC,CAEgC,CAAU,CAClD"}
1
+ {"version":3,"file":"use-web-socket.cjs","names":[],"sources":["../../src/ws/use-web-socket.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n createWebSocket,\n type CreateWebSocketOptions,\n type WebSocketController,\n type WebSocketMessage,\n type WebSocketStatus,\n} from \"./create-web-socket\";\n\nexport interface UseWebSocketOptions<T> extends Omit<CreateWebSocketOptions<T>, \"onStatusChange\"> {\n /** When false, the socket is not opened. Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseWebSocketResult<T> {\n status: WebSocketStatus;\n /** Last decoded frame received. */\n lastMessage: WebSocketMessage<T> | null;\n /** Send a payload through the active connection. Returns false when not open. */\n send: (payload: string | Blob | BufferSource) => boolean;\n /** Force a reconnect, resetting the retry counter. */\n reconnect: () => void;\n}\n\n/**\n * React hook around {@link createWebSocket}. Manages the connection lifecycle\n * for the host component and tears it down on unmount.\n */\nexport function useWebSocket<T = unknown>(\n url: string,\n options: UseWebSocketOptions<T> = {},\n): UseWebSocketResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<WebSocketStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<WebSocketMessage<T> | null>(null);\n const controllerRef = useRef<WebSocketController | null>(null);\n\n const onMessageRef = useRef(onMessage);\n useEffect(() => {\n onMessageRef.current = onMessage;\n }, [onMessage]);\n\n useEffect(() => {\n if (!enabled || !url) {\n setStatus(\"idle\");\n return;\n }\n\n const controller = createWebSocket<T>(url, {\n ...rest,\n onStatusChange: setStatus,\n onMessage: (message) => {\n setLastMessage(message);\n onMessageRef.current?.(message);\n },\n });\n controllerRef.current = controller;\n\n return () => {\n controller.close();\n controllerRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, enabled]);\n\n const send = useCallback((payload: string | Blob | BufferSource): boolean => {\n return controllerRef.current?.send(payload) ?? false;\n }, []);\n\n const reconnect = useCallback((): void => {\n controllerRef.current?.reconnect();\n }, []);\n\n return { status, lastMessage, send, reconnect };\n}\n"],"mappings":"kEA4BA,SAAgB,EACZ,EACA,EAAkC,CAAC,EACd,CACrB,GAAM,CAAE,UAAU,GAAM,YAAW,GAAG,GAAS,EACzC,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAuC,MAAM,EACtD,CAAC,EAAa,IAAA,EAAA,EAAA,SAAA,CAAuD,IAAI,EACzE,GAAA,EAAA,EAAA,OAAA,CAAmD,IAAI,EAEvD,GAAA,EAAA,EAAA,OAAA,CAAsB,CAAS,EAoCrC,OAnCA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAa,QAAU,CAC3B,EAAG,CAAC,CAAS,CAAC,GAEd,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,GAAW,CAAC,EAAK,CAClB,EAAU,MAAM,EAChB,MACJ,CAEA,IAAM,EAAa,EAAA,gBAAmB,EAAK,CACvC,GAAG,EACH,eAAgB,EAChB,UAAY,GAAY,CACpB,EAAe,CAAO,EACtB,EAAa,UAAU,CAAO,CAClC,CACJ,CAAC,EAGD,MAFA,GAAc,QAAU,MAEX,CACT,EAAW,MAAM,EACjB,EAAc,QAAU,IAC5B,CAEJ,EAAG,CAAC,EAAK,CAAO,CAAC,EAUV,CAAE,SAAQ,cAAa,MAAA,EAAA,EAAA,YAAA,CARJ,GACf,EAAc,SAAS,KAAK,CAAO,GAAK,GAChD,CAAC,CAM0B,EAAM,WAAA,EAAA,EAAA,YAAA,KAJM,CACtC,EAAc,SAAS,UAAU,CACrC,EAAG,CAAC,CAEgC,CAAU,CAClD"}
@@ -3,7 +3,9 @@ import { useCallback as t, useEffect as n, useRef as r, useState as i } from "re
3
3
  //#region src/ws/use-web-socket.ts
4
4
  function a(a, o = {}) {
5
5
  let { enabled: s = !0, onMessage: c, ...l } = o, [u, d] = i("idle"), [f, p] = i(null), m = r(null), h = r(c);
6
- return h.current = c, n(() => {
6
+ return n(() => {
7
+ h.current = c;
8
+ }, [c]), n(() => {
7
9
  if (!s || !a) {
8
10
  d("idle");
9
11
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"use-web-socket.js","names":[],"sources":["../../src/ws/use-web-socket.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n createWebSocket,\n type CreateWebSocketOptions,\n type WebSocketController,\n type WebSocketMessage,\n type WebSocketStatus,\n} from \"./create-web-socket\";\n\nexport interface UseWebSocketOptions<T> extends Omit<CreateWebSocketOptions<T>, \"onStatusChange\"> {\n /** When false, the socket is not opened. Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseWebSocketResult<T> {\n status: WebSocketStatus;\n /** Last decoded frame received. */\n lastMessage: WebSocketMessage<T> | null;\n /** Send a payload through the active connection. Returns false when not open. */\n send: (payload: string | Blob | BufferSource) => boolean;\n /** Force a reconnect, resetting the retry counter. */\n reconnect: () => void;\n}\n\n/**\n * React hook around {@link createWebSocket}. Manages the connection lifecycle\n * for the host component and tears it down on unmount.\n */\nexport function useWebSocket<T = unknown>(\n url: string,\n options: UseWebSocketOptions<T> = {},\n): UseWebSocketResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<WebSocketStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<WebSocketMessage<T> | null>(null);\n const controllerRef = useRef<WebSocketController | null>(null);\n\n const onMessageRef = useRef(onMessage);\n onMessageRef.current = onMessage;\n\n useEffect(() => {\n if (!enabled || !url) {\n setStatus(\"idle\");\n return;\n }\n\n const controller = createWebSocket<T>(url, {\n ...rest,\n onStatusChange: setStatus,\n onMessage: (message) => {\n setLastMessage(message);\n onMessageRef.current?.(message);\n },\n });\n controllerRef.current = controller;\n\n return () => {\n controller.close();\n controllerRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, enabled]);\n\n const send = useCallback((payload: string | Blob | BufferSource): boolean => {\n return controllerRef.current?.send(payload) ?? false;\n }, []);\n\n const reconnect = useCallback((): void => {\n controllerRef.current?.reconnect();\n }, []);\n\n return { status, lastMessage, send, reconnect };\n}\n"],"mappings":";;;AA4BA,SAAgB,EACZ,GACA,IAAkC,CAAC,GACd;CACrB,IAAM,EAAE,aAAU,IAAM,cAAW,GAAG,MAAS,GACzC,CAAC,GAAQ,KAAa,EAA0B,MAAM,GACtD,CAAC,GAAa,KAAkB,EAAqC,IAAI,GACzE,IAAgB,EAAmC,IAAI,GAEvD,IAAe,EAAO,CAAS;CAkCrC,OAjCA,EAAa,UAAU,GAEvB,QAAgB;EACZ,IAAI,CAAC,KAAW,CAAC,GAAK;GAClB,EAAU,MAAM;GAChB;EACJ;EAEA,IAAM,IAAa,EAAmB,GAAK;GACvC,GAAG;GACH,gBAAgB;GAChB,YAAY,MAAY;IAEpB,AADA,EAAe,CAAO,GACtB,EAAa,UAAU,CAAO;GAClC;EACJ,CAAC;EAGD,OAFA,EAAc,UAAU,SAEX;GAET,AADA,EAAW,MAAM,GACjB,EAAc,UAAU;EAC5B;CAEJ,GAAG,CAAC,GAAK,CAAO,CAAC,GAUV;EAAE;EAAQ;EAAa,MARjB,GAAa,MACf,EAAc,SAAS,KAAK,CAAO,KAAK,IAChD,CAAC,CAM0B;EAAM,WAJlB,QAAwB;GACtC,EAAc,SAAS,UAAU;EACrC,GAAG,CAAC,CAEgC;CAAU;AAClD"}
1
+ {"version":3,"file":"use-web-socket.js","names":[],"sources":["../../src/ws/use-web-socket.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n createWebSocket,\n type CreateWebSocketOptions,\n type WebSocketController,\n type WebSocketMessage,\n type WebSocketStatus,\n} from \"./create-web-socket\";\n\nexport interface UseWebSocketOptions<T> extends Omit<CreateWebSocketOptions<T>, \"onStatusChange\"> {\n /** When false, the socket is not opened. Default: true. */\n enabled?: boolean;\n}\n\nexport interface UseWebSocketResult<T> {\n status: WebSocketStatus;\n /** Last decoded frame received. */\n lastMessage: WebSocketMessage<T> | null;\n /** Send a payload through the active connection. Returns false when not open. */\n send: (payload: string | Blob | BufferSource) => boolean;\n /** Force a reconnect, resetting the retry counter. */\n reconnect: () => void;\n}\n\n/**\n * React hook around {@link createWebSocket}. Manages the connection lifecycle\n * for the host component and tears it down on unmount.\n */\nexport function useWebSocket<T = unknown>(\n url: string,\n options: UseWebSocketOptions<T> = {},\n): UseWebSocketResult<T> {\n const { enabled = true, onMessage, ...rest } = options;\n const [status, setStatus] = useState<WebSocketStatus>(\"idle\");\n const [lastMessage, setLastMessage] = useState<WebSocketMessage<T> | null>(null);\n const controllerRef = useRef<WebSocketController | null>(null);\n\n const onMessageRef = useRef(onMessage);\n useEffect(() => {\n onMessageRef.current = onMessage;\n }, [onMessage]);\n\n useEffect(() => {\n if (!enabled || !url) {\n setStatus(\"idle\");\n return;\n }\n\n const controller = createWebSocket<T>(url, {\n ...rest,\n onStatusChange: setStatus,\n onMessage: (message) => {\n setLastMessage(message);\n onMessageRef.current?.(message);\n },\n });\n controllerRef.current = controller;\n\n return () => {\n controller.close();\n controllerRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, enabled]);\n\n const send = useCallback((payload: string | Blob | BufferSource): boolean => {\n return controllerRef.current?.send(payload) ?? false;\n }, []);\n\n const reconnect = useCallback((): void => {\n controllerRef.current?.reconnect();\n }, []);\n\n return { status, lastMessage, send, reconnect };\n}\n"],"mappings":";;;AA4BA,SAAgB,EACZ,GACA,IAAkC,CAAC,GACd;CACrB,IAAM,EAAE,aAAU,IAAM,cAAW,GAAG,MAAS,GACzC,CAAC,GAAQ,KAAa,EAA0B,MAAM,GACtD,CAAC,GAAa,KAAkB,EAAqC,IAAI,GACzE,IAAgB,EAAmC,IAAI,GAEvD,IAAe,EAAO,CAAS;CAoCrC,OAnCA,QAAgB;EACZ,EAAa,UAAU;CAC3B,GAAG,CAAC,CAAS,CAAC,GAEd,QAAgB;EACZ,IAAI,CAAC,KAAW,CAAC,GAAK;GAClB,EAAU,MAAM;GAChB;EACJ;EAEA,IAAM,IAAa,EAAmB,GAAK;GACvC,GAAG;GACH,gBAAgB;GAChB,YAAY,MAAY;IAEpB,AADA,EAAe,CAAO,GACtB,EAAa,UAAU,CAAO;GAClC;EACJ,CAAC;EAGD,OAFA,EAAc,UAAU,SAEX;GAET,AADA,EAAW,MAAM,GACjB,EAAc,UAAU;EAC5B;CAEJ,GAAG,CAAC,GAAK,CAAO,CAAC,GAUV;EAAE;EAAQ;EAAa,MARjB,GAAa,MACf,EAAc,SAAS,KAAK,CAAO,KAAK,IAChD,CAAC,CAM0B;EAAM,WAJlB,QAAwB;GACtC,EAAc,SAAS,UAAU;EACrC,GAAG,CAAC,CAEgC;CAAU;AAClD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tempest-react-sdk",
3
- "version": "0.24.0",
3
+ "version": "0.26.0",
4
4
  "description": "SDK público da Tempest com componentes, hooks e integrações para projetos React.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -80,12 +80,21 @@
80
80
  "import": "./dist/br.js",
81
81
  "require": "./dist/br.cjs"
82
82
  },
83
+ "./icons": {
84
+ "types": "./dist/icons.d.ts",
85
+ "import": "./dist/icons.js",
86
+ "require": "./dist/icons.cjs"
87
+ },
88
+ "./icons/virtual": {
89
+ "types": "./dist/icons-virtual.d.ts"
90
+ },
83
91
  "./styles.css": "./dist/styles.css",
84
- "./package.json": "./package.json"
92
+ "./package.json": "./package.json",
93
+ "./utilities.css": "./dist/utilities.css"
85
94
  },
86
95
  "scripts": {
87
96
  "dev": "vite build --watch",
88
- "build": "tsc -b tsconfig.build.json && vite build",
97
+ "build": "tsc -b tsconfig.build.json && node --max-old-space-size=6144 ./node_modules/vite/bin/vite.js build && node scripts/copy-css-assets.mjs",
89
98
  "typecheck": "tsc -b tsconfig.json --noEmit",
90
99
  "lint": "eslint .",
91
100
  "format": "prettier --write .",
@@ -97,6 +106,7 @@
97
106
  "size": "size-limit",
98
107
  "docs:llms": "node scripts/gen-llms.mjs",
99
108
  "gen:geodata": "node scripts/gen-br-geodata.mjs",
109
+ "gen:icons": "node scripts/gen-icons.mjs",
100
110
  "vendor:vision": "node scripts/vendor-vision.mjs",
101
111
  "prepare": "husky",
102
112
  "prepublishOnly": "npm run typecheck && npm run lint && npm run test:run && npm run build",
@@ -116,7 +126,7 @@
116
126
  "@tanstack/react-query": "^5.0.0",
117
127
  "dexie": "^4.4.2",
118
128
  "fflate": "^0.8.3",
119
- "lucide-react": ">=0.400.0",
129
+ "lucide-react": "^1.26.0",
120
130
  "react-hook-form": "^7.76.0",
121
131
  "react-router": "^8.3.0",
122
132
  "zod": "^3.23.0 || ^4.0.0",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "react": "^19.2.8",
19
19
  "react-dom": "^19.2.8",
20
- "tempest-react-sdk": "^0.6.0"
20
+ "tempest-react-sdk": "^0.26.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@eslint/js": "^10.0.1",