@uploadista/core 0.0.2

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 (359) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/.turbo/turbo-check.log +231 -0
  3. package/.turbo/turbo-format.log +5 -0
  4. package/LICENSE +21 -0
  5. package/README.md +1120 -0
  6. package/dist/chunk-CUT6urMc.cjs +1 -0
  7. package/dist/debounce-C2SeqcxD.js +2 -0
  8. package/dist/debounce-C2SeqcxD.js.map +1 -0
  9. package/dist/debounce-LZK7yS7Z.cjs +1 -0
  10. package/dist/errors/index.cjs +1 -0
  11. package/dist/errors/index.d.cts +3 -0
  12. package/dist/errors/index.d.ts +3 -0
  13. package/dist/errors/index.d.ts.map +1 -0
  14. package/dist/errors/index.js +2 -0
  15. package/dist/errors/uploadista-error.d.ts +209 -0
  16. package/dist/errors/uploadista-error.d.ts.map +1 -0
  17. package/dist/errors/uploadista-error.js +322 -0
  18. package/dist/errors-8i_aMxOE.js +1 -0
  19. package/dist/errors-CRm1FHHT.cjs +0 -0
  20. package/dist/flow/edge.d.ts +47 -0
  21. package/dist/flow/edge.d.ts.map +1 -0
  22. package/dist/flow/edge.js +40 -0
  23. package/dist/flow/event.d.ts +206 -0
  24. package/dist/flow/event.d.ts.map +1 -0
  25. package/dist/flow/event.js +53 -0
  26. package/dist/flow/flow-server.d.ts +223 -0
  27. package/dist/flow/flow-server.d.ts.map +1 -0
  28. package/dist/flow/flow-server.js +614 -0
  29. package/dist/flow/flow.d.ts +238 -0
  30. package/dist/flow/flow.d.ts.map +1 -0
  31. package/dist/flow/flow.js +629 -0
  32. package/dist/flow/index.cjs +1 -0
  33. package/dist/flow/index.d.cts +6 -0
  34. package/dist/flow/index.d.ts +24 -0
  35. package/dist/flow/index.d.ts.map +1 -0
  36. package/dist/flow/index.js +24 -0
  37. package/dist/flow/node.d.ts +136 -0
  38. package/dist/flow/node.d.ts.map +1 -0
  39. package/dist/flow/node.js +153 -0
  40. package/dist/flow/nodes/index.d.ts +8 -0
  41. package/dist/flow/nodes/index.d.ts.map +1 -0
  42. package/dist/flow/nodes/index.js +7 -0
  43. package/dist/flow/nodes/input-node.d.ts +78 -0
  44. package/dist/flow/nodes/input-node.d.ts.map +1 -0
  45. package/dist/flow/nodes/input-node.js +233 -0
  46. package/dist/flow/nodes/storage-node.d.ts +67 -0
  47. package/dist/flow/nodes/storage-node.d.ts.map +1 -0
  48. package/dist/flow/nodes/storage-node.js +94 -0
  49. package/dist/flow/nodes/streaming-input-node.d.ts +69 -0
  50. package/dist/flow/nodes/streaming-input-node.d.ts.map +1 -0
  51. package/dist/flow/nodes/streaming-input-node.js +156 -0
  52. package/dist/flow/nodes/transform-node.d.ts +85 -0
  53. package/dist/flow/nodes/transform-node.d.ts.map +1 -0
  54. package/dist/flow/nodes/transform-node.js +107 -0
  55. package/dist/flow/parallel-scheduler.d.ts +175 -0
  56. package/dist/flow/parallel-scheduler.d.ts.map +1 -0
  57. package/dist/flow/parallel-scheduler.js +193 -0
  58. package/dist/flow/plugins/credential-provider.d.ts +47 -0
  59. package/dist/flow/plugins/credential-provider.d.ts.map +1 -0
  60. package/dist/flow/plugins/credential-provider.js +24 -0
  61. package/dist/flow/plugins/image-ai-plugin.d.ts +61 -0
  62. package/dist/flow/plugins/image-ai-plugin.d.ts.map +1 -0
  63. package/dist/flow/plugins/image-ai-plugin.js +21 -0
  64. package/dist/flow/plugins/image-plugin.d.ts +52 -0
  65. package/dist/flow/plugins/image-plugin.d.ts.map +1 -0
  66. package/dist/flow/plugins/image-plugin.js +22 -0
  67. package/dist/flow/plugins/types/describe-image-node.d.ts +16 -0
  68. package/dist/flow/plugins/types/describe-image-node.d.ts.map +1 -0
  69. package/dist/flow/plugins/types/describe-image-node.js +9 -0
  70. package/dist/flow/plugins/types/index.d.ts +9 -0
  71. package/dist/flow/plugins/types/index.d.ts.map +1 -0
  72. package/dist/flow/plugins/types/index.js +8 -0
  73. package/dist/flow/plugins/types/optimize-node.d.ts +20 -0
  74. package/dist/flow/plugins/types/optimize-node.d.ts.map +1 -0
  75. package/dist/flow/plugins/types/optimize-node.js +11 -0
  76. package/dist/flow/plugins/types/remove-background-node.d.ts +16 -0
  77. package/dist/flow/plugins/types/remove-background-node.d.ts.map +1 -0
  78. package/dist/flow/plugins/types/remove-background-node.js +9 -0
  79. package/dist/flow/plugins/types/resize-node.d.ts +21 -0
  80. package/dist/flow/plugins/types/resize-node.d.ts.map +1 -0
  81. package/dist/flow/plugins/types/resize-node.js +16 -0
  82. package/dist/flow/plugins/zip-plugin.d.ts +62 -0
  83. package/dist/flow/plugins/zip-plugin.d.ts.map +1 -0
  84. package/dist/flow/plugins/zip-plugin.js +21 -0
  85. package/dist/flow/typed-flow.d.ts +90 -0
  86. package/dist/flow/typed-flow.d.ts.map +1 -0
  87. package/dist/flow/typed-flow.js +59 -0
  88. package/dist/flow/types/flow-file.d.ts +45 -0
  89. package/dist/flow/types/flow-file.d.ts.map +1 -0
  90. package/dist/flow/types/flow-file.js +27 -0
  91. package/dist/flow/types/flow-job.d.ts +118 -0
  92. package/dist/flow/types/flow-job.d.ts.map +1 -0
  93. package/dist/flow/types/flow-job.js +11 -0
  94. package/dist/flow/types/flow-types.d.ts +321 -0
  95. package/dist/flow/types/flow-types.d.ts.map +1 -0
  96. package/dist/flow/types/flow-types.js +52 -0
  97. package/dist/flow/types/index.d.ts +4 -0
  98. package/dist/flow/types/index.d.ts.map +1 -0
  99. package/dist/flow/types/index.js +3 -0
  100. package/dist/flow/types/run-args.d.ts +38 -0
  101. package/dist/flow/types/run-args.d.ts.map +1 -0
  102. package/dist/flow/types/run-args.js +30 -0
  103. package/dist/flow/types/type-validator.d.ts +26 -0
  104. package/dist/flow/types/type-validator.d.ts.map +1 -0
  105. package/dist/flow/types/type-validator.js +134 -0
  106. package/dist/flow/utils/resolve-upload-metadata.d.ts +11 -0
  107. package/dist/flow/utils/resolve-upload-metadata.d.ts.map +1 -0
  108. package/dist/flow/utils/resolve-upload-metadata.js +28 -0
  109. package/dist/flow-2zXnEiWL.cjs +1 -0
  110. package/dist/flow-CRaKy7Vj.js +2 -0
  111. package/dist/flow-CRaKy7Vj.js.map +1 -0
  112. package/dist/generate-id-Dm-Vboxq.d.ts +34 -0
  113. package/dist/generate-id-Dm-Vboxq.d.ts.map +1 -0
  114. package/dist/generate-id-LjJRLD6N.d.cts +34 -0
  115. package/dist/generate-id-LjJRLD6N.d.cts.map +1 -0
  116. package/dist/generate-id-xHp_Z7Cl.cjs +1 -0
  117. package/dist/generate-id-yohS1ZDk.js +2 -0
  118. package/dist/generate-id-yohS1ZDk.js.map +1 -0
  119. package/dist/index-BO8GZlbD.d.cts +1040 -0
  120. package/dist/index-BO8GZlbD.d.cts.map +1 -0
  121. package/dist/index-BoGG5KAY.d.ts +1 -0
  122. package/dist/index-BtBZHVmz.d.cts +1 -0
  123. package/dist/index-D-CoVpkZ.d.ts +1004 -0
  124. package/dist/index-D-CoVpkZ.d.ts.map +1 -0
  125. package/dist/index.cjs +1 -0
  126. package/dist/index.d.cts +6 -0
  127. package/dist/index.d.ts +5 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +5 -0
  130. package/dist/logger/logger.cjs +1 -0
  131. package/dist/logger/logger.d.cts +8 -0
  132. package/dist/logger/logger.d.cts.map +1 -0
  133. package/dist/logger/logger.d.ts +5 -0
  134. package/dist/logger/logger.d.ts.map +1 -0
  135. package/dist/logger/logger.js +10 -0
  136. package/dist/logger/logger.js.map +1 -0
  137. package/dist/semaphore-0ZwjVpyF.js +2 -0
  138. package/dist/semaphore-0ZwjVpyF.js.map +1 -0
  139. package/dist/semaphore-BHprIjFI.d.cts +37 -0
  140. package/dist/semaphore-BHprIjFI.d.cts.map +1 -0
  141. package/dist/semaphore-DThupBkc.d.ts +37 -0
  142. package/dist/semaphore-DThupBkc.d.ts.map +1 -0
  143. package/dist/semaphore-DVrONiAV.cjs +1 -0
  144. package/dist/stream-limiter-CoWKv39w.js +2 -0
  145. package/dist/stream-limiter-CoWKv39w.js.map +1 -0
  146. package/dist/stream-limiter-JgOwmkMa.cjs +1 -0
  147. package/dist/streams/multi-stream.cjs +1 -0
  148. package/dist/streams/multi-stream.d.cts +91 -0
  149. package/dist/streams/multi-stream.d.cts.map +1 -0
  150. package/dist/streams/multi-stream.d.ts +86 -0
  151. package/dist/streams/multi-stream.d.ts.map +1 -0
  152. package/dist/streams/multi-stream.js +149 -0
  153. package/dist/streams/multi-stream.js.map +1 -0
  154. package/dist/streams/stream-limiter.cjs +1 -0
  155. package/dist/streams/stream-limiter.d.cts +36 -0
  156. package/dist/streams/stream-limiter.d.cts.map +1 -0
  157. package/dist/streams/stream-limiter.d.ts +27 -0
  158. package/dist/streams/stream-limiter.d.ts.map +1 -0
  159. package/dist/streams/stream-limiter.js +49 -0
  160. package/dist/streams/stream-splitter.cjs +1 -0
  161. package/dist/streams/stream-splitter.d.cts +68 -0
  162. package/dist/streams/stream-splitter.d.cts.map +1 -0
  163. package/dist/streams/stream-splitter.d.ts +51 -0
  164. package/dist/streams/stream-splitter.d.ts.map +1 -0
  165. package/dist/streams/stream-splitter.js +175 -0
  166. package/dist/streams/stream-splitter.js.map +1 -0
  167. package/dist/types/data-store-registry.d.ts +13 -0
  168. package/dist/types/data-store-registry.d.ts.map +1 -0
  169. package/dist/types/data-store-registry.js +4 -0
  170. package/dist/types/data-store.d.ts +316 -0
  171. package/dist/types/data-store.d.ts.map +1 -0
  172. package/dist/types/data-store.js +157 -0
  173. package/dist/types/event-broadcaster.d.ts +28 -0
  174. package/dist/types/event-broadcaster.d.ts.map +1 -0
  175. package/dist/types/event-broadcaster.js +6 -0
  176. package/dist/types/event-emitter.d.ts +378 -0
  177. package/dist/types/event-emitter.d.ts.map +1 -0
  178. package/dist/types/event-emitter.js +223 -0
  179. package/dist/types/index.cjs +1 -0
  180. package/dist/types/index.d.cts +6 -0
  181. package/dist/types/index.d.ts +10 -0
  182. package/dist/types/index.d.ts.map +1 -0
  183. package/dist/types/index.js +9 -0
  184. package/dist/types/input-file.d.ts +104 -0
  185. package/dist/types/input-file.d.ts.map +1 -0
  186. package/dist/types/input-file.js +27 -0
  187. package/dist/types/kv-store.d.ts +281 -0
  188. package/dist/types/kv-store.d.ts.map +1 -0
  189. package/dist/types/kv-store.js +234 -0
  190. package/dist/types/middleware.d.ts +17 -0
  191. package/dist/types/middleware.d.ts.map +1 -0
  192. package/dist/types/middleware.js +21 -0
  193. package/dist/types/upload-event.d.ts +105 -0
  194. package/dist/types/upload-event.d.ts.map +1 -0
  195. package/dist/types/upload-event.js +71 -0
  196. package/dist/types/upload-file.d.ts +136 -0
  197. package/dist/types/upload-file.d.ts.map +1 -0
  198. package/dist/types/upload-file.js +34 -0
  199. package/dist/types/websocket.d.ts +144 -0
  200. package/dist/types/websocket.d.ts.map +1 -0
  201. package/dist/types/websocket.js +40 -0
  202. package/dist/types-BT-cvi7T.cjs +1 -0
  203. package/dist/types-DhU2j-XF.js +2 -0
  204. package/dist/types-DhU2j-XF.js.map +1 -0
  205. package/dist/upload/convert-to-stream.d.ts +38 -0
  206. package/dist/upload/convert-to-stream.d.ts.map +1 -0
  207. package/dist/upload/convert-to-stream.js +43 -0
  208. package/dist/upload/convert-upload-to-flow-file.d.ts +14 -0
  209. package/dist/upload/convert-upload-to-flow-file.d.ts.map +1 -0
  210. package/dist/upload/convert-upload-to-flow-file.js +21 -0
  211. package/dist/upload/create-upload.d.ts +68 -0
  212. package/dist/upload/create-upload.d.ts.map +1 -0
  213. package/dist/upload/create-upload.js +157 -0
  214. package/dist/upload/index.cjs +1 -0
  215. package/dist/upload/index.d.cts +6 -0
  216. package/dist/upload/index.d.ts +4 -0
  217. package/dist/upload/index.d.ts.map +1 -0
  218. package/dist/upload/index.js +3 -0
  219. package/dist/upload/mime.d.ts +24 -0
  220. package/dist/upload/mime.d.ts.map +1 -0
  221. package/dist/upload/mime.js +351 -0
  222. package/dist/upload/upload-chunk.d.ts +58 -0
  223. package/dist/upload/upload-chunk.d.ts.map +1 -0
  224. package/dist/upload/upload-chunk.js +277 -0
  225. package/dist/upload/upload-server.d.ts +221 -0
  226. package/dist/upload/upload-server.d.ts.map +1 -0
  227. package/dist/upload/upload-server.js +181 -0
  228. package/dist/upload/upload-strategy-negotiator.d.ts +148 -0
  229. package/dist/upload/upload-strategy-negotiator.d.ts.map +1 -0
  230. package/dist/upload/upload-strategy-negotiator.js +217 -0
  231. package/dist/upload/upload-url.d.ts +68 -0
  232. package/dist/upload/upload-url.d.ts.map +1 -0
  233. package/dist/upload/upload-url.js +142 -0
  234. package/dist/upload/write-to-store.d.ts +77 -0
  235. package/dist/upload/write-to-store.d.ts.map +1 -0
  236. package/dist/upload/write-to-store.js +147 -0
  237. package/dist/upload-DLuICjpP.cjs +1 -0
  238. package/dist/upload-DaXO34dE.js +2 -0
  239. package/dist/upload-DaXO34dE.js.map +1 -0
  240. package/dist/uploadista-error-BB-Wdiz9.cjs +22 -0
  241. package/dist/uploadista-error-BVsVxqvz.js +23 -0
  242. package/dist/uploadista-error-BVsVxqvz.js.map +1 -0
  243. package/dist/uploadista-error-CwxYs4EB.d.ts +52 -0
  244. package/dist/uploadista-error-CwxYs4EB.d.ts.map +1 -0
  245. package/dist/uploadista-error-kKlhLRhY.d.cts +52 -0
  246. package/dist/uploadista-error-kKlhLRhY.d.cts.map +1 -0
  247. package/dist/utils/checksum.d.ts +22 -0
  248. package/dist/utils/checksum.d.ts.map +1 -0
  249. package/dist/utils/checksum.js +49 -0
  250. package/dist/utils/debounce.cjs +1 -0
  251. package/dist/utils/debounce.d.cts +38 -0
  252. package/dist/utils/debounce.d.cts.map +1 -0
  253. package/dist/utils/debounce.d.ts +36 -0
  254. package/dist/utils/debounce.d.ts.map +1 -0
  255. package/dist/utils/debounce.js +73 -0
  256. package/dist/utils/generate-id.cjs +1 -0
  257. package/dist/utils/generate-id.d.cts +2 -0
  258. package/dist/utils/generate-id.d.ts +32 -0
  259. package/dist/utils/generate-id.d.ts.map +1 -0
  260. package/dist/utils/generate-id.js +23 -0
  261. package/dist/utils/md5.cjs +1 -0
  262. package/dist/utils/md5.d.cts +73 -0
  263. package/dist/utils/md5.d.cts.map +1 -0
  264. package/dist/utils/md5.d.ts +71 -0
  265. package/dist/utils/md5.d.ts.map +1 -0
  266. package/dist/utils/md5.js +417 -0
  267. package/dist/utils/md5.js.map +1 -0
  268. package/dist/utils/once.cjs +1 -0
  269. package/dist/utils/once.d.cts +25 -0
  270. package/dist/utils/once.d.cts.map +1 -0
  271. package/dist/utils/once.d.ts +21 -0
  272. package/dist/utils/once.d.ts.map +1 -0
  273. package/dist/utils/once.js +54 -0
  274. package/dist/utils/once.js.map +1 -0
  275. package/dist/utils/semaphore.cjs +1 -0
  276. package/dist/utils/semaphore.d.cts +3 -0
  277. package/dist/utils/semaphore.d.ts +78 -0
  278. package/dist/utils/semaphore.d.ts.map +1 -0
  279. package/dist/utils/semaphore.js +134 -0
  280. package/dist/utils/throttle.cjs +1 -0
  281. package/dist/utils/throttle.d.cts +24 -0
  282. package/dist/utils/throttle.d.cts.map +1 -0
  283. package/dist/utils/throttle.d.ts +18 -0
  284. package/dist/utils/throttle.d.ts.map +1 -0
  285. package/dist/utils/throttle.js +20 -0
  286. package/dist/utils/throttle.js.map +1 -0
  287. package/docs/PARALLEL_EXECUTION.md +206 -0
  288. package/docs/PARALLEL_EXECUTION_QUICKSTART.md +142 -0
  289. package/docs/PARALLEL_EXECUTION_REFACTOR.md +184 -0
  290. package/package.json +80 -0
  291. package/src/errors/__tests__/uploadista-error.test.ts +251 -0
  292. package/src/errors/index.ts +2 -0
  293. package/src/errors/uploadista-error.ts +394 -0
  294. package/src/flow/README.md +352 -0
  295. package/src/flow/edge.test.ts +146 -0
  296. package/src/flow/edge.ts +60 -0
  297. package/src/flow/event.ts +229 -0
  298. package/src/flow/flow-server.ts +1089 -0
  299. package/src/flow/flow.ts +1050 -0
  300. package/src/flow/index.ts +28 -0
  301. package/src/flow/node.ts +249 -0
  302. package/src/flow/nodes/index.ts +8 -0
  303. package/src/flow/nodes/input-node.ts +296 -0
  304. package/src/flow/nodes/storage-node.ts +128 -0
  305. package/src/flow/nodes/transform-node.ts +154 -0
  306. package/src/flow/parallel-scheduler.ts +259 -0
  307. package/src/flow/plugins/credential-provider.ts +48 -0
  308. package/src/flow/plugins/image-ai-plugin.ts +66 -0
  309. package/src/flow/plugins/image-plugin.ts +60 -0
  310. package/src/flow/plugins/types/describe-image-node.ts +16 -0
  311. package/src/flow/plugins/types/index.ts +9 -0
  312. package/src/flow/plugins/types/optimize-node.ts +18 -0
  313. package/src/flow/plugins/types/remove-background-node.ts +18 -0
  314. package/src/flow/plugins/types/resize-node.ts +26 -0
  315. package/src/flow/plugins/zip-plugin.ts +69 -0
  316. package/src/flow/typed-flow.ts +279 -0
  317. package/src/flow/types/flow-file.ts +51 -0
  318. package/src/flow/types/flow-job.ts +138 -0
  319. package/src/flow/types/flow-types.ts +353 -0
  320. package/src/flow/types/index.ts +6 -0
  321. package/src/flow/types/run-args.ts +40 -0
  322. package/src/flow/types/type-validator.ts +204 -0
  323. package/src/flow/utils/resolve-upload-metadata.ts +48 -0
  324. package/src/index.ts +5 -0
  325. package/src/logger/logger.ts +14 -0
  326. package/src/streams/stream-limiter.test.ts +150 -0
  327. package/src/streams/stream-limiter.ts +75 -0
  328. package/src/types/data-store.ts +427 -0
  329. package/src/types/event-broadcaster.ts +39 -0
  330. package/src/types/event-emitter.ts +349 -0
  331. package/src/types/index.ts +9 -0
  332. package/src/types/input-file.ts +107 -0
  333. package/src/types/kv-store.ts +375 -0
  334. package/src/types/middleware.ts +54 -0
  335. package/src/types/upload-event.ts +75 -0
  336. package/src/types/upload-file.ts +139 -0
  337. package/src/types/websocket.ts +65 -0
  338. package/src/upload/convert-to-stream.ts +48 -0
  339. package/src/upload/create-upload.ts +214 -0
  340. package/src/upload/index.ts +3 -0
  341. package/src/upload/mime.ts +436 -0
  342. package/src/upload/upload-chunk.ts +364 -0
  343. package/src/upload/upload-server.ts +390 -0
  344. package/src/upload/upload-strategy-negotiator.ts +316 -0
  345. package/src/upload/upload-url.ts +173 -0
  346. package/src/upload/write-to-store.ts +211 -0
  347. package/src/utils/checksum.ts +61 -0
  348. package/src/utils/debounce.test.ts +126 -0
  349. package/src/utils/debounce.ts +89 -0
  350. package/src/utils/generate-id.ts +35 -0
  351. package/src/utils/md5.ts +475 -0
  352. package/src/utils/once.test.ts +83 -0
  353. package/src/utils/once.ts +63 -0
  354. package/src/utils/throttle.test.ts +101 -0
  355. package/src/utils/throttle.ts +29 -0
  356. package/tsconfig.json +20 -0
  357. package/tsconfig.tsbuildinfo +1 -0
  358. package/tsdown.config.ts +25 -0
  359. package/vitest.config.ts +15 -0
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Core flow type definitions and node specifications.
3
+ *
4
+ * This module defines the fundamental types for the Flow Engine, including node
5
+ * definitions, execution results, edges, and configuration. These types form the
6
+ * foundation of the DAG processing system.
7
+ *
8
+ * @module flow/types/flow-types
9
+ * @see {@link FlowNode} for node specification
10
+ * @see {@link FlowConfig} for flow configuration
11
+ */
12
+
13
+ /** biome-ignore-all lint/suspicious/noExplicitAny: any is used to allow for dynamic types */
14
+
15
+ import type { Effect } from "effect";
16
+ import type { z } from "zod";
17
+ import type { UploadistaError } from "../../errors";
18
+ import type { FlowEvent, FlowEventFlowEnd, FlowEventFlowStart } from "../event";
19
+ import { NodeType } from "../node";
20
+
21
+ /**
22
+ * Type mapping for node input/output schemas.
23
+ * Used for type-safe node connections in typed flows.
24
+ */
25
+ export type NodeTypeMap = Record<string, { input: unknown; output: unknown }>;
26
+
27
+ /**
28
+ * Minimal node data without execution logic.
29
+ * Used for serialization and UI display.
30
+ *
31
+ * @property id - Unique node identifier
32
+ * @property name - Human-readable node name
33
+ * @property description - Explanation of what the node does
34
+ * @property type - Node category (input, transform, conditional, output, etc.)
35
+ */
36
+ export type FlowNodeData = {
37
+ id: string;
38
+ name: string;
39
+ description: string;
40
+ type: NodeType;
41
+ };
42
+
43
+ /**
44
+ * Result of a node execution - either complete or waiting for more data.
45
+ *
46
+ * @template TOutput - Type of the node's output data
47
+ *
48
+ * @remarks
49
+ * Nodes can return "waiting" to pause flow execution when they need additional
50
+ * data (e.g., chunked uploads, external service responses). The flow can be
51
+ * resumed later with the missing data.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // Node completes immediately
56
+ * return completeNodeExecution({ processedData });
57
+ *
58
+ * // Node waits for more chunks
59
+ * if (needsMoreData) {
60
+ * return waitingNodeExecution({ receivedChunks: 3, totalChunks: 10 });
61
+ * }
62
+ * ```
63
+ */
64
+ export type NodeExecutionResult<TOutput> =
65
+ | { type: "complete"; data: TOutput }
66
+ | { type: "waiting"; partialData?: unknown };
67
+
68
+ /**
69
+ * Helper function to create a complete node execution result.
70
+ *
71
+ * @template TOutput - Type of the output data
72
+ * @param data - The output data from the node
73
+ * @returns A complete execution result
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * return completeNodeExecution({
78
+ * url: uploadedFile.url,
79
+ * size: uploadedFile.size
80
+ * });
81
+ * ```
82
+ */
83
+ export const completeNodeExecution = <TOutput>(data: TOutput) => ({
84
+ type: "complete" as const,
85
+ data,
86
+ });
87
+
88
+ /**
89
+ * Helper function to create a waiting node execution result.
90
+ *
91
+ * @param partialData - Optional partial data available so far
92
+ * @returns A waiting execution result that pauses the flow
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * // Wait for more upload chunks
97
+ * return waitingNodeExecution({
98
+ * receivedBytes: currentSize,
99
+ * totalBytes: expectedSize
100
+ * });
101
+ * ```
102
+ */
103
+ export const waitingNodeExecution = (partialData?: unknown) => ({
104
+ type: "waiting" as const,
105
+ partialData,
106
+ });
107
+
108
+ /**
109
+ * A flow node represents a single processing step in the DAG.
110
+ *
111
+ * Nodes are the building blocks of flows. Each node has typed inputs/outputs,
112
+ * execution logic, and optional features like conditions, retries, and pausing.
113
+ *
114
+ * @template TInput - Type of data the node accepts
115
+ * @template TOutput - Type of data the node produces
116
+ * @template TError - Type of errors the node can throw
117
+ *
118
+ * @property inputSchema - Zod schema for validating input data
119
+ * @property outputSchema - Zod schema for validating output data
120
+ * @property run - Effect-based execution function
121
+ * @property condition - Optional conditional execution rule
122
+ * @property multiInput - Whether node accepts multiple inputs (default: false)
123
+ * @property multiOutput - Whether node produces multiple outputs (default: false)
124
+ * @property pausable - Whether node can pause execution (default: false)
125
+ * @property retry - Optional retry configuration
126
+ *
127
+ * @remarks
128
+ * - Nodes use Effect for composable error handling and dependency injection
129
+ * - Input/output schemas ensure type safety at runtime
130
+ * - Conditions are evaluated before execution
131
+ * - Retry logic supports exponential backoff
132
+ * - Pausable nodes can halt flow execution and resume later
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const resizeNode: FlowNode<InputFile, UploadFile> = {
137
+ * id: "resize",
138
+ * name: "Resize Image",
139
+ * description: "Resize image to specified dimensions",
140
+ * type: NodeType.transform,
141
+ * inputSchema: inputFileSchema,
142
+ * outputSchema: uploadFileSchema,
143
+ * run: ({ data, storageId }) => Effect.gen(function* () {
144
+ * const resized = yield* resizeImage(data, { width: 1920, height: 1080 });
145
+ * return completeNodeExecution(resized);
146
+ * }),
147
+ * retry: {
148
+ * maxRetries: 3,
149
+ * retryDelay: 1000,
150
+ * exponentialBackoff: true
151
+ * }
152
+ * };
153
+ * ```
154
+ *
155
+ * @see {@link NodeExecutionResult} for return type options
156
+ * @see {@link FlowCondition} for conditional execution
157
+ */
158
+ export type FlowNode<
159
+ TInput = unknown,
160
+ TOutput = unknown,
161
+ TError = UploadistaError,
162
+ > = FlowNodeData & {
163
+ inputSchema: z.ZodSchema<TInput>;
164
+ outputSchema: z.ZodSchema<TOutput>;
165
+ run: (args: {
166
+ data: TInput;
167
+ jobId: string;
168
+ storageId: string;
169
+ flowId: string;
170
+ inputs?: Record<string, unknown>;
171
+ clientId: string | null;
172
+ }) => Effect.Effect<NodeExecutionResult<TOutput>, TError>;
173
+ condition?: {
174
+ field: string;
175
+ operator: string;
176
+ value: unknown;
177
+ };
178
+ multiInput?: boolean;
179
+ multiOutput?: boolean;
180
+ pausable?: boolean; // Flag to indicate this node can pause execution
181
+ retry?: {
182
+ maxRetries?: number; // Maximum number of retry attempts (default: 0)
183
+ retryDelay?: number; // Base delay in ms between retries (default: 1000)
184
+ exponentialBackoff?: boolean; // Use exponential backoff (default: true)
185
+ };
186
+ };
187
+
188
+ /**
189
+ * Represents a directed edge connecting two nodes in the flow graph.
190
+ *
191
+ * Edges define the data flow direction and can specify ports for multi-input/output nodes.
192
+ *
193
+ * @property source - ID of the source node
194
+ * @property target - ID of the target node
195
+ * @property sourcePort - Optional output port name for multi-output nodes
196
+ * @property targetPort - Optional input port name for multi-input nodes
197
+ *
198
+ * @remarks
199
+ * - Edges must not create cycles (DAG constraint)
200
+ * - Source node's output type should be compatible with target node's input type
201
+ * - Ports allow routing specific outputs to specific inputs
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * // Simple edge
206
+ * const edge: FlowEdge = {
207
+ * source: "resize-node",
208
+ * target: "optimize-node"
209
+ * };
210
+ *
211
+ * // Edge with ports (for multiplex nodes)
212
+ * const multiplexEdge: FlowEdge = {
213
+ * source: "multiplex-node",
214
+ * target: "output-node",
215
+ * sourcePort: "image",
216
+ * targetPort: "primary"
217
+ * };
218
+ * ```
219
+ */
220
+ export type FlowEdge = {
221
+ source: string;
222
+ target: string;
223
+ sourcePort?: string; // For multi-output nodes
224
+ targetPort?: string; // For multi-input nodes
225
+ };
226
+
227
+ /**
228
+ * Function type for checking schema compatibility between nodes.
229
+ *
230
+ * @param from - Source node's output schema
231
+ * @param to - Target node's input schema
232
+ * @returns true if schemas are compatible
233
+ *
234
+ * @remarks
235
+ * Custom type checkers can implement more sophisticated compatibility rules
236
+ * than the default checker.
237
+ *
238
+ * @see {@link FlowTypeValidator} for the default implementation
239
+ */
240
+ export type TypeCompatibilityChecker = (
241
+ from: z.ZodSchema<any>,
242
+ to: z.ZodSchema<any>,
243
+ ) => boolean;
244
+
245
+ /**
246
+ * Interface for validating node connections and schema compatibility.
247
+ *
248
+ * @remarks
249
+ * Validators ensure that connected nodes have compatible types,
250
+ * preventing runtime type errors in flow execution.
251
+ *
252
+ * @see {@link FlowTypeValidator} for the implementation
253
+ */
254
+ export type NodeConnectionValidator = {
255
+ validateConnection: (
256
+ sourceNode: FlowNode<any, any>,
257
+ targetNode: FlowNode<any, any>,
258
+ edge: FlowEdge,
259
+ ) => boolean;
260
+ getCompatibleTypes: (
261
+ sourceSchema: z.ZodSchema<any>,
262
+ targetSchema: z.ZodSchema<any>,
263
+ ) => boolean;
264
+ };
265
+
266
+ /**
267
+ * Configuration object for creating a new flow.
268
+ *
269
+ * FlowConfig defines all aspects of a flow including its nodes, connections,
270
+ * schemas, and optional features like event handlers and parallel execution.
271
+ *
272
+ * @template TFlowInputSchema - Zod schema for flow inputs
273
+ * @template TFlowOutputSchema - Zod schema for flow outputs
274
+ * @template TNodeError - Union of possible errors from node Effects
275
+ * @template TNodeRequirements - Union of requirements from node Effects
276
+ *
277
+ * @property flowId - Unique identifier for the flow
278
+ * @property name - Human-readable flow name
279
+ * @property nodes - Array of nodes (can be plain nodes or Effects resolving to nodes)
280
+ * @property edges - Array of edges connecting the nodes
281
+ * @property inputSchema - Zod schema for validating flow inputs
282
+ * @property outputSchema - Zod schema for validating flow outputs
283
+ * @property typeChecker - Optional custom type compatibility checker
284
+ * @property onEvent - Optional event handler for monitoring execution
285
+ * @property parallelExecution - Optional parallel execution configuration
286
+ *
287
+ * @remarks
288
+ * - Nodes can be provided as plain objects or Effect-wrapped for lazy initialization
289
+ * - Event handlers receive all flow and node events
290
+ * - Parallel execution is experimental and disabled by default
291
+ * - Type checker allows custom schema compatibility rules
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * const config: FlowConfig<
296
+ * z.ZodObject<{ file: z.ZodType<File> }>,
297
+ * z.ZodType<UploadFile>,
298
+ * never,
299
+ * never
300
+ * > = {
301
+ * flowId: "image-upload",
302
+ * name: "Image Upload Pipeline",
303
+ * nodes: [inputNode, resizeNode, optimizeNode, storageNode],
304
+ * edges: [
305
+ * { source: "input", target: "resize" },
306
+ * { source: "resize", target: "optimize" },
307
+ * { source: "optimize", target: "storage" }
308
+ * ],
309
+ * inputSchema: z.object({ file: z.instanceof(File) }),
310
+ * outputSchema: uploadFileSchema,
311
+ * onEvent: (event) => Effect.gen(function* () {
312
+ * yield* logEvent(event);
313
+ * return { eventId: event.jobId };
314
+ * })
315
+ * };
316
+ * ```
317
+ *
318
+ * @see {@link createFlowWithSchema} for creating flows from config
319
+ * @see {@link FlowNode} for node specifications
320
+ * @see {@link FlowEdge} for edge specifications
321
+ */
322
+ export type FlowConfig<
323
+ TFlowInputSchema extends z.ZodSchema<any>,
324
+ TFlowOutputSchema extends z.ZodSchema<any>,
325
+ TNodeError = never,
326
+ TNodeRequirements = never,
327
+ > = {
328
+ flowId: string;
329
+ name: string;
330
+ nodes: Array<
331
+ | FlowNode<any, any, UploadistaError>
332
+ | Effect.Effect<
333
+ FlowNode<any, any, UploadistaError>,
334
+ TNodeError,
335
+ TNodeRequirements
336
+ >
337
+ >;
338
+ edges: FlowEdge[];
339
+ inputSchema: TFlowInputSchema;
340
+ outputSchema: TFlowOutputSchema;
341
+ typeChecker?: TypeCompatibilityChecker;
342
+ onEvent?: (
343
+ event: FlowEvent,
344
+ ) => Effect.Effect<{ eventId: string | null }, UploadistaError>;
345
+ parallelExecution?: {
346
+ enabled?: boolean;
347
+ maxConcurrency?: number;
348
+ };
349
+ };
350
+
351
+ // Re-export existing types for compatibility
352
+ export { NodeType };
353
+ export type { FlowEvent, FlowEventFlowEnd, FlowEventFlowStart };
@@ -0,0 +1,6 @@
1
+ // Re-export legacy types for backward compatibility
2
+ export type { FlowCondition } from "./flow-file";
3
+ // Export all flow types
4
+ export * from "./flow-types";
5
+
6
+ export * from "./type-validator";
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Flow execution argument schemas and types.
3
+ *
4
+ * Defines and validates the arguments passed when running a flow,
5
+ * ensuring inputs are properly structured before execution begins.
6
+ *
7
+ * @module flow/types/run-args
8
+ */
9
+
10
+ import { z } from "zod";
11
+
12
+ /**
13
+ * Zod schema for validating flow run arguments.
14
+ *
15
+ * @property inputs - Record mapping input node IDs to their input data
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const args = {
20
+ * inputs: {
21
+ * "input-node-1": { file: myFile, metadata: { ... } },
22
+ * "input-node-2": { file: anotherFile }
23
+ * }
24
+ * };
25
+ *
26
+ * // Validate before running
27
+ * const validated = runArgsSchema.parse(args);
28
+ * ```
29
+ */
30
+ export const runArgsSchema = z.object({
31
+ inputs: z.record(z.string(), z.any()),
32
+ });
33
+
34
+ /**
35
+ * Type representing validated flow run arguments.
36
+ *
37
+ * This type is inferred from the runArgsSchema and ensures type safety
38
+ * when passing inputs to flow execution.
39
+ */
40
+ export type RunArgs = z.infer<typeof runArgsSchema>;
@@ -0,0 +1,204 @@
1
+ /** biome-ignore-all lint/suspicious/noExplicitAny: any is used to allow for dynamic types */
2
+ import type { z } from "zod";
3
+
4
+ import type {
5
+ FlowEdge,
6
+ FlowNode,
7
+ NodeConnectionValidator,
8
+ TypeCompatibilityChecker,
9
+ } from "./flow-types";
10
+
11
+ // Default type compatibility checker using Zod schemas
12
+ export const defaultTypeChecker: TypeCompatibilityChecker = (
13
+ fromSchema,
14
+ toSchema,
15
+ ) => {
16
+ // Basic schema compatibility rules
17
+ if (fromSchema === toSchema) return true;
18
+
19
+ // Check if schemas are compatible by comparing their types
20
+ try {
21
+ // For now, assume schemas are compatible if they're both Zod schemas
22
+ // In a more sophisticated system, you'd check actual schema compatibility
23
+ if (
24
+ fromSchema &&
25
+ toSchema &&
26
+ typeof fromSchema === "object" &&
27
+ typeof toSchema === "object"
28
+ ) {
29
+ return true;
30
+ }
31
+
32
+ return false;
33
+ } catch {
34
+ // If schema comparison fails, assume compatible
35
+ return true;
36
+ }
37
+ };
38
+
39
+ // Enhanced type validator with Zod schema support
40
+ export class FlowTypeValidator implements NodeConnectionValidator {
41
+ private typeChecker: TypeCompatibilityChecker;
42
+
43
+ constructor(typeChecker: TypeCompatibilityChecker = defaultTypeChecker) {
44
+ this.typeChecker = typeChecker;
45
+ }
46
+
47
+ validateConnection(
48
+ sourceNode: FlowNode<any, any>,
49
+ targetNode: FlowNode<any, any>,
50
+ _edge: FlowEdge,
51
+ ): boolean {
52
+ // Check if source node output schema is compatible with target node input schema
53
+ return this.getCompatibleTypes(
54
+ sourceNode.outputSchema,
55
+ targetNode.inputSchema,
56
+ );
57
+ }
58
+
59
+ getCompatibleTypes(
60
+ sourceSchema: z.ZodSchema<any>,
61
+ targetSchema: z.ZodSchema<any>,
62
+ ): boolean {
63
+ return this.typeChecker(sourceSchema, targetSchema);
64
+ }
65
+
66
+ // Validate entire flow for type compatibility
67
+ validateFlow(
68
+ nodes: FlowNode<any, any>[],
69
+ edges: FlowEdge[],
70
+ ): {
71
+ isValid: boolean;
72
+ errors: string[];
73
+ } {
74
+ const errors: string[] = [];
75
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
76
+
77
+ for (const edge of edges) {
78
+ const sourceNode = nodeMap.get(edge.source);
79
+ const targetNode = nodeMap.get(edge.target);
80
+
81
+ if (!sourceNode) {
82
+ errors.push(`Source node ${edge.source} not found`);
83
+ continue;
84
+ }
85
+
86
+ if (!targetNode) {
87
+ errors.push(`Target node ${edge.target} not found`);
88
+ continue;
89
+ }
90
+
91
+ if (!this.validateConnection(sourceNode, targetNode, edge)) {
92
+ errors.push(
93
+ `Schema mismatch: ${sourceNode.id} output schema incompatible with ${targetNode.id} input schema`,
94
+ );
95
+ }
96
+ }
97
+
98
+ return {
99
+ isValid: errors.length === 0,
100
+ errors,
101
+ };
102
+ }
103
+
104
+ // Get expected input schemas for a node based on its incoming edges
105
+ getExpectedInputSchemas(
106
+ nodeId: string,
107
+ nodes: FlowNode<any, any>[],
108
+ edges: FlowEdge[],
109
+ ): Record<string, unknown> {
110
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
111
+ const expectedSchemas: Record<string, unknown> = {};
112
+
113
+ for (const edge of edges) {
114
+ if (edge.target === nodeId) {
115
+ const sourceNode = nodeMap.get(edge.source);
116
+ if (sourceNode) {
117
+ const portKey = edge.sourcePort || edge.source;
118
+ expectedSchemas[portKey] = sourceNode.outputSchema;
119
+ }
120
+ }
121
+ }
122
+
123
+ return expectedSchemas;
124
+ }
125
+
126
+ // Get actual output schemas for a node based on its outgoing edges
127
+ getActualOutputSchemas(
128
+ nodeId: string,
129
+ nodes: FlowNode<any, any>[],
130
+ edges: FlowEdge[],
131
+ ): Record<string, unknown> {
132
+ const nodeMap = new Map(nodes.map((node) => [node.id, node]));
133
+ const actualSchemas: Record<string, unknown> = {};
134
+
135
+ for (const edge of edges) {
136
+ if (edge.source === nodeId) {
137
+ const targetNode = nodeMap.get(edge.target);
138
+ if (targetNode) {
139
+ const portKey = edge.targetPort || edge.target;
140
+ actualSchemas[portKey] = targetNode.inputSchema;
141
+ }
142
+ }
143
+ }
144
+
145
+ return actualSchemas;
146
+ }
147
+
148
+ // Validate data against a schema
149
+ validateData(
150
+ data: unknown,
151
+ schema: unknown,
152
+ ): { isValid: boolean; errors: string[] } {
153
+ try {
154
+ (schema as z.ZodSchema<any>).parse(data);
155
+ return { isValid: true, errors: [] };
156
+ } catch (error) {
157
+ if (error instanceof Error && "errors" in error) {
158
+ return {
159
+ isValid: false,
160
+ errors: (
161
+ error as { errors: Array<{ path: string[]; message: string }> }
162
+ ).errors.map((err) => `${err.path.join(".")}: ${err.message}`),
163
+ };
164
+ }
165
+ return {
166
+ isValid: false,
167
+ errors: [error instanceof Error ? error.message : "Validation failed"],
168
+ };
169
+ }
170
+ }
171
+ }
172
+
173
+ // Utility functions for common type checks
174
+ export const typeUtils = {
175
+ // Check if a schema is assignable to another
176
+ isAssignable(
177
+ fromSchema: z.ZodSchema<any>,
178
+ toSchema: z.ZodSchema<any>,
179
+ ): boolean {
180
+ return defaultTypeChecker(fromSchema, toSchema);
181
+ },
182
+
183
+ // Get the most specific common schema
184
+ getCommonSchema(
185
+ schema1: z.ZodSchema<any>,
186
+ schema2: z.ZodSchema<any>,
187
+ ): z.ZodSchema<any> {
188
+ if (schema1 === schema2) return schema1;
189
+
190
+ // For now, return the more specific schema or schema1
191
+ // In a more sophisticated system, you'd compute the intersection
192
+ return schema1;
193
+ },
194
+
195
+ // Check if a value matches a schema
196
+ matchesSchema(value: unknown, schema: z.ZodSchema<any>): boolean {
197
+ try {
198
+ schema.parse(value);
199
+ return true;
200
+ } catch {
201
+ return false;
202
+ }
203
+ },
204
+ };
@@ -0,0 +1,48 @@
1
+ import type { UploadFile } from "../../types";
2
+
3
+ type FileMetadata = UploadFile["metadata"];
4
+
5
+ export type ResolvedUploadMetadata = {
6
+ type: string;
7
+ fileName: string;
8
+ metadata: FileMetadata;
9
+ metadataJson: string | undefined;
10
+ };
11
+
12
+ export function resolveUploadMetadata(
13
+ metadata: FileMetadata,
14
+ ): ResolvedUploadMetadata {
15
+ if (!metadata) {
16
+ return {
17
+ type: "",
18
+ fileName: "",
19
+ metadata: undefined,
20
+ metadataJson: undefined,
21
+ };
22
+ }
23
+
24
+ const normalized = { ...metadata };
25
+ const type = String(
26
+ normalized.type || normalized.mimeType || normalized["content-type"] || ""
27
+ );
28
+ if (type) {
29
+ normalized.type ||= type;
30
+ normalized.mimeType ||= type;
31
+ }
32
+
33
+ const fileName = String(
34
+ normalized.fileName || normalized.originalName || normalized.name || ""
35
+ );
36
+ if (fileName) {
37
+ normalized.fileName ||= fileName;
38
+ normalized.originalName ||= fileName;
39
+ normalized.name ||= fileName;
40
+ }
41
+
42
+ return {
43
+ type,
44
+ fileName,
45
+ metadata: normalized,
46
+ metadataJson: JSON.stringify(normalized),
47
+ };
48
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ // Main exports for @uploadista/core
2
+ export * from "./errors/index.js";
3
+ export * from "./flow/index.js";
4
+ export * from "./types/index.js";
5
+ export * from "./upload/index.js";
@@ -0,0 +1,14 @@
1
+ export type Logger = {
2
+ log: (message: string) => void;
3
+ };
4
+
5
+ export function createLogger(enabled: boolean): Logger {
6
+ return {
7
+ log: (message: string) => {
8
+ if (enabled) {
9
+ // eslint-disable-next-line no-console
10
+ console.log(message);
11
+ }
12
+ },
13
+ };
14
+ }