@workflow/web-shared 4.1.0-beta.47 → 4.1.0-beta.49

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 (301) hide show
  1. package/README.md +26 -52
  2. package/dist/components/error-boundary.d.ts.map +1 -0
  3. package/dist/{error-boundary.js → components/error-boundary.js} +1 -1
  4. package/dist/components/error-boundary.js.map +1 -0
  5. package/dist/{event-list-view.d.ts → components/event-list-view.d.ts} +2 -3
  6. package/dist/components/event-list-view.d.ts.map +1 -0
  7. package/dist/{event-list-view.js → components/event-list-view.js} +9 -17
  8. package/dist/components/event-list-view.js.map +1 -0
  9. package/dist/{hook-actions.d.ts → components/hook-actions.d.ts} +2 -3
  10. package/dist/components/hook-actions.d.ts.map +1 -0
  11. package/dist/{hook-actions.js → components/hook-actions.js} +3 -4
  12. package/dist/components/hook-actions.js.map +1 -0
  13. package/dist/components/index.d.ts +10 -0
  14. package/dist/components/index.d.ts.map +1 -0
  15. package/dist/components/index.js +8 -0
  16. package/dist/components/index.js.map +1 -0
  17. package/dist/components/run-trace-view.d.ts +22 -0
  18. package/dist/components/run-trace-view.d.ts.map +1 -0
  19. package/dist/components/run-trace-view.js +11 -0
  20. package/dist/components/run-trace-view.js.map +1 -0
  21. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -0
  22. package/dist/{sidebar → components/sidebar}/attribute-panel.js +3 -3
  23. package/dist/components/sidebar/attribute-panel.js.map +1 -0
  24. package/dist/components/sidebar/conversation-view.d.ts.map +1 -0
  25. package/dist/components/sidebar/conversation-view.js.map +1 -0
  26. package/dist/components/sidebar/detail-card.d.ts.map +1 -0
  27. package/dist/components/sidebar/detail-card.js.map +1 -0
  28. package/dist/components/sidebar/entity-detail-panel.d.ts +32 -0
  29. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -0
  30. package/dist/{sidebar → components/sidebar}/entity-detail-panel.js +61 -49
  31. package/dist/components/sidebar/entity-detail-panel.js.map +1 -0
  32. package/dist/components/sidebar/events-list.d.ts +8 -0
  33. package/dist/components/sidebar/events-list.d.ts.map +1 -0
  34. package/dist/components/sidebar/events-list.js +16 -0
  35. package/dist/components/sidebar/events-list.js.map +1 -0
  36. package/dist/components/sidebar/resolve-hook-modal.d.ts.map +1 -0
  37. package/dist/components/sidebar/resolve-hook-modal.js.map +1 -0
  38. package/dist/components/stream-viewer.d.ts +18 -0
  39. package/dist/components/stream-viewer.d.ts.map +1 -0
  40. package/dist/{stream-viewer.js → components/stream-viewer.js} +1 -59
  41. package/dist/components/stream-viewer.js.map +1 -0
  42. package/dist/components/trace-viewer/components/map.d.ts.map +1 -0
  43. package/dist/components/trace-viewer/components/map.js.map +1 -0
  44. package/dist/components/trace-viewer/components/markers.d.ts.map +1 -0
  45. package/dist/components/trace-viewer/components/markers.js.map +1 -0
  46. package/dist/components/trace-viewer/components/node.d.ts.map +1 -0
  47. package/dist/components/trace-viewer/components/node.js.map +1 -0
  48. package/dist/components/trace-viewer/components/search-input.d.ts.map +1 -0
  49. package/dist/components/trace-viewer/components/search-input.js.map +1 -0
  50. package/dist/components/trace-viewer/components/search.d.ts.map +1 -0
  51. package/dist/components/trace-viewer/components/search.js.map +1 -0
  52. package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +1 -0
  53. package/dist/components/trace-viewer/components/span-detail-panel.js.map +1 -0
  54. package/dist/components/trace-viewer/components/ui.d.ts.map +1 -0
  55. package/dist/components/trace-viewer/components/ui.js.map +1 -0
  56. package/dist/components/trace-viewer/components/zoom-button.d.ts.map +1 -0
  57. package/dist/components/trace-viewer/components/zoom-button.js.map +1 -0
  58. package/dist/components/trace-viewer/components/zoom-icons.d.ts.map +1 -0
  59. package/dist/components/trace-viewer/components/zoom-icons.js.map +1 -0
  60. package/dist/components/trace-viewer/context.d.ts.map +1 -0
  61. package/dist/components/trace-viewer/context.js.map +1 -0
  62. package/dist/components/trace-viewer/index.d.ts.map +1 -0
  63. package/dist/components/trace-viewer/index.js.map +1 -0
  64. package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -0
  65. package/dist/components/trace-viewer/trace-viewer.js.map +1 -0
  66. package/dist/components/trace-viewer/types.d.ts.map +1 -0
  67. package/dist/components/trace-viewer/types.js.map +1 -0
  68. package/dist/components/trace-viewer/util/constants.d.ts.map +1 -0
  69. package/dist/components/trace-viewer/util/constants.js.map +1 -0
  70. package/dist/components/trace-viewer/util/scrollbar-width.d.ts.map +1 -0
  71. package/dist/components/trace-viewer/util/scrollbar-width.js.map +1 -0
  72. package/dist/{trace-viewer → components/trace-viewer}/util/timing.d.ts +1 -1
  73. package/dist/components/trace-viewer/util/timing.d.ts.map +1 -0
  74. package/dist/{trace-viewer → components/trace-viewer}/util/timing.js +1 -1
  75. package/dist/components/trace-viewer/util/timing.js.map +1 -0
  76. package/dist/components/trace-viewer/util/tree.d.ts.map +1 -0
  77. package/dist/components/trace-viewer/util/tree.js.map +1 -0
  78. package/dist/components/trace-viewer/util/use-immediate-style.d.ts.map +1 -0
  79. package/dist/components/trace-viewer/util/use-immediate-style.js.map +1 -0
  80. package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +1 -0
  81. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +1 -0
  82. package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts.map +1 -0
  83. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +1 -0
  84. package/dist/components/trace-viewer/worker.d.ts.map +1 -0
  85. package/dist/components/trace-viewer/worker.js.map +1 -0
  86. package/dist/components/workflow-trace-view.d.ts +24 -0
  87. package/dist/components/workflow-trace-view.d.ts.map +1 -0
  88. package/dist/components/workflow-trace-view.js +152 -0
  89. package/dist/components/workflow-trace-view.js.map +1 -0
  90. package/dist/components/workflow-traces/event-colors.d.ts.map +1 -0
  91. package/dist/components/workflow-traces/event-colors.js.map +1 -0
  92. package/dist/components/workflow-traces/trace-colors.d.ts.map +1 -0
  93. package/dist/components/workflow-traces/trace-colors.js.map +1 -0
  94. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -0
  95. package/dist/components/workflow-traces/trace-span-construction.js.map +1 -0
  96. package/dist/components/workflow-traces/trace-time-utils.d.ts.map +1 -0
  97. package/dist/components/workflow-traces/trace-time-utils.js.map +1 -0
  98. package/dist/index.d.ts +3 -13
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +2 -9
  101. package/dist/index.js.map +1 -1
  102. package/package.json +15 -11
  103. package/src/components/error-boundary.tsx +79 -0
  104. package/src/components/event-list-view.tsx +429 -0
  105. package/src/components/hook-actions.tsx +167 -0
  106. package/src/components/index.d.ts +1 -0
  107. package/src/components/index.ts +23 -0
  108. package/src/components/run-trace-view.tsx +75 -0
  109. package/src/components/sidebar/attribute-panel.tsx +938 -0
  110. package/src/components/sidebar/conversation-view.tsx +235 -0
  111. package/src/components/sidebar/detail-card.tsx +43 -0
  112. package/src/components/sidebar/entity-detail-panel.tsx +338 -0
  113. package/src/components/sidebar/events-list.tsx +119 -0
  114. package/src/components/sidebar/resolve-hook-modal.tsx +219 -0
  115. package/src/components/stream-viewer.tsx +143 -0
  116. package/src/components/trace-viewer/components/map.tsx +226 -0
  117. package/src/components/trace-viewer/components/markers.tsx +564 -0
  118. package/src/components/trace-viewer/components/node.tsx +259 -0
  119. package/src/components/trace-viewer/components/search-input.tsx +52 -0
  120. package/src/components/trace-viewer/components/search.tsx +47 -0
  121. package/src/components/trace-viewer/components/span-detail-panel.tsx +650 -0
  122. package/src/components/trace-viewer/components/ui.tsx +156 -0
  123. package/src/components/trace-viewer/components/zoom-button.tsx +61 -0
  124. package/src/components/trace-viewer/components/zoom-icons.tsx +65 -0
  125. package/src/components/trace-viewer/context.tsx +633 -0
  126. package/src/components/trace-viewer/index.tsx +4 -0
  127. package/src/components/trace-viewer/modules.d.ts +16 -0
  128. package/src/components/trace-viewer/trace-viewer.module.css +1292 -0
  129. package/src/components/trace-viewer/trace-viewer.tsx +448 -0
  130. package/src/components/trace-viewer/types.ts +234 -0
  131. package/src/components/trace-viewer/util/constants.ts +8 -0
  132. package/src/components/trace-viewer/util/scrollbar-width.ts +13 -0
  133. package/src/components/trace-viewer/util/timing.ts +33 -0
  134. package/src/components/trace-viewer/util/tree.ts +277 -0
  135. package/src/components/trace-viewer/util/use-immediate-style.ts +38 -0
  136. package/src/components/trace-viewer/util/use-streaming-spans.ts +415 -0
  137. package/src/components/trace-viewer/util/use-trackpad-zoom.tsx +51 -0
  138. package/src/components/trace-viewer/worker.ts +128 -0
  139. package/src/components/ui/alert.tsx +59 -0
  140. package/src/components/ui/card.tsx +88 -0
  141. package/src/components/ui/error-card.tsx +65 -0
  142. package/src/components/ui/skeleton.tsx +15 -0
  143. package/src/components/workflow-trace-view.tsx +306 -0
  144. package/src/components/workflow-traces/event-colors.ts +94 -0
  145. package/src/components/workflow-traces/trace-colors.ts +112 -0
  146. package/src/components/workflow-traces/trace-span-construction.ts +299 -0
  147. package/src/components/workflow-traces/trace-time-utils.ts +50 -0
  148. package/src/hooks/use-dark-mode.ts +34 -0
  149. package/src/index.d.ts +1 -0
  150. package/src/index.ts +29 -0
  151. package/src/lib/event-analysis.ts +231 -0
  152. package/src/lib/utils.ts +166 -0
  153. package/dist/api/workflow-api-client.d.ts +0 -543
  154. package/dist/api/workflow-api-client.d.ts.map +0 -1
  155. package/dist/api/workflow-api-client.js +0 -953
  156. package/dist/api/workflow-api-client.js.map +0 -1
  157. package/dist/api/workflow-server-actions.d.ts +0 -230
  158. package/dist/api/workflow-server-actions.d.ts.map +0 -1
  159. package/dist/api/workflow-server-actions.js +0 -861
  160. package/dist/api/workflow-server-actions.js.map +0 -1
  161. package/dist/error-boundary.d.ts.map +0 -1
  162. package/dist/error-boundary.js.map +0 -1
  163. package/dist/event-list-view.d.ts.map +0 -1
  164. package/dist/event-list-view.js.map +0 -1
  165. package/dist/hook-actions.d.ts.map +0 -1
  166. package/dist/hook-actions.js.map +0 -1
  167. package/dist/run-trace-view.d.ts +0 -8
  168. package/dist/run-trace-view.d.ts.map +0 -1
  169. package/dist/run-trace-view.js +0 -15
  170. package/dist/run-trace-view.js.map +0 -1
  171. package/dist/sidebar/attribute-panel.d.ts.map +0 -1
  172. package/dist/sidebar/attribute-panel.js.map +0 -1
  173. package/dist/sidebar/conversation-view.d.ts.map +0 -1
  174. package/dist/sidebar/conversation-view.js.map +0 -1
  175. package/dist/sidebar/detail-card.d.ts.map +0 -1
  176. package/dist/sidebar/detail-card.js.map +0 -1
  177. package/dist/sidebar/entity-detail-panel.d.ts +0 -12
  178. package/dist/sidebar/entity-detail-panel.d.ts.map +0 -1
  179. package/dist/sidebar/entity-detail-panel.js.map +0 -1
  180. package/dist/sidebar/events-list.d.ts +0 -9
  181. package/dist/sidebar/events-list.d.ts.map +0 -1
  182. package/dist/sidebar/events-list.js +0 -36
  183. package/dist/sidebar/events-list.js.map +0 -1
  184. package/dist/sidebar/resolve-hook-modal.d.ts.map +0 -1
  185. package/dist/sidebar/resolve-hook-modal.js.map +0 -1
  186. package/dist/stream-viewer.d.ts +0 -13
  187. package/dist/stream-viewer.d.ts.map +0 -1
  188. package/dist/stream-viewer.js.map +0 -1
  189. package/dist/trace-viewer/components/map.d.ts.map +0 -1
  190. package/dist/trace-viewer/components/map.js.map +0 -1
  191. package/dist/trace-viewer/components/markers.d.ts.map +0 -1
  192. package/dist/trace-viewer/components/markers.js.map +0 -1
  193. package/dist/trace-viewer/components/node.d.ts.map +0 -1
  194. package/dist/trace-viewer/components/node.js.map +0 -1
  195. package/dist/trace-viewer/components/search-input.d.ts.map +0 -1
  196. package/dist/trace-viewer/components/search-input.js.map +0 -1
  197. package/dist/trace-viewer/components/search.d.ts.map +0 -1
  198. package/dist/trace-viewer/components/search.js.map +0 -1
  199. package/dist/trace-viewer/components/span-detail-panel.d.ts.map +0 -1
  200. package/dist/trace-viewer/components/span-detail-panel.js.map +0 -1
  201. package/dist/trace-viewer/components/ui.d.ts.map +0 -1
  202. package/dist/trace-viewer/components/ui.js.map +0 -1
  203. package/dist/trace-viewer/components/zoom-button.d.ts.map +0 -1
  204. package/dist/trace-viewer/components/zoom-button.js.map +0 -1
  205. package/dist/trace-viewer/components/zoom-icons.d.ts.map +0 -1
  206. package/dist/trace-viewer/components/zoom-icons.js.map +0 -1
  207. package/dist/trace-viewer/context.d.ts.map +0 -1
  208. package/dist/trace-viewer/context.js.map +0 -1
  209. package/dist/trace-viewer/index.d.ts.map +0 -1
  210. package/dist/trace-viewer/index.js.map +0 -1
  211. package/dist/trace-viewer/trace-viewer.d.ts.map +0 -1
  212. package/dist/trace-viewer/trace-viewer.js.map +0 -1
  213. package/dist/trace-viewer/types.d.ts.map +0 -1
  214. package/dist/trace-viewer/types.js.map +0 -1
  215. package/dist/trace-viewer/util/constants.d.ts.map +0 -1
  216. package/dist/trace-viewer/util/constants.js.map +0 -1
  217. package/dist/trace-viewer/util/scrollbar-width.d.ts.map +0 -1
  218. package/dist/trace-viewer/util/scrollbar-width.js.map +0 -1
  219. package/dist/trace-viewer/util/timing.d.ts.map +0 -1
  220. package/dist/trace-viewer/util/timing.js.map +0 -1
  221. package/dist/trace-viewer/util/tree.d.ts.map +0 -1
  222. package/dist/trace-viewer/util/tree.js.map +0 -1
  223. package/dist/trace-viewer/util/use-immediate-style.d.ts.map +0 -1
  224. package/dist/trace-viewer/util/use-immediate-style.js.map +0 -1
  225. package/dist/trace-viewer/util/use-streaming-spans.d.ts.map +0 -1
  226. package/dist/trace-viewer/util/use-streaming-spans.js.map +0 -1
  227. package/dist/trace-viewer/util/use-trackpad-zoom.d.ts.map +0 -1
  228. package/dist/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  229. package/dist/trace-viewer/worker.d.ts.map +0 -1
  230. package/dist/trace-viewer/worker.js.map +0 -1
  231. package/dist/workflow-trace-view.d.ts +0 -14
  232. package/dist/workflow-trace-view.d.ts.map +0 -1
  233. package/dist/workflow-trace-view.js +0 -135
  234. package/dist/workflow-trace-view.js.map +0 -1
  235. package/dist/workflow-traces/event-colors.d.ts.map +0 -1
  236. package/dist/workflow-traces/event-colors.js.map +0 -1
  237. package/dist/workflow-traces/trace-colors.d.ts.map +0 -1
  238. package/dist/workflow-traces/trace-colors.js.map +0 -1
  239. package/dist/workflow-traces/trace-span-construction.d.ts.map +0 -1
  240. package/dist/workflow-traces/trace-span-construction.js.map +0 -1
  241. package/dist/workflow-traces/trace-time-utils.d.ts.map +0 -1
  242. package/dist/workflow-traces/trace-time-utils.js.map +0 -1
  243. package/server/README.md +0 -1
  244. package/server/package.json +0 -4
  245. /package/dist/{error-boundary.d.ts → components/error-boundary.d.ts} +0 -0
  246. /package/dist/{sidebar → components/sidebar}/attribute-panel.d.ts +0 -0
  247. /package/dist/{sidebar → components/sidebar}/conversation-view.d.ts +0 -0
  248. /package/dist/{sidebar → components/sidebar}/conversation-view.js +0 -0
  249. /package/dist/{sidebar → components/sidebar}/detail-card.d.ts +0 -0
  250. /package/dist/{sidebar → components/sidebar}/detail-card.js +0 -0
  251. /package/dist/{sidebar → components/sidebar}/resolve-hook-modal.d.ts +0 -0
  252. /package/dist/{sidebar → components/sidebar}/resolve-hook-modal.js +0 -0
  253. /package/dist/{trace-viewer → components/trace-viewer}/components/map.d.ts +0 -0
  254. /package/dist/{trace-viewer → components/trace-viewer}/components/map.js +0 -0
  255. /package/dist/{trace-viewer → components/trace-viewer}/components/markers.d.ts +0 -0
  256. /package/dist/{trace-viewer → components/trace-viewer}/components/markers.js +0 -0
  257. /package/dist/{trace-viewer → components/trace-viewer}/components/node.d.ts +0 -0
  258. /package/dist/{trace-viewer → components/trace-viewer}/components/node.js +0 -0
  259. /package/dist/{trace-viewer → components/trace-viewer}/components/search-input.d.ts +0 -0
  260. /package/dist/{trace-viewer → components/trace-viewer}/components/search-input.js +0 -0
  261. /package/dist/{trace-viewer → components/trace-viewer}/components/search.d.ts +0 -0
  262. /package/dist/{trace-viewer → components/trace-viewer}/components/search.js +0 -0
  263. /package/dist/{trace-viewer → components/trace-viewer}/components/span-detail-panel.d.ts +0 -0
  264. /package/dist/{trace-viewer → components/trace-viewer}/components/span-detail-panel.js +0 -0
  265. /package/dist/{trace-viewer → components/trace-viewer}/components/ui.d.ts +0 -0
  266. /package/dist/{trace-viewer → components/trace-viewer}/components/ui.js +0 -0
  267. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-button.d.ts +0 -0
  268. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-button.js +0 -0
  269. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-icons.d.ts +0 -0
  270. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-icons.js +0 -0
  271. /package/dist/{trace-viewer → components/trace-viewer}/context.d.ts +0 -0
  272. /package/dist/{trace-viewer → components/trace-viewer}/context.js +0 -0
  273. /package/dist/{trace-viewer → components/trace-viewer}/index.d.ts +0 -0
  274. /package/dist/{trace-viewer → components/trace-viewer}/index.js +0 -0
  275. /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.d.ts +0 -0
  276. /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.js +0 -0
  277. /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.module.css +0 -0
  278. /package/dist/{trace-viewer → components/trace-viewer}/types.d.ts +0 -0
  279. /package/dist/{trace-viewer → components/trace-viewer}/types.js +0 -0
  280. /package/dist/{trace-viewer → components/trace-viewer}/util/constants.d.ts +0 -0
  281. /package/dist/{trace-viewer → components/trace-viewer}/util/constants.js +0 -0
  282. /package/dist/{trace-viewer → components/trace-viewer}/util/scrollbar-width.d.ts +0 -0
  283. /package/dist/{trace-viewer → components/trace-viewer}/util/scrollbar-width.js +0 -0
  284. /package/dist/{trace-viewer → components/trace-viewer}/util/tree.d.ts +0 -0
  285. /package/dist/{trace-viewer → components/trace-viewer}/util/tree.js +0 -0
  286. /package/dist/{trace-viewer → components/trace-viewer}/util/use-immediate-style.d.ts +0 -0
  287. /package/dist/{trace-viewer → components/trace-viewer}/util/use-immediate-style.js +0 -0
  288. /package/dist/{trace-viewer → components/trace-viewer}/util/use-streaming-spans.d.ts +0 -0
  289. /package/dist/{trace-viewer → components/trace-viewer}/util/use-streaming-spans.js +0 -0
  290. /package/dist/{trace-viewer → components/trace-viewer}/util/use-trackpad-zoom.d.ts +0 -0
  291. /package/dist/{trace-viewer → components/trace-viewer}/util/use-trackpad-zoom.js +0 -0
  292. /package/dist/{trace-viewer → components/trace-viewer}/worker.d.ts +0 -0
  293. /package/dist/{trace-viewer → components/trace-viewer}/worker.js +0 -0
  294. /package/dist/{workflow-traces → components/workflow-traces}/event-colors.d.ts +0 -0
  295. /package/dist/{workflow-traces → components/workflow-traces}/event-colors.js +0 -0
  296. /package/dist/{workflow-traces → components/workflow-traces}/trace-colors.d.ts +0 -0
  297. /package/dist/{workflow-traces → components/workflow-traces}/trace-colors.js +0 -0
  298. /package/dist/{workflow-traces → components/workflow-traces}/trace-span-construction.d.ts +0 -0
  299. /package/dist/{workflow-traces → components/workflow-traces}/trace-span-construction.js +0 -0
  300. /package/dist/{workflow-traces → components/workflow-traces}/trace-time-utils.d.ts +0 -0
  301. /package/dist/{workflow-traces → components/workflow-traces}/trace-time-utils.js +0 -0
@@ -1,953 +0,0 @@
1
- 'use client';
2
- import { VERCEL_403_ERROR_MESSAGE } from '@workflow/errors';
3
- import { useCallback, useEffect, useRef, useState } from 'react';
4
- import { getPaginationDisplay } from '../lib/utils';
5
- import { hookEventsToHookEntity, waitEventsToWaitEntity, } from '../workflow-traces/trace-span-construction';
6
- import { cancelRun as cancelRunServerAction, fetchEvents, fetchEventsByCorrelationId, fetchHook, fetchHooks, fetchRun, fetchRuns, fetchStep, fetchSteps, fetchStreams, readStreamServerAction, recreateRun as recreateRunServerAction, reenqueueRun as reenqueueRunServerAction, resumeHook as resumeHookServerAction, wakeUpRun as wakeUpRunServerAction, } from './workflow-server-actions';
7
- const MAX_ITEMS = 1000;
8
- const LIVE_POLL_LIMIT = 10;
9
- const LIVE_STEP_UPDATE_INTERVAL_MS = 2000;
10
- const LIVE_UPDATE_INTERVAL_MS = 5000;
11
- /**
12
- * Helper to convert ServerActionError to WorkflowWebAPIError
13
- */
14
- function createWorkflowAPIError(serverError) {
15
- return new WorkflowWebAPIError(serverError.message, {
16
- cause: serverError.cause,
17
- request: serverError.request,
18
- layer: serverError.layer,
19
- });
20
- }
21
- /**
22
- * Gets a user-facing error message from an error object.
23
- * Handles both WorkflowWebAPIError and regular Error instances.
24
- */
25
- export const getErrorMessage = (error) => {
26
- if ('layer' in error && error.layer) {
27
- if (error instanceof WorkflowWebAPIError) {
28
- if (error.request?.status === 403) {
29
- return VERCEL_403_ERROR_MESSAGE;
30
- }
31
- }
32
- // WorkflowWebAPIError already has user-facing messages
33
- return error.message;
34
- }
35
- return error instanceof Error ? error.message : 'An error occurred';
36
- };
37
- /**
38
- * Helper to handle server action results and throw WorkflowWebAPIError on failure
39
- */
40
- export async function unwrapServerActionResult(promise) {
41
- let result;
42
- try {
43
- result = await promise;
44
- }
45
- catch (error) {
46
- result = {
47
- success: false,
48
- error: error,
49
- };
50
- }
51
- if (!result.success) {
52
- console.error('[web-api-client] error', result.error);
53
- if (!result.error) {
54
- return {
55
- error: new WorkflowWebAPIError('Unknown error occurred', {
56
- layer: 'client',
57
- }),
58
- result: null,
59
- };
60
- }
61
- return {
62
- error: createWorkflowAPIError(result.error),
63
- result: null,
64
- };
65
- }
66
- return { error: null, result: result.data };
67
- }
68
- /**
69
- * Error instance for API and server-side errors.
70
- * `error.message` will be a user-facing error message, to be displayed in UI.
71
- * `error.cause` will be a developer-facing error message, to be displayed in logs.
72
- *
73
- * If the error originates from an HTTP request made from a server action,
74
- * these fields will be populated:
75
- * - `error.request` will be a JSON-serializable object representing the request made.
76
- * - `error.layer` will be 'API'
77
- *
78
- * If the error originates from inside the server action, or there's an error with
79
- * calling the server action, these fields will be populated:
80
- * - `error.layer` will be 'server'
81
- */
82
- export class WorkflowWebAPIError extends Error {
83
- request;
84
- layer;
85
- constructor(message, options) {
86
- super(message, { cause: options?.cause });
87
- this.name = 'WorkflowWebAPIError';
88
- this.request = options?.request;
89
- this.layer = options?.layer;
90
- if (options?.cause instanceof Error) {
91
- this.stack = `${this.stack}\nCaused by: ${options.cause.stack}`;
92
- }
93
- }
94
- }
95
- /**
96
- * Returns a list of runs with pagination control
97
- */
98
- export function useWorkflowRuns(env, params) {
99
- const { workflowName, status, limit = 10, sortOrder = 'desc' } = params;
100
- const [cursor, setCursor] = useState(undefined);
101
- const [hasMore, setHasMore] = useState(false);
102
- const [currentPage, setCurrentPage] = useState(0);
103
- const [pageHistory, setPageHistory] = useState([
104
- undefined,
105
- ]);
106
- const [maxPagesVisited, setMaxPagesVisited] = useState(1);
107
- // Store PageResult for each page
108
- const [allPageResults, setAllPageResults] = useState(new Map([[0, { data: null, isLoading: true, error: null }]]));
109
- // Cache for fetched pages - key is cursor (or 'initial' for first page)
110
- const pageCache = useRef(new Map());
111
- const fetchPage = useCallback(async (pageIndex, pageCursor, force = false) => {
112
- const cacheKey = pageCursor ?? 'initial';
113
- // Set loading state for this page
114
- setAllPageResults((prev) => {
115
- const newMap = new Map(prev);
116
- newMap.set(pageIndex, {
117
- data: prev.get(pageIndex)?.data ?? null,
118
- isLoading: true,
119
- error: null,
120
- });
121
- return newMap;
122
- });
123
- // Check cache first unless force reload
124
- if (!force && pageCache.current.has(cacheKey)) {
125
- const cached = pageCache.current.get(cacheKey);
126
- if (cached) {
127
- setAllPageResults((prev) => {
128
- const newMap = new Map(prev);
129
- newMap.set(pageIndex, {
130
- data: cached.data,
131
- isLoading: false,
132
- error: null,
133
- });
134
- return newMap;
135
- });
136
- setCursor(cached.cursor);
137
- setHasMore(cached.hasMore);
138
- return;
139
- }
140
- }
141
- const { error, result } = await unwrapServerActionResult(fetchRuns(env, {
142
- cursor: pageCursor,
143
- sortOrder,
144
- limit: limit,
145
- workflowName,
146
- status,
147
- }));
148
- if (error) {
149
- setAllPageResults((prev) => {
150
- const newMap = new Map(prev);
151
- newMap.set(pageIndex, {
152
- data: prev.get(pageIndex)?.data ?? null,
153
- isLoading: false,
154
- error,
155
- });
156
- return newMap;
157
- });
158
- return;
159
- }
160
- // Cache the result
161
- pageCache.current.set(cacheKey, {
162
- data: result.data,
163
- cursor: result.cursor,
164
- hasMore: result.hasMore,
165
- });
166
- setAllPageResults((prev) => {
167
- const newMap = new Map(prev);
168
- newMap.set(pageIndex, {
169
- data: result.data,
170
- isLoading: false,
171
- error: null,
172
- });
173
- return newMap;
174
- });
175
- setCursor(result.cursor);
176
- setHasMore(result.hasMore);
177
- }, [env, workflowName, limit, sortOrder, status]);
178
- // Initial load
179
- // biome-ignore lint/correctness/useExhaustiveDependencies: Want to refetch first page on param change
180
- useEffect(() => {
181
- fetchPage(0, undefined, true);
182
- }, [fetchPage, sortOrder, env, limit, workflowName, status]);
183
- const nextPage = useCallback(() => {
184
- if (hasMore && cursor) {
185
- const newPage = currentPage + 1;
186
- setPageHistory((prev) => [...prev, cursor]);
187
- setCurrentPage(newPage);
188
- setMaxPagesVisited((prev) => Math.max(prev, newPage + 1));
189
- // Initialize next page if not already loaded
190
- if (!allPageResults.has(newPage)) {
191
- setAllPageResults((prev) => {
192
- const newMap = new Map(prev);
193
- newMap.set(newPage, { data: null, isLoading: true, error: null });
194
- return newMap;
195
- });
196
- }
197
- fetchPage(newPage, cursor);
198
- }
199
- }, [hasMore, cursor, fetchPage, currentPage, allPageResults]);
200
- const previousPage = useCallback(() => {
201
- if (currentPage > 0) {
202
- const newPage = currentPage - 1;
203
- const prevCursor = pageHistory[newPage];
204
- setCurrentPage(newPage);
205
- fetchPage(newPage, prevCursor);
206
- }
207
- }, [currentPage, pageHistory, fetchPage]);
208
- const reload = useCallback(() => {
209
- // Clear cache and results
210
- pageCache.current.clear();
211
- setAllPageResults(new Map([[0, { data: null, isLoading: true, error: null }]]));
212
- // Reset to first page
213
- setCurrentPage(0);
214
- setPageHistory([undefined]);
215
- setMaxPagesVisited(1);
216
- // Force fetch first page
217
- fetchPage(0, undefined, true);
218
- }, [fetchPage]);
219
- const refresh = useCallback(() => {
220
- // Refetch current page without resetting state
221
- // This preserves the existing data while loading, preventing flicker
222
- const currentCursor = pageHistory[currentPage];
223
- // Clear cache for current page to ensure fresh data
224
- const cacheKey = currentCursor ?? 'initial';
225
- pageCache.current.delete(cacheKey);
226
- // Force fetch current page
227
- fetchPage(currentPage, currentCursor, true);
228
- }, [fetchPage, currentPage, pageHistory]);
229
- const currentPageResult = allPageResults.get(currentPage) ?? {
230
- data: null,
231
- isLoading: true,
232
- error: null,
233
- };
234
- // Compute global error (any page has error)
235
- const globalError = Array.from(allPageResults.values()).find((p) => p.error)?.error ?? null;
236
- // Compute global loading (any page is loading)
237
- const globalLoading = Array.from(allPageResults.values()).some((p) => p.isLoading);
238
- const totalPages = hasMore ? currentPage + 2 : currentPage + 1;
239
- const currentPageNumber = currentPage + 1;
240
- // Only show "+" if we're on the last visited page AND there are more pages
241
- const isOnLastVisitedPage = currentPageNumber === maxPagesVisited;
242
- const showPlus = isOnLastVisitedPage && hasMore;
243
- const pageInfo = getPaginationDisplay(currentPageNumber, maxPagesVisited, showPlus);
244
- const result = {
245
- data: currentPageResult,
246
- allData: Array.from(allPageResults.values()),
247
- error: globalError,
248
- isLoading: globalLoading,
249
- currentPage,
250
- totalPages,
251
- nextPage,
252
- previousPage,
253
- hasNextPage: hasMore,
254
- hasPreviousPage: currentPage > 0,
255
- reload,
256
- refresh,
257
- pageInfo,
258
- };
259
- return result;
260
- }
261
- /**
262
- * Returns a list of hooks with pagination control
263
- */
264
- export function useWorkflowHooks(env, params) {
265
- const { runId, limit = 10, sortOrder = 'desc' } = params;
266
- const [cursor, setCursor] = useState(undefined);
267
- const [hasMore, setHasMore] = useState(false);
268
- const [currentPage, setCurrentPage] = useState(0);
269
- const [pageHistory, setPageHistory] = useState([
270
- undefined,
271
- ]);
272
- const [maxPagesVisited, setMaxPagesVisited] = useState(1);
273
- // Store PageResult for each page
274
- const [allPageResults, setAllPageResults] = useState(new Map([[0, { data: null, isLoading: true, error: null }]]));
275
- // Cache for fetched pages - key is cursor (or 'initial' for first page)
276
- const pageCache = useRef(new Map());
277
- const fetchPage = useCallback(async (pageIndex, pageCursor, force = false) => {
278
- const cacheKey = pageCursor ?? 'initial';
279
- // Set loading state for this page
280
- setAllPageResults((prev) => {
281
- const newMap = new Map(prev);
282
- newMap.set(pageIndex, {
283
- data: prev.get(pageIndex)?.data ?? null,
284
- isLoading: true,
285
- error: null,
286
- });
287
- return newMap;
288
- });
289
- // Check cache first unless force reload
290
- if (!force && pageCache.current.has(cacheKey)) {
291
- const cached = pageCache.current.get(cacheKey);
292
- if (cached) {
293
- setAllPageResults((prev) => {
294
- const newMap = new Map(prev);
295
- newMap.set(pageIndex, {
296
- data: cached.data,
297
- isLoading: false,
298
- error: null,
299
- });
300
- return newMap;
301
- });
302
- setCursor(cached.cursor);
303
- setHasMore(cached.hasMore);
304
- return;
305
- }
306
- }
307
- const { error, result } = await unwrapServerActionResult(fetchHooks(env, {
308
- runId,
309
- cursor: pageCursor,
310
- sortOrder,
311
- limit: limit,
312
- }));
313
- if (error) {
314
- setAllPageResults((prev) => {
315
- const newMap = new Map(prev);
316
- newMap.set(pageIndex, {
317
- data: prev.get(pageIndex)?.data ?? null,
318
- isLoading: false,
319
- error,
320
- });
321
- return newMap;
322
- });
323
- return;
324
- }
325
- // Cache the result
326
- pageCache.current.set(cacheKey, {
327
- data: result.data,
328
- cursor: result.cursor,
329
- hasMore: result.hasMore,
330
- });
331
- setAllPageResults((prev) => {
332
- const newMap = new Map(prev);
333
- newMap.set(pageIndex, {
334
- data: result.data,
335
- isLoading: false,
336
- error: null,
337
- });
338
- return newMap;
339
- });
340
- setCursor(result.cursor);
341
- setHasMore(result.hasMore);
342
- }, [env, runId, limit, sortOrder]);
343
- // Initial load
344
- useEffect(() => {
345
- fetchPage(0, undefined);
346
- }, [fetchPage]);
347
- const nextPage = useCallback(() => {
348
- if (hasMore && cursor) {
349
- const newPage = currentPage + 1;
350
- setPageHistory((prev) => [...prev, cursor]);
351
- setCurrentPage(newPage);
352
- setMaxPagesVisited((prev) => Math.max(prev, newPage + 1));
353
- // Initialize next page if not already loaded
354
- if (!allPageResults.has(newPage)) {
355
- setAllPageResults((prev) => {
356
- const newMap = new Map(prev);
357
- newMap.set(newPage, { data: null, isLoading: true, error: null });
358
- return newMap;
359
- });
360
- }
361
- fetchPage(newPage, cursor);
362
- }
363
- }, [hasMore, cursor, fetchPage, currentPage, allPageResults]);
364
- const previousPage = useCallback(() => {
365
- if (currentPage > 0) {
366
- const newPage = currentPage - 1;
367
- const prevCursor = pageHistory[newPage];
368
- setCurrentPage(newPage);
369
- fetchPage(newPage, prevCursor);
370
- }
371
- }, [currentPage, pageHistory, fetchPage]);
372
- const reload = useCallback(() => {
373
- // Clear cache and results
374
- pageCache.current.clear();
375
- setAllPageResults(new Map([[0, { data: null, isLoading: true, error: null }]]));
376
- // Reset to first page
377
- setCurrentPage(0);
378
- setPageHistory([undefined]);
379
- setMaxPagesVisited(1);
380
- // Force fetch first page
381
- fetchPage(0, undefined, true);
382
- }, [fetchPage]);
383
- const refresh = useCallback(() => {
384
- // Refetch current page without resetting state
385
- // This preserves the existing data while loading, preventing flicker
386
- const currentCursor = pageHistory[currentPage];
387
- // Clear cache for current page to ensure fresh data
388
- const cacheKey = currentCursor ?? 'initial';
389
- pageCache.current.delete(cacheKey);
390
- // Force fetch current page
391
- fetchPage(currentPage, currentCursor, true);
392
- }, [fetchPage, currentPage, pageHistory]);
393
- const currentPageResult = allPageResults.get(currentPage) ?? {
394
- data: null,
395
- isLoading: true,
396
- error: null,
397
- };
398
- // Compute global error (any page has error)
399
- const globalError = Array.from(allPageResults.values()).find((p) => p.error)?.error ?? null;
400
- // Compute global loading (any page is loading)
401
- const globalLoading = Array.from(allPageResults.values()).some((p) => p.isLoading);
402
- const totalPages = hasMore ? currentPage + 2 : currentPage + 1;
403
- const currentPageNumber = currentPage + 1;
404
- // Only show "+" if we're on the last visited page AND there are more pages
405
- const isOnLastVisitedPage = currentPageNumber === maxPagesVisited;
406
- const showPlus = isOnLastVisitedPage && hasMore;
407
- const pageInfo = getPaginationDisplay(currentPageNumber, maxPagesVisited, showPlus);
408
- return {
409
- data: currentPageResult,
410
- allData: Array.from(allPageResults.values()),
411
- error: globalError,
412
- isLoading: globalLoading,
413
- currentPage,
414
- totalPages,
415
- nextPage,
416
- previousPage,
417
- hasNextPage: hasMore,
418
- hasPreviousPage: currentPage > 0,
419
- reload,
420
- refresh,
421
- pageInfo,
422
- };
423
- }
424
- // Helper function to exhaustively fetch steps
425
- async function fetchAllSteps(env, runId) {
426
- let stepsData = [];
427
- let stepsCursor;
428
- while (true) {
429
- const { error, result } = await unwrapServerActionResult(fetchSteps(env, runId, {
430
- cursor: stepsCursor,
431
- sortOrder: 'asc',
432
- limit: 100,
433
- }));
434
- // TODO: We're not handling errors well for infinite fetches
435
- if (error) {
436
- break;
437
- }
438
- stepsData = [...stepsData, ...result.data];
439
- if (!result.hasMore || !result.cursor || stepsData.length >= MAX_ITEMS) {
440
- break;
441
- }
442
- stepsCursor = result.cursor;
443
- }
444
- return { data: stepsData, cursor: stepsCursor };
445
- }
446
- // Helper function to exhaustively fetch hooks
447
- async function fetchAllHooks(env, runId) {
448
- let hooksData = [];
449
- let hooksCursor;
450
- while (true) {
451
- const { error, result } = await unwrapServerActionResult(fetchHooks(env, {
452
- runId,
453
- cursor: hooksCursor,
454
- sortOrder: 'asc',
455
- limit: 100,
456
- }));
457
- if (error) {
458
- break;
459
- }
460
- hooksData = [...hooksData, ...result.data];
461
- if (!result.hasMore || !result.cursor || hooksData.length >= MAX_ITEMS) {
462
- break;
463
- }
464
- hooksCursor = result.cursor;
465
- }
466
- return { data: hooksData, cursor: hooksCursor };
467
- }
468
- // Helper function to exhaustively fetch events
469
- async function fetchAllEvents(env, runId) {
470
- let eventsData = [];
471
- let eventsCursor;
472
- while (true) {
473
- const { error, result } = await unwrapServerActionResult(fetchEvents(env, runId, {
474
- cursor: eventsCursor,
475
- sortOrder: 'asc',
476
- limit: 1000,
477
- }));
478
- if (error) {
479
- break;
480
- }
481
- eventsData = [...eventsData, ...result.data];
482
- if (!result.hasMore || !result.cursor || eventsData.length >= MAX_ITEMS) {
483
- break;
484
- }
485
- eventsCursor = result.cursor;
486
- }
487
- return { data: eventsData, cursor: eventsCursor };
488
- }
489
- /**
490
- * Returns (and keeps up-to-date) all data related to a run.
491
- * Items returned will _not_ have resolved data (like input/output values).
492
- */
493
- export function useWorkflowTraceViewerData(env, runId, options = {}) {
494
- const { live = false } = options;
495
- const [run, setRun] = useState(null);
496
- const [steps, setSteps] = useState([]);
497
- const [hooks, setHooks] = useState([]);
498
- const [events, setEvents] = useState([]);
499
- const [loading, setLoading] = useState(true);
500
- const [auxiliaryDataLoading, setAuxiliaryDataLoading] = useState(false);
501
- const [error, setError] = useState(null);
502
- const [stepsCursor, setStepsCursor] = useState();
503
- const [hooksCursor, setHooksCursor] = useState();
504
- const [eventsCursor, setEventsCursor] = useState();
505
- const isFetchingRef = useRef(false);
506
- const [initialLoadCompleted, setInitialLoadCompleted] = useState(false);
507
- // Fetch all data for a run
508
- const fetchAllData = useCallback(async () => {
509
- if (isFetchingRef.current) {
510
- return;
511
- }
512
- isFetchingRef.current = true;
513
- setLoading(true);
514
- setAuxiliaryDataLoading(true);
515
- setError(null);
516
- const promises = [
517
- unwrapServerActionResult(fetchRun(env, runId)).then(({ error, result }) => {
518
- if (error) {
519
- setError(error);
520
- return;
521
- }
522
- setRun(result);
523
- return result;
524
- }),
525
- fetchAllSteps(env, runId).then((result) => {
526
- setSteps(result.data);
527
- setStepsCursor(result.cursor);
528
- }),
529
- fetchAllHooks(env, runId).then((result) => {
530
- setHooks(result.data);
531
- setHooksCursor(result.cursor);
532
- }),
533
- fetchAllEvents(env, runId).then((result) => {
534
- setEvents(result.data);
535
- setEventsCursor(result.cursor);
536
- }),
537
- ];
538
- const results = await Promise.allSettled(promises);
539
- setLoading(false);
540
- setAuxiliaryDataLoading(false);
541
- setInitialLoadCompleted(true);
542
- isFetchingRef.current = false;
543
- // Just doing the first error, but would be nice to show multiple
544
- const error = results.find((result) => result.status === 'rejected')
545
- ?.reason;
546
- if (error) {
547
- setError(error);
548
- return;
549
- }
550
- }, [env, runId]);
551
- // Helper to merge steps by ID
552
- const mergeSteps = useCallback((prev, newData) => {
553
- const combined = [...prev, ...newData];
554
- const uniqueById = new Map(combined.map((s) => [s.stepId, s]));
555
- return Array.from(uniqueById.values());
556
- }, []);
557
- // Helper to merge hooks by ID
558
- const mergeHooks = useCallback((prev, newData) => {
559
- const combined = [...prev, ...newData];
560
- const uniqueById = new Map(combined.map((h) => [h.hookId, h]));
561
- return Array.from(uniqueById.values());
562
- }, []);
563
- // Helper to merge events by ID
564
- const mergeEvents = useCallback((prev, newData) => {
565
- const combined = [...prev, ...newData];
566
- const uniqueById = new Map(combined.map((e) => [e.eventId, e]));
567
- return Array.from(uniqueById.values());
568
- }, []);
569
- const pollRun = useCallback(async () => {
570
- if (run?.completedAt) {
571
- return false;
572
- }
573
- const { error, result } = await unwrapServerActionResult(fetchRun(env, runId));
574
- if (error) {
575
- setError(error);
576
- return false;
577
- }
578
- setRun(result);
579
- return true;
580
- }, [env, runId, run?.completedAt]);
581
- // Poll for new steps
582
- const pollSteps = useCallback(async () => {
583
- const { error, result } = await unwrapServerActionResult(fetchSteps(env, runId, {
584
- cursor: stepsCursor,
585
- sortOrder: 'asc',
586
- limit: LIVE_POLL_LIMIT,
587
- }));
588
- if (error) {
589
- setError(error);
590
- return false;
591
- }
592
- if (result.data.length > 0) {
593
- setSteps((prev) => mergeSteps(prev, result.data));
594
- // We intentionally leave the cursor where it is, unless we're at the end of the page
595
- // in which case we roll over. This is so that we re-fetch existing steps, to ensure
596
- // their status gets updated.
597
- if (result.cursor && result.hasMore) {
598
- setStepsCursor(result.cursor);
599
- }
600
- return true;
601
- }
602
- return false;
603
- }, [env, runId, stepsCursor, mergeSteps]);
604
- // Poll for new hooks
605
- const pollHooks = useCallback(async () => {
606
- const { error, result } = await unwrapServerActionResult(fetchHooks(env, {
607
- runId,
608
- cursor: hooksCursor,
609
- sortOrder: 'asc',
610
- limit: LIVE_POLL_LIMIT,
611
- }));
612
- if (error) {
613
- setError(error);
614
- return false;
615
- }
616
- if (result.data.length > 0) {
617
- setHooks((prev) => mergeHooks(prev, result.data));
618
- if (result.cursor) {
619
- setHooksCursor(result.cursor);
620
- }
621
- return true;
622
- }
623
- return false;
624
- }, [env, runId, hooksCursor, mergeHooks]);
625
- // Poll for new events
626
- const pollEvents = useCallback(async () => {
627
- const { error, result } = await unwrapServerActionResult(fetchEvents(env, runId, {
628
- cursor: eventsCursor,
629
- sortOrder: 'asc',
630
- limit: LIVE_POLL_LIMIT,
631
- }));
632
- if (error) {
633
- setError(error);
634
- return false;
635
- }
636
- if (result.data.length > 0) {
637
- setEvents((prev) => mergeEvents(prev, result.data));
638
- if (result.cursor) {
639
- setEventsCursor(result.cursor);
640
- }
641
- return true;
642
- }
643
- return false;
644
- }, [env, runId, eventsCursor, mergeEvents]);
645
- // Update function for live polling
646
- const update = useCallback(async (stepsOnly = false) => {
647
- if (isFetchingRef.current || !initialLoadCompleted) {
648
- return { foundNewItems: false };
649
- }
650
- let foundNewItems = false;
651
- try {
652
- const [_, stepsUpdated, hooksUpdated, eventsUpdated] = await Promise.all([
653
- stepsOnly ? Promise.resolve(false) : pollRun(),
654
- pollSteps(),
655
- stepsOnly ? Promise.resolve(false) : pollHooks(),
656
- stepsOnly ? Promise.resolve(false) : pollEvents(),
657
- ]);
658
- foundNewItems = stepsUpdated || hooksUpdated || eventsUpdated;
659
- }
660
- catch (err) {
661
- console.error('Update error:', err);
662
- }
663
- return { foundNewItems };
664
- }, [pollSteps, pollHooks, pollEvents, initialLoadCompleted, pollRun]);
665
- // Initial load
666
- useEffect(() => {
667
- fetchAllData();
668
- }, [fetchAllData]);
669
- // Live polling
670
- useEffect(() => {
671
- if (!live || !initialLoadCompleted || run?.completedAt) {
672
- return;
673
- }
674
- const interval = setInterval(() => {
675
- update();
676
- }, LIVE_UPDATE_INTERVAL_MS);
677
- const stepInterval = setInterval(() => {
678
- update(true);
679
- }, LIVE_STEP_UPDATE_INTERVAL_MS);
680
- return () => {
681
- clearInterval(interval);
682
- clearInterval(stepInterval);
683
- };
684
- }, [live, initialLoadCompleted, update, run?.completedAt]);
685
- return {
686
- run: run ?? {},
687
- steps,
688
- hooks,
689
- events,
690
- loading,
691
- auxiliaryDataLoading,
692
- error,
693
- update,
694
- };
695
- }
696
- // Helper function to fetch resource and get correlation ID
697
- async function fetchResourceWithCorrelationId(env, resource, resourceId, options = {}) {
698
- let resourceData;
699
- let correlationId;
700
- const resolveData = options.resolveData ?? 'all';
701
- if (resource === 'run') {
702
- const { error, result } = await unwrapServerActionResult(fetchRun(env, resourceId, resolveData));
703
- if (error) {
704
- throw error;
705
- }
706
- resourceData = result;
707
- correlationId = resourceData.runId;
708
- }
709
- else if (resource === 'step') {
710
- const { runId } = options;
711
- if (!runId) {
712
- throw new WorkflowWebAPIError('runId is required for step resource', {
713
- layer: 'client',
714
- });
715
- }
716
- const { error, result } = await unwrapServerActionResult(fetchStep(env, runId, resourceId, resolveData));
717
- if (error) {
718
- throw error;
719
- }
720
- resourceData = result;
721
- correlationId = resourceData.stepId;
722
- }
723
- else if (resource === 'hook') {
724
- const { error, result } = await unwrapServerActionResult(fetchHook(env, resourceId, resolveData));
725
- if (error) {
726
- throw error;
727
- }
728
- resourceData = result;
729
- correlationId = resourceData.hookId;
730
- }
731
- else {
732
- throw new WorkflowWebAPIError(`Unknown resource type: ${resource}`, {
733
- layer: 'client',
734
- });
735
- }
736
- return { data: resourceData, correlationId };
737
- }
738
- /**
739
- * Returns (and keeps up-to-date) data inherent to a specific run/step/hook,
740
- * resolving input/output/metadata, AND loading all related events with full event data.
741
- */
742
- export function useWorkflowResourceData(env, resource, resourceId, options = {}) {
743
- const { refreshInterval = 0, runId } = options;
744
- const [data, setData] = useState(null);
745
- // const [events, setEvents] = useState<Event[]>([]);
746
- const [loading, setLoading] = useState(true);
747
- const [error, setError] = useState(null);
748
- const fetchData = useCallback(async () => {
749
- setData(null);
750
- setError(null);
751
- if (resource === 'hook' || resource === 'sleep') {
752
- const { error, result } = await unwrapServerActionResult(fetchEventsByCorrelationId(env, resourceId, {
753
- sortOrder: 'asc',
754
- limit: 100,
755
- withData: true,
756
- }));
757
- if (error) {
758
- setError(error);
759
- return;
760
- }
761
- const events = result.data;
762
- const data = resource === 'hook'
763
- ? hookEventsToHookEntity(events)
764
- : waitEventsToWaitEntity(events);
765
- if (data === null) {
766
- setError(new Error(`Failed to load ${resource} details: missing required event data`));
767
- return;
768
- }
769
- setData(data);
770
- return;
771
- }
772
- setLoading(true);
773
- // Fetch resource with full data
774
- try {
775
- const { data: resourceData } = await fetchResourceWithCorrelationId(env, resource, resourceId, {
776
- runId,
777
- });
778
- setData(resourceData);
779
- }
780
- catch (error) {
781
- if (error instanceof Error) {
782
- setError(error);
783
- }
784
- else {
785
- setError(new Error(String(error)));
786
- }
787
- return;
788
- }
789
- finally {
790
- setLoading(false);
791
- }
792
- // // Fetch events by correlation ID
793
- // const eventsData = await fetchAllEventsByCorrelationId(
794
- // env,
795
- // correlationId
796
- // );
797
- // setEvents(eventsData);
798
- }, [env, resource, resourceId, runId]);
799
- // Initial load
800
- useEffect(() => {
801
- fetchData();
802
- }, [fetchData]);
803
- // Refresh interval
804
- useEffect(() => {
805
- if (!refreshInterval || refreshInterval <= 0) {
806
- return;
807
- }
808
- const interval = setInterval(fetchData, refreshInterval);
809
- return () => clearInterval(interval);
810
- }, [refreshInterval, fetchData]);
811
- return {
812
- data,
813
- // events,
814
- loading,
815
- error,
816
- refresh: fetchData,
817
- };
818
- }
819
- /**
820
- * Cancel a workflow run
821
- */
822
- export async function cancelRun(env, runId) {
823
- const { error } = await unwrapServerActionResult(cancelRunServerAction(env, runId));
824
- if (error) {
825
- throw error;
826
- }
827
- }
828
- /**
829
- * Start a new workflow run
830
- */
831
- export async function recreateRun(env, runId) {
832
- const { error, result: resultData } = await unwrapServerActionResult(recreateRunServerAction(env, runId));
833
- if (error) {
834
- throw error;
835
- }
836
- return resultData;
837
- }
838
- /**
839
- * Wake up a workflow run by re-enqueuing it
840
- */
841
- export async function reenqueueRun(env, runId) {
842
- const { error } = await unwrapServerActionResult(reenqueueRunServerAction(env, runId));
843
- if (error) {
844
- throw error;
845
- }
846
- }
847
- /**
848
- * Wake up a workflow run by interrupting any pending sleep() calls
849
- */
850
- export async function wakeUpRun(env, runId, options) {
851
- const { error, result: resultData } = await unwrapServerActionResult(wakeUpRunServerAction(env, runId, options));
852
- if (error) {
853
- throw error;
854
- }
855
- return resultData;
856
- }
857
- /**
858
- * Resume a hook by sending a JSON payload
859
- */
860
- export async function resumeHook(env, token, payload) {
861
- const { error, result: resultData } = await unwrapServerActionResult(resumeHookServerAction(env, token, payload));
862
- if (error) {
863
- throw error;
864
- }
865
- return resultData;
866
- }
867
- function isServerActionError(value) {
868
- return (typeof value === 'object' &&
869
- value !== null &&
870
- 'message' in value &&
871
- 'layer' in value &&
872
- 'cause' in value &&
873
- 'request' in value);
874
- }
875
- export async function readStream(env, streamId, startIndex) {
876
- try {
877
- const stream = await readStreamServerAction(env, streamId, startIndex);
878
- if (!stream) {
879
- throw new WorkflowWebAPIError('Failed to read stream', {
880
- layer: 'client',
881
- });
882
- }
883
- if (isServerActionError(stream)) {
884
- throw new WorkflowWebAPIError(stream.message, {
885
- layer: 'client',
886
- cause: stream.cause,
887
- request: stream.request,
888
- });
889
- }
890
- return stream;
891
- }
892
- catch (error) {
893
- if (error instanceof WorkflowWebAPIError) {
894
- throw error;
895
- }
896
- throw new WorkflowWebAPIError('Failed to read stream', {
897
- layer: 'client',
898
- cause: error,
899
- });
900
- }
901
- }
902
- /**
903
- * List all stream IDs for a run
904
- */
905
- export async function listStreams(env, runId) {
906
- const { error, result } = await unwrapServerActionResult(fetchStreams(env, runId));
907
- if (error) {
908
- throw error;
909
- }
910
- return result;
911
- }
912
- const STREAMS_REFRESH_INTERVAL_MS = 10000;
913
- /**
914
- * Hook to fetch and manage stream list for a run
915
- */
916
- export function useWorkflowStreams(env, runId, refreshInterval = STREAMS_REFRESH_INTERVAL_MS) {
917
- const [streams, setStreams] = useState([]);
918
- const [loading, setLoading] = useState(true);
919
- const [error, setError] = useState(null);
920
- const fetchData = useCallback(async () => {
921
- setLoading(true);
922
- setError(null);
923
- try {
924
- const result = await listStreams(env, runId);
925
- setStreams(result);
926
- }
927
- catch (err) {
928
- setError(err instanceof Error ? err : new Error(String(err)));
929
- }
930
- finally {
931
- setLoading(false);
932
- }
933
- }, [env, runId]);
934
- // Initial load
935
- useEffect(() => {
936
- fetchData();
937
- }, [fetchData]);
938
- // Auto-refresh interval
939
- useEffect(() => {
940
- if (!refreshInterval || refreshInterval <= 0) {
941
- return;
942
- }
943
- const interval = setInterval(fetchData, refreshInterval);
944
- return () => clearInterval(interval);
945
- }, [refreshInterval, fetchData]);
946
- return {
947
- streams,
948
- loading,
949
- error,
950
- refresh: fetchData,
951
- };
952
- }
953
- //# sourceMappingURL=workflow-api-client.js.map