@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,861 +0,0 @@
1
- 'use server';
2
- import fs from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { hydrateResourceIO } from '@workflow/core/observability';
5
- import { createWorld, healthCheck, resumeHook as resumeHookRuntime, start, } from '@workflow/core/runtime';
6
- import { getDeserializeStream, getExternalRevivers, } from '@workflow/core/serialization';
7
- import { WorkflowAPIError, WorkflowRunNotFoundError } from '@workflow/errors';
8
- import { findWorkflowDataDir } from '@workflow/utils/check-data-dir';
9
- import { isLegacySpecVersion, SPEC_VERSION_LEGACY, } from '@workflow/world';
10
- import { createVercelWorld } from '@workflow/world-vercel';
11
- /**
12
- * Map from WORKFLOW_TARGET_WORLD value to human-readable display name
13
- */
14
- function getBackendDisplayName(targetWorld) {
15
- if (!targetWorld)
16
- return 'Local';
17
- switch (targetWorld) {
18
- case 'local':
19
- return 'Local';
20
- case 'vercel':
21
- return 'Vercel';
22
- case '@workflow/world-postgres':
23
- case 'postgres':
24
- return 'PostgreSQL';
25
- default:
26
- // For custom worlds, try to make a readable name
27
- if (targetWorld.startsWith('@')) {
28
- // Extract package name without scope for display
29
- const parts = targetWorld.split('/');
30
- return parts[parts.length - 1] || targetWorld;
31
- }
32
- return targetWorld;
33
- }
34
- }
35
- function getEffectiveBackendId() {
36
- const targetWorld = process.env.WORKFLOW_TARGET_WORLD;
37
- if (targetWorld) {
38
- return targetWorld;
39
- }
40
- // Match @workflow/core/runtime defaulting: vercel if VERCEL_DEPLOYMENT_ID is set, else local.
41
- return process.env.VERCEL_DEPLOYMENT_ID ? 'vercel' : 'local';
42
- }
43
- function getObservabilityCwd() {
44
- const raw = process.env.WORKFLOW_OBSERVABILITY_CWD;
45
- if (!raw) {
46
- return process.cwd();
47
- }
48
- return path.isAbsolute(raw) ? raw : path.resolve(process.cwd(), raw);
49
- }
50
- /**
51
- * Ensure local-world env is derived consistently when running `packages/web` directly.
52
- *
53
- * Without this, the UI may *display* a dataDir detected from WORKFLOW_OBSERVABILITY_CWD,
54
- * while the actual World reads from `WORKFLOW_LOCAL_DATA_DIR` (defaulting to `.workflow-data`
55
- * under the web package cwd), resulting in "no runs" even though data exists.
56
- */
57
- async function ensureLocalWorldDataDirEnv() {
58
- if (process.env.WORKFLOW_LOCAL_DATA_DIR)
59
- return;
60
- const cwd = getObservabilityCwd();
61
- const info = await findWorkflowDataDir(cwd);
62
- // Prefer a discovered workflow-data directory (e.g. `.next/workflow-data`).
63
- if (info.dataDir) {
64
- process.env.WORKFLOW_LOCAL_DATA_DIR = info.dataDir;
65
- return;
66
- }
67
- // Fall back to a canonical location under the target project directory.
68
- process.env.WORKFLOW_LOCAL_DATA_DIR = path.resolve(cwd, '.workflow-data');
69
- }
70
- /**
71
- * Extract hostname from a database URL without exposing credentials.
72
- */
73
- function extractHostnameFromUrl(url) {
74
- if (!url)
75
- return undefined;
76
- try {
77
- const parsed = new URL(url);
78
- return parsed.hostname || undefined;
79
- }
80
- catch {
81
- return undefined;
82
- }
83
- }
84
- /**
85
- * Extract database name from a URL where pathname is like "/dbname".
86
- * (Works for postgres/mongodb-style URLs; returns undefined when not applicable.)
87
- */
88
- function extractDatabaseFromUrl(url) {
89
- if (!url)
90
- return undefined;
91
- try {
92
- const parsed = new URL(url);
93
- const dbName = parsed.pathname?.slice(1);
94
- return dbName || undefined;
95
- }
96
- catch {
97
- return undefined;
98
- }
99
- }
100
- // Keep this list in sync with `worlds-manifest.json` env + credentialsNote.
101
- const WORLD_ENV_ALLOWLIST_BY_TARGET_WORLD = {
102
- // Official
103
- local: [
104
- 'WORKFLOW_TARGET_WORLD',
105
- 'WORKFLOW_LOCAL_DATA_DIR',
106
- 'WORKFLOW_MANIFEST_PATH',
107
- 'WORKFLOW_OBSERVABILITY_CWD',
108
- 'PORT',
109
- ],
110
- '@workflow/world-local': [
111
- 'WORKFLOW_TARGET_WORLD',
112
- 'WORKFLOW_LOCAL_DATA_DIR',
113
- 'WORKFLOW_MANIFEST_PATH',
114
- 'WORKFLOW_OBSERVABILITY_CWD',
115
- 'PORT',
116
- ],
117
- postgres: ['WORKFLOW_TARGET_WORLD', 'WORKFLOW_POSTGRES_URL'],
118
- '@workflow/world-postgres': [
119
- 'WORKFLOW_TARGET_WORLD',
120
- 'WORKFLOW_POSTGRES_URL',
121
- ],
122
- vercel: [
123
- 'WORKFLOW_TARGET_WORLD',
124
- 'WORKFLOW_VERCEL_ENV',
125
- 'WORKFLOW_VERCEL_TEAM',
126
- 'WORKFLOW_VERCEL_PROJECT',
127
- 'WORKFLOW_VERCEL_AUTH_TOKEN',
128
- ],
129
- '@workflow/world-vercel': [
130
- 'WORKFLOW_TARGET_WORLD',
131
- 'WORKFLOW_VERCEL_ENV',
132
- 'WORKFLOW_VERCEL_TEAM',
133
- 'WORKFLOW_VERCEL_PROJECT',
134
- 'WORKFLOW_VERCEL_AUTH_TOKEN',
135
- ],
136
- // Community (from worlds-manifest.json)
137
- '@workflow-worlds/starter': ['WORKFLOW_TARGET_WORLD'],
138
- '@workflow-worlds/turso': [
139
- 'WORKFLOW_TARGET_WORLD',
140
- 'WORKFLOW_TURSO_DATABASE_URL',
141
- ],
142
- '@workflow-worlds/mongodb': [
143
- 'WORKFLOW_TARGET_WORLD',
144
- 'WORKFLOW_MONGODB_URI',
145
- 'WORKFLOW_MONGODB_DATABASE_NAME',
146
- ],
147
- '@workflow-worlds/redis': ['WORKFLOW_TARGET_WORLD', 'WORKFLOW_REDIS_URI'],
148
- 'workflow-world-jazz': [
149
- 'WORKFLOW_TARGET_WORLD',
150
- // credentialsNote:
151
- 'JAZZ_API_KEY',
152
- 'JAZZ_WORKER_ACCOUNT',
153
- 'JAZZ_WORKER_SECRET',
154
- ],
155
- };
156
- function getAllowedEnvKeysForBackend(backendId) {
157
- return (WORLD_ENV_ALLOWLIST_BY_TARGET_WORLD[backendId] ?? ['WORKFLOW_TARGET_WORLD']);
158
- }
159
- // Keep this list in sync with `worlds-manifest.json` env + credentialsNote.
160
- //
161
- // IMPORTANT: This is intentionally explicit (no heuristics). We only redact values for env
162
- // vars that are known + whitelisted and that we *know* contain secrets/credentials.
163
- const WORLD_SENSITIVE_ENV_KEYS = new Set([
164
- // Official
165
- 'WORKFLOW_POSTGRES_URL',
166
- 'WORKFLOW_VERCEL_AUTH_TOKEN',
167
- // Community
168
- 'WORKFLOW_TURSO_DATABASE_URL',
169
- 'WORKFLOW_MONGODB_URI',
170
- 'WORKFLOW_REDIS_URI',
171
- 'JAZZ_API_KEY',
172
- 'JAZZ_WORKER_SECRET',
173
- ]);
174
- function isSet(value) {
175
- return value !== undefined && value !== null && value !== '';
176
- }
177
- function deriveDbInfoForKey(key, value) {
178
- // Only attempt for URL-like strings.
179
- if (!value.includes(':'))
180
- return null;
181
- try {
182
- const parsed = new URL(value);
183
- const protocol = (parsed.protocol || '').replace(':', '');
184
- // file: URIs are not useful for hostname/db display
185
- if (protocol === 'file')
186
- return null;
187
- const hostname = extractHostnameFromUrl(value);
188
- const database = extractDatabaseFromUrl(value);
189
- const out = {};
190
- if (hostname)
191
- out[`derived.${key}.hostname`] = hostname;
192
- if (database)
193
- out[`derived.${key}.database`] = database;
194
- if (protocol)
195
- out[`derived.${key}.protocol`] = protocol;
196
- return Object.keys(out).length ? out : null;
197
- }
198
- catch {
199
- return null;
200
- }
201
- }
202
- async function getLocalDisplayInfo() {
203
- const cwd = getObservabilityCwd();
204
- const dataDirInfo = await findWorkflowDataDir(cwd);
205
- const out = {
206
- 'local.shortName': dataDirInfo.shortName,
207
- 'local.projectDir': dataDirInfo.projectDir,
208
- };
209
- if (dataDirInfo.dataDir) {
210
- out['local.dataDirPath'] = dataDirInfo.dataDir;
211
- }
212
- return out;
213
- }
214
- function collectAllowedEnv(allowedKeys) {
215
- const publicEnv = {};
216
- const sensitiveEnvKeys = [];
217
- const derivedDisplayInfo = {};
218
- for (const key of allowedKeys) {
219
- const value = process.env[key];
220
- if (!isSet(value))
221
- continue;
222
- if (WORLD_SENSITIVE_ENV_KEYS.has(key)) {
223
- sensitiveEnvKeys.push(key);
224
- const derived = deriveDbInfoForKey(key, value);
225
- if (derived)
226
- Object.assign(derivedDisplayInfo, derived);
227
- continue;
228
- }
229
- publicEnv[key] = value;
230
- }
231
- return {
232
- publicEnv,
233
- sensitiveEnvKeys: Array.from(new Set(sensitiveEnvKeys)).sort(),
234
- derivedDisplayInfo,
235
- };
236
- }
237
- /**
238
- * Get public configuration info that is safe to send to the client.
239
- *
240
- * This is the ONLY server action that intentionally exposes env-derived data,
241
- * and that data is strictly whitelisted per world backend.
242
- */
243
- export async function getPublicServerConfig() {
244
- const backendId = getEffectiveBackendId();
245
- const backendDisplayName = getBackendDisplayName(backendId);
246
- const allowedKeys = getAllowedEnvKeysForBackend(backendId);
247
- const { publicEnv, sensitiveEnvKeys, derivedDisplayInfo } = collectAllowedEnv(allowedKeys);
248
- const displayInfo = { ...derivedDisplayInfo };
249
- if (backendId === 'local' || backendId === '@workflow/world-local') {
250
- Object.assign(displayInfo, await getLocalDisplayInfo());
251
- }
252
- const config = {
253
- backendDisplayName,
254
- backendId,
255
- publicEnv,
256
- sensitiveEnvKeys,
257
- displayInfo: Object.keys(displayInfo).length ? displayInfo : undefined,
258
- };
259
- // Provide defaults for commonly expected keys without revealing extra secrets.
260
- if ((backendId === 'vercel' || backendId === '@workflow/world-vercel') &&
261
- !publicEnv.WORKFLOW_VERCEL_ENV) {
262
- config.publicEnv.WORKFLOW_VERCEL_ENV = 'production';
263
- }
264
- return config;
265
- }
266
- /**
267
- * Cache for World instances.
268
- *
269
- * IMPORTANT:
270
- * - We only cache non-vercel worlds.
271
- * - Cache keys are derived from **server-side** WORKFLOW_* env vars only.
272
- */
273
- const worldCache = new Map();
274
- /**
275
- * Get or create a World instance based on configuration.
276
- *
277
- * The @workflow/web UI should always pass `{}` for envMap.
278
- */
279
- async function getWorldFromEnv(userEnvMap) {
280
- const backendId = getEffectiveBackendId();
281
- const isVercelWorld = ['vercel', '@workflow/world-vercel'].includes(backendId);
282
- // For the vercel world specifically, we do not cache the world,
283
- // and allow user-provided env, as it can be a multi-tenant environment,
284
- // and we instantiate the world per-user directly to avoid having to set
285
- // process.env.
286
- if (isVercelWorld) {
287
- return createVercelWorld({
288
- token: userEnvMap.WORKFLOW_VERCEL_AUTH_TOKEN ||
289
- process.env.WORKFLOW_VERCEL_AUTH_TOKEN,
290
- projectConfig: {
291
- environment: userEnvMap.WORKFLOW_VERCEL_ENV || process.env.WORKFLOW_VERCEL_ENV,
292
- projectId: userEnvMap.WORKFLOW_VERCEL_PROJECT ||
293
- process.env.WORKFLOW_VERCEL_PROJECT,
294
- teamId: userEnvMap.WORKFLOW_VERCEL_TEAM || process.env.WORKFLOW_VERCEL_TEAM,
295
- },
296
- });
297
- }
298
- // For other worlds, we intentionally do not trust or apply client-provided env,
299
- // to avoid potential security risks in self-hosted scenarios.
300
- // Ensure local-world reads from the same project directory the UI is inspecting.
301
- if (backendId === 'local' || backendId === '@workflow/world-local') {
302
- await ensureLocalWorldDataDirEnv();
303
- }
304
- // Cache key derived ONLY from WORKFLOW_* env vars.
305
- const workflowEnvEntries = Object.entries(process.env).filter(([key]) => key.startsWith('WORKFLOW_'));
306
- workflowEnvEntries.sort(([a], [b]) => a.localeCompare(b));
307
- const cacheKey = JSON.stringify(Object.fromEntries(workflowEnvEntries));
308
- const cachedWorld = worldCache.get(cacheKey);
309
- if (cachedWorld) {
310
- return cachedWorld;
311
- }
312
- const world = createWorld();
313
- worldCache.set(cacheKey, world);
314
- return world;
315
- }
316
- /**
317
- * Creates a structured error object from a caught error
318
- */
319
- function createServerActionError(error, operation, requestParams) {
320
- const err = error instanceof Error ? error : new Error(String(error));
321
- console.error(`[web-api] ${operation} error:`, err);
322
- let errorResponse;
323
- if (WorkflowAPIError.is(error)) {
324
- // If the World threw the error on fetch/fs.read, we add that data
325
- // to the error object
326
- errorResponse = {
327
- message: getUserFacingErrorMessage(err, error.status),
328
- layer: 'API',
329
- cause: err.stack || err.message,
330
- request: {
331
- operation,
332
- params: requestParams ?? {},
333
- status: error.status,
334
- url: error.url,
335
- code: error.code ?? undefined,
336
- },
337
- };
338
- }
339
- else if (WorkflowRunNotFoundError.is(error)) {
340
- // The World might repackage the error as a WorkflowRunNotFoundError
341
- errorResponse = {
342
- message: getUserFacingErrorMessage(error, 404),
343
- layer: 'API',
344
- cause: err.stack || err.message,
345
- request: { operation, status: 404, params: requestParams ?? {} },
346
- };
347
- }
348
- else {
349
- errorResponse = {
350
- message: getUserFacingErrorMessage(err),
351
- layer: 'server',
352
- cause: err.stack || err.message,
353
- request: { status: 500, operation, params: requestParams ?? {} },
354
- };
355
- }
356
- return {
357
- success: false,
358
- error: errorResponse,
359
- };
360
- }
361
- /**
362
- * Converts an error into a user-facing message
363
- */
364
- function getUserFacingErrorMessage(error, status) {
365
- if (!status) {
366
- return `Error creating response: ${error.message}`;
367
- }
368
- // Check for common error patterns
369
- if (status === 403 || status === 401) {
370
- return 'Access denied. Please check your credentials and permissions.';
371
- }
372
- if (status === 404) {
373
- return 'The requested resource was not found.';
374
- }
375
- if (status === 500) {
376
- return 'Error connecting to World backend, please try again later.';
377
- }
378
- if (error.message?.includes('Network') || error.message?.includes('fetch')) {
379
- return 'Network error. Please check your connection and try again.';
380
- }
381
- // Return the original message for other errors
382
- return error.message || 'An unexpected error occurred';
383
- }
384
- const toJSONCompatible = (data) => {
385
- if (data && typeof data === 'object') {
386
- return JSON.parse(JSON.stringify(data));
387
- }
388
- return data;
389
- };
390
- const hydrate = (data) => {
391
- try {
392
- return hydrateResourceIO(data);
393
- }
394
- catch (error) {
395
- throw new Error('Failed to hydrate data', { cause: error });
396
- }
397
- };
398
- /**
399
- * Helper to create successful responses
400
- * @param data - The data to return on success
401
- * @returns ServerActionResult with success=true and the data
402
- */
403
- function createResponse(data) {
404
- data = toJSONCompatible(data);
405
- return {
406
- success: true,
407
- data,
408
- };
409
- }
410
- /**
411
- * Fetch paginated list of workflow runs
412
- */
413
- export async function fetchRuns(worldEnv, params) {
414
- const { cursor, sortOrder = 'desc', limit = 10, workflowName, status, } = params;
415
- try {
416
- const world = await getWorldFromEnv(worldEnv);
417
- const result = await world.runs.list({
418
- ...(workflowName ? { workflowName } : {}),
419
- ...(status ? { status: status } : {}),
420
- pagination: { cursor, limit, sortOrder },
421
- resolveData: 'none',
422
- });
423
- return createResponse({
424
- data: result.data.map(hydrate),
425
- cursor: result.cursor ?? undefined,
426
- hasMore: result.hasMore,
427
- });
428
- }
429
- catch (error) {
430
- return createServerActionError(error, 'world.runs.list', params);
431
- }
432
- }
433
- /**
434
- * Fetch a single workflow run with full data
435
- */
436
- export async function fetchRun(worldEnv, runId, resolveData = 'all') {
437
- try {
438
- const world = await getWorldFromEnv(worldEnv);
439
- const run = await world.runs.get(runId, { resolveData });
440
- const hydratedRun = hydrate(run);
441
- return createResponse(hydratedRun);
442
- }
443
- catch (error) {
444
- return createServerActionError(error, 'world.runs.get', {
445
- runId,
446
- resolveData,
447
- });
448
- }
449
- }
450
- /**
451
- * Fetch paginated list of steps for a run
452
- */
453
- export async function fetchSteps(worldEnv, runId, params) {
454
- const { cursor, sortOrder = 'asc', limit = 100 } = params;
455
- try {
456
- const world = await getWorldFromEnv(worldEnv);
457
- const result = await world.steps.list({
458
- runId,
459
- pagination: { cursor, limit, sortOrder },
460
- resolveData: 'none',
461
- });
462
- return createResponse({
463
- // StepWithoutData has undefined input/output, but after hydration the structure is compatible
464
- data: result.data.map(hydrate),
465
- cursor: result.cursor ?? undefined,
466
- hasMore: result.hasMore,
467
- });
468
- }
469
- catch (error) {
470
- return createServerActionError(error, 'world.steps.list', {
471
- runId,
472
- ...params,
473
- });
474
- }
475
- }
476
- /**
477
- * Fetch a single step with full data
478
- */
479
- export async function fetchStep(worldEnv, runId, stepId, resolveData = 'all') {
480
- try {
481
- const world = await getWorldFromEnv(worldEnv);
482
- const step = await world.steps.get(runId, stepId, { resolveData });
483
- const hydratedStep = hydrate(step);
484
- return createResponse(hydratedStep);
485
- }
486
- catch (error) {
487
- return createServerActionError(error, 'world.steps.get', {
488
- runId,
489
- stepId,
490
- resolveData,
491
- });
492
- }
493
- }
494
- /**
495
- * Fetch paginated list of events for a run
496
- */
497
- export async function fetchEvents(worldEnv, runId, params) {
498
- const { cursor, sortOrder = 'asc', limit = 1000 } = params;
499
- try {
500
- const world = await getWorldFromEnv(worldEnv);
501
- const result = await world.events.list({
502
- runId,
503
- pagination: { cursor, limit, sortOrder },
504
- resolveData: 'none',
505
- });
506
- return createResponse({
507
- data: result.data,
508
- cursor: result.cursor ?? undefined,
509
- hasMore: result.hasMore,
510
- });
511
- }
512
- catch (error) {
513
- return createServerActionError(error, 'world.events.list', {
514
- runId,
515
- ...params,
516
- });
517
- }
518
- }
519
- /**
520
- * Fetch events by correlation ID
521
- */
522
- export async function fetchEventsByCorrelationId(worldEnv, correlationId, params) {
523
- const { cursor, sortOrder = 'asc', limit = 1000, withData = false } = params;
524
- try {
525
- const world = await getWorldFromEnv(worldEnv);
526
- const result = await world.events.listByCorrelationId({
527
- correlationId,
528
- pagination: { cursor, limit, sortOrder },
529
- resolveData: withData ? 'all' : 'none',
530
- });
531
- return createResponse({
532
- data: result.data.map(hydrate),
533
- cursor: result.cursor ?? undefined,
534
- hasMore: result.hasMore,
535
- });
536
- }
537
- catch (error) {
538
- return createServerActionError(error, 'world.events.listByCorrelationId', {
539
- correlationId,
540
- ...params,
541
- });
542
- }
543
- }
544
- /**
545
- * Fetch paginated list of hooks
546
- */
547
- export async function fetchHooks(worldEnv, params) {
548
- const { runId, cursor, sortOrder = 'desc', limit = 10 } = params;
549
- try {
550
- const world = await getWorldFromEnv(worldEnv);
551
- const result = await world.hooks.list({
552
- ...(runId ? { runId } : {}),
553
- pagination: { cursor, limit, sortOrder },
554
- resolveData: 'none',
555
- });
556
- return createResponse({
557
- data: result.data.map(hydrate),
558
- cursor: result.cursor ?? undefined,
559
- hasMore: result.hasMore,
560
- });
561
- }
562
- catch (error) {
563
- return createServerActionError(error, 'world.hooks.list', params);
564
- }
565
- }
566
- /**
567
- * Fetch a single hook with full data
568
- */
569
- export async function fetchHook(worldEnv, hookId, resolveData = 'all') {
570
- try {
571
- const world = await getWorldFromEnv(worldEnv);
572
- const hook = await world.hooks.get(hookId, { resolveData });
573
- return createResponse(hydrate(hook));
574
- }
575
- catch (error) {
576
- return createServerActionError(error, 'world.hooks.get', {
577
- hookId,
578
- resolveData,
579
- });
580
- }
581
- }
582
- /**
583
- * Cancel a workflow run
584
- */
585
- export async function cancelRun(worldEnv, runId) {
586
- try {
587
- const world = await getWorldFromEnv(worldEnv);
588
- const run = await world.runs.get(runId, { resolveData: 'none' });
589
- const compatMode = isLegacySpecVersion(run.specVersion);
590
- const eventData = {
591
- eventType: 'run_cancelled',
592
- specVersion: run.specVersion || 1,
593
- };
594
- await world.events.create(runId, eventData, { v1Compat: compatMode });
595
- return createResponse(undefined);
596
- }
597
- catch (error) {
598
- return createServerActionError(error, 'world.events.create', {
599
- runId,
600
- });
601
- }
602
- }
603
- /**
604
- * Start a new workflow run.
605
- *
606
- * This requires the ID of an existing run of which to re-use the deployment ID of.
607
- */
608
- export async function recreateRun(worldEnv, runId, deploymentId) {
609
- try {
610
- const world = await getWorldFromEnv({ ...worldEnv });
611
- const run = await world.runs.get(runId);
612
- // Get original input/output
613
- const hydratedRun = hydrate(run);
614
- // Preserve original specVersion - if undefined (legacy v1), use SPEC_VERSION_LEGACY
615
- const newRun = await start({ workflowId: run.workflowName }, hydratedRun.input, {
616
- deploymentId: deploymentId ?? run.deploymentId,
617
- world,
618
- specVersion: run.specVersion ?? SPEC_VERSION_LEGACY,
619
- });
620
- return createResponse(newRun.runId);
621
- }
622
- catch (error) {
623
- return createServerActionError(error, 'recreateRun', { runId });
624
- }
625
- }
626
- /**
627
- * Re-enqueue a workflow run.
628
- *
629
- * This re-enqueues the workflow orchestration layer. It's a no-op unless the workflow
630
- * got stuck due to an implementation issue in the World. Useful for debugging custom Worlds.
631
- */
632
- export async function reenqueueRun(worldEnv, runId) {
633
- try {
634
- const world = await getWorldFromEnv({ ...worldEnv });
635
- const run = await world.runs.get(runId);
636
- const deploymentId = run.deploymentId;
637
- await world.queue(`__wkf_workflow_${run.workflowName}`, {
638
- runId,
639
- }, {
640
- deploymentId,
641
- });
642
- return createResponse(undefined);
643
- }
644
- catch (error) {
645
- return createServerActionError(error, 'reenqueueRun', { runId });
646
- }
647
- }
648
- /**
649
- * Wake up a workflow run by interrupting pending sleep() calls.
650
- *
651
- * This finds wait_created events without matching wait_completed events,
652
- * creates wait_completed events for them, and then re-enqueues the run.
653
- *
654
- * @param worldEnv - Environment configuration for the World
655
- * @param runId - The run ID to wake up
656
- * @param options - Optional settings to narrow down targeting (specific correlation IDs)
657
- */
658
- export async function wakeUpRun(worldEnv, runId, options) {
659
- try {
660
- const world = await getWorldFromEnv({ ...worldEnv });
661
- const run = await world.runs.get(runId);
662
- const deploymentId = run.deploymentId;
663
- const compatMode = isLegacySpecVersion(run.specVersion);
664
- // Fetch all events for the run
665
- const eventsResult = await world.events.list({
666
- runId,
667
- pagination: { limit: 1000 },
668
- resolveData: 'none',
669
- });
670
- // Find wait_created events without matching wait_completed events
671
- const waitCreatedEvents = eventsResult.data.filter((e) => e.eventType === 'wait_created');
672
- const waitCompletedCorrelationIds = new Set(eventsResult.data
673
- .filter((e) => e.eventType === 'wait_completed')
674
- .map((e) => e.correlationId));
675
- let pendingWaits = waitCreatedEvents.filter((e) => !waitCompletedCorrelationIds.has(e.correlationId));
676
- // If specific correlation IDs are provided, filter to only those
677
- if (options?.correlationIds && options.correlationIds.length > 0) {
678
- const targetCorrelationIds = new Set(options.correlationIds);
679
- pendingWaits = pendingWaits.filter((e) => e.correlationId && targetCorrelationIds.has(e.correlationId));
680
- }
681
- // Create wait_completed events for each pending wait
682
- for (const waitEvent of pendingWaits) {
683
- if (waitEvent.correlationId) {
684
- // For v2, include specVersion in event data; for v1Compat, it's not needed
685
- const eventData = compatMode
686
- ? {
687
- eventType: 'wait_completed',
688
- correlationId: waitEvent.correlationId,
689
- }
690
- : {
691
- eventType: 'wait_completed',
692
- correlationId: waitEvent.correlationId,
693
- specVersion: run.specVersion,
694
- };
695
- await world.events.create(runId, eventData, { v1Compat: compatMode });
696
- }
697
- }
698
- // Re-enqueue the run to wake it up
699
- if (pendingWaits.length > 0) {
700
- await world.queue(`__wkf_workflow_${run.workflowName}`, {
701
- runId,
702
- }, {
703
- deploymentId,
704
- });
705
- }
706
- return createResponse({ stoppedCount: pendingWaits.length });
707
- }
708
- catch (error) {
709
- return createServerActionError(error, 'wakeUpRun', {
710
- runId,
711
- correlationIds: options?.correlationIds,
712
- });
713
- }
714
- }
715
- /**
716
- * Resume a hook by sending a payload.
717
- *
718
- * This sends a payload to a hook identified by its token, which resumes
719
- * the associated workflow run. The payload will be available as the return
720
- * value of the `createHook()` call in the workflow.
721
- *
722
- * @param worldEnv - Environment configuration for the World
723
- * @param token - The hook token
724
- * @param payload - The JSON payload to send to the hook
725
- */
726
- export async function resumeHook(worldEnv, token, payload) {
727
- try {
728
- // Initialize the world so resumeHookRuntime can access it
729
- await getWorldFromEnv({ ...worldEnv });
730
- const hook = await resumeHookRuntime(token, payload);
731
- return createResponse({
732
- hookId: hook.hookId,
733
- runId: hook.runId,
734
- });
735
- }
736
- catch (error) {
737
- return createServerActionError(error, 'resumeHook', {
738
- token,
739
- });
740
- }
741
- }
742
- export async function readStreamServerAction(env, streamId, startIndex) {
743
- try {
744
- const world = await getWorldFromEnv(env);
745
- // We should probably use getRun().getReadable() instead, to make the UI
746
- // more consistent with runtime behavior, and also expose a "replay" and "startIndex",
747
- // feature, to allow for testing World behavior.
748
- const stream = await world.readFromStream(streamId, startIndex);
749
- const revivers = getExternalRevivers(globalThis, [], '');
750
- const transform = getDeserializeStream(revivers);
751
- return stream.pipeThrough(transform);
752
- }
753
- catch (error) {
754
- const actionError = createServerActionError(error, 'world.readFromStream', {
755
- streamId,
756
- startIndex,
757
- });
758
- if (!actionError.success) {
759
- return actionError.error;
760
- }
761
- // Shouldn't happen, this is just a type guard
762
- throw new Error();
763
- }
764
- }
765
- /**
766
- * List all stream IDs for a run
767
- */
768
- export async function fetchStreams(env, runId) {
769
- try {
770
- const world = await getWorldFromEnv(env);
771
- const streams = await world.listStreamsByRunId(runId);
772
- return createResponse(streams);
773
- }
774
- catch (error) {
775
- return createServerActionError(error, 'world.listStreamsByRunId', {
776
- runId,
777
- });
778
- }
779
- }
780
- /**
781
- * Fetch the workflows manifest from the workflow route directory
782
- * The manifest is generated at build time and contains static structure info about workflows
783
- *
784
- * Configuration priority:
785
- * 1. WORKFLOW_MANIFEST_PATH - explicit path to the manifest file
786
- * 2. Standard Next.js app router locations (app/.well-known/workflow/v1/manifest.json)
787
- * 3. WORKFLOW_EMBEDDED_DATA_DIR - legacy data directory
788
- */
789
- export async function fetchWorkflowsManifest(_worldEnv) {
790
- const cwd = getObservabilityCwd();
791
- // Helper to resolve path (absolute or relative to cwd)
792
- const resolvePath = (p) => path.isAbsolute(p) ? p : path.join(cwd, p);
793
- // Build list of paths to try, in priority order
794
- const manifestPaths = [];
795
- // 1. Explicit manifest path configuration (highest priority)
796
- if (process.env.WORKFLOW_MANIFEST_PATH) {
797
- manifestPaths.push(resolvePath(process.env.WORKFLOW_MANIFEST_PATH));
798
- }
799
- // 2. Standard Next.js app router locations
800
- manifestPaths.push(path.join(cwd, 'app/.well-known/workflow/v1/manifest.json'), path.join(cwd, 'src/app/.well-known/workflow/v1/manifest.json'));
801
- // 3. Legacy data directory locations
802
- if (process.env.WORKFLOW_EMBEDDED_DATA_DIR) {
803
- manifestPaths.push(path.join(resolvePath(process.env.WORKFLOW_EMBEDDED_DATA_DIR), 'manifest.json'));
804
- }
805
- // Try each path until we find the manifest
806
- for (const manifestPath of manifestPaths) {
807
- try {
808
- const content = await fs.readFile(manifestPath, 'utf-8');
809
- const manifest = JSON.parse(content);
810
- return createResponse(manifest);
811
- }
812
- catch (_err) {
813
- // Continue to next path
814
- }
815
- }
816
- // If no manifest found, return an empty manifest
817
- // This allows the UI to work without workflows graph data
818
- return createResponse({
819
- version: '1.0.0',
820
- steps: {},
821
- workflows: {},
822
- });
823
- }
824
- /**
825
- * Run a queue-based health check on a workflow endpoint.
826
- *
827
- * This sends a health check message through the Queue infrastructure,
828
- * bypassing Vercel Deployment Protection. The endpoint processes the
829
- * message and writes a response to a stream, which we then read to
830
- * verify the endpoint is healthy.
831
- *
832
- * @param worldEnv - Environment configuration for the World
833
- * @param endpoint - Which endpoint to check: 'workflow' or 'step'
834
- * @param options - Optional configuration (timeout in ms)
835
- */
836
- export async function runHealthCheck(worldEnv, endpoint, options) {
837
- const startTime = Date.now();
838
- try {
839
- const world = await getWorldFromEnv(worldEnv);
840
- const result = await healthCheck(world, endpoint, options);
841
- const latencyMs = Date.now() - startTime;
842
- return createResponse({
843
- ...result,
844
- latencyMs,
845
- });
846
- }
847
- catch (error) {
848
- const latencyMs = Date.now() - startTime;
849
- // For health check failures, we want to return success=true with healthy=false
850
- // so the UI can display the error properly, rather than propagating the server
851
- // action error. This allows the health check result to be parsed by the UI
852
- // even when the endpoint is down or unreachable.
853
- const errorMessage = error instanceof Error ? error.message : String(error);
854
- return createResponse({
855
- healthy: false,
856
- error: errorMessage,
857
- latencyMs,
858
- });
859
- }
860
- }
861
- //# sourceMappingURL=workflow-server-actions.js.map