@everysk/apps-sdk 0.2.0 → 0.3.0-beta-20261016180126

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 (349) hide show
  1. package/README.md +298 -12
  2. package/dist/EveryskApp.d.ts +34 -2
  3. package/dist/EveryskApp.d.ts.map +1 -1
  4. package/dist/EveryskApp.js +35 -2
  5. package/dist/EveryskApp.js.map +1 -1
  6. package/dist/agGrid/handleRowsScrollEnd.d.ts +53 -0
  7. package/dist/agGrid/handleRowsScrollEnd.d.ts.map +1 -0
  8. package/dist/agGrid/handleRowsScrollEnd.js +47 -0
  9. package/dist/agGrid/handleRowsScrollEnd.js.map +1 -0
  10. package/dist/agGrid/index.d.ts +2 -0
  11. package/dist/agGrid/index.d.ts.map +1 -1
  12. package/dist/agGrid/index.js +2 -1
  13. package/dist/api/datastore.d.ts +10 -8
  14. package/dist/api/datastore.d.ts.map +1 -1
  15. package/dist/api/datastore.js +24 -55
  16. package/dist/api/datastore.js.map +1 -1
  17. package/dist/api/entityQuery.d.ts +46 -41
  18. package/dist/api/entityQuery.d.ts.map +1 -1
  19. package/dist/api/entityQuery.js +55 -14
  20. package/dist/api/entityQuery.js.map +1 -1
  21. package/dist/api/file.d.ts +26 -9
  22. package/dist/api/file.d.ts.map +1 -1
  23. package/dist/api/file.js +45 -55
  24. package/dist/api/file.js.map +1 -1
  25. package/dist/api/portfolio.d.ts +11 -8
  26. package/dist/api/portfolio.d.ts.map +1 -1
  27. package/dist/api/portfolio.js +24 -55
  28. package/dist/api/portfolio.js.map +1 -1
  29. package/dist/api/profile.d.ts +3 -2
  30. package/dist/api/profile.d.ts.map +1 -1
  31. package/dist/api/profile.js +4 -9
  32. package/dist/api/profile.js.map +1 -1
  33. package/dist/api/request.d.ts +106 -0
  34. package/dist/api/request.d.ts.map +1 -0
  35. package/dist/api/request.js +132 -0
  36. package/dist/api/request.js.map +1 -0
  37. package/dist/api/websocketsConfig.d.ts +7 -2
  38. package/dist/api/websocketsConfig.d.ts.map +1 -1
  39. package/dist/api/websocketsConfig.js +2 -10
  40. package/dist/api/websocketsConfig.js.map +1 -1
  41. package/dist/api/workflow.d.ts +84 -89
  42. package/dist/api/workflow.d.ts.map +1 -1
  43. package/dist/api/workflow.js +121 -208
  44. package/dist/api/workflow.js.map +1 -1
  45. package/dist/api/workspace.d.ts +18 -8
  46. package/dist/api/workspace.d.ts.map +1 -1
  47. package/dist/api/workspace.js +21 -26
  48. package/dist/api/workspace.js.map +1 -1
  49. package/dist/components/ui/Footer/index.d.ts.map +1 -1
  50. package/dist/components/ui/Footer/index.js.map +1 -1
  51. package/dist/components/ui/GlobalLoading/index.d.ts.map +1 -1
  52. package/dist/components/ui/GlobalLoading/index.js.map +1 -1
  53. package/dist/components/ui/PageContainer/index.d.ts +1 -1
  54. package/dist/components/ui/PageContainer/index.d.ts.map +1 -1
  55. package/dist/components/ui/PageContainer/index.js.map +1 -1
  56. package/dist/components/ui/Toolbar/index.d.ts +40 -3
  57. package/dist/components/ui/Toolbar/index.d.ts.map +1 -1
  58. package/dist/components/ui/Toolbar/index.js +42 -15
  59. package/dist/components/ui/Toolbar/index.js.map +1 -1
  60. package/dist/contexts/appAlertContext/provider.js.map +1 -1
  61. package/dist/contexts/appAlertContext/types.d.ts.map +1 -1
  62. package/dist/contexts/appConfigContext/index.d.ts.map +1 -1
  63. package/dist/contexts/appConfigContext/index.js.map +1 -1
  64. package/dist/contexts/appConfigContext/provider.d.ts.map +1 -1
  65. package/dist/contexts/appConfigContext/provider.js.map +1 -1
  66. package/dist/contexts/webSocketContext/handler.d.ts +3 -2
  67. package/dist/contexts/webSocketContext/handler.d.ts.map +1 -1
  68. package/dist/contexts/webSocketContext/handler.js.map +1 -1
  69. package/dist/contexts/webSocketContext/hooks/useWebSocket/index.d.ts +1 -1
  70. package/dist/contexts/webSocketContext/hooks/useWebSocket/index.js +1 -1
  71. package/dist/contexts/webSocketContext/hooks/useWebSocket/index.js.map +1 -1
  72. package/dist/contexts/webSocketContext/provider.d.ts +6 -3
  73. package/dist/contexts/webSocketContext/provider.d.ts.map +1 -1
  74. package/dist/contexts/webSocketContext/provider.js +42 -7
  75. package/dist/contexts/webSocketContext/provider.js.map +1 -1
  76. package/dist/contexts/webSocketContext/types.d.ts +7 -5
  77. package/dist/contexts/webSocketContext/types.d.ts.map +1 -1
  78. package/dist/file/index.d.ts +2 -0
  79. package/dist/file/index.d.ts.map +1 -1
  80. package/dist/hooks/datastore/useDatastoreMutations.d.ts +4 -4
  81. package/dist/hooks/datastore/useDatastoreMutations.d.ts.map +1 -1
  82. package/dist/hooks/datastore/useDatastoreMutations.js +17 -55
  83. package/dist/hooks/datastore/useDatastoreMutations.js.map +1 -1
  84. package/dist/hooks/datastore/useFetchDatastore.d.ts +30 -41
  85. package/dist/hooks/datastore/useFetchDatastore.d.ts.map +1 -1
  86. package/dist/hooks/datastore/useFetchDatastore.js +25 -59
  87. package/dist/hooks/datastore/useFetchDatastore.js.map +1 -1
  88. package/dist/hooks/datastore/useFetchDatastores.d.ts +47 -52
  89. package/dist/hooks/datastore/useFetchDatastores.d.ts.map +1 -1
  90. package/dist/hooks/datastore/useFetchDatastores.js +55 -70
  91. package/dist/hooks/datastore/useFetchDatastores.js.map +1 -1
  92. package/dist/hooks/file/fileData.d.ts +17 -0
  93. package/dist/hooks/file/fileData.d.ts.map +1 -0
  94. package/dist/hooks/file/fileData.js +10 -0
  95. package/dist/hooks/file/fileData.js.map +1 -0
  96. package/dist/hooks/file/useFetchFile.d.ts +38 -58
  97. package/dist/hooks/file/useFetchFile.d.ts.map +1 -1
  98. package/dist/hooks/file/useFetchFile.js +26 -66
  99. package/dist/hooks/file/useFetchFile.js.map +1 -1
  100. package/dist/hooks/file/useFetchFiles.d.ts +18 -52
  101. package/dist/hooks/file/useFetchFiles.d.ts.map +1 -1
  102. package/dist/hooks/file/useFetchFiles.js +53 -69
  103. package/dist/hooks/file/useFetchFiles.js.map +1 -1
  104. package/dist/hooks/file/useFileMutations.d.ts +9 -8
  105. package/dist/hooks/file/useFileMutations.d.ts.map +1 -1
  106. package/dist/hooks/file/useFileMutations.js +23 -60
  107. package/dist/hooks/file/useFileMutations.js.map +1 -1
  108. package/dist/hooks/portfolio/useFetchPortfolio.d.ts +16 -50
  109. package/dist/hooks/portfolio/useFetchPortfolio.d.ts.map +1 -1
  110. package/dist/hooks/portfolio/useFetchPortfolio.js +15 -63
  111. package/dist/hooks/portfolio/useFetchPortfolio.js.map +1 -1
  112. package/dist/hooks/portfolio/useFetchPortfolios.d.ts +13 -52
  113. package/dist/hooks/portfolio/useFetchPortfolios.d.ts.map +1 -1
  114. package/dist/hooks/portfolio/useFetchPortfolios.js +29 -71
  115. package/dist/hooks/portfolio/useFetchPortfolios.js.map +1 -1
  116. package/dist/hooks/portfolio/usePortfolioMutations.d.ts +8 -8
  117. package/dist/hooks/portfolio/usePortfolioMutations.d.ts.map +1 -1
  118. package/dist/hooks/portfolio/usePortfolioMutations.js +20 -58
  119. package/dist/hooks/portfolio/usePortfolioMutations.js.map +1 -1
  120. package/dist/hooks/profile/useFetchProfile.d.ts +18 -44
  121. package/dist/hooks/profile/useFetchProfile.d.ts.map +1 -1
  122. package/dist/hooks/profile/useFetchProfile.js +16 -48
  123. package/dist/hooks/profile/useFetchProfile.js.map +1 -1
  124. package/dist/hooks/useAxios.js.map +1 -1
  125. package/dist/hooks/useEntityInfiniteQuery.d.ts +88 -0
  126. package/dist/hooks/useEntityInfiniteQuery.d.ts.map +1 -0
  127. package/dist/hooks/useEntityInfiniteQuery.js +111 -0
  128. package/dist/hooks/useEntityInfiniteQuery.js.map +1 -0
  129. package/dist/hooks/useEntityMutation.d.ts +47 -0
  130. package/dist/hooks/useEntityMutation.d.ts.map +1 -0
  131. package/dist/hooks/useEntityMutation.js +58 -0
  132. package/dist/hooks/useEntityMutation.js.map +1 -0
  133. package/dist/hooks/useEntityQuery.d.ts +68 -0
  134. package/dist/hooks/useEntityQuery.d.ts.map +1 -0
  135. package/dist/hooks/useEntityQuery.js +75 -0
  136. package/dist/hooks/useEntityQuery.js.map +1 -0
  137. package/dist/hooks/workflow/useFetchWorkerExecution.d.ts +17 -34
  138. package/dist/hooks/workflow/useFetchWorkerExecution.d.ts.map +1 -1
  139. package/dist/hooks/workflow/useFetchWorkerExecution.js +16 -46
  140. package/dist/hooks/workflow/useFetchWorkerExecution.js.map +1 -1
  141. package/dist/hooks/workflow/useFetchWorkerExecutions.d.ts +179 -41
  142. package/dist/hooks/workflow/useFetchWorkerExecutions.d.ts.map +1 -1
  143. package/dist/hooks/workflow/useFetchWorkerExecutions.js +29 -62
  144. package/dist/hooks/workflow/useFetchWorkerExecutions.js.map +1 -1
  145. package/dist/hooks/workflow/useFetchWorkflow.d.ts +16 -35
  146. package/dist/hooks/workflow/useFetchWorkflow.d.ts.map +1 -1
  147. package/dist/hooks/workflow/useFetchWorkflow.js +15 -48
  148. package/dist/hooks/workflow/useFetchWorkflow.js.map +1 -1
  149. package/dist/hooks/workflow/useFetchWorkflowExecution.d.ts +17 -34
  150. package/dist/hooks/workflow/useFetchWorkflowExecution.d.ts.map +1 -1
  151. package/dist/hooks/workflow/useFetchWorkflowExecution.js +16 -46
  152. package/dist/hooks/workflow/useFetchWorkflowExecution.js.map +1 -1
  153. package/dist/hooks/workflow/useFetchWorkflowExecutions.d.ts +22 -36
  154. package/dist/hooks/workflow/useFetchWorkflowExecutions.d.ts.map +1 -1
  155. package/dist/hooks/workflow/useFetchWorkflowExecutions.js +43 -56
  156. package/dist/hooks/workflow/useFetchWorkflowExecutions.js.map +1 -1
  157. package/dist/hooks/workflow/useFetchWorkflows.d.ts +20 -37
  158. package/dist/hooks/workflow/useFetchWorkflows.d.ts.map +1 -1
  159. package/dist/hooks/workflow/useFetchWorkflows.js +32 -47
  160. package/dist/hooks/workflow/useFetchWorkflows.js.map +1 -1
  161. package/dist/hooks/workflow/useRunWorkflow.d.ts +21 -16
  162. package/dist/hooks/workflow/useRunWorkflow.d.ts.map +1 -1
  163. package/dist/hooks/workflow/useRunWorkflow.js +66 -29
  164. package/dist/hooks/workflow/useRunWorkflow.js.map +1 -1
  165. package/dist/hooks/workflow/useTriggerWorkflow.d.ts +20 -0
  166. package/dist/hooks/workflow/useTriggerWorkflow.d.ts.map +1 -0
  167. package/dist/hooks/workflow/useTriggerWorkflow.js +32 -0
  168. package/dist/hooks/workflow/useTriggerWorkflow.js.map +1 -0
  169. package/dist/hooks/workspace/useFetchWorkspace.d.ts +19 -34
  170. package/dist/hooks/workspace/useFetchWorkspace.d.ts.map +1 -1
  171. package/dist/hooks/workspace/useFetchWorkspace.js +16 -46
  172. package/dist/hooks/workspace/useFetchWorkspace.js.map +1 -1
  173. package/dist/hooks/workspace/useFetchWorkspaces.d.ts +17 -37
  174. package/dist/hooks/workspace/useFetchWorkspaces.d.ts.map +1 -1
  175. package/dist/hooks/workspace/useFetchWorkspaces.js +25 -47
  176. package/dist/hooks/workspace/useFetchWorkspaces.js.map +1 -1
  177. package/dist/index.d.ts +13 -10
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +13 -11
  180. package/dist/lib/abort.d.ts +58 -0
  181. package/dist/lib/abort.d.ts.map +1 -0
  182. package/dist/lib/abort.js +112 -0
  183. package/dist/lib/abort.js.map +1 -0
  184. package/dist/lib/datastoreTable.d.ts +59 -54
  185. package/dist/lib/datastoreTable.d.ts.map +1 -1
  186. package/dist/lib/datastoreTable.js +58 -62
  187. package/dist/lib/datastoreTable.js.map +1 -1
  188. package/dist/lib/file.d.ts +34 -0
  189. package/dist/lib/file.d.ts.map +1 -0
  190. package/dist/lib/file.js +63 -0
  191. package/dist/lib/file.js.map +1 -0
  192. package/dist/lib/queryClient.d.ts.map +1 -1
  193. package/dist/lib/queryClient.js.map +1 -1
  194. package/dist/lib/workflowRun.d.ts +91 -0
  195. package/dist/lib/workflowRun.d.ts.map +1 -0
  196. package/dist/lib/workflowRun.js +224 -0
  197. package/dist/lib/workflowRun.js.map +1 -0
  198. package/dist/socket/index.d.ts +1 -3
  199. package/dist/socket/index.d.ts.map +1 -1
  200. package/dist/socket/index.js +3 -5
  201. package/dist/test/mocks/index.d.ts +1 -1
  202. package/dist/test/mocks/index.d.ts.map +1 -1
  203. package/dist/test/renderWithProviders.d.ts +2 -2
  204. package/dist/test/renderWithProviders.d.ts.map +1 -1
  205. package/dist/test/renderWithProviders.js.map +1 -1
  206. package/dist/test/setup.js.map +1 -1
  207. package/dist/theme/index.d.ts +1 -1
  208. package/dist/theme/index.d.ts.map +1 -1
  209. package/dist/theme/overrides/index.d.ts +4 -2
  210. package/dist/theme/overrides/index.d.ts.map +1 -1
  211. package/dist/theme/overrides/index.js +5 -3
  212. package/dist/theme/overrides/index.js.map +1 -1
  213. package/dist/theme/overrides/muiButton.d.ts +2 -2
  214. package/dist/theme/overrides/muiButton.js.map +1 -1
  215. package/dist/theme/overrides/muiCssBaseline.d.ts.map +1 -1
  216. package/dist/theme/overrides/muiCssBaseline.js.map +1 -1
  217. package/dist/theme/overrides/muiDatePicker.js.map +1 -1
  218. package/dist/theme/overrides/muiFormControl.js.map +1 -1
  219. package/dist/theme/overrides/muiIconButton.d.ts +2 -2
  220. package/dist/theme/overrides/muiIconButton.js.map +1 -1
  221. package/dist/theme/overrides/muiSelect.d.ts.map +1 -1
  222. package/dist/theme/overrides/muiSelect.js.map +1 -1
  223. package/dist/theme/overrides/muiSvgIcon.d.ts.map +1 -1
  224. package/dist/theme/overrides/muiSvgIcon.js.map +1 -1
  225. package/dist/theme/overrides/muiTextField.js.map +1 -1
  226. package/dist/theme/overrides/muiToggleButton.d.ts +2 -2
  227. package/dist/theme/overrides/muiToggleButton.js.map +1 -1
  228. package/dist/theme/overrides/muiToggleButtonGroup.d.ts +2 -2
  229. package/dist/theme/overrides/muiToggleButtonGroup.js.map +1 -1
  230. package/dist/theme/themes/DefaultDark.js +2 -2
  231. package/dist/theme/themes/DefaultDark.js.map +1 -1
  232. package/dist/theme/themes/DefaultLight.js +2 -2
  233. package/dist/theme/themes/DefaultLight.js.map +1 -1
  234. package/dist/theme/themes/EveryskDark.js +2 -2
  235. package/dist/theme/themes/EveryskDark.js.map +1 -1
  236. package/dist/theme/themes/EveryskLight.js +2 -2
  237. package/dist/theme/themes/EveryskLight.js.map +1 -1
  238. package/dist/theme/themes/MidnightEmber.js +2 -2
  239. package/dist/theme/themes/MidnightEmber.js.map +1 -1
  240. package/dist/types/anyRecord.d.ts.map +1 -1
  241. package/dist/types/datastore.d.ts +35 -5
  242. package/dist/types/datastore.d.ts.map +1 -1
  243. package/dist/types/datastoreDataFormat.d.ts +13 -0
  244. package/dist/types/datastoreDataFormat.d.ts.map +1 -0
  245. package/dist/types/entityQuery.d.ts +86 -16
  246. package/dist/types/entityQuery.d.ts.map +1 -1
  247. package/dist/types/file.d.ts +7 -3
  248. package/dist/types/file.d.ts.map +1 -1
  249. package/dist/types/portfolio.d.ts +1 -3
  250. package/dist/types/portfolio.d.ts.map +1 -1
  251. package/dist/types/profile.d.ts +0 -10
  252. package/dist/types/profile.d.ts.map +1 -1
  253. package/dist/types/workflow.d.ts +35 -6
  254. package/dist/types/workflow.d.ts.map +1 -1
  255. package/dist/types/workspace.d.ts +1 -2
  256. package/dist/types/workspace.d.ts.map +1 -1
  257. package/dist/ui/index.d.ts +1 -1
  258. package/dist/ui/index.d.ts.map +1 -1
  259. package/dist/workflow/index.d.ts +2 -0
  260. package/dist/workflow/index.d.ts.map +1 -1
  261. package/package.json +1 -1
  262. package/src/EveryskApp.tsx +53 -2
  263. package/src/agGrid/handleRowsScrollEnd.ts +71 -0
  264. package/src/agGrid/index.ts +5 -1
  265. package/src/api/datastore.ts +79 -107
  266. package/src/api/entityQuery.ts +86 -17
  267. package/src/api/file.ts +110 -103
  268. package/src/api/portfolio.ts +82 -125
  269. package/src/api/profile.ts +25 -18
  270. package/src/api/request.ts +168 -0
  271. package/src/api/websocketsConfig.ts +11 -19
  272. package/src/api/workflow.ts +232 -334
  273. package/src/api/workspace.ts +43 -43
  274. package/src/components/ui/Footer/index.tsx +8 -7
  275. package/src/components/ui/GlobalLoading/index.tsx +13 -3
  276. package/src/components/ui/PageContainer/index.tsx +9 -2
  277. package/src/components/ui/Toolbar/index.tsx +105 -30
  278. package/src/contexts/appAlertContext/provider.tsx +1 -1
  279. package/src/contexts/appAlertContext/types.ts +3 -3
  280. package/src/contexts/appConfigContext/index.tsx +1 -1
  281. package/src/contexts/appConfigContext/provider.tsx +1 -5
  282. package/src/contexts/webSocketContext/handler.ts +8 -2
  283. package/src/contexts/webSocketContext/hooks/useWebSocket/index.ts +1 -1
  284. package/src/contexts/webSocketContext/provider.tsx +64 -14
  285. package/src/contexts/webSocketContext/types.ts +7 -6
  286. package/src/file/index.ts +2 -0
  287. package/src/hooks/datastore/useDatastoreMutations.ts +19 -60
  288. package/src/hooks/datastore/useFetchDatastore.ts +45 -73
  289. package/src/hooks/datastore/useFetchDatastores.ts +106 -131
  290. package/src/hooks/file/fileData.ts +19 -0
  291. package/src/hooks/file/useFetchFile.ts +41 -76
  292. package/src/hooks/file/useFetchFiles.ts +92 -87
  293. package/src/hooks/file/useFileMutations.ts +23 -73
  294. package/src/hooks/portfolio/useFetchPortfolio.ts +26 -78
  295. package/src/hooks/portfolio/useFetchPortfolios.ts +50 -93
  296. package/src/hooks/portfolio/usePortfolioMutations.ts +22 -72
  297. package/src/hooks/profile/useFetchProfile.ts +24 -65
  298. package/src/hooks/useAxios.ts +5 -5
  299. package/src/hooks/useEntityInfiniteQuery.ts +193 -0
  300. package/src/hooks/useEntityMutation.ts +70 -0
  301. package/src/hooks/useEntityQuery.ts +117 -0
  302. package/src/hooks/workflow/useFetchWorkerExecution.ts +27 -56
  303. package/src/hooks/workflow/useFetchWorkerExecutions.ts +54 -79
  304. package/src/hooks/workflow/useFetchWorkflow.ts +24 -58
  305. package/src/hooks/workflow/useFetchWorkflowExecution.ts +27 -57
  306. package/src/hooks/workflow/useFetchWorkflowExecutions.ts +64 -73
  307. package/src/hooks/workflow/useFetchWorkflows.ts +48 -64
  308. package/src/hooks/workflow/useRunWorkflow.ts +82 -36
  309. package/src/hooks/workflow/useTriggerWorkflow.ts +36 -0
  310. package/src/hooks/workspace/useFetchWorkspace.ts +25 -58
  311. package/src/hooks/workspace/useFetchWorkspaces.ts +38 -69
  312. package/src/index.ts +34 -19
  313. package/src/lib/abort.ts +131 -0
  314. package/src/lib/datastoreTable.ts +127 -74
  315. package/src/lib/file.ts +67 -0
  316. package/src/lib/queryClient.ts +11 -13
  317. package/src/lib/workflowRun.ts +329 -0
  318. package/src/socket/index.ts +1 -3
  319. package/src/test/mocks/index.ts +1 -5
  320. package/src/test/renderWithProviders.tsx +8 -3
  321. package/src/test/setup.ts +16 -16
  322. package/src/theme/index.ts +1 -1
  323. package/src/theme/overrides/index.ts +5 -3
  324. package/src/theme/overrides/muiButton.ts +3 -3
  325. package/src/theme/overrides/muiCssBaseline.ts +11 -12
  326. package/src/theme/overrides/muiDatePicker.ts +2 -2
  327. package/src/theme/overrides/muiFormControl.ts +2 -2
  328. package/src/theme/overrides/muiIconButton.ts +3 -3
  329. package/src/theme/overrides/muiSelect.ts +2 -2
  330. package/src/theme/overrides/muiSvgIcon.ts +2 -2
  331. package/src/theme/overrides/muiTextField.ts +1 -1
  332. package/src/theme/overrides/muiToggleButton.ts +4 -4
  333. package/src/theme/overrides/muiToggleButtonGroup.ts +4 -4
  334. package/src/theme/themes/DefaultDark.ts +2 -2
  335. package/src/theme/themes/DefaultLight.ts +2 -2
  336. package/src/theme/themes/EveryskDark.ts +2 -2
  337. package/src/theme/themes/EveryskLight.ts +2 -2
  338. package/src/theme/themes/MidnightEmber.ts +15 -15
  339. package/src/types/anyRecord.ts +2 -2
  340. package/src/types/datastore.ts +56 -22
  341. package/src/types/datastoreDataFormat.ts +12 -0
  342. package/src/types/entityQuery.ts +122 -38
  343. package/src/types/file.ts +8 -6
  344. package/src/types/portfolio.ts +70 -74
  345. package/src/types/profile.ts +0 -11
  346. package/src/types/workflow.ts +38 -9
  347. package/src/types/workspace.ts +2 -4
  348. package/src/ui/index.ts +1 -1
  349. package/src/workflow/index.ts +5 -0
@@ -1,4 +1,4 @@
1
- import { isAxiosError } from "axios";
1
+ import { pageParams, request } from "./request.js";
2
2
  //#region src/api/workspace.ts
3
3
  var baseUrl = "workspaces";
4
4
  /**
@@ -8,45 +8,40 @@ var baseUrl = "workspaces";
8
8
  *
9
9
  * @param {AxiosInstance} api - Axios instance.
10
10
  * @param {string} name - Workspace name.
11
+ * @param {AbortSignal} [signal] - Aborts the request itself; the entity hooks pass the query's own.
11
12
  * @returns {Promise<Workspace>} The fetched workspace.
12
13
  *
13
14
  * @throws {Error} If the request fails.
14
15
  */
15
- var getWorkspace = async (api, name) => {
16
+ var getWorkspace = async (api, name, signal) => {
16
17
  if (!name) throw new Error("Workspace name is required to fetch a workspace");
17
- try {
18
- return (await api.get(`${baseUrl}/${name}`)).data.workspace;
19
- } catch (error) {
20
- if (isAxiosError(error)) throw new Error(error.message || "Error while fetching workspace", { cause: error });
21
- if (error instanceof Error) throw error;
22
- throw new Error("Error while fetching workspace", { cause: error });
23
- }
18
+ return (await request(() => api.get(`${baseUrl}/${name}`, { signal }), "Error fetching workspace")).workspace;
24
19
  };
25
20
  /**
26
21
  * listWorkspaces
27
22
  *
28
- * Fetches a list of workspaces with optional cursor-based pagination.
23
+ * Lists the account's workspaces, a page at a time.
24
+ *
25
+ * The one list that takes no workspace: the docs exempt it, and the endpoint ignores one. This
26
+ * function used to send it anyway, documented as "required by some API configurations".
29
27
  *
30
28
  * @param {AxiosInstance} api - Axios instance.
31
- * @param {string} [workspace] - Current workspace name. Sent as a query param via the legacy method, required by some API configurations.
32
- * @param {number} [pageSize] - Number of items per page.
33
- * @param {string} [pageToken] - Cursor token for the next page.
34
- * @returns {Promise<WorkspaceListResponse>} List of workspaces.
29
+ * @param {WorkspaceListParams} [params] - Search and paging.
30
+ * @param {AbortSignal} [signal] - Aborts the request itself; the list hooks pass the query's own.
31
+ * @returns {Promise<WorkspaceListResponse>} A page of workspaces, with the cursor to the next one.
35
32
  *
36
33
  * @throws {Error} If the request fails.
37
34
  */
38
- var listWorkspaces = async (api, workspace, pageSize, pageToken) => {
39
- const params = {};
40
- if (workspace) params.workspace = workspace;
41
- if (pageSize) params.page_size = pageSize;
42
- if (pageToken) params.page_token = pageToken;
43
- try {
44
- return (await api.get(baseUrl, { params })).data;
45
- } catch (error) {
46
- if (isAxiosError(error)) throw new Error(error.message || "Error while fetching workspaces", { cause: error });
47
- if (error instanceof Error) throw error;
48
- throw new Error("Error while fetching workspaces", { cause: error });
49
- }
35
+ var listWorkspaces = async (api, { search, pageSize, pageToken } = {}, signal) => {
36
+ const params = pageParams({
37
+ search,
38
+ pageSize,
39
+ pageToken
40
+ });
41
+ return request(() => api.get(baseUrl, {
42
+ params,
43
+ signal
44
+ }), "Error listing workspaces");
50
45
  };
51
46
  //#endregion
52
47
  export { getWorkspace, listWorkspaces };
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","names":[],"sources":["../../src/api/workspace.ts"],"sourcesContent":["import { isAxiosError, type AxiosInstance, type AxiosResponse } from \"axios\";\n\nimport type { AnyRecord } from \"@/types/anyRecord\";\nimport type { Workspace, WorkspaceListResponse, WorkspaceSingleResponse } from \"@/types/workspace\";\n\nconst baseUrl = \"workspaces\";\n\n/**\n * getWorkspace\n *\n * Fetches a single workspace by name.\n *\n * @param {AxiosInstance} api - Axios instance.\n * @param {string} name - Workspace name.\n * @returns {Promise<Workspace>} The fetched workspace.\n *\n * @throws {Error} If the request fails.\n */\nexport const getWorkspace = async (api: AxiosInstance, name: string): Promise<Workspace> => {\n if (!name) throw new Error(\"Workspace name is required to fetch a workspace\");\n\n try {\n const response: AxiosResponse<WorkspaceSingleResponse> = await api.get(`${baseUrl}/${name}`);\n return response.data.workspace;\n } catch (error: unknown) {\n if (isAxiosError<AnyRecord>(error)) {\n throw new Error(error.message || \"Error while fetching workspace\", { cause: error });\n }\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new Error(\"Error while fetching workspace\", { cause: error });\n }\n};\n\n/**\n * listWorkspaces\n *\n * Fetches a list of workspaces with optional cursor-based pagination.\n *\n * @param {AxiosInstance} api - Axios instance.\n * @param {string} [workspace] - Current workspace name. Sent as a query param via the legacy method, required by some API configurations.\n * @param {number} [pageSize] - Number of items per page.\n * @param {string} [pageToken] - Cursor token for the next page.\n * @returns {Promise<WorkspaceListResponse>} List of workspaces.\n *\n * @throws {Error} If the request fails.\n */\nexport const listWorkspaces = async (api: AxiosInstance, workspace?: string, pageSize?: number, pageToken?: string): Promise<WorkspaceListResponse> => {\n const params: AnyRecord = {};\n\n if (workspace) params.workspace = workspace;\n if (pageSize) params.page_size = pageSize;\n if (pageToken) params.page_token = pageToken;\n\n try {\n const response: AxiosResponse<WorkspaceListResponse> = await api.get(baseUrl, { params });\n return response.data;\n } catch (error: unknown) {\n if (isAxiosError<AnyRecord>(error)) {\n throw new Error(error.message || \"Error while fetching workspaces\", { cause: error });\n }\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new Error(\"Error while fetching workspaces\", { cause: error });\n }\n};\n"],"mappings":";;AAKA,IAAM,UAAU;;;;;;;;;;;;AAahB,IAAa,eAAe,OAAO,KAAoB,SAAqC;CAC1F,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,iDAAiD;CAE5E,IAAI;EAEF,QAAO,MADwD,IAAI,IAAI,GAAG,QAAQ,GAAG,MAAM,EAAA,CAC3E,KAAK;CACvB,SAAS,OAAgB;EACvB,IAAI,aAAwB,KAAK,GAC/B,MAAM,IAAI,MAAM,MAAM,WAAW,kCAAkC,EAAE,OAAO,MAAM,CAAC;EAGrF,IAAI,iBAAiB,OACnB,MAAM;EAGR,MAAM,IAAI,MAAM,kCAAkC,EAAE,OAAO,MAAM,CAAC;CACpE;AACF;;;;;;;;;;;;;;AAeA,IAAa,iBAAiB,OAAO,KAAoB,WAAoB,UAAmB,cAAuD;CACrJ,MAAM,SAAoB,CAAC;CAE3B,IAAI,WAAW,OAAO,YAAY;CAClC,IAAI,UAAU,OAAO,YAAY;CACjC,IAAI,WAAW,OAAO,aAAa;CAEnC,IAAI;EAEF,QAAO,MADsD,IAAI,IAAI,SAAS,EAAE,OAAO,CAAC,EAAA,CACxE;CAClB,SAAS,OAAgB;EACvB,IAAI,aAAwB,KAAK,GAC/B,MAAM,IAAI,MAAM,MAAM,WAAW,mCAAmC,EAAE,OAAO,MAAM,CAAC;EAGtF,IAAI,iBAAiB,OACnB,MAAM;EAGR,MAAM,IAAI,MAAM,mCAAmC,EAAE,OAAO,MAAM,CAAC;CACrE;AACF"}
1
+ {"version":3,"file":"workspace.js","names":[],"sources":["../../src/api/workspace.ts"],"sourcesContent":["import type { AxiosInstance } from \"axios\";\n\nimport type { EntitySingleResponse } from \"@/types/entityQuery\";\nimport type { Workspace, WorkspaceListResponse } from \"@/types/workspace\";\nimport { pageParams, request } from \"./request\";\n\nconst baseUrl = \"workspaces\";\n\n/** The endpoint's envelope, private: `getWorkspace` returns the workspace itself. */\ntype WorkspaceSingleResponse = EntitySingleResponse<\"workspace\", Workspace>;\n\n/**\n * getWorkspace\n *\n * Fetches a single workspace by name.\n *\n * @param {AxiosInstance} api - Axios instance.\n * @param {string} name - Workspace name.\n * @param {AbortSignal} [signal] - Aborts the request itself; the entity hooks pass the query's own.\n * @returns {Promise<Workspace>} The fetched workspace.\n *\n * @throws {Error} If the request fails.\n */\nexport const getWorkspace = async (\n api: AxiosInstance,\n name: string,\n signal?: AbortSignal,\n): Promise<Workspace> => {\n if (!name) throw new Error(\"Workspace name is required to fetch a workspace\");\n\n const body = await request(\n () => api.get<WorkspaceSingleResponse>(`${baseUrl}/${name}`, { signal }),\n \"Error fetching workspace\",\n );\n return body.workspace;\n};\n\n/** What `listWorkspaces` sends. */\nexport type WorkspaceListParams = {\n /** A name prefix. Sent as `query`. */\n search?: string;\n pageSize?: number;\n pageToken?: string;\n};\n\n/**\n * listWorkspaces\n *\n * Lists the account's workspaces, a page at a time.\n *\n * The one list that takes no workspace: the docs exempt it, and the endpoint ignores one. This\n * function used to send it anyway, documented as \"required by some API configurations\".\n *\n * @param {AxiosInstance} api - Axios instance.\n * @param {WorkspaceListParams} [params] - Search and paging.\n * @param {AbortSignal} [signal] - Aborts the request itself; the list hooks pass the query's own.\n * @returns {Promise<WorkspaceListResponse>} A page of workspaces, with the cursor to the next one.\n *\n * @throws {Error} If the request fails.\n */\nexport const listWorkspaces = async (\n api: AxiosInstance,\n { search, pageSize, pageToken }: WorkspaceListParams = {},\n signal?: AbortSignal,\n): Promise<WorkspaceListResponse> => {\n const params = pageParams({ search, pageSize, pageToken });\n\n return request(\n () => api.get<WorkspaceListResponse>(baseUrl, { params, signal }),\n \"Error listing workspaces\",\n );\n};\n"],"mappings":";;AAMA,IAAM,UAAU;;;;;;;;;;;;;AAiBhB,IAAa,eAAe,OACxB,KACA,MACA,WACqB;CACrB,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,iDAAiD;CAM5E,QAAO,MAJY,cACT,IAAI,IAA6B,GAAG,QAAQ,GAAG,QAAQ,EAAE,OAAO,CAAC,GACvE,0BACJ,EAAA,CACY;AAChB;;;;;;;;;;;;;;;;AAyBA,IAAa,iBAAiB,OAC1B,KACA,EAAE,QAAQ,UAAU,cAAmC,CAAC,GACxD,WACiC;CACjC,MAAM,SAAS,WAAW;EAAE;EAAQ;EAAU;CAAU,CAAC;CAEzD,OAAO,cACG,IAAI,IAA2B,SAAS;EAAE;EAAQ;CAAO,CAAC,GAChE,0BACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Footer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAQ9C,eAAO,MAAM,MAAM,GAAI,yBAAyB,iBAAiB,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,gCAqBxF,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Footer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAQ/C,eAAO,MAAM,MAAM,GAAI,yBAAyB,iBAAiB,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,gCAsBxF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/Footer/index.tsx"],"sourcesContent":["import type { PropsWithChildren } from \"react\"\n\nimport { clsx } from 'clsx';\nimport Paper from \"@mui/material/Paper\";\nimport { useTheme, type Theme } from \"@mui/material/styles\";\n\nimport type { AnyRecord } from \"@/types/anyRecord\";\n\nexport const Footer = ({ className, children }: PropsWithChildren<{ className?: string }>) => {\n const theme: Theme = useTheme();\n const paperProps: AnyRecord = {\n light: {\n variant: 'outlined',\n },\n dark: {\n variant: 'elevation'\n }\n };\n\n return (\n <Paper\n square\n elevation={1}\n component=\"footer\"\n className={clsx(\"flex shrink-0 grow-0 basis-auto h-16 pl-6 pr-6\", className)}\n {...paperProps?.[theme.palette.mode]} >\n {children}\n </Paper>\n );\n}\n"],"mappings":";;;;;AAQA,IAAa,UAAU,EAAE,WAAW,eAA0D;CAC1F,MAAM,QAAe,SAAS;CAU9B,OACI,oBAAC,OAAD;EACI,QAAA;EACA,WAAW;EACX,WAAU;EACV,WAAW,KAAK,kDAAkD,SAAS;EAC3E,GAAI;GAdR,OAAO,EACH,SAAS,WACb;GACA,MAAM,EACF,SAAS,YACb;EASQ,EAAa,MAAM,QAAQ;EAC9B;CACE,CAAA;AAEf"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/Footer/index.tsx"],"sourcesContent":["import type { PropsWithChildren } from \"react\";\n\nimport { clsx } from \"clsx\";\nimport Paper from \"@mui/material/Paper\";\nimport { useTheme, type Theme } from \"@mui/material/styles\";\n\nimport type { AnyRecord } from \"@/types/anyRecord\";\n\nexport const Footer = ({ className, children }: PropsWithChildren<{ className?: string }>) => {\n const theme: Theme = useTheme();\n const paperProps: AnyRecord = {\n light: {\n variant: \"outlined\",\n },\n dark: {\n variant: \"elevation\",\n },\n };\n\n return (\n <Paper\n square\n elevation={1}\n component=\"footer\"\n className={clsx(\"flex shrink-0 grow-0 basis-auto h-16 pl-6 pr-6\", className)}\n {...paperProps?.[theme.palette.mode]}\n >\n {children}\n </Paper>\n );\n};\n"],"mappings":";;;;;AAQA,IAAa,UAAU,EAAE,WAAW,eAA0D;CAC1F,MAAM,QAAe,SAAS;CAU9B,OACI,oBAAC,OAAD;EACI,QAAA;EACA,WAAW;EACX,WAAU;EACV,WAAW,KAAK,kDAAkD,SAAS;EAC3E,GAAI;GAdR,OAAO,EACH,SAAS,WACb;GACA,MAAM,EACF,SAAS,YACb;EASQ,EAAa,MAAM,QAAQ;EAE9B;CACE,CAAA;AAEf"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/GlobalLoading/index.tsx"],"names":[],"mappings":"AAKA,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,GAAI,kCAAyC,kBAAkB,uCA0BxF,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/GlobalLoading/index.tsx"],"names":[],"mappings":"AAKA,UAAU,kBAAkB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,GAAI,kCAAyC,kBAAkB,uCAoCxF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/GlobalLoading/index.tsx"],"sourcesContent":["import Backdrop from \"@mui/material/Backdrop\";\nimport Box from \"@mui/material/Box\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface GlobalLoadingProps {\n isLoading: boolean;\n backdrop?: boolean;\n message?: string;\n}\n\nexport const GlobalLoading = ({ isLoading, backdrop = true, message }: GlobalLoadingProps) => {\n if (!isLoading) return null;\n\n const content = (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 2 }}>\n <CircularProgress color=\"primary\" />\n {message && <Typography color=\"text.secondary\">{message}</Typography>}\n </Box>\n );\n\n if (!backdrop) {\n return (\n <Box sx={{ display: \"flex\", justifyContent: \"center\", alignItems: \"center\", height: \"100%\" }}>\n {content}\n </Box>\n );\n }\n\n return (\n <Backdrop\n open\n sx={{ zIndex: (theme) => theme.zIndex.modal + 1, backgroundColor: \"rgba(0, 0, 0, 0.3)\" }}\n >\n {content}\n </Backdrop>\n );\n}\n"],"mappings":";;;;;;AAWA,IAAa,iBAAiB,EAAE,WAAW,WAAW,MAAM,cAAkC;CAC1F,IAAI,CAAC,WAAW,OAAO;CAEvB,MAAM,UACF,qBAAC,KAAD;EAAK,IAAI;GAAE,SAAS;GAAQ,eAAe;GAAU,YAAY;GAAU,KAAK;EAAE;EAAlF,UAAA,CACI,oBAAC,kBAAD,EAAkB,OAAM,UAAW,CAAA,GAClC,WAAW,oBAAC,YAAD;GAAY,OAAM;GAAkB,UAAA;EAAoB,CAAA,CACnE;;CAGT,IAAI,CAAC,UACD,OACI,oBAAC,KAAD;EAAK,IAAI;GAAE,SAAS;GAAQ,gBAAgB;GAAU,YAAY;GAAU,QAAQ;EAAO;EACtF,UAAA;CACA,CAAA;CAIb,OACI,oBAAC,UAAD;EACI,MAAA;EACA,IAAI;GAAE,SAAS,UAAU,MAAM,OAAO,QAAQ;GAAG,iBAAiB;EAAqB;EAEtF,UAAA;CACK,CAAA;AAElB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/GlobalLoading/index.tsx"],"sourcesContent":["import Backdrop from \"@mui/material/Backdrop\";\nimport Box from \"@mui/material/Box\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport Typography from \"@mui/material/Typography\";\n\ninterface GlobalLoadingProps {\n isLoading: boolean;\n backdrop?: boolean;\n message?: string;\n}\n\nexport const GlobalLoading = ({ isLoading, backdrop = true, message }: GlobalLoadingProps) => {\n if (!isLoading) return null;\n\n const content = (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 2 }}>\n <CircularProgress color=\"primary\" />\n {message && <Typography color=\"text.secondary\">{message}</Typography>}\n </Box>\n );\n\n if (!backdrop) {\n return (\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n height: \"100%\",\n }}\n >\n {content}\n </Box>\n );\n }\n\n return (\n <Backdrop\n open\n sx={{\n zIndex: (theme) => theme.zIndex.modal + 1,\n backgroundColor: \"rgba(0, 0, 0, 0.3)\",\n }}\n >\n {content}\n </Backdrop>\n );\n};\n"],"mappings":";;;;;;AAWA,IAAa,iBAAiB,EAAE,WAAW,WAAW,MAAM,cAAkC;CAC1F,IAAI,CAAC,WAAW,OAAO;CAEvB,MAAM,UACF,qBAAC,KAAD;EAAK,IAAI;GAAE,SAAS;GAAQ,eAAe;GAAU,YAAY;GAAU,KAAK;EAAE;EAAlF,UAAA,CACI,oBAAC,kBAAD,EAAkB,OAAM,UAAW,CAAA,GAClC,WAAW,oBAAC,YAAD;GAAY,OAAM;GAAkB,UAAA;EAAoB,CAAA,CACnE;;CAGT,IAAI,CAAC,UACD,OACI,oBAAC,KAAD;EACI,IAAI;GACA,SAAS;GACT,gBAAgB;GAChB,YAAY;GACZ,QAAQ;EACZ;EAEC,UAAA;CACA,CAAA;CAIb,OACI,oBAAC,UAAD;EACI,MAAA;EACA,IAAI;GACA,SAAS,UAAU,MAAM,OAAO,QAAQ;GACxC,iBAAiB;EACrB;EAEC,UAAA;CACK,CAAA;AAElB"}
@@ -1,5 +1,5 @@
1
1
  import type { PropsWithChildren, ReactNode } from "react";
2
- export declare const PageContainer: ({ header, footer, contentClassName, children }: PropsWithChildren<{
2
+ export declare const PageContainer: ({ header, footer, contentClassName, children, }: PropsWithChildren<{
3
3
  header?: ReactNode;
4
4
  footer?: ReactNode;
5
5
  contentClassName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/PageContainer/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1D,eAAO,MAAM,aAAa,GAAI,gDAAgD,iBAAiB,CAAC;IAAE,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,gCAUrK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/PageContainer/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1D,eAAO,MAAM,aAAa,GAAI,iDAK3B,iBAAiB,CAAC;IAAE,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,gCAY1F,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/PageContainer/index.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\n\nexport const PageContainer = ({ header, footer, contentClassName, children }: PropsWithChildren<{ header?: ReactNode, footer?: ReactNode, contentClassName?: string }>) => {\n return (\n <div className=\"flex flex-col w-full h-full overflow-hidden\">\n {header}\n <div className={clsx(\"flex shrink-1 grow-1 basis-auto overflow-auto\", contentClassName)}>\n {children}\n </div>\n {footer}\n </div>\n );\n};\n"],"mappings":";;;AAGA,IAAa,iBAAiB,EAAE,QAAQ,QAAQ,kBAAkB,eAAyG;CACvK,OACI,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACK;GACD,oBAAC,OAAD;IAAK,WAAW,OAAK,iDAAiD,gBAAgB;IACjF;GACA,CAAA;GACJ;EACA;;AAEb"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/PageContainer/index.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\n\nexport const PageContainer = ({\n header,\n footer,\n contentClassName,\n children,\n}: PropsWithChildren<{ header?: ReactNode; footer?: ReactNode; contentClassName?: string }>) => {\n return (\n <div className=\"flex flex-col w-full h-full overflow-hidden\">\n {header}\n <div\n className={clsx(\"flex shrink-1 grow-1 basis-auto overflow-auto\", contentClassName)}\n >\n {children}\n </div>\n {footer}\n </div>\n );\n};\n"],"mappings":";;;AAGA,IAAa,iBAAiB,EAC1B,QACA,QACA,kBACA,eAC4F;CAC5F,OACI,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACK;GACD,oBAAC,OAAD;IACI,WAAW,OAAK,iDAAiD,gBAAgB;IAEhF;GACA,CAAA;GACJ;EACA;;AAEb"}
@@ -1,5 +1,42 @@
1
- import type { PropsWithChildren } from 'react';
2
- export declare const Toolbar: ({ children, className }: PropsWithChildren<{
1
+ import type { PropsWithChildren, ReactNode } from "react";
2
+ import { type AppBarProps } from "@mui/material/AppBar";
3
+ /**
4
+ * The names follow MUI's own header components: `title`, `subheader` and `action` are
5
+ * `CardHeader`'s, `logo` is Toolpad's `branding.logo`, and the boolean reads as what turning
6
+ * it *on* does (`hideLogo`), because an MUI boolean defaults to `false`.
7
+ */
8
+ export type ToolbarProps = PropsWithChildren<{
9
+ /**
10
+ * Rendered before the logo. It is a slot rather than `onToggleMenu`/`onBack` props because
11
+ * the buttons that go here belong to whatever shell hosts the bar (a drawer toggle, a back
12
+ * button), and a prop per button would make the bar grow with every shell.
13
+ */
14
+ startAction?: ReactNode;
15
+ /** Replaces the Everysk mark, for an app that carries its client's. */
16
+ logo?: ReactNode;
17
+ /**
18
+ * A flag rather than `logo={null}` or `logo={false}` (MUI's `Alert.icon` spelling), so
19
+ * that no single prop means default, replace and remove at once. It wins over `logo`.
20
+ */
21
+ hideLogo?: boolean;
22
+ /** The page heading. An `h1`: the bar is where the page says what it is. */
23
+ title?: ReactNode;
24
+ subheader?: ReactNode;
25
+ /** Pushed to the far end of the bar, so no page has to align it with `justify-between`. */
26
+ action?: ReactNode;
27
+ /**
28
+ * `relative` by default: in `PageContainer` only the content scrolls, so the bar stays put
29
+ * by layout. `sticky` is for a page that scrolls as a whole.
30
+ */
31
+ position?: AppBarProps["position"];
32
+ /** Applied to the content row. */
3
33
  className?: string;
4
- }>) => import("react").JSX.Element;
34
+ }>;
35
+ /**
36
+ * What a page supplies, as opposed to what the chrome around it decides (`startAction`, the
37
+ * logo, `position`). A shell that renders the bar for its pages holds this, and a page
38
+ * publishes it without ever rendering the bar itself.
39
+ */
40
+ export type ToolbarContent = Pick<ToolbarProps, "title" | "subheader" | "action" | "children">;
41
+ export declare const Toolbar: ({ startAction, logo, hideLogo, title, subheader, action, position, className, children, }: ToolbarProps) => import("react").JSX.Element;
5
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Toolbar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAY/C,eAAO,MAAM,OAAO,GAAI,yBAAyB,iBAAiB,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,gCA+BzF,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/Toolbar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1D,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAShE;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC;IACzC;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,uEAAuE;IACvE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACnC,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC;AAsB/F,eAAO,MAAM,OAAO,GAAI,2FAUrB,YAAY,gCAqCd,CAAC"}
@@ -2,27 +2,54 @@ import { EveryskIcon } from "../EveryskIcon/index.js";
2
2
  import { useTheme } from "@mui/material/styles";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import clsx$1 from "clsx";
5
+ import Typography from "@mui/material/Typography";
5
6
  import AppBar from "@mui/material/AppBar";
6
7
  import MuiToolbar from "@mui/material/Toolbar";
7
8
  //#region src/components/ui/Toolbar/index.tsx
8
- var Toolbar = ({ children, className }) => {
9
+ var MODE_PROPS = {
10
+ light: {
11
+ color: "transparent",
12
+ elevation: 0,
13
+ sx: { border: "1px solid rgba(0, 0, 0, 0.12)" }
14
+ },
15
+ dark: {
16
+ color: "default",
17
+ elevation: 1
18
+ }
19
+ };
20
+ var Toolbar = ({ startAction, logo, hideLogo = false, title, subheader, action, position = "relative", className, children }) => {
9
21
  const theme = useTheme();
10
22
  return /* @__PURE__ */ jsx(AppBar, {
11
- position: "relative",
12
- ...{
13
- light: {
14
- color: "transparent",
15
- elevation: 0,
16
- sx: { border: "1px solid rgba(0, 0, 0, 0.12)" }
17
- },
18
- dark: {
19
- color: "default",
20
- elevation: 1
21
- }
22
- }[theme.palette.mode],
23
+ position,
24
+ ...MODE_PROPS[theme.palette.mode],
23
25
  children: /* @__PURE__ */ jsx(MuiToolbar, { children: /* @__PURE__ */ jsxs("div", {
24
- className: clsx$1("flex items-center gap-4", className),
25
- children: [/* @__PURE__ */ jsx(EveryskIcon, {}), children]
26
+ className: clsx$1("flex items-center gap-4 w-full min-w-0", className),
27
+ children: [
28
+ startAction && /* @__PURE__ */ jsx("div", {
29
+ className: "flex items-center shrink-0",
30
+ children: startAction
31
+ }),
32
+ !hideLogo && (logo ?? /* @__PURE__ */ jsx(EveryskIcon, { titleAccess: "Everysk" })),
33
+ (title || subheader) && /* @__PURE__ */ jsxs("div", {
34
+ className: "flex flex-col min-w-0",
35
+ children: [title && /* @__PURE__ */ jsx(Typography, {
36
+ variant: "h6",
37
+ component: "h1",
38
+ noWrap: true,
39
+ children: title
40
+ }), subheader && /* @__PURE__ */ jsx(Typography, {
41
+ variant: "body2",
42
+ color: "text.secondary",
43
+ noWrap: true,
44
+ children: subheader
45
+ })]
46
+ }),
47
+ children,
48
+ action && /* @__PURE__ */ jsx("div", {
49
+ className: "flex items-center gap-3 ml-auto shrink-0",
50
+ children: action
51
+ })
52
+ ]
26
53
  }) })
27
54
  });
28
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/Toolbar/index.tsx"],"sourcesContent":["import type { PropsWithChildren } from 'react';\n\nimport AppBar from '@mui/material/AppBar';\nimport { useTheme, type Theme } from '@mui/material/styles';\nimport MuiToolbar from '@mui/material/Toolbar';\n\nimport clsx from 'clsx';\n\nimport { EveryskIcon } from '@/components/ui/EveryskIcon';\n\nimport type { AnyRecord } from '@/types/anyRecord';\n\nexport const Toolbar = ({ children, className }: PropsWithChildren<{ className?: string }>) => {\n const theme: Theme = useTheme();\n\n const styles: AnyRecord = {\n light: {\n color: 'transparent',\n elevation: 0,\n sx: {\n border: \"1px solid rgba(0, 0, 0, 0.12)\"\n }\n },\n dark: {\n // 'default', not ''. An empty string is not a value the AppBar API takes — it\n // produced the class `MuiAppBar-color` with no variant suffix, which rendered the\n // same only because the brand theme overrides AppBar anyway. This is the explicit\n // spelling of what already happens, and it survives a theme that does not.\n color: 'default',\n elevation: 1\n }\n };\n\n return (\n <AppBar position='relative' {...styles?.[theme.palette.mode]}>\n <MuiToolbar >\n <div className={clsx(\"flex items-center gap-4\", className)}>\n <EveryskIcon />\n {children}\n </div>\n </MuiToolbar>\n </AppBar>\n );\n}\n"],"mappings":";;;;;;;AAYA,IAAa,WAAW,EAAE,UAAU,gBAA2D;CAC3F,MAAM,QAAe,SAAS;CAoB9B,OACI,oBAAC,QAAD;EAAQ,UAAS;EAAW,GAAI;GAlBhC,OAAO;IACH,OAAO;IACP,WAAW;IACX,IAAI,EACA,QAAQ,gCACZ;GACJ;GACA,MAAM;IAKF,OAAO;IACP,WAAW;GACf;EAIgC,EAAS,MAAM,QAAQ;EACnD,UAAA,oBAAC,YAAD,EAAA,UACI,qBAAC,OAAD;GAAK,WAAW,OAAK,2BAA2B,SAAS;GAAzD,UAAA,CACI,oBAAC,aAAD,CAAc,CAAA,GACb,QACA;EACG,CAAA,EAAA,CAAA;CACR,CAAA;AAEhB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/ui/Toolbar/index.tsx"],"sourcesContent":["import type { PropsWithChildren, ReactNode } from \"react\";\n\nimport AppBar, { type AppBarProps } from \"@mui/material/AppBar\";\nimport { useTheme, type PaletteMode, type Theme } from \"@mui/material/styles\";\nimport MuiToolbar from \"@mui/material/Toolbar\";\nimport Typography from \"@mui/material/Typography\";\n\nimport clsx from \"clsx\";\n\nimport { EveryskIcon } from \"@/components/ui/EveryskIcon\";\n\n/**\n * The names follow MUI's own header components: `title`, `subheader` and `action` are\n * `CardHeader`'s, `logo` is Toolpad's `branding.logo`, and the boolean reads as what turning\n * it *on* does (`hideLogo`), because an MUI boolean defaults to `false`.\n */\nexport type ToolbarProps = PropsWithChildren<{\n /**\n * Rendered before the logo. It is a slot rather than `onToggleMenu`/`onBack` props because\n * the buttons that go here belong to whatever shell hosts the bar (a drawer toggle, a back\n * button), and a prop per button would make the bar grow with every shell.\n */\n startAction?: ReactNode;\n /** Replaces the Everysk mark, for an app that carries its client's. */\n logo?: ReactNode;\n /**\n * A flag rather than `logo={null}` or `logo={false}` (MUI's `Alert.icon` spelling), so\n * that no single prop means default, replace and remove at once. It wins over `logo`.\n */\n hideLogo?: boolean;\n /** The page heading. An `h1`: the bar is where the page says what it is. */\n title?: ReactNode;\n subheader?: ReactNode;\n /** Pushed to the far end of the bar, so no page has to align it with `justify-between`. */\n action?: ReactNode;\n /**\n * `relative` by default: in `PageContainer` only the content scrolls, so the bar stays put\n * by layout. `sticky` is for a page that scrolls as a whole.\n */\n position?: AppBarProps[\"position\"];\n /** Applied to the content row. */\n className?: string;\n}>;\n\n/**\n * What a page supplies, as opposed to what the chrome around it decides (`startAction`, the\n * logo, `position`). A shell that renders the bar for its pages holds this, and a page\n * publishes it without ever rendering the bar itself.\n */\nexport type ToolbarContent = Pick<ToolbarProps, \"title\" | \"subheader\" | \"action\" | \"children\">;\n\n// Typed as AppBar props, not `AnyRecord`: a loose map here is what let an invalid `color: ''`\n// through for as long as it did.\nconst MODE_PROPS: Record<PaletteMode, AppBarProps> = {\n light: {\n color: \"transparent\",\n elevation: 0,\n sx: {\n border: \"1px solid rgba(0, 0, 0, 0.12)\",\n },\n },\n dark: {\n // 'default', not ''. An empty string is not a value the AppBar API takes — it\n // produced the class `MuiAppBar-color` with no variant suffix, which rendered the\n // same only because the brand theme overrides AppBar anyway. This is the explicit\n // spelling of what already happens, and it survives a theme that does not.\n color: \"default\",\n elevation: 1,\n },\n};\n\nexport const Toolbar = ({\n startAction,\n logo,\n hideLogo = false,\n title,\n subheader,\n action,\n position = \"relative\",\n className,\n children,\n}: ToolbarProps) => {\n const theme: Theme = useTheme();\n\n return (\n <AppBar position={position} {...MODE_PROPS[theme.palette.mode]}>\n <MuiToolbar>\n <div className={clsx(\"flex items-center gap-4 w-full min-w-0\", className)}>\n {startAction && <div className=\"flex items-center shrink-0\">{startAction}</div>}\n\n {!hideLogo && (logo ?? <EveryskIcon titleAccess=\"Everysk\" />)}\n\n {(title || subheader) && (\n // `min-w-0` is what lets the title truncate instead of pushing the\n // action out of the bar.\n <div className=\"flex flex-col min-w-0\">\n {title && (\n <Typography variant=\"h6\" component=\"h1\" noWrap>\n {title}\n </Typography>\n )}\n {subheader && (\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {subheader}\n </Typography>\n )}\n </div>\n )}\n\n {children}\n\n {action && (\n <div className=\"flex items-center gap-3 ml-auto shrink-0\">{action}</div>\n )}\n </div>\n </MuiToolbar>\n </AppBar>\n );\n};\n"],"mappings":";;;;;;;;AAqDA,IAAM,aAA+C;CACjD,OAAO;EACH,OAAO;EACP,WAAW;EACX,IAAI,EACA,QAAQ,gCACZ;CACJ;CACA,MAAM;EAKF,OAAO;EACP,WAAW;CACf;AACJ;AAEA,IAAa,WAAW,EACpB,aACA,MACA,WAAW,OACX,OACA,WACA,QACA,WAAW,YACX,WACA,eACgB;CAChB,MAAM,QAAe,SAAS;CAE9B,OACI,oBAAC,QAAD;EAAkB;EAAU,GAAI,WAAW,MAAM,QAAQ;EACrD,UAAA,oBAAC,YAAD,EAAA,UACI,qBAAC,OAAD;GAAK,WAAW,OAAK,0CAA0C,SAAS;GAAxE,UAAA;IACK,eAAe,oBAAC,OAAD;KAAK,WAAU;KAA8B,UAAA;IAAiB,CAAA;IAE7E,CAAC,aAAa,QAAQ,oBAAC,aAAD,EAAa,aAAY,UAAW,CAAA;KAEzD,SAAS,cAGP,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACK,SACG,oBAAC,YAAD;MAAY,SAAQ;MAAK,WAAU;MAAK,QAAA;MACnC,UAAA;KACO,CAAA,GAEf,aACG,oBAAC,YAAD;MAAY,SAAQ;MAAQ,OAAM;MAAiB,QAAA;MAC9C,UAAA;KACO,CAAA,CAEf;;IAGR;IAEA,UACG,oBAAC,OAAD;KAAK,WAAU;KAA4C,UAAA;IAAY,CAAA;GAE1E;EACG,CAAA,EAAA,CAAA;CACR,CAAA;AAEhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","names":[],"sources":["../../../src/contexts/appAlertContext/provider.tsx"],"sourcesContent":["import { useCallback, useMemo, useState, type PropsWithChildren } from \"react\";\nimport Alert from \"@mui/material/Alert\";\nimport Snackbar, { type SnackbarCloseReason } from \"@mui/material/Snackbar\";\n\nimport { AppAlertContext } from \".\";\nimport type { AppAlertContextType, AppAlertState, ShowAlertOptions } from \"./types\";\n\n/**\n * AppAlertProvider\n *\n * React context provider responsible for exposing a global application alert API and rendering\n * a Material UI `Snackbar` + `Alert` pair anchored to the viewport.\n *\n * What this provider does:\n * - Maintains an internal `AppAlertState` that controls:\n * - visibility (`open`)\n * - displayed text (`message`)\n * - alert tone (`severity`)\n * - auto-dismiss timing (`autoHideDuration`)\n * - screen position (`anchorOrigin`)\n * - Exposes an imperative API via context:\n * - `showAlert(options)` to open/update the alert\n * - `hideAlert()` to close the alert\n * - Renders the `Snackbar`/`Alert` components once (at the provider level), so any descendant can\n * trigger alerts without needing to manage UI state locally.\n *\n * Behavior:\n * - `showAlert(options)` performs a shallow merge of the provided options into the current state\n * and forces `open: true`.\n * - `hideAlert()` sets `open: false` (preserving the remaining state).\n * - Snackbar `onClose` ignores the `\"clickaway\"` reason to prevent accidental dismissals when the user\n * clicks outside the toast.\n *\n * Performance / stability:\n * - `showAlert` and `hideAlert` should be stable (e.g., created with `useCallback`) so the context value\n * does not change on every render, avoiding unnecessary re-renders in consumers.\n *\n * Usage:\n * ```ts\n * <AppAlertProvider>\n * <App />\n * </AppAlertProvider>\n * ```\n */\n\nexport const AppAlertProvider = ({ children }: PropsWithChildren) => {\n const [state, setState] = useState<AppAlertState>({\n open: false,\n message: \"\",\n severity: \"info\",\n autoHideDuration: 4000,\n anchorOrigin: { vertical: \"bottom\", horizontal: \"right\" },\n });\n\n const hideAlert = useCallback(() => {\n setState((prev) => ({ ...prev, open: false }));\n }, []);\n\n const showAlert = useCallback((options: ShowAlertOptions) => {\n setState((prev) => ({\n ...prev,\n ...options,\n open: true,\n }));\n }, []);\n\n const value: AppAlertContextType = useMemo(\n () => ({ showAlert, hideAlert }),\n [showAlert, hideAlert]\n );\n\n return (\n <AppAlertContext.Provider value={value}>\n {children}\n\n <Snackbar\n open={state.open}\n message={state.message}\n autoHideDuration={state.autoHideDuration}\n anchorOrigin={state.anchorOrigin}\n onClose={(_, reason: SnackbarCloseReason) => {\n if (reason === \"clickaway\") return;\n hideAlert();\n }}\n >\n <Alert onClose={hideAlert} severity={state.severity} variant=\"filled\" elevation={6}>\n {state.message}\n </Alert>\n </Snackbar>\n </AppAlertContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAa,oBAAoB,EAAE,eAAkC;CACjE,MAAM,CAAC,OAAO,YAAY,SAAwB;EAC9C,MAAM;EACN,SAAS;EACT,UAAU;EACV,kBAAkB;EAClB,cAAc;GAAE,UAAU;GAAU,YAAY;EAAQ;CAC5D,CAAC;CAED,MAAM,YAAY,kBAAkB;EAChC,UAAU,UAAU;GAAE,GAAG;GAAM,MAAM;EAAM,EAAE;CACjD,GAAG,CAAC,CAAC;CAEL,MAAM,YAAY,aAAa,YAA8B;EACzD,UAAU,UAAU;GAChB,GAAG;GACH,GAAG;GACH,MAAM;EACV,EAAE;CACN,GAAG,CAAC,CAAC;CAEL,MAAM,QAA6B,eACxB;EAAE;EAAW;CAAU,IAC9B,CAAC,WAAW,SAAS,CACzB;CAEA,OACI,qBAAC,gBAAgB,UAAjB;EAAiC;EAAjC,UAAA,CACK,UAED,oBAAC,UAAD;GACI,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,kBAAkB,MAAM;GACxB,cAAc,MAAM;GACpB,UAAU,GAAG,WAAgC;IACzC,IAAI,WAAW,aAAa;IAC5B,UAAU;GACd;GAEA,UAAA,oBAAC,OAAD;IAAO,SAAS;IAAW,UAAU,MAAM;IAAU,SAAQ;IAAS,WAAW;IAC5E,UAAA,MAAM;GACJ,CAAA;EACD,CAAA,CACY;;AAElC"}
1
+ {"version":3,"file":"provider.js","names":[],"sources":["../../../src/contexts/appAlertContext/provider.tsx"],"sourcesContent":["import { useCallback, useMemo, useState, type PropsWithChildren } from \"react\";\nimport Alert from \"@mui/material/Alert\";\nimport Snackbar, { type SnackbarCloseReason } from \"@mui/material/Snackbar\";\n\nimport { AppAlertContext } from \".\";\nimport type { AppAlertContextType, AppAlertState, ShowAlertOptions } from \"./types\";\n\n/**\n * AppAlertProvider\n *\n * React context provider responsible for exposing a global application alert API and rendering\n * a Material UI `Snackbar` + `Alert` pair anchored to the viewport.\n *\n * What this provider does:\n * - Maintains an internal `AppAlertState` that controls:\n * - visibility (`open`)\n * - displayed text (`message`)\n * - alert tone (`severity`)\n * - auto-dismiss timing (`autoHideDuration`)\n * - screen position (`anchorOrigin`)\n * - Exposes an imperative API via context:\n * - `showAlert(options)` to open/update the alert\n * - `hideAlert()` to close the alert\n * - Renders the `Snackbar`/`Alert` components once (at the provider level), so any descendant can\n * trigger alerts without needing to manage UI state locally.\n *\n * Behavior:\n * - `showAlert(options)` performs a shallow merge of the provided options into the current state\n * and forces `open: true`.\n * - `hideAlert()` sets `open: false` (preserving the remaining state).\n * - Snackbar `onClose` ignores the `\"clickaway\"` reason to prevent accidental dismissals when the user\n * clicks outside the toast.\n *\n * Performance / stability:\n * - `showAlert` and `hideAlert` should be stable (e.g., created with `useCallback`) so the context value\n * does not change on every render, avoiding unnecessary re-renders in consumers.\n *\n * Usage:\n * ```ts\n * <AppAlertProvider>\n * <App />\n * </AppAlertProvider>\n * ```\n */\n\nexport const AppAlertProvider = ({ children }: PropsWithChildren) => {\n const [state, setState] = useState<AppAlertState>({\n open: false,\n message: \"\",\n severity: \"info\",\n autoHideDuration: 4000,\n anchorOrigin: { vertical: \"bottom\", horizontal: \"right\" },\n });\n\n const hideAlert = useCallback(() => {\n setState((prev) => ({ ...prev, open: false }));\n }, []);\n\n const showAlert = useCallback((options: ShowAlertOptions) => {\n setState((prev) => ({\n ...prev,\n ...options,\n open: true,\n }));\n }, []);\n\n const value: AppAlertContextType = useMemo(\n () => ({ showAlert, hideAlert }),\n [showAlert, hideAlert],\n );\n\n return (\n <AppAlertContext.Provider value={value}>\n {children}\n\n <Snackbar\n open={state.open}\n message={state.message}\n autoHideDuration={state.autoHideDuration}\n anchorOrigin={state.anchorOrigin}\n onClose={(_, reason: SnackbarCloseReason) => {\n if (reason === \"clickaway\") return;\n hideAlert();\n }}\n >\n <Alert onClose={hideAlert} severity={state.severity} variant=\"filled\" elevation={6}>\n {state.message}\n </Alert>\n </Snackbar>\n </AppAlertContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAa,oBAAoB,EAAE,eAAkC;CACjE,MAAM,CAAC,OAAO,YAAY,SAAwB;EAC9C,MAAM;EACN,SAAS;EACT,UAAU;EACV,kBAAkB;EAClB,cAAc;GAAE,UAAU;GAAU,YAAY;EAAQ;CAC5D,CAAC;CAED,MAAM,YAAY,kBAAkB;EAChC,UAAU,UAAU;GAAE,GAAG;GAAM,MAAM;EAAM,EAAE;CACjD,GAAG,CAAC,CAAC;CAEL,MAAM,YAAY,aAAa,YAA8B;EACzD,UAAU,UAAU;GAChB,GAAG;GACH,GAAG;GACH,MAAM;EACV,EAAE;CACN,GAAG,CAAC,CAAC;CAEL,MAAM,QAA6B,eACxB;EAAE;EAAW;CAAU,IAC9B,CAAC,WAAW,SAAS,CACzB;CAEA,OACI,qBAAC,gBAAgB,UAAjB;EAAiC;EAAjC,UAAA,CACK,UAED,oBAAC,UAAD;GACI,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,kBAAkB,MAAM;GACxB,cAAc,MAAM;GACpB,UAAU,GAAG,WAAgC;IACzC,IAAI,WAAW,aAAa;IAC5B,UAAU;GACd;GAEA,UAAA,oBAAC,OAAD;IAAO,SAAS;IAAW,UAAU,MAAM;IAAU,SAAQ;IAAS,WAAW;IAC5E,UAAA,MAAM;GACJ,CAAA;EACD,CAAA,CACY;;AAElC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/contexts/appAlertContext/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC,GAAG;IAC9E,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG;IAClE,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/contexts/appAlertContext/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC,GAAG;IAC9E,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG;IAClE,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,SAAS,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/contexts/appConfigContext/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,eAAO,MAAM,gBAAgB,sDAAmD,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/contexts/appConfigContext/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,eAAO,MAAM,gBAAgB,sDAAmD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/contexts/appConfigContext/index.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { AppConfigContextType } from \"./types\";\n\nexport const AppConfigContext = createContext<AppConfigContextType | null>(null)\n"],"mappings":";;AAGA,IAAa,mBAAmB,cAA2C,IAAI"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/contexts/appConfigContext/index.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { AppConfigContextType } from \"./types\";\n\nexport const AppConfigContext = createContext<AppConfigContextType | null>(null);\n"],"mappings":";;AAGA,IAAa,mBAAmB,cAA2C,IAAI"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/contexts/appConfigContext/provider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAwB,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,iBAAiB,GAAI,yCAI/B,sBAAsB,gCAexB,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/contexts/appConfigContext/provider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAwB,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,iBAAiB,GAAI,yCAI/B,sBAAsB,gCAWxB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","names":[],"sources":["../../../src/contexts/appConfigContext/provider.tsx"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport { AppConfigContext } from \".\";\nimport type { AppConfigContextType, AppConfigProviderProps } from \"./types\";\n\n/**\n * AppConfigProvider\n *\n * React context provider responsible for exposing the application's runtime configuration\n * (`AppConfigContextType`) to the component tree.\n *\n * Configuration sources, in order of precedence:\n *\n * 1. The `appId` / `appEnvironmentVar` props.\n * Explicit injection, for tests and for hosts that resolve configuration themselves rather\n * than through the page globals. A prop wins over the corresponding global; passing\n * `appId={null}` forces \"no app id\" instead of falling through to `window.APP_ID`.\n *\n * 2. `window.APP_ID` and `window.APP_CONFIG`.\n * Injected into the page by the platform (from the app's `config.json` `env_vars`) before\n * the bundle executes.\n *\n * In dev there is no platform to inject them, so the app's dev server serves the `env_vars` at\n * `/app-config.json` and the app merges them into `window.APP_CONFIG` during bootstrap, before\n * React mounts. That merge is shallow and belongs to the app, not to this provider: nested\n * objects are replaced whole, not deep-merged.\n *\n * Lifecycle notes:\n * - This provider performs no network request and does not update its value after mount.\n * - Because configuration is resolved before `createRoot(...).render(...)`, the tree receives a\n * consistent configuration from the first render.\n *\n * Example:\n * ```tsx\n * <AppConfigProvider>\n * <App />\n * </AppConfigProvider>\n *\n * // In a test, with no page globals:\n * <AppConfigProvider appId=\"app_42\" appEnvironmentVar={{ API_URL: \"/api\" }}>\n * <ComponentUnderTest />\n * </AppConfigProvider>\n *\n * // Consumer hook usage\n * const { appId, appEnvironmentVar } = useAppConfig();\n * ```\n */\nexport const AppConfigProvider = ({\n children,\n appId,\n appEnvironmentVar,\n}: AppConfigProviderProps) => {\n const value: AppConfigContextType = useMemo(() => {\n const globalConfig = (globalThis.window?.APP_CONFIG ?? {}) as Record<string, unknown>;\n\n return {\n appId: appId !== undefined ? appId : (globalThis.window?.APP_ID ?? null),\n appEnvironmentVar: appEnvironmentVar ?? globalConfig,\n };\n }, [appId, appEnvironmentVar]);\n\n return (\n <AppConfigContext.Provider value={value}>\n {children}\n </AppConfigContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,IAAa,qBAAqB,EAC9B,UACA,OACA,wBAC0B;CAC1B,MAAM,QAA8B,cAAc;EAC9C,MAAM,eAAgB,WAAW,QAAQ,cAAc,CAAC;EAExD,OAAO;GACH,OAAO,UAAU,KAAA,IAAY,QAAS,WAAW,QAAQ,UAAU;GACnE,mBAAmB,qBAAqB;EAC5C;CACJ,GAAG,CAAC,OAAO,iBAAiB,CAAC;CAE7B,OACI,oBAAC,iBAAiB,UAAlB;EAAkC;EAC7B;CACsB,CAAA;AAEnC"}
1
+ {"version":3,"file":"provider.js","names":[],"sources":["../../../src/contexts/appConfigContext/provider.tsx"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport { AppConfigContext } from \".\";\nimport type { AppConfigContextType, AppConfigProviderProps } from \"./types\";\n\n/**\n * AppConfigProvider\n *\n * React context provider responsible for exposing the application's runtime configuration\n * (`AppConfigContextType`) to the component tree.\n *\n * Configuration sources, in order of precedence:\n *\n * 1. The `appId` / `appEnvironmentVar` props.\n * Explicit injection, for tests and for hosts that resolve configuration themselves rather\n * than through the page globals. A prop wins over the corresponding global; passing\n * `appId={null}` forces \"no app id\" instead of falling through to `window.APP_ID`.\n *\n * 2. `window.APP_ID` and `window.APP_CONFIG`.\n * Injected into the page by the platform (from the app's `config.json` `env_vars`) before\n * the bundle executes.\n *\n * In dev there is no platform to inject them, so the app's dev server serves the `env_vars` at\n * `/app-config.json` and the app merges them into `window.APP_CONFIG` during bootstrap, before\n * React mounts. That merge is shallow and belongs to the app, not to this provider: nested\n * objects are replaced whole, not deep-merged.\n *\n * Lifecycle notes:\n * - This provider performs no network request and does not update its value after mount.\n * - Because configuration is resolved before `createRoot(...).render(...)`, the tree receives a\n * consistent configuration from the first render.\n *\n * Example:\n * ```tsx\n * <AppConfigProvider>\n * <App />\n * </AppConfigProvider>\n *\n * // In a test, with no page globals:\n * <AppConfigProvider appId=\"app_42\" appEnvironmentVar={{ API_URL: \"/api\" }}>\n * <ComponentUnderTest />\n * </AppConfigProvider>\n *\n * // Consumer hook usage\n * const { appId, appEnvironmentVar } = useAppConfig();\n * ```\n */\nexport const AppConfigProvider = ({\n children,\n appId,\n appEnvironmentVar,\n}: AppConfigProviderProps) => {\n const value: AppConfigContextType = useMemo(() => {\n const globalConfig = (globalThis.window?.APP_CONFIG ?? {}) as Record<string, unknown>;\n\n return {\n appId: appId !== undefined ? appId : (globalThis.window?.APP_ID ?? null),\n appEnvironmentVar: appEnvironmentVar ?? globalConfig,\n };\n }, [appId, appEnvironmentVar]);\n\n return <AppConfigContext.Provider value={value}>{children}</AppConfigContext.Provider>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,IAAa,qBAAqB,EAC9B,UACA,OACA,wBAC0B;CAC1B,MAAM,QAA8B,cAAc;EAC9C,MAAM,eAAgB,WAAW,QAAQ,cAAc,CAAC;EAExD,OAAO;GACH,OAAO,UAAU,KAAA,IAAY,QAAS,WAAW,QAAQ,UAAU;GACnE,mBAAmB,qBAAqB;EAC5C;CACJ,GAAG,CAAC,OAAO,iBAAiB,CAAC;CAE7B,OAAO,oBAAC,iBAAiB,UAAlB;EAAkC;EAAQ;CAAoC,CAAA;AACzF"}
@@ -1,4 +1,5 @@
1
- import type { WebSocketNotification, WebSocketStatus, WebsocketsConfig } from "./types";
1
+ import type { WebsocketsConfig } from "../../api/websocketsConfig.js";
2
+ import type { WebSocketNotification, WebSocketStatus } from "./types";
2
3
  type StatusListener = (status: Exclude<WebSocketStatus, "idle">) => void;
3
4
  type WebSocketHandlerConfig = WebsocketsConfig & {
4
5
  onStatusChange?: StatusListener;
@@ -20,7 +21,7 @@ export declare class WebSocketHandler {
20
21
  private _socket;
21
22
  private _everyskUID;
22
23
  private _listeners;
23
- constructor({ appConnectionURL, appChannelID, everyskUID, onStatusChange }: WebSocketHandlerConfig);
24
+ constructor({ appConnectionURL, appChannelID, everyskUID, onStatusChange, }: WebSocketHandlerConfig);
24
25
  private _isEcho;
25
26
  /**
26
27
  * listen
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/contexts/webSocketContext/handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAWxF,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;AAEzE,KAAK,sBAAsB,GAAG,gBAAgB,GAAG;IAC7C,cAAc,CAAC,EAAE,cAAc,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAwD;gBAE9D,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,EAAE,sBAAsB;IAoClG,OAAO,CAAC,OAAO;IAUf;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,GAAG,MAAM,IAAI;IAKlE;;;;;OAKG;IACH,KAAK,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/contexts/webSocketContext/handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAWtE,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;AAEzE,KAAK,sBAAsB,GAAG,gBAAgB,GAAG;IAC7C,cAAc,CAAC,EAAE,cAAc,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAwD;gBAE9D,EACR,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,cAAc,GACjB,EAAE,sBAAsB;IAoCzB,OAAO,CAAC,OAAO;IAUf;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,GAAG,MAAM,IAAI;IAKlE;;;;;OAKG;IACH,KAAK,IAAI,IAAI;CAKhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","names":[],"sources":["../../../src/contexts/webSocketContext/handler.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\n\nimport type { WebSocketNotification, WebSocketStatus, WebsocketsConfig } from \"./types\";\n\nfunction isWebSocketNotification(value: unknown): value is WebSocketNotification {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as Record<string, unknown>)[\"event_type\"] === \"string\"\n );\n}\nimport { JOIN_EVENT, NOTIFICATION_EVENT } from \"./constants\";\n\ntype StatusListener = (status: Exclude<WebSocketStatus, \"idle\">) => void;\n\ntype WebSocketHandlerConfig = WebsocketsConfig & {\n onStatusChange?: StatusListener;\n};\n\n/**\n * WebSocketHandler\n *\n * Low-level Socket.IO wrapper with a pub/sub layer.\n *\n * - Connects to the notification server.\n * - Joins the per-user channel.\n * - Forwards notifications to registered listeners.\n *\n * API:\n * - `listen(callback)`: register a notification listener; returns an unsubscribe function.\n * - `close()`: disconnect the socket and clear all listeners.\n */\nexport class WebSocketHandler {\n private _socket: Socket;\n private _everyskUID: string;\n private _listeners: Set<(msg: WebSocketNotification) => void> = new Set();\n\n constructor({ appConnectionURL, appChannelID, everyskUID, onStatusChange }: WebSocketHandlerConfig) {\n this._everyskUID = everyskUID;\n\n this._socket = io(appConnectionURL, {\n auth: { appChannelID, everyskUID },\n transports: [\"websocket\"],\n });\n\n this._socket.on(\"connect\", () => {\n this._socket.emit(JOIN_EVENT, appChannelID);\n onStatusChange?.(\"connected\");\n });\n\n this._socket.on(\"connect_error\", (error) => {\n console.error(\"Socket.IO connection error:\", error);\n onStatusChange?.(\"error\");\n });\n\n this._socket.on(\"disconnect\", (reason: string) => {\n console.error(\"Socket.IO disconnected:\", reason);\n onStatusChange?.(reason === \"io server disconnect\" ? \"error\" : \"connecting\");\n });\n\n this._socket.on(NOTIFICATION_EVENT, (msg: unknown) => {\n if (!isWebSocketNotification(msg)) return;\n if (this._isEcho(msg)) return;\n this._listeners.forEach((callback) => {\n try {\n callback(msg);\n } catch (error) {\n console.error(\"Socket.IO notification listener threw:\", error);\n }\n });\n });\n }\n\n private _isEcho(msg: WebSocketNotification): boolean {\n // Echo-cancellation is disabled by default.\n // Set ECHO_UID_FIELD to the message field that carries the originating uid\n // once the server team confirms the field name.\n const ECHO_UID_FIELD: string | null = null;\n if (!ECHO_UID_FIELD) return false;\n const originating = (msg as Record<string, unknown>)[ECHO_UID_FIELD];\n return originating === this._everyskUID;\n }\n\n /**\n * listen\n *\n * Registers a listener that receives every incoming notification.\n *\n * @param {(msg: WebSocketNotification) => void} callback - Invoked for each notification.\n * @returns {() => void} Unsubscribe function.\n */\n listen(callback: (msg: WebSocketNotification) => void): () => void {\n this._listeners.add(callback);\n return () => this._listeners.delete(callback);\n }\n\n /**\n * close\n *\n * Clears all listeners and disconnects the socket.\n * After calling this, the handler should be considered unusable.\n */\n close(): void {\n this._listeners.clear();\n this._socket.removeAllListeners();\n this._socket.disconnect();\n }\n}\n"],"mappings":";;;AAIA,SAAS,wBAAwB,OAAgD;CAC7E,OACI,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAkC,kBAAkB;AAEpE;;;;;;;;;;;;;;AAsBA,IAAa,mBAAb,MAA8B;CAC1B;CACA;CACA,6BAAgE,IAAI,IAAI;CAExE,YAAY,EAAE,kBAAkB,cAAc,YAAY,kBAA0C;EAChG,KAAK,cAAc;EAEnB,KAAK,UAAU,GAAG,kBAAkB;GAChC,MAAM;IAAE;IAAc;GAAW;GACjC,YAAY,CAAC,WAAW;EAC5B,CAAC;EAED,KAAK,QAAQ,GAAG,iBAAiB;GAC7B,KAAK,QAAQ,KAAK,YAAY,YAAY;GAC1C,iBAAiB,WAAW;EAChC,CAAC;EAED,KAAK,QAAQ,GAAG,kBAAkB,UAAU;GACxC,QAAQ,MAAM,+BAA+B,KAAK;GAClD,iBAAiB,OAAO;EAC5B,CAAC;EAED,KAAK,QAAQ,GAAG,eAAe,WAAmB;GAC9C,QAAQ,MAAM,2BAA2B,MAAM;GAC/C,iBAAiB,WAAW,yBAAyB,UAAU,YAAY;EAC/E,CAAC;EAED,KAAK,QAAQ,GAAG,qBAAqB,QAAiB;GAClD,IAAI,CAAC,wBAAwB,GAAG,GAAG;GACnC,IAAI,KAAK,QAAQ,GAAG,GAAG;GACvB,KAAK,WAAW,SAAS,aAAa;IAClC,IAAI;KACA,SAAS,GAAG;IAChB,SAAS,OAAO;KACZ,QAAQ,MAAM,0CAA0C,KAAK;IACjE;GACJ,CAAC;EACL,CAAC;CACL;CAEA,QAAgB,KAAqC;EAK5B,OAAO;CAGhC;;;;;;;;;CAUA,OAAO,UAA4D;EAC/D,KAAK,WAAW,IAAI,QAAQ;EAC5B,aAAa,KAAK,WAAW,OAAO,QAAQ;CAChD;;;;;;;CAQA,QAAc;EACV,KAAK,WAAW,MAAM;EACtB,KAAK,QAAQ,mBAAmB;EAChC,KAAK,QAAQ,WAAW;CAC5B;AACJ"}
1
+ {"version":3,"file":"handler.js","names":[],"sources":["../../../src/contexts/webSocketContext/handler.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\n\nimport type { WebsocketsConfig } from \"@/api/websocketsConfig\";\nimport type { WebSocketNotification, WebSocketStatus } from \"./types\";\n\nfunction isWebSocketNotification(value: unknown): value is WebSocketNotification {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as Record<string, unknown>)[\"event_type\"] === \"string\"\n );\n}\nimport { JOIN_EVENT, NOTIFICATION_EVENT } from \"./constants\";\n\ntype StatusListener = (status: Exclude<WebSocketStatus, \"idle\">) => void;\n\ntype WebSocketHandlerConfig = WebsocketsConfig & {\n onStatusChange?: StatusListener;\n};\n\n/**\n * WebSocketHandler\n *\n * Low-level Socket.IO wrapper with a pub/sub layer.\n *\n * - Connects to the notification server.\n * - Joins the per-user channel.\n * - Forwards notifications to registered listeners.\n *\n * API:\n * - `listen(callback)`: register a notification listener; returns an unsubscribe function.\n * - `close()`: disconnect the socket and clear all listeners.\n */\nexport class WebSocketHandler {\n private _socket: Socket;\n private _everyskUID: string;\n private _listeners: Set<(msg: WebSocketNotification) => void> = new Set();\n\n constructor({\n appConnectionURL,\n appChannelID,\n everyskUID,\n onStatusChange,\n }: WebSocketHandlerConfig) {\n this._everyskUID = everyskUID;\n\n this._socket = io(appConnectionURL, {\n auth: { appChannelID, everyskUID },\n transports: [\"websocket\"],\n });\n\n this._socket.on(\"connect\", () => {\n this._socket.emit(JOIN_EVENT, appChannelID);\n onStatusChange?.(\"connected\");\n });\n\n this._socket.on(\"connect_error\", (error) => {\n console.error(\"Socket.IO connection error:\", error);\n onStatusChange?.(\"error\");\n });\n\n this._socket.on(\"disconnect\", (reason: string) => {\n console.error(\"Socket.IO disconnected:\", reason);\n onStatusChange?.(reason === \"io server disconnect\" ? \"error\" : \"connecting\");\n });\n\n this._socket.on(NOTIFICATION_EVENT, (msg: unknown) => {\n if (!isWebSocketNotification(msg)) return;\n if (this._isEcho(msg)) return;\n this._listeners.forEach((callback) => {\n try {\n callback(msg);\n } catch (error) {\n console.error(\"Socket.IO notification listener threw:\", error);\n }\n });\n });\n }\n\n private _isEcho(msg: WebSocketNotification): boolean {\n // Echo-cancellation is disabled by default.\n // Set ECHO_UID_FIELD to the message field that carries the originating uid\n // once the server team confirms the field name.\n const ECHO_UID_FIELD: string | null = null;\n if (!ECHO_UID_FIELD) return false;\n const originating = (msg as Record<string, unknown>)[ECHO_UID_FIELD];\n return originating === this._everyskUID;\n }\n\n /**\n * listen\n *\n * Registers a listener that receives every incoming notification.\n *\n * @param {(msg: WebSocketNotification) => void} callback - Invoked for each notification.\n * @returns {() => void} Unsubscribe function.\n */\n listen(callback: (msg: WebSocketNotification) => void): () => void {\n this._listeners.add(callback);\n return () => this._listeners.delete(callback);\n }\n\n /**\n * close\n *\n * Clears all listeners and disconnects the socket.\n * After calling this, the handler should be considered unusable.\n */\n close(): void {\n this._listeners.clear();\n this._socket.removeAllListeners();\n this._socket.disconnect();\n }\n}\n"],"mappings":";;;AAKA,SAAS,wBAAwB,OAAgD;CAC7E,OACI,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAkC,kBAAkB;AAEpE;;;;;;;;;;;;;;AAsBA,IAAa,mBAAb,MAA8B;CAC1B;CACA;CACA,6BAAgE,IAAI,IAAI;CAExE,YAAY,EACR,kBACA,cACA,YACA,kBACuB;EACvB,KAAK,cAAc;EAEnB,KAAK,UAAU,GAAG,kBAAkB;GAChC,MAAM;IAAE;IAAc;GAAW;GACjC,YAAY,CAAC,WAAW;EAC5B,CAAC;EAED,KAAK,QAAQ,GAAG,iBAAiB;GAC7B,KAAK,QAAQ,KAAK,YAAY,YAAY;GAC1C,iBAAiB,WAAW;EAChC,CAAC;EAED,KAAK,QAAQ,GAAG,kBAAkB,UAAU;GACxC,QAAQ,MAAM,+BAA+B,KAAK;GAClD,iBAAiB,OAAO;EAC5B,CAAC;EAED,KAAK,QAAQ,GAAG,eAAe,WAAmB;GAC9C,QAAQ,MAAM,2BAA2B,MAAM;GAC/C,iBAAiB,WAAW,yBAAyB,UAAU,YAAY;EAC/E,CAAC;EAED,KAAK,QAAQ,GAAG,qBAAqB,QAAiB;GAClD,IAAI,CAAC,wBAAwB,GAAG,GAAG;GACnC,IAAI,KAAK,QAAQ,GAAG,GAAG;GACvB,KAAK,WAAW,SAAS,aAAa;IAClC,IAAI;KACA,SAAS,GAAG;IAChB,SAAS,OAAO;KACZ,QAAQ,MAAM,0CAA0C,KAAK;IACjE;GACJ,CAAC;EACL,CAAC;CACL;CAEA,QAAgB,KAAqC;EAK5B,OAAO;CAGhC;;;;;;;;;CAUA,OAAO,UAA4D;EAC/D,KAAK,WAAW,IAAI,QAAQ;EAC5B,aAAa,KAAK,WAAW,OAAO,QAAQ;CAChD;;;;;;;CAQA,QAAc;EACV,KAAK,WAAW,MAAM;EACtB,KAAK,QAAQ,mBAAmB;EAChC,KAAK,QAAQ,WAAW;CAC5B;AACJ"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Convenience hook that reads the WebSocket API from `WebSocketContext`.
5
5
  *
6
- * Returns: `{ subscribe, lastMessage, status }` (see `WebSocketContextType`).
6
+ * Returns: `{ subscribe, subscribeStatus, lastMessage, status }` (see `WebSocketContextType`).
7
7
  *
8
8
  * @throws {Error} If used outside of `<WebSocketProvider>`.
9
9
  */
@@ -6,7 +6,7 @@ import { useContext } from "react";
6
6
  *
7
7
  * Convenience hook that reads the WebSocket API from `WebSocketContext`.
8
8
  *
9
- * Returns: `{ subscribe, lastMessage, status }` (see `WebSocketContextType`).
9
+ * Returns: `{ subscribe, subscribeStatus, lastMessage, status }` (see `WebSocketContextType`).
10
10
  *
11
11
  * @throws {Error} If used outside of `<WebSocketProvider>`.
12
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/contexts/webSocketContext/hooks/useWebSocket/index.ts"],"sourcesContent":["import { useContext } from \"react\";\n\nimport { WebSocketContext } from \"../..\";\n\n/**\n * useWebSocket\n *\n * Convenience hook that reads the WebSocket API from `WebSocketContext`.\n *\n * Returns: `{ subscribe, lastMessage, status }` (see `WebSocketContextType`).\n *\n * @throws {Error} If used outside of `<WebSocketProvider>`.\n */\nexport const useWebSocket = () => {\n const context = useContext(WebSocketContext);\n if (!context) throw new Error(\"useWebSocket must be used within <WebSocketProvider>.\");\n return context;\n};\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,qBAAqB;CAC9B,MAAM,UAAU,WAAW,gBAAgB;CAC3C,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,uDAAuD;CACrF,OAAO;AACX"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/contexts/webSocketContext/hooks/useWebSocket/index.ts"],"sourcesContent":["import { useContext } from \"react\";\n\nimport { WebSocketContext } from \"../..\";\n\n/**\n * useWebSocket\n *\n * Convenience hook that reads the WebSocket API from `WebSocketContext`.\n *\n * Returns: `{ subscribe, subscribeStatus, lastMessage, status }` (see `WebSocketContextType`).\n *\n * @throws {Error} If used outside of `<WebSocketProvider>`.\n */\nexport const useWebSocket = () => {\n const context = useContext(WebSocketContext);\n if (!context) throw new Error(\"useWebSocket must be used within <WebSocketProvider>.\");\n return context;\n};\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,qBAAqB;CAC9B,MAAM,UAAU,WAAW,gBAAgB;CAC3C,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,uDAAuD;CACrF,OAAO;AACX"}
@@ -6,9 +6,10 @@ import type { WebSocketProviderProps } from "./types";
6
6
  *
7
7
  * What this provider does:
8
8
  * - Fetches `/api/websockets_config` once on mount to get the connection URL, channel id,
9
- * and session uid. Socket.IO handles reconnection internally — the config is not re-fetched.
9
+ * and session uid. Socket.IO handles reconnection internally — the config is not re-fetched,
10
+ * and the effect that does it runs once (`changeStatus`, its only dependency, is stable).
10
11
  * - Opens a `WebSocketHandler` instance that connects and joins the per-user channel.
11
- * - Exposes `subscribe`, `lastMessage`, and `status` via `WebSocketContext`.
12
+ * - Exposes `subscribe`, `subscribeStatus`, `lastMessage`, and `status` via `WebSocketContext`.
12
13
  *
13
14
  * Why the pending buffer exists (`pendingRef`):
14
15
  * - The handler is created asynchronously (after the config fetch resolves).
@@ -32,8 +33,10 @@ import type { WebSocketProviderProps } from "./types";
32
33
  * Context value (WebSocketContextType):
33
34
  * @returns {object}
34
35
  * - `subscribe(fn)`: register a listener; returns an unsubscribe function.
36
+ * - `subscribeStatus(fn)`: hear the current status at once, then every status the socket
37
+ * reports, repeats included; returns an unsubscribe function.
35
38
  * - `lastMessage`: the most recently received notification (or null).
36
- * - `status`: current connection status ("connecting" | "connected" | "error").
39
+ * - `status`: current connection status ("idle" | "connecting" | "connected" | "error").
37
40
  */
38
41
  export declare const WebSocketProvider: ({ children }: WebSocketProviderProps) => import("react").JSX.Element;
39
42
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/contexts/webSocketContext/provider.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA+C,sBAAsB,EAAmB,MAAM,SAAS,CAAC;AAEpH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,iBAAiB,GAAI,cAAc,sBAAsB,gCA+ErE,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/contexts/webSocketContext/provider.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGR,sBAAsB,EAEzB,MAAM,SAAS,CAAC;AAcjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,iBAAiB,GAAI,cAAc,sBAAsB,gCA6GrE,CAAC"}
@@ -7,15 +7,27 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
  //#region src/contexts/webSocketContext/provider.tsx
9
9
  /**
10
+ * Calls a status listener, logging and skipping one that throws, as notification listeners are,
11
+ * so it cannot keep the others from hearing the change.
12
+ */
13
+ var tellStatus = (listener, status) => {
14
+ try {
15
+ listener(status);
16
+ } catch (error) {
17
+ console.error("WebSocket status listener threw:", error);
18
+ }
19
+ };
20
+ /**
10
21
  * WebSocketProvider
11
22
  *
12
23
  * React context provider that exposes a receive-only pub/sub API backed by Socket.IO.
13
24
  *
14
25
  * What this provider does:
15
26
  * - Fetches `/api/websockets_config` once on mount to get the connection URL, channel id,
16
- * and session uid. Socket.IO handles reconnection internally — the config is not re-fetched.
27
+ * and session uid. Socket.IO handles reconnection internally — the config is not re-fetched,
28
+ * and the effect that does it runs once (`changeStatus`, its only dependency, is stable).
17
29
  * - Opens a `WebSocketHandler` instance that connects and joins the per-user channel.
18
- * - Exposes `subscribe`, `lastMessage`, and `status` via `WebSocketContext`.
30
+ * - Exposes `subscribe`, `subscribeStatus`, `lastMessage`, and `status` via `WebSocketContext`.
19
31
  *
20
32
  * Why the pending buffer exists (`pendingRef`):
21
33
  * - The handler is created asynchronously (after the config fetch resolves).
@@ -39,8 +51,10 @@ import { jsx } from "react/jsx-runtime";
39
51
  * Context value (WebSocketContextType):
40
52
  * @returns {object}
41
53
  * - `subscribe(fn)`: register a listener; returns an unsubscribe function.
54
+ * - `subscribeStatus(fn)`: hear the current status at once, then every status the socket
55
+ * reports, repeats included; returns an unsubscribe function.
42
56
  * - `lastMessage`: the most recently received notification (or null).
43
- * - `status`: current connection status ("connecting" | "connected" | "error").
57
+ * - `status`: current connection status ("idle" | "connecting" | "connected" | "error").
44
58
  */
45
59
  var WebSocketProvider = ({ children }) => {
46
60
  const { api } = useAxios();
@@ -57,16 +71,28 @@ var WebSocketProvider = ({ children }) => {
57
71
  const unsubscribeProviderRef = useRef(null);
58
72
  const [lastMessage, setLastMessage] = useState(null);
59
73
  const [status, setStatus] = useState("idle");
74
+ const statusListenersRef = useRef(/* @__PURE__ */ new Set());
75
+ const currentStatusRef = useRef("idle");
76
+ /**
77
+ * Sets `status` and tells the status listeners, so both see the same sequence. The current
78
+ * status is also kept in a ref, so a new listener is told it at once rather than from React
79
+ * state, which lags a change until the next render.
80
+ */
81
+ const changeStatus = useCallback((next) => {
82
+ currentStatusRef.current = next;
83
+ setStatus(next);
84
+ statusListenersRef.current.forEach((listener) => tellStatus(listener, next));
85
+ }, []);
60
86
  const pendingRef = useRef(/* @__PURE__ */ new Map());
61
87
  useEffect(() => {
62
88
  let cancelled = false;
63
89
  const pending = pendingRef.current;
64
90
  getWebsocketsConfig(apiRef.current).then((config) => {
65
91
  if (cancelled) return;
66
- setStatus("connecting");
92
+ changeStatus("connecting");
67
93
  const handler = new WebSocketHandler({
68
94
  ...config,
69
- onStatusChange: (s) => setStatus(s)
95
+ onStatusChange: changeStatus
70
96
  });
71
97
  handlerRef.current = handler;
72
98
  unsubscribeProviderRef.current = handler.listen((message) => setLastMessage(message));
@@ -77,7 +103,7 @@ var WebSocketProvider = ({ children }) => {
77
103
  }).catch((error) => {
78
104
  if (cancelled) return;
79
105
  console.error("Failed to initialize WebSocket connection:", error);
80
- setStatus("error");
106
+ changeStatus("error");
81
107
  showAlertRef.current({
82
108
  message: "Real-time notifications are unavailable. Please refresh the page.",
83
109
  severity: "error"
@@ -91,7 +117,7 @@ var WebSocketProvider = ({ children }) => {
91
117
  handlerRef.current = null;
92
118
  pending.clear();
93
119
  };
94
- }, []);
120
+ }, [changeStatus]);
95
121
  const subscribe = useCallback((fn) => {
96
122
  if (handlerRef.current) return handlerRef.current.listen(fn);
97
123
  pendingRef.current.set(fn, null);
@@ -101,12 +127,21 @@ var WebSocketProvider = ({ children }) => {
101
127
  pendingRef.current.delete(fn);
102
128
  };
103
129
  }, []);
130
+ const subscribeStatus = useCallback((listener) => {
131
+ statusListenersRef.current.add(listener);
132
+ tellStatus(listener, currentStatusRef.current);
133
+ return () => {
134
+ statusListenersRef.current.delete(listener);
135
+ };
136
+ }, []);
104
137
  const value = useMemo(() => ({
105
138
  subscribe,
139
+ subscribeStatus,
106
140
  lastMessage,
107
141
  status
108
142
  }), [
109
143
  subscribe,
144
+ subscribeStatus,
110
145
  lastMessage,
111
146
  status
112
147
  ]);