@everysk/apps-sdk 0.1.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 +395 -8
  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 +6 -6
  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,10 +1,14 @@
1
- import { isAxiosError, type AxiosInstance, type AxiosResponse } from "axios";
1
+ import type { AxiosInstance } from "axios";
2
2
 
3
- import type { AnyRecord } from "@/types/anyRecord";
4
- import type { Workspace, WorkspaceListResponse, WorkspaceSingleResponse } from "@/types/workspace";
3
+ import type { EntitySingleResponse } from "@/types/entityQuery";
4
+ import type { Workspace, WorkspaceListResponse } from "@/types/workspace";
5
+ import { pageParams, request } from "./request";
5
6
 
6
7
  const baseUrl = "workspaces";
7
8
 
9
+ /** The endpoint's envelope, private: `getWorkspace` returns the workspace itself. */
10
+ type WorkspaceSingleResponse = EntitySingleResponse<"workspace", Workspace>;
11
+
8
12
  /**
9
13
  * getWorkspace
10
14
  *
@@ -12,61 +16,57 @@ const baseUrl = "workspaces";
12
16
  *
13
17
  * @param {AxiosInstance} api - Axios instance.
14
18
  * @param {string} name - Workspace name.
19
+ * @param {AbortSignal} [signal] - Aborts the request itself; the entity hooks pass the query's own.
15
20
  * @returns {Promise<Workspace>} The fetched workspace.
16
21
  *
17
22
  * @throws {Error} If the request fails.
18
23
  */
19
- export const getWorkspace = async (api: AxiosInstance, name: string): Promise<Workspace> => {
20
- if (!name) throw new Error("Workspace name is required to fetch a workspace");
21
-
22
- try {
23
- const response: AxiosResponse<WorkspaceSingleResponse> = await api.get(`${baseUrl}/${name}`);
24
- return response.data.workspace;
25
- } catch (error: unknown) {
26
- if (isAxiosError<AnyRecord>(error)) {
27
- throw new Error(error.message || "Error while fetching workspace");
28
- }
24
+ export const getWorkspace = async (
25
+ api: AxiosInstance,
26
+ name: string,
27
+ signal?: AbortSignal,
28
+ ): Promise<Workspace> => {
29
+ if (!name) throw new Error("Workspace name is required to fetch a workspace");
29
30
 
30
- if (error instanceof Error) {
31
- throw error;
32
- }
31
+ const body = await request(
32
+ () => api.get<WorkspaceSingleResponse>(`${baseUrl}/${name}`, { signal }),
33
+ "Error fetching workspace",
34
+ );
35
+ return body.workspace;
36
+ };
33
37
 
34
- throw new Error("Error while fetching workspace");
35
- }
38
+ /** What `listWorkspaces` sends. */
39
+ export type WorkspaceListParams = {
40
+ /** A name prefix. Sent as `query`. */
41
+ search?: string;
42
+ pageSize?: number;
43
+ pageToken?: string;
36
44
  };
37
45
 
38
46
  /**
39
47
  * listWorkspaces
40
48
  *
41
- * Fetches a list of workspaces with optional cursor-based pagination.
49
+ * Lists the account's workspaces, a page at a time.
50
+ *
51
+ * The one list that takes no workspace: the docs exempt it, and the endpoint ignores one. This
52
+ * function used to send it anyway, documented as "required by some API configurations".
42
53
  *
43
54
  * @param {AxiosInstance} api - Axios instance.
44
- * @param {string} [workspace] - Current workspace name. Sent as a query param via the legacy method, required by some API configurations.
45
- * @param {number} [pageSize] - Number of items per page.
46
- * @param {string} [pageToken] - Cursor token for the next page.
47
- * @returns {Promise<WorkspaceListResponse>} List of workspaces.
55
+ * @param {WorkspaceListParams} [params] - Search and paging.
56
+ * @param {AbortSignal} [signal] - Aborts the request itself; the list hooks pass the query's own.
57
+ * @returns {Promise<WorkspaceListResponse>} A page of workspaces, with the cursor to the next one.
48
58
  *
49
59
  * @throws {Error} If the request fails.
50
60
  */
51
- export const listWorkspaces = async (api: AxiosInstance, workspace?: string, pageSize?: number, pageToken?: string): Promise<WorkspaceListResponse> => {
52
- const params: AnyRecord = {};
53
-
54
- if (workspace) params.workspace = workspace;
55
- if (pageSize) params.page_size = pageSize;
56
- if (pageToken) params.page_token = pageToken;
57
-
58
- try {
59
- const response: AxiosResponse<WorkspaceListResponse> = await api.get(baseUrl, { params });
60
- return response.data;
61
- } catch (error: unknown) {
62
- if (isAxiosError<AnyRecord>(error)) {
63
- throw new Error(error.message || "Error while fetching workspaces");
64
- }
65
-
66
- if (error instanceof Error) {
67
- throw error;
68
- }
61
+ export const listWorkspaces = async (
62
+ api: AxiosInstance,
63
+ { search, pageSize, pageToken }: WorkspaceListParams = {},
64
+ signal?: AbortSignal,
65
+ ): Promise<WorkspaceListResponse> => {
66
+ const params = pageParams({ search, pageSize, pageToken });
69
67
 
70
- throw new Error("Error while fetching workspaces");
71
- }
68
+ return request(
69
+ () => api.get<WorkspaceListResponse>(baseUrl, { params, signal }),
70
+ "Error listing workspaces",
71
+ );
72
72
  };
@@ -1,6 +1,6 @@
1
- import type { PropsWithChildren } from "react"
1
+ import type { PropsWithChildren } from "react";
2
2
 
3
- import { clsx } from 'clsx';
3
+ import { clsx } from "clsx";
4
4
  import Paper from "@mui/material/Paper";
5
5
  import { useTheme, type Theme } from "@mui/material/styles";
6
6
 
@@ -10,11 +10,11 @@ export const Footer = ({ className, children }: PropsWithChildren<{ className?:
10
10
  const theme: Theme = useTheme();
11
11
  const paperProps: AnyRecord = {
12
12
  light: {
13
- variant: 'outlined',
13
+ variant: "outlined",
14
14
  },
15
15
  dark: {
16
- variant: 'elevation'
17
- }
16
+ variant: "elevation",
17
+ },
18
18
  };
19
19
 
20
20
  return (
@@ -23,8 +23,9 @@ export const Footer = ({ className, children }: PropsWithChildren<{ className?:
23
23
  elevation={1}
24
24
  component="footer"
25
25
  className={clsx("flex shrink-0 grow-0 basis-auto h-16 pl-6 pr-6", className)}
26
- {...paperProps?.[theme.palette.mode]} >
26
+ {...paperProps?.[theme.palette.mode]}
27
+ >
27
28
  {children}
28
29
  </Paper>
29
30
  );
30
- }
31
+ };
@@ -21,7 +21,14 @@ export const GlobalLoading = ({ isLoading, backdrop = true, message }: GlobalLoa
21
21
 
22
22
  if (!backdrop) {
23
23
  return (
24
- <Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100%" }}>
24
+ <Box
25
+ sx={{
26
+ display: "flex",
27
+ justifyContent: "center",
28
+ alignItems: "center",
29
+ height: "100%",
30
+ }}
31
+ >
25
32
  {content}
26
33
  </Box>
27
34
  );
@@ -30,9 +37,12 @@ export const GlobalLoading = ({ isLoading, backdrop = true, message }: GlobalLoa
30
37
  return (
31
38
  <Backdrop
32
39
  open
33
- sx={{ zIndex: (theme) => theme.zIndex.modal + 1, backgroundColor: "rgba(0, 0, 0, 0.3)" }}
40
+ sx={{
41
+ zIndex: (theme) => theme.zIndex.modal + 1,
42
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
43
+ }}
34
44
  >
35
45
  {content}
36
46
  </Backdrop>
37
47
  );
38
- }
48
+ };
@@ -1,11 +1,18 @@
1
1
  import clsx from "clsx";
2
2
  import type { PropsWithChildren, ReactNode } from "react";
3
3
 
4
- export const PageContainer = ({ header, footer, contentClassName, children }: PropsWithChildren<{ header?: ReactNode, footer?: ReactNode, contentClassName?: string }>) => {
4
+ export const PageContainer = ({
5
+ header,
6
+ footer,
7
+ contentClassName,
8
+ children,
9
+ }: PropsWithChildren<{ header?: ReactNode; footer?: ReactNode; contentClassName?: string }>) => {
5
10
  return (
6
11
  <div className="flex flex-col w-full h-full overflow-hidden">
7
12
  {header}
8
- <div className={clsx("flex shrink-1 grow-1 basis-auto overflow-auto", contentClassName)}>
13
+ <div
14
+ className={clsx("flex shrink-1 grow-1 basis-auto overflow-auto", contentClassName)}
15
+ >
9
16
  {children}
10
17
  </div>
11
18
  {footer}
@@ -1,44 +1,119 @@
1
- import type { PropsWithChildren } from 'react';
1
+ import type { PropsWithChildren, ReactNode } from "react";
2
2
 
3
- import AppBar from '@mui/material/AppBar';
4
- import { useTheme, type Theme } from '@mui/material/styles';
5
- import MuiToolbar from '@mui/material/Toolbar';
3
+ import AppBar, { type AppBarProps } from "@mui/material/AppBar";
4
+ import { useTheme, type PaletteMode, type Theme } from "@mui/material/styles";
5
+ import MuiToolbar from "@mui/material/Toolbar";
6
+ import Typography from "@mui/material/Typography";
6
7
 
7
- import clsx from 'clsx';
8
+ import clsx from "clsx";
8
9
 
9
- import { EveryskIcon } from '@/components/ui/EveryskIcon';
10
+ import { EveryskIcon } from "@/components/ui/EveryskIcon";
10
11
 
11
- import type { AnyRecord } from '@/types/anyRecord';
12
+ /**
13
+ * The names follow MUI's own header components: `title`, `subheader` and `action` are
14
+ * `CardHeader`'s, `logo` is Toolpad's `branding.logo`, and the boolean reads as what turning
15
+ * it *on* does (`hideLogo`), because an MUI boolean defaults to `false`.
16
+ */
17
+ export type ToolbarProps = PropsWithChildren<{
18
+ /**
19
+ * Rendered before the logo. It is a slot rather than `onToggleMenu`/`onBack` props because
20
+ * the buttons that go here belong to whatever shell hosts the bar (a drawer toggle, a back
21
+ * button), and a prop per button would make the bar grow with every shell.
22
+ */
23
+ startAction?: ReactNode;
24
+ /** Replaces the Everysk mark, for an app that carries its client's. */
25
+ logo?: ReactNode;
26
+ /**
27
+ * A flag rather than `logo={null}` or `logo={false}` (MUI's `Alert.icon` spelling), so
28
+ * that no single prop means default, replace and remove at once. It wins over `logo`.
29
+ */
30
+ hideLogo?: boolean;
31
+ /** The page heading. An `h1`: the bar is where the page says what it is. */
32
+ title?: ReactNode;
33
+ subheader?: ReactNode;
34
+ /** Pushed to the far end of the bar, so no page has to align it with `justify-between`. */
35
+ action?: ReactNode;
36
+ /**
37
+ * `relative` by default: in `PageContainer` only the content scrolls, so the bar stays put
38
+ * by layout. `sticky` is for a page that scrolls as a whole.
39
+ */
40
+ position?: AppBarProps["position"];
41
+ /** Applied to the content row. */
42
+ className?: string;
43
+ }>;
12
44
 
13
- export const Toolbar = ({ children, className }: PropsWithChildren<{ className?: string }>) => {
14
- const theme: Theme = useTheme();
45
+ /**
46
+ * What a page supplies, as opposed to what the chrome around it decides (`startAction`, the
47
+ * logo, `position`). A shell that renders the bar for its pages holds this, and a page
48
+ * publishes it without ever rendering the bar itself.
49
+ */
50
+ export type ToolbarContent = Pick<ToolbarProps, "title" | "subheader" | "action" | "children">;
15
51
 
16
- const styles: AnyRecord = {
17
- light: {
18
- color: 'transparent',
19
- elevation: 0,
20
- sx: {
21
- border: "1px solid rgba(0, 0, 0, 0.12)"
22
- }
52
+ // Typed as AppBar props, not `AnyRecord`: a loose map here is what let an invalid `color: ''`
53
+ // through for as long as it did.
54
+ const MODE_PROPS: Record<PaletteMode, AppBarProps> = {
55
+ light: {
56
+ color: "transparent",
57
+ elevation: 0,
58
+ sx: {
59
+ border: "1px solid rgba(0, 0, 0, 0.12)",
23
60
  },
24
- dark: {
25
- // 'default', not ''. An empty string is not a value the AppBar API takes — it
26
- // produced the class `MuiAppBar-color` with no variant suffix, which rendered the
27
- // same only because the brand theme overrides AppBar anyway. This is the explicit
28
- // spelling of what already happens, and it survives a theme that does not.
29
- color: 'default',
30
- elevation: 1
31
- }
32
- };
61
+ },
62
+ dark: {
63
+ // 'default', not ''. An empty string is not a value the AppBar API takes — it
64
+ // produced the class `MuiAppBar-color` with no variant suffix, which rendered the
65
+ // same only because the brand theme overrides AppBar anyway. This is the explicit
66
+ // spelling of what already happens, and it survives a theme that does not.
67
+ color: "default",
68
+ elevation: 1,
69
+ },
70
+ };
71
+
72
+ export const Toolbar = ({
73
+ startAction,
74
+ logo,
75
+ hideLogo = false,
76
+ title,
77
+ subheader,
78
+ action,
79
+ position = "relative",
80
+ className,
81
+ children,
82
+ }: ToolbarProps) => {
83
+ const theme: Theme = useTheme();
33
84
 
34
85
  return (
35
- <AppBar position='relative' {...styles?.[theme.palette.mode]}>
36
- <MuiToolbar >
37
- <div className={clsx("flex items-center gap-4", className)}>
38
- <EveryskIcon />
86
+ <AppBar position={position} {...MODE_PROPS[theme.palette.mode]}>
87
+ <MuiToolbar>
88
+ <div className={clsx("flex items-center gap-4 w-full min-w-0", className)}>
89
+ {startAction && <div className="flex items-center shrink-0">{startAction}</div>}
90
+
91
+ {!hideLogo && (logo ?? <EveryskIcon titleAccess="Everysk" />)}
92
+
93
+ {(title || subheader) && (
94
+ // `min-w-0` is what lets the title truncate instead of pushing the
95
+ // action out of the bar.
96
+ <div className="flex flex-col min-w-0">
97
+ {title && (
98
+ <Typography variant="h6" component="h1" noWrap>
99
+ {title}
100
+ </Typography>
101
+ )}
102
+ {subheader && (
103
+ <Typography variant="body2" color="text.secondary" noWrap>
104
+ {subheader}
105
+ </Typography>
106
+ )}
107
+ </div>
108
+ )}
109
+
39
110
  {children}
111
+
112
+ {action && (
113
+ <div className="flex items-center gap-3 ml-auto shrink-0">{action}</div>
114
+ )}
40
115
  </div>
41
116
  </MuiToolbar>
42
117
  </AppBar>
43
118
  );
44
- }
119
+ };
@@ -66,7 +66,7 @@ export const AppAlertProvider = ({ children }: PropsWithChildren) => {
66
66
 
67
67
  const value: AppAlertContextType = useMemo(
68
68
  () => ({ showAlert, hideAlert }),
69
- [showAlert, hideAlert]
69
+ [showAlert, hideAlert],
70
70
  );
71
71
 
72
72
  return (
@@ -12,6 +12,6 @@ export type ShowAlertOptions = Partial<Omit<AppAlertState, "open">> & {
12
12
  };
13
13
 
14
14
  export type AppAlertContextType = {
15
- showAlert: (options: ShowAlertOptions) => void;
16
- hideAlert: () => void;
17
- };
15
+ showAlert: (options: ShowAlertOptions) => void;
16
+ hideAlert: () => void;
17
+ };
@@ -1,4 +1,4 @@
1
1
  import { createContext } from "react";
2
2
  import type { AppConfigContextType } from "./types";
3
3
 
4
- export const AppConfigContext = createContext<AppConfigContextType | null>(null)
4
+ export const AppConfigContext = createContext<AppConfigContextType | null>(null);
@@ -59,9 +59,5 @@ export const AppConfigProvider = ({
59
59
  };
60
60
  }, [appId, appEnvironmentVar]);
61
61
 
62
- return (
63
- <AppConfigContext.Provider value={value}>
64
- {children}
65
- </AppConfigContext.Provider>
66
- );
62
+ return <AppConfigContext.Provider value={value}>{children}</AppConfigContext.Provider>;
67
63
  };
@@ -1,6 +1,7 @@
1
1
  import { io, type Socket } from "socket.io-client";
2
2
 
3
- import type { WebSocketNotification, WebSocketStatus, WebsocketsConfig } from "./types";
3
+ import type { WebsocketsConfig } from "@/api/websocketsConfig";
4
+ import type { WebSocketNotification, WebSocketStatus } from "./types";
4
5
 
5
6
  function isWebSocketNotification(value: unknown): value is WebSocketNotification {
6
7
  return (
@@ -35,7 +36,12 @@ export class WebSocketHandler {
35
36
  private _everyskUID: string;
36
37
  private _listeners: Set<(msg: WebSocketNotification) => void> = new Set();
37
38
 
38
- constructor({ appConnectionURL, appChannelID, everyskUID, onStatusChange }: WebSocketHandlerConfig) {
39
+ constructor({
40
+ appConnectionURL,
41
+ appChannelID,
42
+ everyskUID,
43
+ onStatusChange,
44
+ }: WebSocketHandlerConfig) {
39
45
  this._everyskUID = everyskUID;
40
46
 
41
47
  this._socket = io(appConnectionURL, {
@@ -7,7 +7,7 @@ import { WebSocketContext } from "../..";
7
7
  *
8
8
  * Convenience hook that reads the WebSocket API from `WebSocketContext`.
9
9
  *
10
- * Returns: `{ subscribe, lastMessage, status }` (see `WebSocketContextType`).
10
+ * Returns: `{ subscribe, subscribeStatus, lastMessage, status }` (see `WebSocketContextType`).
11
11
  *
12
12
  * @throws {Error} If used outside of `<WebSocketProvider>`.
13
13
  */
@@ -5,7 +5,24 @@ import { useAxios } from "@/hooks/useAxios";
5
5
  import { useAppAlert } from "@/contexts/appAlertContext/useAppAlert";
6
6
  import { WebSocketContext } from ".";
7
7
  import { WebSocketHandler } from "./handler";
8
- import type { WebSocketContextType, WebSocketNotification, WebSocketProviderProps, WebSocketStatus } from "./types";
8
+ import type {
9
+ WebSocketContextType,
10
+ WebSocketNotification,
11
+ WebSocketProviderProps,
12
+ WebSocketStatus,
13
+ } from "./types";
14
+
15
+ /**
16
+ * Calls a status listener, logging and skipping one that throws, as notification listeners are,
17
+ * so it cannot keep the others from hearing the change.
18
+ */
19
+ const tellStatus = (listener: (status: WebSocketStatus) => void, status: WebSocketStatus) => {
20
+ try {
21
+ listener(status);
22
+ } catch (error) {
23
+ console.error("WebSocket status listener threw:", error);
24
+ }
25
+ };
9
26
 
10
27
  /**
11
28
  * WebSocketProvider
@@ -14,9 +31,10 @@ import type { WebSocketContextType, WebSocketNotification, WebSocketProviderProp
14
31
  *
15
32
  * What this provider does:
16
33
  * - Fetches `/api/websockets_config` once on mount to get the connection URL, channel id,
17
- * and session uid. Socket.IO handles reconnection internally — the config is not re-fetched.
34
+ * and session uid. Socket.IO handles reconnection internally — the config is not re-fetched,
35
+ * and the effect that does it runs once (`changeStatus`, its only dependency, is stable).
18
36
  * - Opens a `WebSocketHandler` instance that connects and joins the per-user channel.
19
- * - Exposes `subscribe`, `lastMessage`, and `status` via `WebSocketContext`.
37
+ * - Exposes `subscribe`, `subscribeStatus`, `lastMessage`, and `status` via `WebSocketContext`.
20
38
  *
21
39
  * Why the pending buffer exists (`pendingRef`):
22
40
  * - The handler is created asynchronously (after the config fetch resolves).
@@ -40,8 +58,10 @@ import type { WebSocketContextType, WebSocketNotification, WebSocketProviderProp
40
58
  * Context value (WebSocketContextType):
41
59
  * @returns {object}
42
60
  * - `subscribe(fn)`: register a listener; returns an unsubscribe function.
61
+ * - `subscribeStatus(fn)`: hear the current status at once, then every status the socket
62
+ * reports, repeats included; returns an unsubscribe function.
43
63
  * - `lastMessage`: the most recently received notification (or null).
44
- * - `status`: current connection status ("connecting" | "connected" | "error").
64
+ * - `status`: current connection status ("idle" | "connecting" | "connected" | "error").
45
65
  */
46
66
  export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
47
67
  const { api } = useAxios();
@@ -51,13 +71,30 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
51
71
  // making it re-run when api or showAlert change.
52
72
  const apiRef = useRef(api);
53
73
  const showAlertRef = useRef(showAlert);
54
- useEffect(() => { apiRef.current = api; });
55
- useEffect(() => { showAlertRef.current = showAlert; });
74
+ useEffect(() => {
75
+ apiRef.current = api;
76
+ });
77
+ useEffect(() => {
78
+ showAlertRef.current = showAlert;
79
+ });
56
80
 
57
81
  const handlerRef = useRef<WebSocketHandler | null>(null);
58
82
  const unsubscribeProviderRef = useRef<(() => void) | null>(null);
59
83
  const [lastMessage, setLastMessage] = useState<WebSocketNotification | null>(null);
60
84
  const [status, setStatus] = useState<WebSocketStatus>("idle");
85
+ const statusListenersRef = useRef(new Set<(status: WebSocketStatus) => void>());
86
+ const currentStatusRef = useRef<WebSocketStatus>("idle");
87
+
88
+ /**
89
+ * Sets `status` and tells the status listeners, so both see the same sequence. The current
90
+ * status is also kept in a ref, so a new listener is told it at once rather than from React
91
+ * state, which lags a change until the next render.
92
+ */
93
+ const changeStatus = useCallback((next: WebSocketStatus) => {
94
+ currentStatusRef.current = next;
95
+ setStatus(next);
96
+ statusListenersRef.current.forEach((listener) => tellStatus(listener, next));
97
+ }, []);
61
98
 
62
99
  const pendingRef = useRef(new Map<(m: WebSocketNotification) => void, (() => void) | null>());
63
100
 
@@ -69,14 +106,16 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
69
106
  .then((config) => {
70
107
  if (cancelled) return;
71
108
 
72
- setStatus("connecting");
109
+ changeStatus("connecting");
73
110
  const handler = new WebSocketHandler({
74
111
  ...config,
75
- onStatusChange: (s) => setStatus(s),
112
+ onStatusChange: changeStatus,
76
113
  });
77
114
  handlerRef.current = handler;
78
115
 
79
- unsubscribeProviderRef.current = handler.listen((message) => setLastMessage(message));
116
+ unsubscribeProviderRef.current = handler.listen((message) =>
117
+ setLastMessage(message),
118
+ );
80
119
 
81
120
  for (const [fn, unsub] of pending.entries()) {
82
121
  if (!unsub) {
@@ -88,8 +127,11 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
88
127
  .catch((error) => {
89
128
  if (cancelled) return;
90
129
  console.error("Failed to initialize WebSocket connection:", error);
91
- setStatus("error");
92
- showAlertRef.current({ message: "Real-time notifications are unavailable. Please refresh the page.", severity: "error" });
130
+ changeStatus("error");
131
+ showAlertRef.current({
132
+ message: "Real-time notifications are unavailable. Please refresh the page.",
133
+ severity: "error",
134
+ });
93
135
  });
94
136
 
95
137
  return () => {
@@ -100,7 +142,7 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
100
142
  handlerRef.current = null;
101
143
  pending.clear();
102
144
  };
103
- }, []); // mount-only — Socket.IO handles reconnection; no re-init needed when api changes
145
+ }, [changeStatus]);
104
146
 
105
147
  const subscribe = useCallback((fn: (m: WebSocketNotification) => void) => {
106
148
  if (handlerRef.current) {
@@ -116,9 +158,17 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
116
158
  };
117
159
  }, []);
118
160
 
161
+ const subscribeStatus = useCallback((listener: (status: WebSocketStatus) => void) => {
162
+ statusListenersRef.current.add(listener);
163
+ tellStatus(listener, currentStatusRef.current);
164
+ return () => {
165
+ statusListenersRef.current.delete(listener);
166
+ };
167
+ }, []);
168
+
119
169
  const value: WebSocketContextType = useMemo(
120
- () => ({ subscribe, lastMessage, status }),
121
- [subscribe, lastMessage, status]
170
+ () => ({ subscribe, subscribeStatus, lastMessage, status }),
171
+ [subscribe, subscribeStatus, lastMessage, status],
122
172
  );
123
173
 
124
174
  return <WebSocketContext.Provider value={value}>{children}</WebSocketContext.Provider>;
@@ -1,11 +1,5 @@
1
1
  import type { ReactNode } from "react";
2
2
 
3
- export type WebsocketsConfig = {
4
- appConnectionURL: string;
5
- appChannelID: string;
6
- everyskUID: string;
7
- };
8
-
9
3
  export type WebSocketStatus = "idle" | "connecting" | "connected" | "error";
10
4
 
11
5
  export type AppNotificationPayload = {
@@ -38,6 +32,13 @@ export type AppNotification = WebSocketNotification & {
38
32
 
39
33
  export type WebSocketContextType = {
40
34
  subscribe: (listener: (msg: WebSocketNotification) => void) => () => void;
35
+ /**
36
+ * Calls `listener` with the current status at once, then on every status the socket reports,
37
+ * repeats included; returns the unsubscribe. For code that waits on the socket outside React,
38
+ * where `status` cannot be watched: a reconnect is when it must catch up on what was
39
+ * published in between, which the server does not replay.
40
+ */
41
+ subscribeStatus: (listener: (status: WebSocketStatus) => void) => () => void;
41
42
  lastMessage: WebSocketNotification | null;
42
43
  status: WebSocketStatus;
43
44
  };
package/src/file/index.ts CHANGED
@@ -11,3 +11,5 @@ export * from "@/types/file";
11
11
  export * from "@/hooks/file/useFetchFile";
12
12
  export * from "@/hooks/file/useFetchFiles";
13
13
  export * from "@/hooks/file/useFileMutations";
14
+ export * from "@/lib/file";
15
+ export type { FileDataProps } from "@/hooks/file/fileData";