flingit 0.0.63 → 0.0.65

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 (517) hide show
  1. package/dist/cli/commands/dev.d.ts.map +1 -1
  2. package/dist/cli/commands/dev.js +9 -5
  3. package/dist/cli/commands/dev.js.map +1 -1
  4. package/dist/cli/commands/workflow.d.ts +51 -0
  5. package/dist/cli/commands/workflow.d.ts.map +1 -0
  6. package/dist/cli/commands/workflow.js +479 -0
  7. package/dist/cli/commands/workflow.js.map +1 -0
  8. package/dist/cli/deploy/bundler.d.ts.map +1 -1
  9. package/dist/cli/deploy/bundler.js +17 -1
  10. package/dist/cli/deploy/bundler.js.map +1 -1
  11. package/dist/cli/index.d.ts.map +1 -1
  12. package/dist/cli/index.js +2 -0
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/index.d.ts +4 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +3 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/runtime/entry.d.ts +7 -0
  19. package/dist/runtime/entry.d.ts.map +1 -1
  20. package/dist/runtime/entry.js +71 -2
  21. package/dist/runtime/entry.js.map +1 -1
  22. package/dist/types/workflow.d.ts +82 -0
  23. package/dist/types/workflow.d.ts.map +1 -0
  24. package/dist/types/workflow.js +8 -0
  25. package/dist/types/workflow.js.map +1 -0
  26. package/dist/worker-runtime/d1-event-store.d.ts +22 -0
  27. package/dist/worker-runtime/d1-event-store.d.ts.map +1 -0
  28. package/dist/worker-runtime/d1-event-store.js +227 -0
  29. package/dist/worker-runtime/d1-event-store.js.map +1 -0
  30. package/dist/worker-runtime/entry-extract.d.ts.map +1 -1
  31. package/dist/worker-runtime/entry-extract.js +6 -3
  32. package/dist/worker-runtime/entry-extract.js.map +1 -1
  33. package/dist/worker-runtime/entry.d.ts.map +1 -1
  34. package/dist/worker-runtime/entry.js +105 -3
  35. package/dist/worker-runtime/entry.js.map +1 -1
  36. package/dist/worker-runtime/index.d.ts +2 -0
  37. package/dist/worker-runtime/index.d.ts.map +1 -1
  38. package/dist/worker-runtime/index.js +5 -0
  39. package/dist/worker-runtime/index.js.map +1 -1
  40. package/dist/workflow/runtime.d.ts +56 -0
  41. package/dist/workflow/runtime.d.ts.map +1 -0
  42. package/dist/workflow/runtime.js +450 -0
  43. package/dist/workflow/runtime.js.map +1 -0
  44. package/node_modules/@glideapps/ts-necessities/LICENSE +21 -0
  45. package/node_modules/@glideapps/ts-necessities/README.md +16 -0
  46. package/node_modules/@glideapps/ts-necessities/dist/branded-strings.d.ts +39 -0
  47. package/node_modules/@glideapps/ts-necessities/dist/default-map.d.ts +53 -0
  48. package/node_modules/@glideapps/ts-necessities/dist/index.d.mts +113 -0
  49. package/node_modules/@glideapps/ts-necessities/dist/index.d.ts +113 -0
  50. package/node_modules/@glideapps/ts-necessities/dist/index.js +237 -0
  51. package/node_modules/@glideapps/ts-necessities/dist/index.mjs +189 -0
  52. package/node_modules/@glideapps/ts-necessities/package.json +52 -0
  53. package/node_modules/@rollup/rollup-linux-x64-gnu/README.md +3 -0
  54. package/node_modules/@rollup/rollup-linux-x64-gnu/package.json +25 -0
  55. package/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node +0 -0
  56. package/node_modules/base64-js/LICENSE +21 -0
  57. package/node_modules/base64-js/README.md +34 -0
  58. package/node_modules/base64-js/base64js.min.js +1 -0
  59. package/node_modules/base64-js/index.d.ts +3 -0
  60. package/node_modules/base64-js/index.js +150 -0
  61. package/node_modules/base64-js/package.json +47 -0
  62. package/node_modules/better-sqlite3/LICENSE +21 -0
  63. package/node_modules/better-sqlite3/README.md +99 -0
  64. package/node_modules/better-sqlite3/binding.gyp +38 -0
  65. package/node_modules/better-sqlite3/deps/common.gypi +68 -0
  66. package/node_modules/better-sqlite3/deps/copy.js +31 -0
  67. package/node_modules/better-sqlite3/deps/defines.gypi +41 -0
  68. package/node_modules/better-sqlite3/deps/download.sh +122 -0
  69. package/node_modules/better-sqlite3/deps/patches/1208.patch +15 -0
  70. package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.c +265994 -0
  71. package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.h +13968 -0
  72. package/node_modules/better-sqlite3/deps/sqlite3/sqlite3ext.h +730 -0
  73. package/node_modules/better-sqlite3/deps/sqlite3.gyp +80 -0
  74. package/node_modules/better-sqlite3/deps/test_extension.c +21 -0
  75. package/node_modules/better-sqlite3/lib/database.js +90 -0
  76. package/node_modules/better-sqlite3/lib/index.js +3 -0
  77. package/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
  78. package/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
  79. package/node_modules/better-sqlite3/lib/methods/function.js +31 -0
  80. package/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
  81. package/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
  82. package/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
  83. package/node_modules/better-sqlite3/lib/methods/table.js +189 -0
  84. package/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
  85. package/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
  86. package/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
  87. package/node_modules/better-sqlite3/lib/util.js +12 -0
  88. package/node_modules/better-sqlite3/package.json +59 -0
  89. package/node_modules/better-sqlite3/src/addon.cpp +47 -0
  90. package/node_modules/better-sqlite3/src/better_sqlite3.cpp +74 -0
  91. package/node_modules/better-sqlite3/src/objects/backup.cpp +120 -0
  92. package/node_modules/better-sqlite3/src/objects/backup.hpp +36 -0
  93. package/node_modules/better-sqlite3/src/objects/database.cpp +417 -0
  94. package/node_modules/better-sqlite3/src/objects/database.hpp +103 -0
  95. package/node_modules/better-sqlite3/src/objects/statement-iterator.cpp +113 -0
  96. package/node_modules/better-sqlite3/src/objects/statement-iterator.hpp +50 -0
  97. package/node_modules/better-sqlite3/src/objects/statement.cpp +383 -0
  98. package/node_modules/better-sqlite3/src/objects/statement.hpp +58 -0
  99. package/node_modules/better-sqlite3/src/util/bind-map.cpp +73 -0
  100. package/node_modules/better-sqlite3/src/util/binder.cpp +193 -0
  101. package/node_modules/better-sqlite3/src/util/constants.cpp +172 -0
  102. package/node_modules/better-sqlite3/src/util/custom-aggregate.cpp +121 -0
  103. package/node_modules/better-sqlite3/src/util/custom-function.cpp +59 -0
  104. package/node_modules/better-sqlite3/src/util/custom-table.cpp +409 -0
  105. package/node_modules/better-sqlite3/src/util/data-converter.cpp +17 -0
  106. package/node_modules/better-sqlite3/src/util/data.cpp +194 -0
  107. package/node_modules/better-sqlite3/src/util/helpers.cpp +109 -0
  108. package/node_modules/better-sqlite3/src/util/macros.cpp +83 -0
  109. package/node_modules/better-sqlite3/src/util/query-macros.cpp +71 -0
  110. package/node_modules/better-sqlite3/src/util/row-builder.cpp +49 -0
  111. package/node_modules/bindings/LICENSE.md +22 -0
  112. package/node_modules/bindings/README.md +98 -0
  113. package/node_modules/bindings/bindings.js +221 -0
  114. package/node_modules/bindings/package.json +28 -0
  115. package/node_modules/bl/.travis.yml +17 -0
  116. package/node_modules/bl/BufferList.js +396 -0
  117. package/node_modules/bl/LICENSE.md +13 -0
  118. package/node_modules/bl/README.md +247 -0
  119. package/node_modules/bl/bl.js +84 -0
  120. package/node_modules/bl/package.json +37 -0
  121. package/node_modules/bl/test/convert.js +21 -0
  122. package/node_modules/bl/test/indexOf.js +492 -0
  123. package/node_modules/bl/test/isBufferList.js +32 -0
  124. package/node_modules/bl/test/test.js +869 -0
  125. package/node_modules/buffer/AUTHORS.md +70 -0
  126. package/node_modules/buffer/LICENSE +21 -0
  127. package/node_modules/buffer/README.md +410 -0
  128. package/node_modules/buffer/index.d.ts +186 -0
  129. package/node_modules/buffer/index.js +1817 -0
  130. package/node_modules/buffer/package.json +96 -0
  131. package/node_modules/chownr/LICENSE +15 -0
  132. package/node_modules/chownr/README.md +3 -0
  133. package/node_modules/chownr/chownr.js +167 -0
  134. package/node_modules/chownr/package.json +29 -0
  135. package/node_modules/decompress-response/index.d.ts +22 -0
  136. package/node_modules/decompress-response/index.js +58 -0
  137. package/node_modules/decompress-response/license +9 -0
  138. package/node_modules/decompress-response/package.json +56 -0
  139. package/node_modules/decompress-response/readme.md +48 -0
  140. package/node_modules/deep-extend/LICENSE +20 -0
  141. package/node_modules/deep-extend/README.md +91 -0
  142. package/node_modules/deep-extend/index.js +1 -0
  143. package/node_modules/deep-extend/lib/deep-extend.js +150 -0
  144. package/node_modules/deep-extend/package.json +62 -0
  145. package/node_modules/detect-libc/LICENSE +201 -0
  146. package/node_modules/detect-libc/README.md +163 -0
  147. package/node_modules/detect-libc/index.d.ts +14 -0
  148. package/node_modules/detect-libc/lib/detect-libc.js +313 -0
  149. package/node_modules/detect-libc/lib/elf.js +39 -0
  150. package/node_modules/detect-libc/lib/filesystem.js +51 -0
  151. package/node_modules/detect-libc/lib/process.js +24 -0
  152. package/node_modules/detect-libc/package.json +44 -0
  153. package/node_modules/determined/LICENSE +18 -0
  154. package/node_modules/determined/README.md +317 -0
  155. package/node_modules/determined/dist/index.cjs +370 -0
  156. package/node_modules/determined/dist/index.d.cts +110 -0
  157. package/node_modules/determined/dist/index.d.ts +110 -0
  158. package/node_modules/determined/dist/index.js +332 -0
  159. package/node_modules/determined/package.json +45 -0
  160. package/node_modules/end-of-stream/LICENSE +21 -0
  161. package/node_modules/end-of-stream/README.md +54 -0
  162. package/node_modules/end-of-stream/index.js +96 -0
  163. package/node_modules/end-of-stream/package.json +37 -0
  164. package/node_modules/expand-template/.travis.yml +6 -0
  165. package/node_modules/expand-template/LICENSE +21 -0
  166. package/node_modules/expand-template/README.md +43 -0
  167. package/node_modules/expand-template/index.js +26 -0
  168. package/node_modules/expand-template/package.json +29 -0
  169. package/node_modules/expand-template/test.js +67 -0
  170. package/node_modules/file-uri-to-path/.npmignore +1 -0
  171. package/node_modules/file-uri-to-path/.travis.yml +30 -0
  172. package/node_modules/file-uri-to-path/History.md +21 -0
  173. package/node_modules/file-uri-to-path/LICENSE +20 -0
  174. package/node_modules/file-uri-to-path/README.md +74 -0
  175. package/node_modules/file-uri-to-path/index.d.ts +2 -0
  176. package/node_modules/file-uri-to-path/index.js +66 -0
  177. package/node_modules/file-uri-to-path/package.json +32 -0
  178. package/node_modules/file-uri-to-path/test/test.js +24 -0
  179. package/node_modules/file-uri-to-path/test/tests.json +13 -0
  180. package/node_modules/flingflow/.nvmrc +1 -0
  181. package/node_modules/flingflow/AGENTS.md +5 -0
  182. package/node_modules/flingflow/README.md +679 -0
  183. package/node_modules/flingflow/SPEC.md +554 -0
  184. package/node_modules/flingflow/TESTING.md +506 -0
  185. package/node_modules/flingflow/dist/backoff.d.ts +9 -0
  186. package/node_modules/flingflow/dist/backoff.js +14 -0
  187. package/node_modules/flingflow/dist/backoff.js.map +1 -0
  188. package/node_modules/flingflow/dist/clock.d.ts +13 -0
  189. package/node_modules/flingflow/dist/clock.js +21 -0
  190. package/node_modules/flingflow/dist/clock.js.map +1 -0
  191. package/node_modules/flingflow/dist/context.d.ts +8 -0
  192. package/node_modules/flingflow/dist/context.js +45 -0
  193. package/node_modules/flingflow/dist/context.js.map +1 -0
  194. package/node_modules/flingflow/dist/engine.d.ts +29 -0
  195. package/node_modules/flingflow/dist/engine.js +306 -0
  196. package/node_modules/flingflow/dist/engine.js.map +1 -0
  197. package/node_modules/flingflow/dist/index.d.ts +18 -0
  198. package/node_modules/flingflow/dist/index.js +14 -0
  199. package/node_modules/flingflow/dist/index.js.map +1 -0
  200. package/node_modules/flingflow/dist/recovery.d.ts +16 -0
  201. package/node_modules/flingflow/dist/recovery.js +118 -0
  202. package/node_modules/flingflow/dist/recovery.js.map +1 -0
  203. package/node_modules/flingflow/dist/registry.d.ts +24 -0
  204. package/node_modules/flingflow/dist/registry.js +29 -0
  205. package/node_modules/flingflow/dist/registry.js.map +1 -0
  206. package/node_modules/flingflow/dist/store-memory.d.ts +29 -0
  207. package/node_modules/flingflow/dist/store-memory.js +349 -0
  208. package/node_modules/flingflow/dist/store-memory.js.map +1 -0
  209. package/node_modules/flingflow/dist/store-sqlite.d.ts +30 -0
  210. package/node_modules/flingflow/dist/store-sqlite.js +400 -0
  211. package/node_modules/flingflow/dist/store-sqlite.js.map +1 -0
  212. package/node_modules/flingflow/dist/store.d.ts +39 -0
  213. package/node_modules/flingflow/dist/store.js +21 -0
  214. package/node_modules/flingflow/dist/store.js.map +1 -0
  215. package/node_modules/flingflow/dist/stress.d.ts +1 -0
  216. package/node_modules/flingflow/dist/stress.js +377 -0
  217. package/node_modules/flingflow/dist/stress.js.map +1 -0
  218. package/node_modules/flingflow/dist/transitions.d.ts +14 -0
  219. package/node_modules/flingflow/dist/transitions.js +28 -0
  220. package/node_modules/flingflow/dist/transitions.js.map +1 -0
  221. package/node_modules/flingflow/dist/types.d.ts +114 -0
  222. package/node_modules/flingflow/dist/types.js +10 -0
  223. package/node_modules/flingflow/dist/types.js.map +1 -0
  224. package/node_modules/flingflow/eslint.config.js +94 -0
  225. package/node_modules/flingflow/package.json +66 -0
  226. package/node_modules/flingflow/src/backoff.ts +14 -0
  227. package/node_modules/flingflow/src/clock.ts +29 -0
  228. package/node_modules/flingflow/src/context.ts +60 -0
  229. package/node_modules/flingflow/src/engine.ts +367 -0
  230. package/node_modules/flingflow/src/index.ts +52 -0
  231. package/node_modules/flingflow/src/recovery.ts +144 -0
  232. package/node_modules/flingflow/src/registry.ts +52 -0
  233. package/node_modules/flingflow/src/store-memory.ts +378 -0
  234. package/node_modules/flingflow/src/store-sqlite.ts +451 -0
  235. package/node_modules/flingflow/src/store.ts +55 -0
  236. package/node_modules/flingflow/src/stress.ts +423 -0
  237. package/node_modules/flingflow/src/transitions.ts +38 -0
  238. package/node_modules/flingflow/src/types.ts +84 -0
  239. package/node_modules/flingflow/test/backoff.test.ts +54 -0
  240. package/node_modules/flingflow/test/context.test.ts +94 -0
  241. package/node_modules/flingflow/test/engine.test.ts +362 -0
  242. package/node_modules/flingflow/test/fixtures.ts +58 -0
  243. package/node_modules/flingflow/test/recovery.test.ts +176 -0
  244. package/node_modules/flingflow/test/simulation.test.ts +395 -0
  245. package/node_modules/flingflow/test/store-conformance.ts +344 -0
  246. package/node_modules/flingflow/test/store-memory.test.ts +8 -0
  247. package/node_modules/flingflow/test/store-sqlite.test.ts +8 -0
  248. package/node_modules/flingflow/tsconfig.json +18 -0
  249. package/node_modules/flingflow/tsconfig.lint.json +5 -0
  250. package/node_modules/flingflow/tsconfig.typecheck.json +20 -0
  251. package/node_modules/flingflow/vitest.config.ts +10 -0
  252. package/node_modules/fs-constants/LICENSE +21 -0
  253. package/node_modules/fs-constants/README.md +26 -0
  254. package/node_modules/fs-constants/browser.js +1 -0
  255. package/node_modules/fs-constants/index.js +1 -0
  256. package/node_modules/fs-constants/package.json +19 -0
  257. package/node_modules/github-from-package/.travis.yml +4 -0
  258. package/node_modules/github-from-package/LICENSE +18 -0
  259. package/node_modules/github-from-package/example/package.json +8 -0
  260. package/node_modules/github-from-package/example/url.js +3 -0
  261. package/node_modules/github-from-package/index.js +17 -0
  262. package/node_modules/github-from-package/package.json +30 -0
  263. package/node_modules/github-from-package/readme.markdown +53 -0
  264. package/node_modules/github-from-package/test/a.json +8 -0
  265. package/node_modules/github-from-package/test/b.json +5 -0
  266. package/node_modules/github-from-package/test/c.json +5 -0
  267. package/node_modules/github-from-package/test/d.json +7 -0
  268. package/node_modules/github-from-package/test/e.json +5 -0
  269. package/node_modules/github-from-package/test/url.js +19 -0
  270. package/node_modules/ieee754/LICENSE +11 -0
  271. package/node_modules/ieee754/README.md +51 -0
  272. package/node_modules/ieee754/index.d.ts +10 -0
  273. package/node_modules/ieee754/index.js +85 -0
  274. package/node_modules/ieee754/package.json +52 -0
  275. package/node_modules/inherits/LICENSE +16 -0
  276. package/node_modules/inherits/README.md +42 -0
  277. package/node_modules/inherits/inherits.js +9 -0
  278. package/node_modules/inherits/inherits_browser.js +27 -0
  279. package/node_modules/inherits/package.json +29 -0
  280. package/node_modules/ini/LICENSE +15 -0
  281. package/node_modules/ini/README.md +102 -0
  282. package/node_modules/ini/ini.js +206 -0
  283. package/node_modules/ini/package.json +33 -0
  284. package/node_modules/mimic-response/index.d.ts +17 -0
  285. package/node_modules/mimic-response/index.js +77 -0
  286. package/node_modules/mimic-response/license +9 -0
  287. package/node_modules/mimic-response/package.json +42 -0
  288. package/node_modules/mimic-response/readme.md +78 -0
  289. package/node_modules/minimist/.eslintrc +29 -0
  290. package/node_modules/minimist/.github/FUNDING.yml +12 -0
  291. package/node_modules/minimist/.nycrc +14 -0
  292. package/node_modules/minimist/CHANGELOG.md +298 -0
  293. package/node_modules/minimist/LICENSE +18 -0
  294. package/node_modules/minimist/README.md +121 -0
  295. package/node_modules/minimist/example/parse.js +4 -0
  296. package/node_modules/minimist/index.js +263 -0
  297. package/node_modules/minimist/package.json +75 -0
  298. package/node_modules/minimist/test/all_bool.js +34 -0
  299. package/node_modules/minimist/test/bool.js +177 -0
  300. package/node_modules/minimist/test/dash.js +43 -0
  301. package/node_modules/minimist/test/default_bool.js +37 -0
  302. package/node_modules/minimist/test/dotted.js +24 -0
  303. package/node_modules/minimist/test/kv_short.js +32 -0
  304. package/node_modules/minimist/test/long.js +33 -0
  305. package/node_modules/minimist/test/num.js +38 -0
  306. package/node_modules/minimist/test/parse.js +209 -0
  307. package/node_modules/minimist/test/parse_modified.js +11 -0
  308. package/node_modules/minimist/test/proto.js +64 -0
  309. package/node_modules/minimist/test/short.js +69 -0
  310. package/node_modules/minimist/test/stop_early.js +17 -0
  311. package/node_modules/minimist/test/unknown.js +104 -0
  312. package/node_modules/minimist/test/whitespace.js +10 -0
  313. package/node_modules/mkdirp-classic/LICENSE +21 -0
  314. package/node_modules/mkdirp-classic/README.md +18 -0
  315. package/node_modules/mkdirp-classic/index.js +98 -0
  316. package/node_modules/mkdirp-classic/package.json +18 -0
  317. package/node_modules/napi-build-utils/.github/workflows/run-npm-tests.yml +31 -0
  318. package/node_modules/napi-build-utils/LICENSE +21 -0
  319. package/node_modules/napi-build-utils/README.md +52 -0
  320. package/node_modules/napi-build-utils/index.js +214 -0
  321. package/node_modules/napi-build-utils/index.md +0 -0
  322. package/node_modules/napi-build-utils/package.json +42 -0
  323. package/node_modules/neverthrow/LICENSE +22 -0
  324. package/node_modules/neverthrow/README.md +1683 -0
  325. package/node_modules/neverthrow/dist/index.cjs.js +510 -0
  326. package/node_modules/neverthrow/dist/index.d.ts +408 -0
  327. package/node_modules/neverthrow/dist/index.es.js +497 -0
  328. package/node_modules/neverthrow/package.json +64 -0
  329. package/node_modules/node-abi/LICENSE +21 -0
  330. package/node_modules/node-abi/README.md +54 -0
  331. package/node_modules/node-abi/abi_registry.json +425 -0
  332. package/node_modules/node-abi/index.js +179 -0
  333. package/node_modules/node-abi/package.json +45 -0
  334. package/node_modules/once/LICENSE +15 -0
  335. package/node_modules/once/README.md +79 -0
  336. package/node_modules/once/once.js +42 -0
  337. package/node_modules/once/package.json +33 -0
  338. package/node_modules/prebuild-install/CHANGELOG.md +131 -0
  339. package/node_modules/prebuild-install/CONTRIBUTING.md +6 -0
  340. package/node_modules/prebuild-install/LICENSE +21 -0
  341. package/node_modules/prebuild-install/README.md +163 -0
  342. package/node_modules/prebuild-install/asset.js +44 -0
  343. package/node_modules/prebuild-install/bin.js +78 -0
  344. package/node_modules/prebuild-install/download.js +142 -0
  345. package/node_modules/prebuild-install/error.js +14 -0
  346. package/node_modules/prebuild-install/help.txt +16 -0
  347. package/node_modules/prebuild-install/index.js +1 -0
  348. package/node_modules/prebuild-install/log.js +33 -0
  349. package/node_modules/prebuild-install/package.json +67 -0
  350. package/node_modules/prebuild-install/proxy.js +35 -0
  351. package/node_modules/prebuild-install/rc.js +64 -0
  352. package/node_modules/prebuild-install/util.js +143 -0
  353. package/node_modules/pump/.github/FUNDING.yml +2 -0
  354. package/node_modules/pump/.travis.yml +5 -0
  355. package/node_modules/pump/LICENSE +21 -0
  356. package/node_modules/pump/README.md +74 -0
  357. package/node_modules/pump/SECURITY.md +5 -0
  358. package/node_modules/pump/index.js +86 -0
  359. package/node_modules/pump/package.json +24 -0
  360. package/node_modules/pump/test-browser.js +66 -0
  361. package/node_modules/pump/test-node.js +53 -0
  362. package/node_modules/rc/LICENSE.APACHE2 +15 -0
  363. package/node_modules/rc/LICENSE.BSD +26 -0
  364. package/node_modules/rc/LICENSE.MIT +24 -0
  365. package/node_modules/rc/README.md +227 -0
  366. package/node_modules/rc/browser.js +7 -0
  367. package/node_modules/rc/cli.js +4 -0
  368. package/node_modules/rc/index.js +53 -0
  369. package/node_modules/rc/lib/utils.js +104 -0
  370. package/node_modules/rc/package.json +29 -0
  371. package/node_modules/rc/test/ini.js +16 -0
  372. package/node_modules/rc/test/nested-env-vars.js +50 -0
  373. package/node_modules/rc/test/test.js +59 -0
  374. package/node_modules/readable-stream/CONTRIBUTING.md +38 -0
  375. package/node_modules/readable-stream/GOVERNANCE.md +136 -0
  376. package/node_modules/readable-stream/LICENSE +47 -0
  377. package/node_modules/readable-stream/README.md +106 -0
  378. package/node_modules/readable-stream/errors-browser.js +127 -0
  379. package/node_modules/readable-stream/errors.js +116 -0
  380. package/node_modules/readable-stream/experimentalWarning.js +17 -0
  381. package/node_modules/readable-stream/lib/_stream_duplex.js +126 -0
  382. package/node_modules/readable-stream/lib/_stream_passthrough.js +37 -0
  383. package/node_modules/readable-stream/lib/_stream_readable.js +1027 -0
  384. package/node_modules/readable-stream/lib/_stream_transform.js +190 -0
  385. package/node_modules/readable-stream/lib/_stream_writable.js +641 -0
  386. package/node_modules/readable-stream/lib/internal/streams/async_iterator.js +180 -0
  387. package/node_modules/readable-stream/lib/internal/streams/buffer_list.js +183 -0
  388. package/node_modules/readable-stream/lib/internal/streams/destroy.js +96 -0
  389. package/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +86 -0
  390. package/node_modules/readable-stream/lib/internal/streams/from-browser.js +3 -0
  391. package/node_modules/readable-stream/lib/internal/streams/from.js +52 -0
  392. package/node_modules/readable-stream/lib/internal/streams/pipeline.js +86 -0
  393. package/node_modules/readable-stream/lib/internal/streams/state.js +22 -0
  394. package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
  395. package/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
  396. package/node_modules/readable-stream/package.json +68 -0
  397. package/node_modules/readable-stream/readable-browser.js +9 -0
  398. package/node_modules/readable-stream/readable.js +16 -0
  399. package/node_modules/safe-buffer/LICENSE +21 -0
  400. package/node_modules/safe-buffer/README.md +584 -0
  401. package/node_modules/safe-buffer/index.d.ts +187 -0
  402. package/node_modules/safe-buffer/index.js +65 -0
  403. package/node_modules/safe-buffer/package.json +51 -0
  404. package/node_modules/semver/LICENSE +15 -0
  405. package/node_modules/semver/README.md +664 -0
  406. package/node_modules/semver/bin/semver.js +191 -0
  407. package/node_modules/semver/classes/comparator.js +143 -0
  408. package/node_modules/semver/classes/index.js +7 -0
  409. package/node_modules/semver/classes/range.js +557 -0
  410. package/node_modules/semver/classes/semver.js +333 -0
  411. package/node_modules/semver/functions/clean.js +8 -0
  412. package/node_modules/semver/functions/cmp.js +54 -0
  413. package/node_modules/semver/functions/coerce.js +62 -0
  414. package/node_modules/semver/functions/compare-build.js +9 -0
  415. package/node_modules/semver/functions/compare-loose.js +5 -0
  416. package/node_modules/semver/functions/compare.js +7 -0
  417. package/node_modules/semver/functions/diff.js +60 -0
  418. package/node_modules/semver/functions/eq.js +5 -0
  419. package/node_modules/semver/functions/gt.js +5 -0
  420. package/node_modules/semver/functions/gte.js +5 -0
  421. package/node_modules/semver/functions/inc.js +21 -0
  422. package/node_modules/semver/functions/lt.js +5 -0
  423. package/node_modules/semver/functions/lte.js +5 -0
  424. package/node_modules/semver/functions/major.js +5 -0
  425. package/node_modules/semver/functions/minor.js +5 -0
  426. package/node_modules/semver/functions/neq.js +5 -0
  427. package/node_modules/semver/functions/parse.js +18 -0
  428. package/node_modules/semver/functions/patch.js +5 -0
  429. package/node_modules/semver/functions/prerelease.js +8 -0
  430. package/node_modules/semver/functions/rcompare.js +5 -0
  431. package/node_modules/semver/functions/rsort.js +5 -0
  432. package/node_modules/semver/functions/satisfies.js +12 -0
  433. package/node_modules/semver/functions/sort.js +5 -0
  434. package/node_modules/semver/functions/valid.js +8 -0
  435. package/node_modules/semver/index.js +91 -0
  436. package/node_modules/semver/internal/constants.js +37 -0
  437. package/node_modules/semver/internal/debug.js +11 -0
  438. package/node_modules/semver/internal/identifiers.js +29 -0
  439. package/node_modules/semver/internal/lrucache.js +42 -0
  440. package/node_modules/semver/internal/parse-options.js +17 -0
  441. package/node_modules/semver/internal/re.js +223 -0
  442. package/node_modules/semver/package.json +78 -0
  443. package/node_modules/semver/preload.js +4 -0
  444. package/node_modules/semver/range.bnf +16 -0
  445. package/node_modules/semver/ranges/gtr.js +6 -0
  446. package/node_modules/semver/ranges/intersects.js +9 -0
  447. package/node_modules/semver/ranges/ltr.js +6 -0
  448. package/node_modules/semver/ranges/max-satisfying.js +27 -0
  449. package/node_modules/semver/ranges/min-satisfying.js +26 -0
  450. package/node_modules/semver/ranges/min-version.js +63 -0
  451. package/node_modules/semver/ranges/outside.js +82 -0
  452. package/node_modules/semver/ranges/simplify.js +49 -0
  453. package/node_modules/semver/ranges/subset.js +249 -0
  454. package/node_modules/semver/ranges/to-comparators.js +10 -0
  455. package/node_modules/semver/ranges/valid.js +13 -0
  456. package/node_modules/simple-concat/.travis.yml +3 -0
  457. package/node_modules/simple-concat/LICENSE +20 -0
  458. package/node_modules/simple-concat/README.md +44 -0
  459. package/node_modules/simple-concat/index.js +15 -0
  460. package/node_modules/simple-concat/package.json +47 -0
  461. package/node_modules/simple-concat/test/basic.js +41 -0
  462. package/node_modules/simple-get/.github/dependabot.yml +15 -0
  463. package/node_modules/simple-get/.github/workflows/ci.yml +23 -0
  464. package/node_modules/simple-get/LICENSE +20 -0
  465. package/node_modules/simple-get/README.md +333 -0
  466. package/node_modules/simple-get/index.js +108 -0
  467. package/node_modules/simple-get/package.json +67 -0
  468. package/node_modules/string_decoder/LICENSE +48 -0
  469. package/node_modules/string_decoder/README.md +47 -0
  470. package/node_modules/string_decoder/lib/string_decoder.js +296 -0
  471. package/node_modules/string_decoder/package.json +34 -0
  472. package/node_modules/strip-json-comments/index.js +70 -0
  473. package/node_modules/strip-json-comments/license +21 -0
  474. package/node_modules/strip-json-comments/package.json +42 -0
  475. package/node_modules/strip-json-comments/readme.md +64 -0
  476. package/node_modules/tar-fs/.travis.yml +6 -0
  477. package/node_modules/tar-fs/LICENSE +21 -0
  478. package/node_modules/tar-fs/README.md +165 -0
  479. package/node_modules/tar-fs/index.js +363 -0
  480. package/node_modules/tar-fs/package.json +41 -0
  481. package/node_modules/tar-fs/test/fixtures/a/hello.txt +1 -0
  482. package/node_modules/tar-fs/test/fixtures/b/a/test.txt +1 -0
  483. package/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
  484. package/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
  485. package/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
  486. package/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
  487. package/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
  488. package/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
  489. package/node_modules/tar-fs/test/fixtures/e/file +0 -0
  490. package/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
  491. package/node_modules/tar-fs/test/index.js +346 -0
  492. package/node_modules/tar-stream/LICENSE +21 -0
  493. package/node_modules/tar-stream/README.md +168 -0
  494. package/node_modules/tar-stream/extract.js +257 -0
  495. package/node_modules/tar-stream/headers.js +295 -0
  496. package/node_modules/tar-stream/index.js +2 -0
  497. package/node_modules/tar-stream/pack.js +255 -0
  498. package/node_modules/tar-stream/package.json +58 -0
  499. package/node_modules/tar-stream/sandbox.js +11 -0
  500. package/node_modules/tunnel-agent/LICENSE +55 -0
  501. package/node_modules/tunnel-agent/README.md +4 -0
  502. package/node_modules/tunnel-agent/index.js +244 -0
  503. package/node_modules/tunnel-agent/package.json +22 -0
  504. package/node_modules/util-deprecate/History.md +16 -0
  505. package/node_modules/util-deprecate/LICENSE +24 -0
  506. package/node_modules/util-deprecate/README.md +53 -0
  507. package/node_modules/util-deprecate/browser.js +67 -0
  508. package/node_modules/util-deprecate/node.js +6 -0
  509. package/node_modules/util-deprecate/package.json +27 -0
  510. package/node_modules/wrappy/LICENSE +15 -0
  511. package/node_modules/wrappy/README.md +36 -0
  512. package/node_modules/wrappy/package.json +29 -0
  513. package/node_modules/wrappy/wrappy.js +33 -0
  514. package/package.json +12 -2
  515. package/templates/default/dot-claude/skills/fling/.hash +1 -1
  516. package/templates/default/dot-claude/skills/fling/SKILL.md +56 -29
  517. package/templates/default/dot-claude/skills/fling/references/WORKFLOWS.md +368 -0
@@ -0,0 +1,506 @@
1
+ # Testing
2
+
3
+ flingflow uses [Vitest](https://vitest.dev/) as its test runner and the [`determined`](https://www.npmjs.com/package/determined) package for deterministic simulation testing.
4
+
5
+ ## Running Tests
6
+
7
+ ```bash
8
+ # Run all tests
9
+ npm test
10
+
11
+ # Run in watch mode
12
+ npm run test:watch
13
+
14
+ # Run a specific test file
15
+ npx vitest run test/engine.test.ts
16
+
17
+ # Run tests matching a pattern
18
+ npx vitest run -t "retries"
19
+ ```
20
+
21
+ ## Test Suite Summary
22
+
23
+ | File | Tests | Category | Description |
24
+ |---|---|---|---|
25
+ | `test/store-memory.test.ts` | 17 | Unit | Conformance tests on `MemoryEventStore` |
26
+ | `test/store-sqlite.test.ts` | 17 | Unit | Conformance tests on `SqliteEventStore` |
27
+ | `test/context.test.ts` | 8 | Unit | Scratchpad loading, buffered writes, overrides |
28
+ | `test/engine.test.ts` | 22 | Unit | Engine state machine: happy path, retries, failures, workflow ID uniqueness |
29
+ | `test/recovery.test.ts` | 10 | Integration | Timeout detection, stuck workflows, recovery + engine |
30
+ | `test/simulation.test.ts` | 8 | Simulation | Concurrent workers, failure injection, multi-seed (both stores) |
31
+ | **Total** | **82** | | |
32
+
33
+ There is also a CLI stress test (`src/stress.ts`) that runs outside of Vitest. See [Stress Test (CLI)](#stress-test-cli) below.
34
+
35
+ ## Test Architecture
36
+
37
+ ### Three Tiers
38
+
39
+ 1. **Unit tests** — Single-component, `MemoryEventStore`, `ManualClock`, deterministic IDs. No concurrency.
40
+ 2. **Integration tests** — Multiple components wired together (engine + store + recovery). Still single-threaded, but tests cross-component interactions.
41
+ 3. **Simulation tests** — Multiple concurrent tasks via `determined`'s `SimulationImpl`. Tests interleaving, race conditions, and crash recovery.
42
+
43
+ ### Shared Infrastructure
44
+
45
+ All unit and integration tests use the same setup pattern:
46
+
47
+ ```typescript
48
+ let store: EventStore;
49
+ let registry: WorkflowRegistry;
50
+ let clock: ManualClock;
51
+
52
+ beforeEach(async () => {
53
+ store = new MemoryEventStore();
54
+ (await store.initialize())._unsafeUnwrap();
55
+ registry = new WorkflowRegistry();
56
+ clock = new ManualClock(1000); // deterministic starting time
57
+ engine = new Engine({
58
+ store,
59
+ registry,
60
+ clock,
61
+ generateId: () => `run-${++idCounter}`, // deterministic run IDs
62
+ });
63
+ });
64
+ ```
65
+
66
+ This gives every test:
67
+ - A fresh, empty store
68
+ - Deterministic timestamps via `ManualClock`
69
+ - Deterministic run IDs via a counter
70
+
71
+ ---
72
+
73
+ ## Store Conformance Tests
74
+
75
+ **Files:** `test/store-conformance.ts`, `test/store-memory.test.ts`, `test/store-sqlite.test.ts`
76
+
77
+ A parameterized test suite that runs against any `EventStore` implementation. Each implementation file instantiates the suite with a factory function:
78
+
79
+ ```typescript
80
+ // test/store-memory.test.ts
81
+ storeConformanceTests("MemoryEventStore", async () => {
82
+ const store = new MemoryEventStore();
83
+ (await store.initialize())._unsafeUnwrap();
84
+ return store;
85
+ });
86
+ ```
87
+
88
+ ### Tests (17 per implementation, 34 total)
89
+
90
+ | Test | What It Verifies |
91
+ |---|---|
92
+ | `append + getLastEvent round-trip` | Basic write-then-read returns the same event |
93
+ | `getLastEvent returns null for unknown run` | Querying a non-existent run returns `null` |
94
+ | `getLastEvent returns highest seq` | With multiple events, returns the one with the highest sequence number |
95
+ | `returns UniqueConstraintError on duplicate (run_id, seq)` | Inserting the same `(run_id, seq)` twice returns `UniqueConstraintError` |
96
+ | `appendBatch inserts multiple events atomically` | Multiple events inserted in one call are all readable |
97
+ | `appendBatch is atomic — no partial inserts on duplicate` | If any event in a batch conflicts, the entire batch is rolled back. Events that were valid are **not** persisted. |
98
+ | `getEvent returns specific event` | Retrieve a single event by `(run_id, seq)` |
99
+ | `getEvent returns null for missing seq` | Missing events return `null` |
100
+ | `getCompletedEvents returns step_completed events in seq DESC order` | Only `step_completed` events are returned, newest first |
101
+ | `getAllEvents returns events in seq ASC order` | Full event log in chronological order |
102
+ | `getActiveWorkflows excludes terminal workflows` | Workflows ending in `workflow_completed` or `workflow_failed` are not returned |
103
+ | `JSON round-trips payloads correctly` | Nested objects, arrays, nulls, booleans, and floats survive serialization. Retrieved payload is a deep copy, not a reference. |
104
+ | `isolates events between different runs` | Events from run A are not visible when querying run B |
105
+ | `appendIfNoActiveWorkflow succeeds when no active run` | First creation of a workflow ID succeeds |
106
+ | `appendIfNoActiveWorkflow rejects when active run exists` | Second creation of the same workflow ID while the first is active returns `WorkflowAlreadyActiveError` |
107
+ | `appendIfNoActiveWorkflow allows after terminal event` | After a workflow completes or fails, the same workflow ID can be reused for a new run |
108
+ | `rejects appending event with mismatched workflow_id for existing run_id` | Adding an event with a different `workflow_id` than existing events for the same `run_id` returns `WorkflowIdMismatchError` |
109
+
110
+ ### Why Both Implementations
111
+
112
+ The `MemoryEventStore` serializes/deserializes payloads via JSON on every write/read, matching the behavior of SQLite's text column storage. This ensures:
113
+
114
+ - Serialization bugs are caught in fast, in-memory tests
115
+ - Both stores produce identical behavior (same test suite, same assertions)
116
+ - Tests don't accidentally rely on object identity or non-serializable values (functions, `undefined` as object values, etc.)
117
+
118
+ ---
119
+
120
+ ## Context Tests
121
+
122
+ **File:** `test/context.test.ts`
123
+
124
+ Tests for `buildContext()`, which constructs the `Ctx` object for step execution by loading the scratchpad from persisted `step_completed` events.
125
+
126
+ ### Tests (8)
127
+
128
+ | Test | What It Verifies |
129
+ |---|---|
130
+ | `loads initial writes into scratchpad` | `ctx.get()` returns values from the `workflow_created` event's `writes`, and `ctx.workflowId`, `ctx.runId`, and `ctx.step` are set from the arguments passed to `buildContext` |
131
+ | `reads scratchpad from step_completed events` | Values written by previous steps via `ctx.set()` are available via `ctx.get()` in subsequent steps |
132
+ | `later writes override earlier ones` | When multiple steps write the same key, the most recent value wins (newest-first scan, first match) |
133
+ | `returns undefined for missing keys` | `ctx.get("nonexistent")` returns `undefined` |
134
+ | `buffers writes without persisting` | `ctx.set()` calls are buffered in memory. The store remains empty. `getPendingWrites()` returns the buffered state. |
135
+ | `pending writes are readable via get` | A value set with `ctx.set()` in the current step is immediately readable via `ctx.get()` without a store round-trip |
136
+ | `pending writes override scratchpad values` | If a key exists in the persisted scratchpad and is also set via `ctx.set()`, the pending write takes priority |
137
+ | `empty scratchpad when no step_completed events exist` | On the first step of a workflow, all `ctx.get()` calls return `undefined` |
138
+
139
+ ---
140
+
141
+ ## Engine Tests
142
+
143
+ **File:** `test/engine.test.ts`
144
+
145
+ Tests for the `Engine` class using `MemoryEventStore` and `ManualClock`.
146
+
147
+ ### Test Fixtures (`test/fixtures.ts`)
148
+
149
+ Reusable workflow definitions:
150
+
151
+ | Fixture | Behavior |
152
+ |---|---|
153
+ | `singleStepWorkflow` | Completes in one step. Returns `{ done: true, result: { value: "processed-{input}" } }`. |
154
+ | `multiStepWorkflow` | Three steps (`start` → `process` → `finish`) that use the scratchpad to pass data. Counts input items, doubles the count. |
155
+ | `failingWorkflow` | Always throws `Error("transient failure")`. Used to test max-attempts exhaustion. |
156
+ | `failOnceWorkflow` | Throws on first invocation per run ID, succeeds on retry. Uses an in-memory counter keyed by `runId`. Call `resetFailOnceCounter()` in `beforeEach`. |
157
+ | `nonRetryableWorkflow` | Throws `NonRetryableError("invalid input")`. Tests non-retryable failure path. |
158
+
159
+ ### Tests (22)
160
+
161
+ #### `createWorkflow` (2)
162
+
163
+ | Test | What It Verifies |
164
+ |---|---|
165
+ | `creates a workflow_created event` | Inserts a single event at `seq=0` with correct `event_type`, `payload`, and `created_at` |
166
+ | `rejects unknown workflow names` | Returns `UnknownWorkflowError` if the name isn't in the registry |
167
+
168
+ #### `claimStep` (4)
169
+
170
+ | Test | What It Verifies |
171
+ |---|---|
172
+ | `claims the first step after workflow_created` | Returns a `ClaimResult` with `step: "start"`, `attempt: 1`, and correct `workflowName` |
173
+ | `returns null for non-existent workflow` | No crash, just `null` |
174
+ | `returns null when step is already in progress` | After one successful claim, a second claim returns `null` (the `step_started` event is the last event, and `resolveTransition` returns `action: "none"`) |
175
+ | `transitions to workflow_failed on non-retryable step_failed` | After executing a non-retryable workflow, calling `claimStep` emits `workflow_failed` and returns `null` |
176
+
177
+ #### `executeStep` (2)
178
+
179
+ | Test | What It Verifies |
180
+ |---|---|
181
+ | `single-step happy path` | Creates event trace: `workflow_created → step_started → step_completed → workflow_completed`. Result payload is correct. |
182
+ | `returns false when nothing to execute` | On an already-completed workflow, returns `false` |
183
+
184
+ #### `runToCompletion` (1)
185
+
186
+ | Test | What It Verifies |
187
+ |---|---|
188
+ | `multi-step workflow with scratchpad` | Drives a 3-step workflow to completion. Verifies the full 8-event trace and that scratchpad values are passed correctly between steps (input items counted → doubled → returned as result). |
189
+
190
+ #### `retries` (3)
191
+
192
+ | Test | What It Verifies |
193
+ |---|---|
194
+ | `retries on retryable failure` | `failOnceWorkflow` produces: `step_started(attempt=1) → step_failed → step_started(attempt=2) → step_completed → workflow_completed` |
195
+ | `max attempts exceeded → workflow_failed` | `failingWorkflow` (maxAttempts=5) produces 5 start/fail cycles, then `workflow_failed` with reason containing `"max attempts (5) exceeded"` |
196
+ | `non-retryable failure → immediate workflow_failed` | `nonRetryableWorkflow` produces: `step_started → step_failed(retryable=false) → workflow_failed`. Only 1 attempt. |
197
+
198
+ #### `event log validity` (5)
199
+
200
+ Structural invariant checks that run against completed workflows:
201
+
202
+ | Test | What It Verifies |
203
+ |---|---|
204
+ | `all events have ascending seq numbers` | `events[i].seq === i` for all events |
205
+ | `all events have the same run_id` | No cross-run contamination |
206
+ | `all events have the same workflow_id` | No cross-workflow contamination |
207
+ | `created_at values come from the clock` | Timestamps match the `ManualClock` values at the time of creation |
208
+ | `event trace follows valid state machine transitions` | Every consecutive pair of events is a valid transition per the state machine table. Uses a lookup table of `{ from_event_type: [allowed_to_event_types] }`. |
209
+
210
+ #### `workflow ID uniqueness` (5)
211
+
212
+ | Test | What It Verifies |
213
+ |---|---|
214
+ | `rejects duplicate active workflow ID` | Creating a second workflow with the same `workflowId` while the first is active returns `WorkflowAlreadyActiveError` |
215
+ | `allows reuse of workflow ID after completion` | After a workflow completes, the same `workflowId` can be used for a new run |
216
+ | `allows reuse of workflow ID after failure` | After a workflow fails, the same `workflowId` can be reused |
217
+ | `different workflow IDs coexist` | Two workflows with different `workflowId`s can be active simultaneously |
218
+ | `successive runs of same workflow ID get different run IDs` | Each `createWorkflow` call generates a unique `runId` |
219
+
220
+ ---
221
+
222
+ ## Recovery Tests
223
+
224
+ **File:** `test/recovery.test.ts`
225
+
226
+ Tests for `runRecovery()` using manually constructed event histories and `ManualClock`.
227
+
228
+ ### Tests (10)
229
+
230
+ | Test | What It Verifies |
231
+ |---|---|
232
+ | `detects timed-out step_started` | A `step_started` event that's been sitting for >= `stepTimeoutMS` gets a `step_failed(reason: "timeout", retryable: true)` appended. Also verifies that just-under-timeout workflows are **not** recovered. |
233
+ | `detects stuck workflow at workflow_created` | A workflow with only `workflow_created` (no `step_started` ever inserted) is flagged as stuck. |
234
+ | `detects stuck workflow at step_completed with next_step` | A workflow whose last event is `step_completed` with a `next_step` but no subsequent `step_started` is flagged as stuck. |
235
+ | `detects stuck workflow at retryable step_failed` | A workflow whose last event is a retryable `step_failed` (under max attempts) but with no retry `step_started` is flagged as stuck. |
236
+ | `ignores terminal workflows` | Workflows in `workflow_completed` or `workflow_failed` state are not included in the active workflow scan (verified at the `getActiveWorkflows` level). |
237
+ | `ignores non-timed-out in-progress steps` | A `step_started` that hasn't exceeded the timeout is left alone. |
238
+ | `recovery + engine integration` | End-to-end: a worker "dies" (leaves a `step_started` that times out), recovery marks it as `step_failed`, then the engine retries and completes the workflow. |
239
+ | `detects step_completed without next_step as needing workflow_completed` | A workflow whose last event is `step_completed` without `next_step` (meaning it should transition to `workflow_completed`) is flagged as `stuck_terminal`. |
240
+ | `detects non-retryable step_failed as needing workflow_failed` | A workflow whose last event is a non-retryable `step_failed` (should transition to `workflow_failed`) is flagged as `stuck_terminal`. |
241
+ | `detects max-attempts-exhausted step_failed as needing workflow_failed` | A workflow whose last event is a `step_failed` at max attempts (should transition to `workflow_failed`) is flagged as `stuck_terminal`. |
242
+
243
+ ---
244
+
245
+ ## Simulation Tests
246
+
247
+ **File:** `test/simulation.test.ts`
248
+
249
+ Tests using `determined`'s `SimulationImpl` for deterministic simulation testing. These tests run multiple concurrent "worker" tasks that compete to execute workflow steps, with `determined` controlling the interleaving at every checkpoint and failpoint in the engine and stores.
250
+
251
+ The entire test suite is parameterized and runs against both `MemoryEventStore` and `SqliteEventStore` (in-memory), giving 8 tests total (4 per store).
252
+
253
+ ### How It Works
254
+
255
+ 1. A store is created with an `EventStoreCheck` callback that validates the event log on every mutation.
256
+ 2. An `Engine` is wired to the store.
257
+ 3. A `SimulationImpl` is instantiated with a logger, entropy source, and failure probability.
258
+ 4. Multiple `TaskSpec`s are defined — each runs a loop calling `engine.executeStep(runId, task)` where `task` is the `SimulationTask` provided by `determined`.
259
+ 5. `sim.runTasks(specs)` runs all tasks concurrently with controlled interleaving.
260
+ 6. After completion, the event log is validated for structural correctness.
261
+
262
+ ### Validation Function
263
+
264
+ `validateEventTrace(events)` checks three invariants on a completed workflow's event log:
265
+
266
+ 1. **Ascending sequence numbers**: `events[i].seq === i` for all `i`
267
+ 2. **Valid state machine transitions**: every consecutive pair `(events[i], events[i+1])` is a legal transition per the state machine table
268
+ 3. **Terminal state**: the last event is `workflow_completed` or `workflow_failed`
269
+
270
+ ### Event-Log Check Callback
271
+
272
+ Both store implementations are constructed with an `EventStoreCheck` callback (`makeCheck()`) that runs after every `append` and `appendBatch`. On every single store mutation, it verifies:
273
+
274
+ 1. Contiguous sequence numbers (`seq = 0, 1, 2, ...`)
275
+ 2. First event is `workflow_created`
276
+ 3. Every consecutive pair is a valid state machine transition
277
+ 4. At most one terminal event (`workflow_completed` or `workflow_failed`)
278
+
279
+ This catches corruption the moment it occurs, rather than only at the end of the test.
280
+
281
+ ### Tests (4 per store, 8 total)
282
+
283
+ #### `concurrent workers: exactly one claims each step`
284
+
285
+ - 3 workers race to execute steps on a single `counter` workflow (loops 4 times via scratchpad).
286
+ - No failure injection (`failureProbability: 0`).
287
+ - Verifies the event trace is valid and the workflow completes with `{ finalCount: 3 }`.
288
+ - The core concurrency guarantee: despite interleaving, exactly one worker wins each step claim.
289
+
290
+ #### `concurrent workers across multiple seeds`
291
+
292
+ - Runs 100 iterations with different entropy seeds.
293
+ - 2 workers per iteration, racing on a single-step `simple` workflow.
294
+ - Each iteration gets a fresh store, registry, engine.
295
+ - Validates the event trace for every seed.
296
+ - Ensures correctness is not dependent on a lucky interleaving schedule.
297
+
298
+ #### `failure injection with recovery`
299
+
300
+ - 2 workers + 1 recovery task, all concurrent.
301
+ - `failureProbability: 0.3` — 30% chance that each `sim.failpoint()` call throws, simulating a crash.
302
+ - Workers catch failpoint exceptions and keep retrying.
303
+ - The recovery task periodically advances the `ManualClock` past the step timeout and runs `runRecovery()` to unstick timed-out workflows.
304
+ - Validates the event log's structural integrity (ascending seq, valid transitions) regardless of the simulation outcome.
305
+ - This test exercises the most adversarial conditions: concurrent access + arbitrary crash timing + recovery racing normal workers.
306
+
307
+ #### `appendBatch atomicity under concurrency`
308
+
309
+ - 3 workers race on a single-step `simple` workflow.
310
+ - The final step uses `appendBatch` to write both `step_completed` and `workflow_completed` atomically.
311
+ - Validates the event trace and asserts exactly 1 terminal event exists.
312
+ - Ensures `appendBatch` doesn't produce partial writes even under concurrent access.
313
+
314
+ ---
315
+
316
+ ## Stress Test (CLI)
317
+
318
+ **File:** `src/stress.ts`
319
+
320
+ A configurable CLI stress test that runs a non-trivial multi-step workflow under simulation with concurrent workers, failure injection, and recovery. Unlike the Vitest simulation tests (which are fast, focused, and run in CI), the stress test is designed for manual exploration — crank up the parameters and shake out concurrency bugs.
321
+
322
+ ### Running
323
+
324
+ ```bash
325
+ # Defaults: count=10, memory store, 4 workers, 50 seeds, 10% failure, 5 max attempts
326
+ npm run stress
327
+
328
+ # All options
329
+ npm run stress -- --count 20 --store sqlite --workers 8 --seeds 100 --failure 0.2 --max-attempts 10
330
+ ```
331
+
332
+ | Flag | Default | Description |
333
+ |---|---|---|
334
+ | `--count N` | `10` | Number of items to process (controls workflow length) |
335
+ | `--store TYPE` | `memory` | Store backend: `memory` or `sqlite` (both use in-memory databases) |
336
+ | `--workers N` | `4` | Number of concurrent worker tasks in the simulation |
337
+ | `--seeds N` | `50` | Number of simulation seeds to run (each seed = one full workflow) |
338
+ | `--failure P` | `0.1` | Failpoint failure probability (0-1) |
339
+ | `--max-attempts N` | `5` | Max step attempts before workflow fails |
340
+
341
+ Exit code is 0 if all seeds pass, 1 if any fail.
342
+
343
+ ### SimKV: In-Memory Key-Value Store
344
+
345
+ The stress test uses a `SimKV` class — a simple `Map<string, unknown>` with failpoints before and after every `get` and `set` operation. The workflow function accesses the simulation task via `ctx.sim`, which `buildContext` sets from the engine's `sim` parameter.
346
+
347
+ ```typescript
348
+ class SimKV {
349
+ async get(key: string, sim: SimulationTask): Promise<unknown>;
350
+ async set(key: string, value: unknown, sim: SimulationTask): Promise<void>;
351
+ }
352
+ ```
353
+
354
+ Each method has two failpoints (`kv.get:before`/`kv.get:after`, `kv.set:before`/`kv.set:after`). Since these failpoints run inside the workflow function's try/catch in `executeStep`, a thrown failpoint is recorded as a retryable `step_failed` and the step is retried. The kv operations are idempotent (same input always produces the same value), so retries are safe.
355
+
356
+ ### Workflow: Sum of Squares
357
+
358
+ Given `count = N`, the workflow computes `1² + 2² + ... + N²` across `2N + 1` steps:
359
+
360
+ | Steps | Phase | What each step does |
361
+ |---|---|---|
362
+ | `start`, `set-2` .. `set-N` | Set | Store `kv[i] = i²` in the external SimKV |
363
+ | `sum-init` | Init | Set scratchpad `sum = 0` |
364
+ | `add-1` .. `add-N` | Add | Read `kv[i]`, add to scratchpad `sum` |
365
+
366
+ The final step returns `{ sum }`. The expected result is `N(N+1)(2N+1)/6`.
367
+
368
+ This workflow exercises both the scratchpad (passing `sum` between steps) and an external service with its own failpoints (SimKV). Each step is small and deterministic, making the expected result easy to verify.
369
+
370
+ ### Simulation Structure
371
+
372
+ Each seed creates a fresh store, kv, engine, and `ManualClock`, then runs a `SimulationImpl` with:
373
+
374
+ - **N worker tasks** — each loops calling `engine.executeStep(runId, task)`, catching failpoint errors and retrying. Workers break out of their loop when the workflow reaches a terminal state.
375
+ - **1 recovery task** — loops calling `clock.advance(stepTimeoutMS + 1000)` followed by `runRecovery()`. This advances time past the step timeout so that stuck `step_started` events (from workers that "crashed" at a failpoint) are detected, marked as `step_failed(reason: "timeout")`, and retried.
376
+
377
+ All tasks run concurrently via `determined`'s cooperative scheduler, which interleaves them at every checkpoint and failpoint.
378
+
379
+ ### Iteration Budget
380
+
381
+ With store-level failpoints, there are approximately 16 failpoints per step execution attempt (store reads/writes in `claimStep`, `buildContext`, `commitStep`, plus kv failpoints in the workflow function, plus engine-level failpoints). The probability that a single attempt succeeds end-to-end is `(1 - failureProbability)^16`.
382
+
383
+ The iteration budget per worker scales automatically:
384
+
385
+ ```
386
+ attemptsPerStep = ceil(1 / (1 - failureProbability)^16)
387
+ iterationsPerWorker = max(1000, totalSteps * attemptsPerStep * 5)
388
+ ```
389
+
390
+ This ensures the workflow completes even at higher failure rates. Examples:
391
+
392
+ | `--failure` | Attempts/step | Iterations/worker (count=10) |
393
+ |---|---|---|
394
+ | 0.05 | 3 | 1000 (floor) |
395
+ | 0.1 | 6 | 1000 (floor) |
396
+ | 0.2 | 36 | 3,780 |
397
+ | 0.3 | 170 | 17,850 |
398
+
399
+ ### Consistency Check
400
+
401
+ Every store is constructed with an `EventStoreCheck` callback (same as the simulation tests) that validates the event log on every mutation — contiguous seq numbers, valid transitions, at most one terminal event. This catches corruption at the point it occurs.
402
+
403
+ ### Verification
404
+
405
+ After each seed's simulation completes, the test:
406
+
407
+ 1. Reads the full event log and validates the trace structure (contiguous seq, valid transitions)
408
+ 2. Asserts the last event is `workflow_completed`
409
+ 3. Compares the result payload's `sum` against `N(N+1)(2N+1)/6`
410
+
411
+ A seed passes only if all three checks succeed.
412
+
413
+ ### Seeded Entropy
414
+
415
+ Each seed uses a deterministic LCG-based entropy source seeded by the seed number. This makes failures reproducible — if seed 42 fails, running with `--seeds 43` will reproduce it.
416
+
417
+ ---
418
+
419
+ ## Failpoint Coverage
420
+
421
+ Failpoints are placed at every I/O boundary across the engine, stores, and external services. They serve two purposes: (1) yield points for `determined`'s cooperative scheduler to interleave concurrent tasks, and (2) failure injection points where `determined` can throw to simulate process crashes.
422
+
423
+ ### Store Failpoints
424
+
425
+ Every `EventStore` method (except `initialize`) has failpoints before and after the actual operation. Both `MemoryEventStore` and `SqliteEventStore` share the same failpoint labels:
426
+
427
+ | Method | Failpoints |
428
+ |---|---|
429
+ | `append` | `store.append:before`, `store.append:after` |
430
+ | `appendBatch` | `store.appendBatch:before`, `store.appendBatch:after` |
431
+ | `appendIfNoActiveWorkflow` | `store.appendIfNoActiveWorkflow:before`, `store.appendIfNoActiveWorkflow:after` |
432
+ | `getLastEvent` | `store.getLastEvent:before`, `store.getLastEvent:after` |
433
+ | `getEvent` | `store.getEvent:before`, `store.getEvent:after` |
434
+ | `getCompletedEvents` | `store.getCompletedEvents:before`, `store.getCompletedEvents:after` |
435
+ | `getAllEvents` | `store.getAllEvents:before`, `store.getAllEvents:after` |
436
+ | `getActiveWorkflows` | `store.getActiveWorkflows:before`, `store.getActiveWorkflows:after` |
437
+
438
+ Store failpoints propagate out of the engine (they are not caught as step failures). A store failpoint throwing simulates a process crash mid-I/O — recovery handles the aftermath.
439
+
440
+ ### Engine Failpoints and Checkpoints
441
+
442
+ | Location | Type | Label |
443
+ |---|---|---|
444
+ | `createWorkflow` | checkpoint | `createWorkflow:before-append`, `createWorkflow:after-append` |
445
+ | `claimStep` | checkpoint | `claimStep:after-getLastEvent`, `claimStep:after-append` |
446
+ | `executeStep` | failpoint | `executeStep:before-fn`, `executeStep:after-fn` |
447
+ | `commitStep` | failpoint | `commitStep:before-append` |
448
+
449
+ Checkpoints yield control but don't throw. Failpoints can throw. The `executeStep` method only catches errors from the workflow function body — failpoints around the function call and commit propagate as crashes.
450
+
451
+ ### Recovery Checkpoints
452
+
453
+ | Location | Type | Label |
454
+ |---|---|---|
455
+ | `runRecovery` | checkpoint | `recovery:before-getActiveWorkflows`, `recovery:per-workflow` |
456
+
457
+ ### External Service Failpoints (Stress Test)
458
+
459
+ The stress test's `SimKV` key-value store adds failpoints inside the workflow function:
460
+
461
+ | Method | Failpoints |
462
+ |---|---|
463
+ | `kv.get` | `kv.get:before`, `kv.get:after` |
464
+ | `kv.set` | `kv.set:before`, `kv.set:after` |
465
+
466
+ Since these execute inside `def.fn(ctx)`, thrown failpoints are caught by the engine and recorded as retryable `step_failed` events.
467
+
468
+ ---
469
+
470
+ ## Invariants Verified Across All Tests
471
+
472
+ These invariants hold across unit, integration, simulation, and stress tests:
473
+
474
+ 1. **Sequential seq numbers**: Every workflow's events have `seq = 0, 1, 2, ...` with no gaps or duplicates.
475
+ 2. **Valid state machine**: Every consecutive event pair is a legal transition per the state machine in SPEC.md.
476
+ 3. **Exactly-once step execution**: At most one worker succeeds at claiming any given step (enforced by `UniqueConstraintError` on `(run_id, seq)`).
477
+ 4. **Atomic batch writes**: `appendBatch` either writes all events or none. No partial inserts.
478
+ 5. **Scratchpad consistency**: Later writes to the same key override earlier writes. Failed steps discard their buffered writes.
479
+ 6. **Terminal state correctness**: Completed workflows end with exactly one `workflow_completed` or `workflow_failed` event.
480
+ 7. **Clock-driven timestamps**: All `created_at` values come from the injected `Clock`, not from system time or SQLite defaults.
481
+ 8. **JSON serialization round-trip**: Both store implementations serialize payloads through JSON, ensuring no non-serializable data slips through.
482
+ 9. **Continuous consistency** (simulation and stress tests): The `EventStoreCheck` callback validates the event log after every single store mutation, not just at the end of the test. Corruption is caught at the point of introduction.
483
+ 10. **Workflow ID uniqueness**: Only one active run per workflow ID at a time, enforced atomically by `appendIfNoActiveWorkflow`.
484
+
485
+ ---
486
+
487
+ ## Adding a New EventStore Implementation
488
+
489
+ To add a new store backend:
490
+
491
+ 1. Implement the `EventStore` interface.
492
+ 2. Create a test file that calls the conformance suite:
493
+
494
+ ```typescript
495
+ // test/store-mybackend.test.ts
496
+ import { storeConformanceTests } from "./store-conformance.js";
497
+ import { MyBackendEventStore } from "../src/store-mybackend.js";
498
+
499
+ storeConformanceTests("MyBackendEventStore", async () => {
500
+ const store = new MyBackendEventStore(/* ... */);
501
+ (await store.initialize())._unsafeUnwrap();
502
+ return store;
503
+ });
504
+ ```
505
+
506
+ The conformance tests will verify your implementation handles all edge cases correctly.
@@ -0,0 +1,9 @@
1
+ import type { WorkflowConfig } from "./types.js";
2
+ /**
3
+ * Calculate the backoff delay for a given attempt number.
4
+ *
5
+ * Attempt 1 has no delay (first try).
6
+ * Attempt 2 has `initialBackoffMS` delay.
7
+ * Attempt N has `min(initialBackoffMS * backoffMultiplier^(N-2), maxBackoffMS)`.
8
+ */
9
+ export declare function calculateBackoffMS(config: WorkflowConfig, attempt: number): number;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Calculate the backoff delay for a given attempt number.
3
+ *
4
+ * Attempt 1 has no delay (first try).
5
+ * Attempt 2 has `initialBackoffMS` delay.
6
+ * Attempt N has `min(initialBackoffMS * backoffMultiplier^(N-2), maxBackoffMS)`.
7
+ */
8
+ export function calculateBackoffMS(config, attempt) {
9
+ if (attempt <= 1)
10
+ return 0;
11
+ const raw = config.initialBackoffMS * Math.pow(config.backoffMultiplier, attempt - 2);
12
+ return Math.min(raw, config.maxBackoffMS);
13
+ }
14
+ //# sourceMappingURL=backoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backoff.js","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAE,OAAe;IACxE,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;IACtF,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface Clock {
2
+ now(): number;
3
+ }
4
+ export declare class SystemClock implements Clock {
5
+ now(): number;
6
+ }
7
+ export declare class ManualClock implements Clock {
8
+ private _now;
9
+ constructor(initial: number);
10
+ now(): number;
11
+ advance(ms: number): void;
12
+ set(ms: number): void;
13
+ }
@@ -0,0 +1,21 @@
1
+ export class SystemClock {
2
+ now() {
3
+ return Date.now();
4
+ }
5
+ }
6
+ export class ManualClock {
7
+ _now;
8
+ constructor(initial) {
9
+ this._now = initial;
10
+ }
11
+ now() {
12
+ return this._now;
13
+ }
14
+ advance(ms) {
15
+ this._now += ms;
16
+ }
17
+ set(ms) {
18
+ this._now = ms;
19
+ }
20
+ }
21
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,WAAW;IACtB,GAAG;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IACpB,CAAC;CACF;AAED,MAAM,OAAO,WAAW;IACd,IAAI,CAAS;IAErB,YAAY,OAAe;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;IACtB,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import { type Result } from "neverthrow";
2
+ import type { SimulationTask } from "determined";
3
+ import type { EventStore } from "./store.js";
4
+ import type { Ctx } from "./types.js";
5
+ export declare function buildContext(store: EventStore, runId: string, workflowId: string, step: string, initialWrites: Record<string, unknown>, sim: SimulationTask): Promise<Result<{
6
+ ctx: Ctx;
7
+ getPendingWrites: () => Record<string, unknown>;
8
+ }, Error>>;
@@ -0,0 +1,45 @@
1
+ import { ok, err } from "neverthrow";
2
+ export async function buildContext(store, runId, workflowId, step, initialWrites, sim) {
3
+ // Load scratchpad from step_completed events (newest first, first match wins)
4
+ const completedResult = await store.getCompletedEvents(runId, sim);
5
+ if (completedResult.isErr())
6
+ return err(completedResult.error);
7
+ const completedEvents = completedResult.value;
8
+ const scratchpad = new Map();
9
+ for (const event of completedEvents) {
10
+ const payload = event.payload;
11
+ for (const [key, value] of Object.entries(payload.writes)) {
12
+ if (!scratchpad.has(key)) {
13
+ scratchpad.set(key, value);
14
+ }
15
+ }
16
+ }
17
+ // Apply initial writes (lowest priority — step writes take precedence)
18
+ for (const [key, value] of Object.entries(initialWrites)) {
19
+ if (!scratchpad.has(key)) {
20
+ scratchpad.set(key, value);
21
+ }
22
+ }
23
+ const pendingWrites = {};
24
+ const ctx = {
25
+ workflowId,
26
+ runId,
27
+ step,
28
+ sim,
29
+ get(key) {
30
+ // Pending writes take priority
31
+ if (key in pendingWrites) {
32
+ return Promise.resolve(pendingWrites[key]);
33
+ }
34
+ return Promise.resolve(scratchpad.get(key));
35
+ },
36
+ set(key, value) {
37
+ pendingWrites[key] = value;
38
+ },
39
+ };
40
+ return ok({
41
+ ctx,
42
+ getPendingWrites: () => ({ ...pendingWrites }),
43
+ });
44
+ }
45
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAe,MAAM,YAAY,CAAC;AAKlD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,KAAa,EACb,UAAkB,EAClB,IAAY,EACZ,aAAsC,EACtC,GAAmB;IAEnB,8EAA8E;IAC9E,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnE,IAAI,eAAe,CAAC,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC;IAE9C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE9C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,KAAK,CAAC,OAA+B,CAAC;QACtD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAA4B,EAAE,CAAC;IAElD,MAAM,GAAG,GAAQ;QACf,UAAU;QACV,KAAK;QACL,IAAI;QACJ,GAAG;QACH,GAAG,CAAC,GAAW;YACb,+BAA+B;YAC/B,IAAI,GAAG,IAAI,aAAa,EAAE,CAAC;gBACzB,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,GAAG,CAAC,GAAW,EAAE,KAAc;YAC7B,aAAa,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC7B,CAAC;KACF,CAAC;IAEF,OAAO,EAAE,CAAC;QACR,GAAG;QACH,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE,CAAC;KAC/C,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type Result } from "neverthrow";
2
+ import { type SimulationTask } from "determined";
3
+ import { type WorkflowAlreadyActiveError, type EventStore } from "./store.js";
4
+ import { type Clock } from "./clock.js";
5
+ import type { WorkflowRegistry } from "./registry.js";
6
+ import type { ClaimResult, StepOutcome } from "./types.js";
7
+ export declare class UnknownWorkflowError extends Error {
8
+ constructor(name: string);
9
+ }
10
+ export type CreateWorkflowError = WorkflowAlreadyActiveError | UnknownWorkflowError | Error;
11
+ export interface EngineConfig {
12
+ store: EventStore;
13
+ registry: WorkflowRegistry;
14
+ clock?: Clock;
15
+ generateId?: () => string;
16
+ }
17
+ export declare class Engine {
18
+ private store;
19
+ private registry;
20
+ private clock;
21
+ private generateId;
22
+ constructor(config: EngineConfig);
23
+ initialize(): Promise<Result<void, Error>>;
24
+ createWorkflow(workflowId: string, name: string, writes: Record<string, unknown>, sim: SimulationTask): Promise<Result<string, CreateWorkflowError>>;
25
+ claimStep(runId: string, sim: SimulationTask): Promise<Result<ClaimResult | null, Error>>;
26
+ executeStep(runId: string, sim: SimulationTask): Promise<Result<StepOutcome, Error>>;
27
+ private commitStep;
28
+ runToCompletion(runId: string, sim: SimulationTask): Promise<Result<void, Error>>;
29
+ }