@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
@@ -12,6 +12,55 @@ import type { Theme } from "@mui/material/styles";
12
12
  /** A provider is any component that renders its children. */
13
13
  export type ProviderComponent = ComponentType<PropsWithChildren>;
14
14
 
15
+ /** A provider with the props it is mounted with, as `withProps` describes it. */
16
+ export type ConfiguredProvider = {
17
+ readonly component: ComponentType<PropsWithChildren<AnyRecord>>;
18
+ readonly props: AnyRecord;
19
+ };
20
+
21
+ /** What `providers` takes: a provider, or one with its props. */
22
+ export type ProviderEntry = ProviderComponent | ConfiguredProvider;
23
+
24
+ /**
25
+ * withProps
26
+ *
27
+ * A provider for `EveryskApp`'s `providers`, mounted with these props. `providers` mounts a bare
28
+ * component as `<Provider>{children}</Provider>`, so a provider configured by a prop — AG Grid's
29
+ * license key — needs its props said here:
30
+ *
31
+ * ```tsx
32
+ * <EveryskApp
33
+ * providers={[
34
+ * withProps(AgGridLicenseProvider, { licenseKey: import.meta.env.VITE_AG_GRID_LICENSE_KEY }),
35
+ * WebSocketProvider,
36
+ * ]}
37
+ * >
38
+ * ```
39
+ *
40
+ * It describes the provider rather than returning a wrapper component: a wrapper made in `App`'s
41
+ * render is a new component type each time, and React would remount the whole app under it on
42
+ * every render. The props are checked against the component's own.
43
+ */
44
+ export const withProps = <P extends { children?: ReactNode }>(
45
+ component: ComponentType<P>,
46
+ props: NoInfer<Omit<P, "children">>,
47
+ ): ConfiguredProvider => ({
48
+ component: component as ComponentType<PropsWithChildren<AnyRecord>>,
49
+ props: props as AnyRecord,
50
+ });
51
+
52
+ const isConfigured = (entry: ProviderEntry): entry is ConfiguredProvider =>
53
+ typeof entry === "object" && entry !== null && "component" in entry && "props" in entry;
54
+
55
+ const mount = (entry: ProviderEntry, children: ReactNode): ReactNode => {
56
+ if (!isConfigured(entry)) {
57
+ const Provider = entry;
58
+ return <Provider>{children}</Provider>;
59
+ }
60
+ const { component: Provider, props } = entry;
61
+ return <Provider {...props}>{children}</Provider>;
62
+ };
63
+
15
64
  export type EveryskAppProps = PropsWithChildren<{
16
65
  /**
17
66
  * The client every `useQuery` in the tree talks to. Defaults to a fresh
@@ -36,8 +85,10 @@ export type EveryskAppProps = PropsWithChildren<{
36
85
  * `modules.json` kept an explicit `providerOrder` only because the app owned the tree and
37
86
  * each module had to be hand-wired into the right slot; owning the tree here is what
38
87
  * retires that contract.
88
+ *
89
+ * A provider configured by props goes in through `withProps`.
39
90
  */
40
- providers?: ProviderComponent[];
91
+ providers?: ProviderEntry[];
41
92
  }>;
42
93
 
43
94
  /**
@@ -92,7 +143,7 @@ export const EveryskApp = ({
92
143
  const client = queryClient ?? fallbackQueryClient;
93
144
 
94
145
  const wrapped = (providers ?? []).reduceRight<ReactNode>(
95
- (inner, Provider) => <Provider>{inner}</Provider>,
146
+ (inner, entry) => mount(entry, inner),
96
147
  children,
97
148
  );
98
149
 
@@ -0,0 +1,71 @@
1
+ import type { GridApi } from "ag-grid-community";
2
+
3
+ /**
4
+ * The part of an infinite query this needs. Structural, so it takes any list hook's `query`,
5
+ * or a `useInfiniteQuery` an app writes itself.
6
+ */
7
+ export type InfiniteQueryPaging = {
8
+ hasNextPage: boolean;
9
+ isFetchingNextPage: boolean;
10
+ fetchNextPage: (options?: { cancelRefetch?: boolean }) => Promise<unknown>;
11
+ };
12
+
13
+ export type HandleRowsScrollEndOptions = {
14
+ /**
15
+ * Distance in pixels from the end of the rows at which the next page is requested. Named and
16
+ * measured as MUI X DataGrid's `scrollEndThreshold`, whose default it shares. Pixels rather
17
+ * than rows, so it holds with rows of different heights.
18
+ */
19
+ scrollEndThreshold?: number;
20
+ };
21
+
22
+ /**
23
+ * handleRowsScrollEnd
24
+ *
25
+ * Requests the next page when an AG Grid is scrolled near its last row, or shows none — the
26
+ * grid paging on demand. The handler for what MUI X DataGrid calls `onRowsScrollEnd`; wire it
27
+ * to AG Grid's `onBodyScrollEnd` and `onModelUpdated`, the second so that a grid whose rows a
28
+ * client-side filter hid entirely keeps loading.
29
+ *
30
+ * A function, not part of any hook: the data hook does not know a grid exists, and the grid
31
+ * does not know where its rows come from. It lives in this subpath because it needs `GridApi`,
32
+ * and AG Grid is an optional peer.
33
+ *
34
+ * Events fire in bursts, before `isFetchingNextPage` has flipped, so the request is made with
35
+ * `cancelRefetch: false`: TanStack then ignores a repeat while the first one is in flight,
36
+ * instead of cancelling it and asking for the same page again.
37
+ *
38
+ * @param {GridApi} gridApi - The grid, from the event (`event.api`).
39
+ * @param {InfiniteQueryPaging} query - The infinite query feeding the grid.
40
+ * @param {HandleRowsScrollEndOptions} [options] - `scrollEndThreshold`, in pixels (default 80).
41
+ *
42
+ * Example:
43
+ * ```tsx
44
+ * const { query } = useFetchDatastores({ filters, select: toRows });
45
+ *
46
+ * <AgGridReact
47
+ * rowData={query.data}
48
+ * onBodyScrollEnd={(event) => handleRowsScrollEnd(event.api, query)}
49
+ * onModelUpdated={(event) => handleRowsScrollEnd(event.api, query)}
50
+ * />
51
+ * ```
52
+ */
53
+ export const handleRowsScrollEnd = (
54
+ gridApi: GridApi,
55
+ query: InfiniteQueryPaging,
56
+ { scrollEndThreshold = 80 }: HandleRowsScrollEndOptions = {},
57
+ ): void => {
58
+ if (!query.hasNextPage || query.isFetchingNextPage) return;
59
+
60
+ const rowCount = gridApi.getDisplayedRowCount();
61
+ const lastRow = rowCount > 0 ? gridApi.getDisplayedRowAtIndex(rowCount - 1) : undefined;
62
+
63
+ if (lastRow) {
64
+ const rowsEnd = (lastRow.rowTop ?? 0) + (lastRow.rowHeight ?? 0);
65
+ const { bottom } = gridApi.getVerticalPixelRange();
66
+
67
+ if (rowsEnd - bottom > scrollEndThreshold) return;
68
+ }
69
+
70
+ void query.fetchNextPage({ cancelRefetch: false });
71
+ };
@@ -1,4 +1,5 @@
1
- // `@everysk/apps-sdk/ag-grid` — the grid layer: license registration and the grid theme.
1
+ // `@everysk/apps-sdk/ag-grid` — the grid layer: license registration, the grid theme and
2
+ // paging on scroll.
2
3
  //
3
4
  // `ag-grid-community` and `ag-grid-enterprise` are OPTIONAL peers: an app that never imports
4
5
  // this subpath does not install them, which keeps the grid out of the lockfile, out of CI
@@ -13,3 +14,6 @@ export { setAgGridLicense, AgGridLicenseProvider } from "@/contexts/agGridLicens
13
14
  export type { AgGridLicenseProviderProps } from "@/contexts/agGridLicenseContext/provider";
14
15
 
15
16
  export { getAgGridTheme, useAgGridTheme, agGridThemeParams } from "./agGridTheme";
17
+
18
+ export { handleRowsScrollEnd } from "./handleRowsScrollEnd";
19
+ export type { HandleRowsScrollEndOptions, InfiniteQueryPaging } from "./handleRowsScrollEnd";
@@ -1,11 +1,20 @@
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 { DeleteEntityDefaultResponse, FilterExpression, QueryObject } from "@/types/entityQuery";
5
- import type { Datastore, DatastoreSingleResponse, DatastoreListResponse, DeleteDatastoreResponse } from "@/types/datastore";
3
+ import type {
4
+ DeletedEntity,
5
+ DeleteEntityResponse,
6
+ EntitySingleResponse,
7
+ QueryObject,
8
+ } from "@/types/entityQuery";
9
+ import type { Datastore, DatastoreListResponse } from "@/types/datastore";
10
+ import { listParams, request, requireWorkspace } from "./request";
6
11
 
7
12
  const baseUrl = "datastores";
8
13
 
14
+ /** The endpoint's envelopes, private: every function here returns the entity itself. */
15
+ type DatastoreSingleResponse = EntitySingleResponse<"datastore", Datastore>;
16
+ type DeleteDatastoreResponse = DeleteEntityResponse<"datastore">;
17
+
9
18
  /**
10
19
  * getDatastore
11
20
  *
@@ -14,29 +23,25 @@ const baseUrl = "datastores";
14
23
  * @param {AxiosInstance} api - Axios instance.
15
24
  * @param {string} id - Datastore identifier.
16
25
  * @param {string} workspace - Workspace the datastore belongs to.
26
+ * @param {AbortSignal} [signal] - Aborts the request itself; the entity hooks pass the query's own.
17
27
  * @returns {Promise<Datastore>} The fetched datastore.
18
28
  *
19
29
  * @throws {Error} If the request fails.
20
30
  */
21
- export const getDatastore = async (api: AxiosInstance, id: string, workspace: string): Promise<Datastore> => {
22
- const params: AnyRecord = { workspace };
23
-
24
- if (!workspace) throw new Error("Workspace filter is required to fetch a datastore");
25
-
26
- try {
27
- const response: AxiosResponse<DatastoreSingleResponse> = await api.get(`${baseUrl}/${id}`, { params });
28
- return response.data.datastore;
29
- } catch (error: unknown) {
30
- if (isAxiosError<AnyRecord>(error)) {
31
- throw new Error(error.message || "Error fetching datastore");
32
- }
33
-
34
- if (error instanceof Error) {
35
- throw error;
36
- }
37
-
38
- throw new Error("Error fetching datastore");
39
- }
31
+ export const getDatastore = async (
32
+ api: AxiosInstance,
33
+ id: string,
34
+ workspace: string,
35
+ signal?: AbortSignal,
36
+ ): Promise<Datastore> => {
37
+ requireWorkspace(workspace, "fetch a datastore");
38
+
39
+ const body = await request(
40
+ () =>
41
+ api.get<DatastoreSingleResponse>(`${baseUrl}/${id}`, { params: { workspace }, signal }),
42
+ "Error fetching datastore",
43
+ );
44
+ return body.datastore;
40
45
  };
41
46
 
42
47
  /**
@@ -45,37 +50,24 @@ export const getDatastore = async (api: AxiosInstance, id: string, workspace: st
45
50
  * Fetches a list of datastores using a query object (filters, order, pagination, etc.).
46
51
  *
47
52
  * @param {AxiosInstance} api - Axios instance.
48
- * @param {AnyRecord} query - Query object built via `buildQueryObject`.
53
+ * @param {QueryObject} query - Query object built via `buildQueryObject`.
54
+ * @param {AbortSignal} [signal] - Aborts the request itself; the list hooks pass the query's own.
49
55
  * @returns {Promise<DatastoreListResponse>} Paginated list of datastores.
50
56
  *
51
- * @throws {Error} If workspace filter is missing.
57
+ * @throws {Error} If the query has no workspace filter.
52
58
  * @throws {Error} If the request fails.
53
59
  */
54
- export const listDatastores = async (api: AxiosInstance, query: QueryObject): Promise<DatastoreListResponse> => {
55
- const workspaceFilter = query.filters.find((filter: FilterExpression) => filter[0] === "workspace");
56
- const workspace = workspaceFilter?.[workspaceFilter.length - 1];
57
-
58
- if (!workspace) throw new Error("Workspace filter is required to list datastores");
59
-
60
- const params: AnyRecord = {
61
- workspace,
62
- ...(query ? { query: JSON.stringify(query) } : {}),
63
- };
64
-
65
- try {
66
- const response: AxiosResponse<DatastoreListResponse> = await api.get(baseUrl, { params });
67
- return response.data;
68
- } catch (error: unknown) {
69
- if (isAxiosError<AnyRecord>(error)) {
70
- throw new Error(error.message || "Error listing datastores");
71
- }
72
-
73
- if (error instanceof Error) {
74
- throw error;
75
- }
76
-
77
- throw new Error("Error listing datastores");
78
- }
60
+ export const listDatastores = async (
61
+ api: AxiosInstance,
62
+ query: QueryObject,
63
+ signal?: AbortSignal,
64
+ ): Promise<DatastoreListResponse> => {
65
+ const params = listParams(query, "list datastores");
66
+
67
+ return request(
68
+ () => api.get<DatastoreListResponse>(baseUrl, { params, signal }),
69
+ "Error listing datastores",
70
+ );
79
71
  };
80
72
 
81
73
  /**
@@ -89,25 +81,17 @@ export const listDatastores = async (api: AxiosInstance, query: QueryObject): Pr
89
81
  *
90
82
  * @throws {Error} If the request fails.
91
83
  */
92
- export const createDatastore = async (api: AxiosInstance, data: Partial<Datastore>): Promise<Datastore> => {
93
-
94
- const { workspace } = data;
95
- if (!workspace) throw new Error("Workspace filter is required to create a datastore");
96
-
97
- try {
98
- const response: AxiosResponse<DatastoreSingleResponse> = await api.post(baseUrl, data);
99
- return response.data.datastore;
100
- } catch (error: unknown) {
101
- if (isAxiosError<AnyRecord>(error)) {
102
- throw new Error(error.message || "Error creating datastore");
103
- }
104
-
105
- if (error instanceof Error) {
106
- throw error;
107
- }
108
-
109
- throw new Error("Error creating datastore");
110
- }
84
+ export const createDatastore = async (
85
+ api: AxiosInstance,
86
+ data: Partial<Datastore>,
87
+ ): Promise<Datastore> => {
88
+ requireWorkspace(data.workspace, "create a datastore");
89
+
90
+ const body = await request(
91
+ () => api.post<DatastoreSingleResponse>(baseUrl, data),
92
+ "Error creating datastore",
93
+ );
94
+ return body.datastore;
111
95
  };
112
96
 
113
97
  /**
@@ -122,25 +106,18 @@ export const createDatastore = async (api: AxiosInstance, data: Partial<Datastor
122
106
  *
123
107
  * @throws {Error} If the request fails.
124
108
  */
125
- export const updateDatastore = async (api: AxiosInstance, id: string, data: Partial<Datastore>): Promise<Datastore> => {
126
-
127
- const { workspace } = data;
128
- if (!workspace) throw new Error("Workspace filter is required to update a datastore");
129
-
130
- try {
131
- const response: AxiosResponse<DatastoreSingleResponse> = await api.put(`${baseUrl}/${id}`, data);
132
- return response.data.datastore;
133
- } catch (error: unknown) {
134
- if (isAxiosError<AnyRecord>(error)) {
135
- throw new Error(error.message || "Error updating datastore");
136
- }
137
-
138
- if (error instanceof Error) {
139
- throw error;
140
- }
141
-
142
- throw new Error("Error updating datastore");
143
- }
109
+ export const updateDatastore = async (
110
+ api: AxiosInstance,
111
+ id: string,
112
+ data: Partial<Datastore>,
113
+ ): Promise<Datastore> => {
114
+ requireWorkspace(data.workspace, "update a datastore");
115
+
116
+ const body = await request(
117
+ () => api.put<DatastoreSingleResponse>(`${baseUrl}/${id}`, data),
118
+ "Error updating datastore",
119
+ );
120
+ return body.datastore;
144
121
  };
145
122
 
146
123
  /**
@@ -151,25 +128,20 @@ export const updateDatastore = async (api: AxiosInstance, id: string, data: Part
151
128
  * @param {AxiosInstance} api - Axios instance.
152
129
  * @param {string} id - Datastore identifier.
153
130
  * @param {string} workspace - Workspace the datastore belongs to.
154
- * @returns {Promise<DeleteEntityDefaultResponse[]>} List of deleted entity records.
131
+ * @returns {Promise<DeletedEntity>} The deletion record: id, name and `deleted`.
155
132
  *
156
133
  * @throws {Error} If the request fails.
157
134
  */
158
- export const deleteDatastore = async (api: AxiosInstance, id: string, workspace: string): Promise<DeleteEntityDefaultResponse[]> => {
159
- const params: AnyRecord = { workspace };
160
-
161
- try {
162
- const response: AxiosResponse<DeleteDatastoreResponse> = await api.delete(`${baseUrl}/${id}`, { params });
163
- return response.data.datastores;
164
- } catch (error: unknown) {
165
- if (isAxiosError<AnyRecord>(error)) {
166
- throw new Error(error.message || "Error removing datastore");
167
- }
168
-
169
- if (error instanceof Error) {
170
- throw error;
171
- }
172
-
173
- throw new Error("Error removing datastore");
174
- }
175
- };
135
+ export const deleteDatastore = async (
136
+ api: AxiosInstance,
137
+ id: string,
138
+ workspace: string,
139
+ ): Promise<DeletedEntity> => {
140
+ requireWorkspace(workspace, "delete a datastore");
141
+
142
+ const body = await request(
143
+ () => api.delete<DeleteDatastoreResponse>(`${baseUrl}/${id}`, { params: { workspace } }),
144
+ "Error deleting datastore",
145
+ );
146
+ return body.datastore;
147
+ };
@@ -1,4 +1,11 @@
1
- import type { FilterClause, FilterExpression, EntityQueryParams, QueryObject } from "@/types/entityQuery";
1
+ import type {
2
+ FilterClause,
3
+ FilterExpression,
4
+ EntityQueryParams,
5
+ Projection,
6
+ QueryObject,
7
+ } from "@/types/entityQuery";
8
+ import { workspaceOf } from "./request";
2
9
 
3
10
  /**
4
11
  * toFilterTuple
@@ -23,7 +30,7 @@ import type { FilterClause, FilterExpression, EntityQueryParams, QueryObject } f
23
30
  */
24
31
  export const toFilterTuple = (filter: FilterClause): FilterExpression => {
25
32
  const { field, op, value } = filter;
26
- if (!op || op === '=') {
33
+ if (!op || op === "=") {
27
34
  return [field, value];
28
35
  }
29
36
  return [field, op, value];
@@ -40,9 +47,10 @@ export const toFilterTuple = (filter: FilterClause): FilterExpression => {
40
47
  * @param {string[]} params.order - Sorting fields.
41
48
  * @param {number} [params.pageSize] - Number of items per page.
42
49
  * @param {string} [params.pageToken] - Cursor token for the next page.
43
- * @param {string} [params.projection] - Single field to project. `"field"` returns only that
44
- * field (every other field comes back null); `"-field"` returns all fields except that one.
45
- * One field only — comma/space lists return a 500. Omitted from payload if empty.
50
+ * @param {Projection} [params.projection] - The fields to return: one, or a list. `"field"`
51
+ * returns only that field (every other field comes back null); `"-field"` returns all fields
52
+ * except that one. Pass several as a list, never comma-joined: `"a,b"` is a 500. Omitted from
53
+ * the payload when empty.
46
54
  * @returns {QueryObject} Query payload ready to be passed to the API.
47
55
  *
48
56
  * Example:
@@ -63,39 +71,100 @@ export const toFilterTuple = (filter: FilterClause): FilterExpression => {
63
71
  * // }
64
72
  * ```
65
73
  */
74
+ /** An empty string or list asks for every field, as no projection does. */
75
+ const hasProjection = (projection: Projection | undefined): projection is Projection =>
76
+ projection !== undefined && projection.length > 0;
77
+
66
78
  export const buildQueryObject = (params: EntityQueryParams): QueryObject => {
67
79
  const { filters, pageSize, pageToken, order, projection } = params;
68
80
 
69
81
  return {
70
82
  filters: filters.map(toFilterTuple),
71
83
  order,
72
- ...(!!projection && { projection }),
84
+ ...(hasProjection(projection) && { projection }),
73
85
  page_size: pageSize,
74
86
  page_token: pageToken,
75
87
  };
76
- }
88
+ };
89
+
90
+ /** What, besides the filters, changes the response a list read gets back. */
91
+ export type QueryKeyParams = {
92
+ order?: string[];
93
+ projection?: Projection;
94
+ pageSize?: number;
95
+ fetchAllPages?: boolean;
96
+ /** The datastore hooks' `dataFormat`. In the key whenever a hook passes it; only those hooks do. */
97
+ dataFormat?: "object" | "matrix";
98
+ };
77
99
 
78
100
  /**
79
101
  * buildQueryKey
80
102
  *
81
- * Builds a stable React Query cache key by combining a base key array
82
- * with the values of the provided filters.
103
+ * Builds the React Query cache key of a list read: the base keys, then one object holding
104
+ * everything that changes the response.
83
105
  *
84
- * This ensures the query is re-executed whenever filter values change.
106
+ * Every part of the request is in the key, not only the filter values. The key used to be
107
+ * `[...keys, ...values]`, so a `-data` metadata read and a full read of the same workspace,
108
+ * or `date = X` and `date >= X`, shared one cache entry and one of them rendered the other's
109
+ * data. Filters go in as the tuples the API receives, so field and operator are included.
85
110
  *
86
- * @param {(string | number)[]} keys - Base keys (e.g. entity name, id).
87
- * @param {FilterClause[]} filters - Filters whose values are appended to the key.
111
+ * The base keys stay in front, so prefix invalidation keeps working:
112
+ * `invalidateQueries({ queryKey: ["workflow_executions", workflowId] })`.
113
+ *
114
+ * @param {(string | number | null)[]} keys - Base keys (entity name, then any ids).
115
+ * @param {FilterClause[]} filters - The filters of the read.
116
+ * @param {QueryKeyParams} [params] - Order, projection, page size and paging mode.
88
117
  * @returns {unknown[]} Cache key array for use in `queryKey`.
89
118
  *
90
119
  * Example:
91
120
  * ```ts
92
- * buildQueryKey(["datastores"], [{ field: "workspace", value: "ws-1" }]);
93
- * // -> ["datastores", "ws-1"]
121
+ * buildQueryKey(["datastores"], [{ field: "workspace", value: "ws-1" }], { pageSize: 10 });
122
+ * // -> ["datastores", { filters: [["workspace", "ws-1"]], pageSize: 10 }]
94
123
  * ```
95
124
  */
96
- export const buildQueryKey = (keys: (string | number)[], filters: FilterClause[]): unknown[] => {
125
+ export const buildQueryKey = (
126
+ keys: (string | number | null)[],
127
+ filters: FilterClause[],
128
+ { order, projection, pageSize, fetchAllPages, dataFormat }: QueryKeyParams = {},
129
+ ): unknown[] => {
97
130
  return [
98
131
  ...keys,
99
- ...filters.flatMap((filter) => filter.value)
132
+ {
133
+ filters: filters.map(toFilterTuple),
134
+ ...(order?.length ? { order } : {}),
135
+ // The request omits an empty projection, so the key must not tell it apart.
136
+ ...(hasProjection(projection) ? { projection } : {}),
137
+ ...(pageSize !== undefined ? { pageSize } : {}),
138
+ ...(fetchAllPages ? { fetchAllPages } : {}),
139
+ ...(dataFormat ? { dataFormat } : {}),
140
+ },
100
141
  ];
101
- }
142
+ };
143
+
144
+ /**
145
+ * hasWorkspaceFilter
146
+ *
147
+ * Whether a read can be sent: every endpoint that takes filters rejects a request with no
148
+ * workspace. It reads the workspace through `workspaceOf`, as the list functions in `api/` do:
149
+ * while each read it its own way, it passed on a filter the request then ignored.
150
+ *
151
+ * @param {FilterClause[]} filters - The filters of the read.
152
+ * @returns {boolean} True when the first `workspace` filter carries a value.
153
+ */
154
+ export const hasWorkspaceFilter = (filters: FilterClause[]): boolean =>
155
+ Boolean(workspaceOf(filters.map(toFilterTuple)));
156
+
157
+ /**
158
+ * missingWorkspaceError
159
+ *
160
+ * The reason a hook gives, as `configError`, when it has no workspace to read. A missing
161
+ * workspace is a misconfigured app, never a state to wait out: the app config is merged into
162
+ * `window.APP_CONFIG` before the app renders, so an empty value there is a wrong or misspelled
163
+ * key. The message names the hook, so it points at the call to fix.
164
+ *
165
+ * @param {string} hookName - The hook that could not send its request.
166
+ * @returns {string} The error message.
167
+ */
168
+ export const missingWorkspaceError = (hookName: string): string =>
169
+ `[apps-sdk] ${hookName}: the "workspace" filter is missing or empty, so the request was not ` +
170
+ "sent. Check the workspace the app config provides.";