@smthrs/flow 0.0.0-stage → 1.0.0-rc.12

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 (654) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/LICENSE +21 -0
  3. package/README.md +212 -2
  4. package/THIRD_PARTY_NOTICES.md +52 -0
  5. package/dist/cjs/Action/Action.d.ts +250 -0
  6. package/dist/cjs/Action/Action.d.ts.map +1 -0
  7. package/dist/cjs/Action/Action.js +42 -0
  8. package/dist/cjs/Action/Action.js.map +7 -0
  9. package/dist/cjs/Action/AttemptTimedOut.d.ts +33 -0
  10. package/dist/cjs/Action/AttemptTimedOut.d.ts.map +1 -0
  11. package/dist/cjs/Action/AttemptTimedOut.js +51 -0
  12. package/dist/cjs/Action/AttemptTimedOut.js.map +7 -0
  13. package/dist/cjs/Action/BoundaryMode.d.ts +29 -0
  14. package/dist/cjs/Action/BoundaryMode.d.ts.map +1 -0
  15. package/dist/cjs/Action/BoundaryMode.js +36 -0
  16. package/dist/cjs/Action/BoundaryMode.js.map +7 -0
  17. package/dist/cjs/Action/CacheEnvironment.d.ts +158 -0
  18. package/dist/cjs/Action/CacheEnvironment.d.ts.map +1 -0
  19. package/dist/cjs/Action/CacheEnvironment.js +57 -0
  20. package/dist/cjs/Action/CacheEnvironment.js.map +7 -0
  21. package/dist/cjs/Action/ConcurrentKeylessDispatch.d.ts +34 -0
  22. package/dist/cjs/Action/ConcurrentKeylessDispatch.d.ts.map +1 -0
  23. package/dist/cjs/Action/ConcurrentKeylessDispatch.js +46 -0
  24. package/dist/cjs/Action/ConcurrentKeylessDispatch.js.map +7 -0
  25. package/dist/cjs/Action/Context.d.ts +131 -0
  26. package/dist/cjs/Action/Context.d.ts.map +1 -0
  27. package/dist/cjs/Action/Context.js +68 -0
  28. package/dist/cjs/Action/Context.js.map +7 -0
  29. package/dist/cjs/Action/DuplicateImplementation.d.ts +20 -0
  30. package/dist/cjs/Action/DuplicateImplementation.d.ts.map +1 -0
  31. package/dist/cjs/Action/DuplicateImplementation.js +46 -0
  32. package/dist/cjs/Action/DuplicateImplementation.js.map +7 -0
  33. package/dist/cjs/Action/FileBoundary.d.ts +59 -0
  34. package/dist/cjs/Action/FileBoundary.d.ts.map +1 -0
  35. package/dist/cjs/Action/FileBoundary.js +81 -0
  36. package/dist/cjs/Action/FileBoundary.js.map +7 -0
  37. package/dist/cjs/Action/FileInput.d.ts +28 -0
  38. package/dist/cjs/Action/FileInput.d.ts.map +1 -0
  39. package/dist/cjs/Action/FileInput.js +42 -0
  40. package/dist/cjs/Action/FileInput.js.map +7 -0
  41. package/dist/cjs/Action/Filegroup.d.ts +16 -0
  42. package/dist/cjs/Action/Filegroup.d.ts.map +1 -0
  43. package/dist/cjs/Action/Filegroup.js +27 -0
  44. package/dist/cjs/Action/Filegroup.js.map +7 -0
  45. package/dist/cjs/Action/Glob.d.ts +8 -0
  46. package/dist/cjs/Action/Glob.d.ts.map +1 -0
  47. package/dist/cjs/Action/Glob.js +28 -0
  48. package/dist/cjs/Action/Glob.js.map +7 -0
  49. package/dist/cjs/Action/ImplementationVersionMismatch.d.ts +26 -0
  50. package/dist/cjs/Action/ImplementationVersionMismatch.d.ts.map +1 -0
  51. package/dist/cjs/Action/ImplementationVersionMismatch.js +45 -0
  52. package/dist/cjs/Action/ImplementationVersionMismatch.js.map +7 -0
  53. package/dist/cjs/Action/Implementations.d.ts +114 -0
  54. package/dist/cjs/Action/Implementations.d.ts.map +1 -0
  55. package/dist/cjs/Action/Implementations.js +65 -0
  56. package/dist/cjs/Action/Implementations.js.map +7 -0
  57. package/dist/cjs/Action/InfraInterrupt.d.ts +26 -0
  58. package/dist/cjs/Action/InfraInterrupt.d.ts.map +1 -0
  59. package/dist/cjs/Action/InfraInterrupt.js +46 -0
  60. package/dist/cjs/Action/InfraInterrupt.js.map +7 -0
  61. package/dist/cjs/Action/InfraInterruptRetriesExhausted.d.ts +33 -0
  62. package/dist/cjs/Action/InfraInterruptRetriesExhausted.d.ts.map +1 -0
  63. package/dist/cjs/Action/InfraInterruptRetriesExhausted.js +54 -0
  64. package/dist/cjs/Action/InfraInterruptRetriesExhausted.js.map +7 -0
  65. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts +26 -0
  66. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts.map +1 -0
  67. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.js +47 -0
  68. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.js.map +7 -0
  69. package/dist/cjs/Action/StepIdentity.d.ts +153 -0
  70. package/dist/cjs/Action/StepIdentity.d.ts.map +1 -0
  71. package/dist/cjs/Action/StepIdentity.js +75 -0
  72. package/dist/cjs/Action/StepIdentity.js.map +7 -0
  73. package/dist/cjs/Action/TreeArtifact.d.ts +8 -0
  74. package/dist/cjs/Action/TreeArtifact.d.ts.map +1 -0
  75. package/dist/cjs/Action/TreeArtifact.js +25 -0
  76. package/dist/cjs/Action/TreeArtifact.js.map +7 -0
  77. package/dist/cjs/Action/TypeId.d.ts +8 -0
  78. package/dist/cjs/Action/TypeId.d.ts.map +1 -0
  79. package/dist/cjs/Action/TypeId.js +25 -0
  80. package/dist/cjs/Action/TypeId.js.map +7 -0
  81. package/dist/cjs/Action/UncanonicalIdempotencyKey.d.ts +32 -0
  82. package/dist/cjs/Action/UncanonicalIdempotencyKey.d.ts.map +1 -0
  83. package/dist/cjs/Action/UncanonicalIdempotencyKey.js +51 -0
  84. package/dist/cjs/Action/UncanonicalIdempotencyKey.js.map +7 -0
  85. package/dist/cjs/Action/idempotencyKey.d.ts +21 -0
  86. package/dist/cjs/Action/idempotencyKey.d.ts.map +1 -0
  87. package/dist/cjs/Action/idempotencyKey.js +59 -0
  88. package/dist/cjs/Action/idempotencyKey.js.map +7 -0
  89. package/dist/cjs/Action/index.d.ts +29 -0
  90. package/dist/cjs/Action/index.d.ts.map +1 -0
  91. package/dist/cjs/Action/index.js +60 -0
  92. package/dist/cjs/Action/index.js.map +7 -0
  93. package/dist/cjs/Action/make.d.ts +128 -0
  94. package/dist/cjs/Action/make.d.ts.map +1 -0
  95. package/dist/cjs/Action/make.js +387 -0
  96. package/dist/cjs/Action/make.js.map +7 -0
  97. package/dist/cjs/Action/raceAll.d.ts +21 -0
  98. package/dist/cjs/Action/raceAll.d.ts.map +1 -0
  99. package/dist/cjs/Action/raceAll.js +46 -0
  100. package/dist/cjs/Action/raceAll.js.map +7 -0
  101. package/dist/cjs/Action/retry.d.ts +19 -0
  102. package/dist/cjs/Action/retry.d.ts.map +1 -0
  103. package/dist/cjs/Action/retry.js +75 -0
  104. package/dist/cjs/Action/retry.js.map +7 -0
  105. package/dist/cjs/Deadline.d.ts +110 -0
  106. package/dist/cjs/Deadline.d.ts.map +1 -0
  107. package/dist/cjs/Deadline.js +112 -0
  108. package/dist/cjs/Deadline.js.map +7 -0
  109. package/dist/cjs/DurableClock.d.ts +60 -0
  110. package/dist/cjs/DurableClock.d.ts.map +1 -0
  111. package/dist/cjs/DurableClock.js +107 -0
  112. package/dist/cjs/DurableClock.js.map +7 -0
  113. package/dist/cjs/DurableDeferred.d.ts +311 -0
  114. package/dist/cjs/DurableDeferred.d.ts.map +1 -0
  115. package/dist/cjs/DurableDeferred.js +322 -0
  116. package/dist/cjs/DurableDeferred.js.map +7 -0
  117. package/dist/cjs/DurableQueue.d.ts +160 -0
  118. package/dist/cjs/DurableQueue.d.ts.map +1 -0
  119. package/dist/cjs/DurableQueue.js +229 -0
  120. package/dist/cjs/DurableQueue.js.map +7 -0
  121. package/dist/cjs/ExternalJob.d.ts +179 -0
  122. package/dist/cjs/ExternalJob.d.ts.map +1 -0
  123. package/dist/cjs/ExternalJob.js +339 -0
  124. package/dist/cjs/ExternalJob.js.map +7 -0
  125. package/dist/cjs/Fault.d.ts +131 -0
  126. package/dist/cjs/Fault.d.ts.map +1 -0
  127. package/dist/cjs/Fault.js +157 -0
  128. package/dist/cjs/Fault.js.map +7 -0
  129. package/dist/cjs/Flow/Annotations.d.ts +245 -0
  130. package/dist/cjs/Flow/Annotations.d.ts.map +1 -0
  131. package/dist/cjs/Flow/Annotations.js +72 -0
  132. package/dist/cjs/Flow/Annotations.js.map +7 -0
  133. package/dist/cjs/Flow/CapabilityCeiling.d.ts +21 -0
  134. package/dist/cjs/Flow/CapabilityCeiling.d.ts.map +1 -0
  135. package/dist/cjs/Flow/CapabilityCeiling.js +49 -0
  136. package/dist/cjs/Flow/CapabilityCeiling.js.map +7 -0
  137. package/dist/cjs/Flow/DeadlineExceeded.d.ts +33 -0
  138. package/dist/cjs/Flow/DeadlineExceeded.d.ts.map +1 -0
  139. package/dist/cjs/Flow/DeadlineExceeded.js +52 -0
  140. package/dist/cjs/Flow/DeadlineExceeded.js.map +7 -0
  141. package/dist/cjs/Flow/ExecutionIdRequired.d.ts +25 -0
  142. package/dist/cjs/Flow/ExecutionIdRequired.d.ts.map +1 -0
  143. package/dist/cjs/Flow/ExecutionIdRequired.js +46 -0
  144. package/dist/cjs/Flow/ExecutionIdRequired.js.map +7 -0
  145. package/dist/cjs/Flow/ExecutionIds.d.ts +80 -0
  146. package/dist/cjs/Flow/ExecutionIds.d.ts.map +1 -0
  147. package/dist/cjs/Flow/ExecutionIds.js +66 -0
  148. package/dist/cjs/Flow/ExecutionIds.js.map +7 -0
  149. package/dist/cjs/Flow/Flow.d.ts +422 -0
  150. package/dist/cjs/Flow/Flow.d.ts.map +1 -0
  151. package/dist/cjs/Flow/Flow.js +17 -0
  152. package/dist/cjs/Flow/Flow.js.map +7 -0
  153. package/dist/cjs/Flow/MaxRoundsExceeded.d.ts +35 -0
  154. package/dist/cjs/Flow/MaxRoundsExceeded.d.ts.map +1 -0
  155. package/dist/cjs/Flow/MaxRoundsExceeded.js +50 -0
  156. package/dist/cjs/Flow/MaxRoundsExceeded.js.map +7 -0
  157. package/dist/cjs/Flow/Outcome.d.ts +162 -0
  158. package/dist/cjs/Flow/Outcome.d.ts.map +1 -0
  159. package/dist/cjs/Flow/Outcome.js +80 -0
  160. package/dist/cjs/Flow/Outcome.js.map +7 -0
  161. package/dist/cjs/Flow/Result.d.ts +186 -0
  162. package/dist/cjs/Flow/Result.d.ts.map +1 -0
  163. package/dist/cjs/Flow/Result.js +159 -0
  164. package/dist/cjs/Flow/Result.js.map +7 -0
  165. package/dist/cjs/Flow/Runtime.d.ts +98 -0
  166. package/dist/cjs/Flow/Runtime.d.ts.map +1 -0
  167. package/dist/cjs/Flow/Runtime.js +186 -0
  168. package/dist/cjs/Flow/Runtime.js.map +7 -0
  169. package/dist/cjs/Flow/TypeId.d.ts +8 -0
  170. package/dist/cjs/Flow/TypeId.d.ts.map +1 -0
  171. package/dist/cjs/Flow/TypeId.js +25 -0
  172. package/dist/cjs/Flow/TypeId.js.map +7 -0
  173. package/dist/cjs/Flow/index.d.ts +17 -0
  174. package/dist/cjs/Flow/index.d.ts.map +1 -0
  175. package/dist/cjs/Flow/index.js +29 -0
  176. package/dist/cjs/Flow/index.js.map +7 -0
  177. package/dist/cjs/Flow/internal.d.ts +34 -0
  178. package/dist/cjs/Flow/internal.d.ts.map +1 -0
  179. package/dist/cjs/Flow/internal.js +187 -0
  180. package/dist/cjs/Flow/internal.js.map +7 -0
  181. package/dist/cjs/Flow/make.d.ts +135 -0
  182. package/dist/cjs/Flow/make.d.ts.map +1 -0
  183. package/dist/cjs/Flow/make.js +107 -0
  184. package/dist/cjs/Flow/make.js.map +7 -0
  185. package/dist/cjs/FlowRuntime/CancelRequestFailed.d.ts +55 -0
  186. package/dist/cjs/FlowRuntime/CancelRequestFailed.d.ts.map +1 -0
  187. package/dist/cjs/FlowRuntime/CancelRequestFailed.js +51 -0
  188. package/dist/cjs/FlowRuntime/CancelRequestFailed.js.map +7 -0
  189. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.d.ts +23 -0
  190. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.d.ts.map +1 -0
  191. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.js +55 -0
  192. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.js.map +7 -0
  193. package/dist/cjs/FlowRuntime/FlowCycleDetected.d.ts +28 -0
  194. package/dist/cjs/FlowRuntime/FlowCycleDetected.d.ts.map +1 -0
  195. package/dist/cjs/FlowRuntime/FlowCycleDetected.js +49 -0
  196. package/dist/cjs/FlowRuntime/FlowCycleDetected.js.map +7 -0
  197. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.d.ts +38 -0
  198. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.d.ts.map +1 -0
  199. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.js +53 -0
  200. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.js.map +7 -0
  201. package/dist/cjs/FlowRuntime/FlowInstance.d.ts +115 -0
  202. package/dist/cjs/FlowRuntime/FlowInstance.d.ts.map +1 -0
  203. package/dist/cjs/FlowRuntime/FlowInstance.js +37 -0
  204. package/dist/cjs/FlowRuntime/FlowInstance.js.map +7 -0
  205. package/dist/cjs/FlowRuntime/FlowRuntime.d.ts +204 -0
  206. package/dist/cjs/FlowRuntime/FlowRuntime.d.ts.map +1 -0
  207. package/dist/cjs/FlowRuntime/FlowRuntime.js +37 -0
  208. package/dist/cjs/FlowRuntime/FlowRuntime.js.map +7 -0
  209. package/dist/cjs/FlowRuntime/NodeRecord.d.ts +177 -0
  210. package/dist/cjs/FlowRuntime/NodeRecord.d.ts.map +1 -0
  211. package/dist/cjs/FlowRuntime/NodeRecord.js +17 -0
  212. package/dist/cjs/FlowRuntime/NodeRecord.js.map +7 -0
  213. package/dist/cjs/FlowRuntime/WaitingAnnotation.d.ts +69 -0
  214. package/dist/cjs/FlowRuntime/WaitingAnnotation.d.ts.map +1 -0
  215. package/dist/cjs/FlowRuntime/WaitingAnnotation.js +53 -0
  216. package/dist/cjs/FlowRuntime/WaitingAnnotation.js.map +7 -0
  217. package/dist/cjs/FlowRuntime/index.d.ts +14 -0
  218. package/dist/cjs/FlowRuntime/index.d.ts.map +1 -0
  219. package/dist/cjs/FlowRuntime/index.js +26 -0
  220. package/dist/cjs/FlowRuntime/index.js.map +7 -0
  221. package/dist/cjs/Graph.d.ts +325 -0
  222. package/dist/cjs/Graph.d.ts.map +1 -0
  223. package/dist/cjs/Graph.js +1020 -0
  224. package/dist/cjs/Graph.js.map +7 -0
  225. package/dist/cjs/HumanTask.d.ts +442 -0
  226. package/dist/cjs/HumanTask.d.ts.map +1 -0
  227. package/dist/cjs/HumanTask.js +413 -0
  228. package/dist/cjs/HumanTask.js.map +7 -0
  229. package/dist/cjs/Interpreter.d.ts +223 -0
  230. package/dist/cjs/Interpreter.d.ts.map +1 -0
  231. package/dist/cjs/Interpreter.js +908 -0
  232. package/dist/cjs/Interpreter.js.map +7 -0
  233. package/dist/cjs/Poll.d.ts +240 -0
  234. package/dist/cjs/Poll.d.ts.map +1 -0
  235. package/dist/cjs/Poll.js +154 -0
  236. package/dist/cjs/Poll.js.map +7 -0
  237. package/dist/cjs/RetryPolicy.d.ts +273 -0
  238. package/dist/cjs/RetryPolicy.d.ts.map +1 -0
  239. package/dist/cjs/RetryPolicy.js +251 -0
  240. package/dist/cjs/RetryPolicy.js.map +7 -0
  241. package/dist/cjs/Sleep.d.ts +98 -0
  242. package/dist/cjs/Sleep.d.ts.map +1 -0
  243. package/dist/cjs/Sleep.js +141 -0
  244. package/dist/cjs/Sleep.js.map +7 -0
  245. package/dist/cjs/Stall.d.ts +173 -0
  246. package/dist/cjs/Stall.d.ts.map +1 -0
  247. package/dist/cjs/Stall.js +92 -0
  248. package/dist/cjs/Stall.js.map +7 -0
  249. package/dist/cjs/WaitFor.d.ts +109 -0
  250. package/dist/cjs/WaitFor.d.ts.map +1 -0
  251. package/dist/cjs/WaitFor.js +117 -0
  252. package/dist/cjs/WaitFor.js.map +7 -0
  253. package/dist/cjs/index.d.ts +107 -0
  254. package/dist/cjs/index.d.ts.map +1 -0
  255. package/dist/cjs/index.js +69 -0
  256. package/dist/cjs/index.js.map +7 -0
  257. package/dist/cjs/internal/BoundedJson.d.ts +48 -0
  258. package/dist/cjs/internal/BoundedJson.d.ts.map +1 -0
  259. package/dist/cjs/internal/BoundedJson.js +96 -0
  260. package/dist/cjs/internal/BoundedJson.js.map +7 -0
  261. package/dist/cjs/internal/DeclarationSite.d.ts +135 -0
  262. package/dist/cjs/internal/DeclarationSite.d.ts.map +1 -0
  263. package/dist/cjs/internal/DeclarationSite.js +89 -0
  264. package/dist/cjs/internal/DeclarationSite.js.map +7 -0
  265. package/dist/cjs/internal/Declarations.d.ts +35 -0
  266. package/dist/cjs/internal/Declarations.d.ts.map +1 -0
  267. package/dist/cjs/internal/Declarations.js +50 -0
  268. package/dist/cjs/internal/Declarations.js.map +7 -0
  269. package/dist/cjs/internal/ExecutionMiddleware.d.ts +21 -0
  270. package/dist/cjs/internal/ExecutionMiddleware.d.ts.map +1 -0
  271. package/dist/cjs/internal/ExecutionMiddleware.js +39 -0
  272. package/dist/cjs/internal/ExecutionMiddleware.js.map +7 -0
  273. package/dist/cjs/internal/JsonSchemaSubset.d.ts +133 -0
  274. package/dist/cjs/internal/JsonSchemaSubset.d.ts.map +1 -0
  275. package/dist/cjs/internal/JsonSchemaSubset.js +229 -0
  276. package/dist/cjs/internal/JsonSchemaSubset.js.map +7 -0
  277. package/dist/cjs/internal/OutcomeMarker.d.ts +18 -0
  278. package/dist/cjs/internal/OutcomeMarker.d.ts.map +1 -0
  279. package/dist/cjs/internal/OutcomeMarker.js +27 -0
  280. package/dist/cjs/internal/OutcomeMarker.js.map +7 -0
  281. package/dist/cjs/package.json +1 -0
  282. package/dist/esm/Action/Action.d.ts +250 -0
  283. package/dist/esm/Action/Action.d.ts.map +1 -0
  284. package/dist/esm/Action/Action.js +30 -0
  285. package/dist/esm/Action/Action.js.map +1 -0
  286. package/dist/esm/Action/AttemptTimedOut.d.ts +33 -0
  287. package/dist/esm/Action/AttemptTimedOut.d.ts.map +1 -0
  288. package/dist/esm/Action/AttemptTimedOut.js +32 -0
  289. package/dist/esm/Action/AttemptTimedOut.js.map +1 -0
  290. package/dist/esm/Action/BoundaryMode.d.ts +29 -0
  291. package/dist/esm/Action/BoundaryMode.d.ts.map +1 -0
  292. package/dist/esm/Action/BoundaryMode.js +23 -0
  293. package/dist/esm/Action/BoundaryMode.js.map +1 -0
  294. package/dist/esm/Action/CacheEnvironment.d.ts +158 -0
  295. package/dist/esm/Action/CacheEnvironment.d.ts.map +1 -0
  296. package/dist/esm/Action/CacheEnvironment.js +130 -0
  297. package/dist/esm/Action/CacheEnvironment.js.map +1 -0
  298. package/dist/esm/Action/ConcurrentKeylessDispatch.d.ts +34 -0
  299. package/dist/esm/Action/ConcurrentKeylessDispatch.d.ts.map +1 -0
  300. package/dist/esm/Action/ConcurrentKeylessDispatch.js +33 -0
  301. package/dist/esm/Action/ConcurrentKeylessDispatch.js.map +1 -0
  302. package/dist/esm/Action/Context.d.ts +131 -0
  303. package/dist/esm/Action/Context.d.ts.map +1 -0
  304. package/dist/esm/Action/Context.js +99 -0
  305. package/dist/esm/Action/Context.js.map +1 -0
  306. package/dist/esm/Action/DuplicateImplementation.d.ts +20 -0
  307. package/dist/esm/Action/DuplicateImplementation.d.ts.map +1 -0
  308. package/dist/esm/Action/DuplicateImplementation.js +20 -0
  309. package/dist/esm/Action/DuplicateImplementation.js.map +1 -0
  310. package/dist/esm/Action/FileBoundary.d.ts +59 -0
  311. package/dist/esm/Action/FileBoundary.d.ts.map +1 -0
  312. package/dist/esm/Action/FileBoundary.js +60 -0
  313. package/dist/esm/Action/FileBoundary.js.map +1 -0
  314. package/dist/esm/Action/FileInput.d.ts +28 -0
  315. package/dist/esm/Action/FileInput.d.ts.map +1 -0
  316. package/dist/esm/Action/FileInput.js +32 -0
  317. package/dist/esm/Action/FileInput.js.map +1 -0
  318. package/dist/esm/Action/Filegroup.d.ts +16 -0
  319. package/dist/esm/Action/Filegroup.d.ts.map +1 -0
  320. package/dist/esm/Action/Filegroup.js +15 -0
  321. package/dist/esm/Action/Filegroup.js.map +1 -0
  322. package/dist/esm/Action/Glob.d.ts +8 -0
  323. package/dist/esm/Action/Glob.d.ts.map +1 -0
  324. package/dist/esm/Action/Glob.js +7 -0
  325. package/dist/esm/Action/Glob.js.map +1 -0
  326. package/dist/esm/Action/ImplementationVersionMismatch.d.ts +26 -0
  327. package/dist/esm/Action/ImplementationVersionMismatch.d.ts.map +1 -0
  328. package/dist/esm/Action/ImplementationVersionMismatch.js +24 -0
  329. package/dist/esm/Action/ImplementationVersionMismatch.js.map +1 -0
  330. package/dist/esm/Action/Implementations.d.ts +114 -0
  331. package/dist/esm/Action/Implementations.d.ts.map +1 -0
  332. package/dist/esm/Action/Implementations.js +94 -0
  333. package/dist/esm/Action/Implementations.js.map +1 -0
  334. package/dist/esm/Action/InfraInterrupt.d.ts +26 -0
  335. package/dist/esm/Action/InfraInterrupt.d.ts.map +1 -0
  336. package/dist/esm/Action/InfraInterrupt.js +25 -0
  337. package/dist/esm/Action/InfraInterrupt.js.map +1 -0
  338. package/dist/esm/Action/InfraInterruptRetriesExhausted.d.ts +33 -0
  339. package/dist/esm/Action/InfraInterruptRetriesExhausted.d.ts.map +1 -0
  340. package/dist/esm/Action/InfraInterruptRetriesExhausted.js +32 -0
  341. package/dist/esm/Action/InfraInterruptRetriesExhausted.js.map +1 -0
  342. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts +26 -0
  343. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts.map +1 -0
  344. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.js +25 -0
  345. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.js.map +1 -0
  346. package/dist/esm/Action/StepIdentity.d.ts +153 -0
  347. package/dist/esm/Action/StepIdentity.d.ts.map +1 -0
  348. package/dist/esm/Action/StepIdentity.js +139 -0
  349. package/dist/esm/Action/StepIdentity.js.map +1 -0
  350. package/dist/esm/Action/TreeArtifact.d.ts +8 -0
  351. package/dist/esm/Action/TreeArtifact.d.ts.map +1 -0
  352. package/dist/esm/Action/TreeArtifact.js +7 -0
  353. package/dist/esm/Action/TreeArtifact.js.map +1 -0
  354. package/dist/esm/Action/TypeId.d.ts +8 -0
  355. package/dist/esm/Action/TypeId.d.ts.map +1 -0
  356. package/dist/esm/Action/TypeId.js +9 -0
  357. package/dist/esm/Action/TypeId.js.map +1 -0
  358. package/dist/esm/Action/UncanonicalIdempotencyKey.d.ts +32 -0
  359. package/dist/esm/Action/UncanonicalIdempotencyKey.d.ts.map +1 -0
  360. package/dist/esm/Action/UncanonicalIdempotencyKey.js +31 -0
  361. package/dist/esm/Action/UncanonicalIdempotencyKey.js.map +1 -0
  362. package/dist/esm/Action/idempotencyKey.d.ts +21 -0
  363. package/dist/esm/Action/idempotencyKey.d.ts.map +1 -0
  364. package/dist/esm/Action/idempotencyKey.js +50 -0
  365. package/dist/esm/Action/idempotencyKey.js.map +1 -0
  366. package/dist/esm/Action/index.d.ts +29 -0
  367. package/dist/esm/Action/index.d.ts.map +1 -0
  368. package/dist/esm/Action/index.js +30 -0
  369. package/dist/esm/Action/index.js.map +1 -0
  370. package/dist/esm/Action/make.d.ts +128 -0
  371. package/dist/esm/Action/make.d.ts.map +1 -0
  372. package/dist/esm/Action/make.js +413 -0
  373. package/dist/esm/Action/make.js.map +1 -0
  374. package/dist/esm/Action/raceAll.d.ts +21 -0
  375. package/dist/esm/Action/raceAll.d.ts.map +1 -0
  376. package/dist/esm/Action/raceAll.js +20 -0
  377. package/dist/esm/Action/raceAll.js.map +1 -0
  378. package/dist/esm/Action/retry.d.ts +19 -0
  379. package/dist/esm/Action/retry.d.ts.map +1 -0
  380. package/dist/esm/Action/retry.js +72 -0
  381. package/dist/esm/Action/retry.js.map +1 -0
  382. package/dist/esm/Deadline.d.ts +110 -0
  383. package/dist/esm/Deadline.d.ts.map +1 -0
  384. package/dist/esm/Deadline.js +164 -0
  385. package/dist/esm/Deadline.js.map +1 -0
  386. package/dist/esm/DurableClock.d.ts +60 -0
  387. package/dist/esm/DurableClock.d.ts.map +1 -0
  388. package/dist/esm/DurableClock.js +122 -0
  389. package/dist/esm/DurableClock.js.map +1 -0
  390. package/dist/esm/DurableDeferred.d.ts +311 -0
  391. package/dist/esm/DurableDeferred.d.ts.map +1 -0
  392. package/dist/esm/DurableDeferred.js +357 -0
  393. package/dist/esm/DurableDeferred.js.map +1 -0
  394. package/dist/esm/DurableQueue.d.ts +160 -0
  395. package/dist/esm/DurableQueue.d.ts.map +1 -0
  396. package/dist/esm/DurableQueue.js +303 -0
  397. package/dist/esm/DurableQueue.js.map +1 -0
  398. package/dist/esm/ExternalJob.d.ts +179 -0
  399. package/dist/esm/ExternalJob.d.ts.map +1 -0
  400. package/dist/esm/ExternalJob.js +296 -0
  401. package/dist/esm/ExternalJob.js.map +1 -0
  402. package/dist/esm/Fault.d.ts +131 -0
  403. package/dist/esm/Fault.d.ts.map +1 -0
  404. package/dist/esm/Fault.js +198 -0
  405. package/dist/esm/Fault.js.map +1 -0
  406. package/dist/esm/Flow/Annotations.d.ts +245 -0
  407. package/dist/esm/Flow/Annotations.d.ts.map +1 -0
  408. package/dist/esm/Flow/Annotations.js +110 -0
  409. package/dist/esm/Flow/Annotations.js.map +1 -0
  410. package/dist/esm/Flow/CapabilityCeiling.d.ts +21 -0
  411. package/dist/esm/Flow/CapabilityCeiling.d.ts.map +1 -0
  412. package/dist/esm/Flow/CapabilityCeiling.js +27 -0
  413. package/dist/esm/Flow/CapabilityCeiling.js.map +1 -0
  414. package/dist/esm/Flow/DeadlineExceeded.d.ts +33 -0
  415. package/dist/esm/Flow/DeadlineExceeded.d.ts.map +1 -0
  416. package/dist/esm/Flow/DeadlineExceeded.js +34 -0
  417. package/dist/esm/Flow/DeadlineExceeded.js.map +1 -0
  418. package/dist/esm/Flow/ExecutionIdRequired.d.ts +25 -0
  419. package/dist/esm/Flow/ExecutionIdRequired.d.ts.map +1 -0
  420. package/dist/esm/Flow/ExecutionIdRequired.js +30 -0
  421. package/dist/esm/Flow/ExecutionIdRequired.js.map +1 -0
  422. package/dist/esm/Flow/ExecutionIds.d.ts +80 -0
  423. package/dist/esm/Flow/ExecutionIds.d.ts.map +1 -0
  424. package/dist/esm/Flow/ExecutionIds.js +91 -0
  425. package/dist/esm/Flow/ExecutionIds.js.map +1 -0
  426. package/dist/esm/Flow/Flow.d.ts +422 -0
  427. package/dist/esm/Flow/Flow.d.ts.map +1 -0
  428. package/dist/esm/Flow/Flow.js +3 -0
  429. package/dist/esm/Flow/Flow.js.map +1 -0
  430. package/dist/esm/Flow/MaxRoundsExceeded.d.ts +35 -0
  431. package/dist/esm/Flow/MaxRoundsExceeded.d.ts.map +1 -0
  432. package/dist/esm/Flow/MaxRoundsExceeded.js +34 -0
  433. package/dist/esm/Flow/MaxRoundsExceeded.js.map +1 -0
  434. package/dist/esm/Flow/Outcome.d.ts +162 -0
  435. package/dist/esm/Flow/Outcome.d.ts.map +1 -0
  436. package/dist/esm/Flow/Outcome.js +115 -0
  437. package/dist/esm/Flow/Outcome.js.map +1 -0
  438. package/dist/esm/Flow/Result.d.ts +186 -0
  439. package/dist/esm/Flow/Result.d.ts.map +1 -0
  440. package/dist/esm/Flow/Result.js +171 -0
  441. package/dist/esm/Flow/Result.js.map +1 -0
  442. package/dist/esm/Flow/Runtime.d.ts +98 -0
  443. package/dist/esm/Flow/Runtime.d.ts.map +1 -0
  444. package/dist/esm/Flow/Runtime.js +252 -0
  445. package/dist/esm/Flow/Runtime.js.map +1 -0
  446. package/dist/esm/Flow/TypeId.d.ts +8 -0
  447. package/dist/esm/Flow/TypeId.d.ts.map +1 -0
  448. package/dist/esm/Flow/TypeId.js +9 -0
  449. package/dist/esm/Flow/TypeId.js.map +1 -0
  450. package/dist/esm/Flow/index.d.ts +17 -0
  451. package/dist/esm/Flow/index.d.ts.map +1 -0
  452. package/dist/esm/Flow/index.js +18 -0
  453. package/dist/esm/Flow/index.js.map +1 -0
  454. package/dist/esm/Flow/internal.d.ts +34 -0
  455. package/dist/esm/Flow/internal.d.ts.map +1 -0
  456. package/dist/esm/Flow/internal.js +149 -0
  457. package/dist/esm/Flow/internal.js.map +1 -0
  458. package/dist/esm/Flow/make.d.ts +135 -0
  459. package/dist/esm/Flow/make.d.ts.map +1 -0
  460. package/dist/esm/Flow/make.js +111 -0
  461. package/dist/esm/Flow/make.js.map +1 -0
  462. package/dist/esm/FlowRuntime/CancelRequestFailed.d.ts +55 -0
  463. package/dist/esm/FlowRuntime/CancelRequestFailed.d.ts.map +1 -0
  464. package/dist/esm/FlowRuntime/CancelRequestFailed.js +53 -0
  465. package/dist/esm/FlowRuntime/CancelRequestFailed.js.map +1 -0
  466. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.d.ts +23 -0
  467. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.d.ts.map +1 -0
  468. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.js +24 -0
  469. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.js.map +1 -0
  470. package/dist/esm/FlowRuntime/FlowCycleDetected.d.ts +28 -0
  471. package/dist/esm/FlowRuntime/FlowCycleDetected.d.ts.map +1 -0
  472. package/dist/esm/FlowRuntime/FlowCycleDetected.js +35 -0
  473. package/dist/esm/FlowRuntime/FlowCycleDetected.js.map +1 -0
  474. package/dist/esm/FlowRuntime/FlowExecutionNotFound.d.ts +38 -0
  475. package/dist/esm/FlowRuntime/FlowExecutionNotFound.d.ts.map +1 -0
  476. package/dist/esm/FlowRuntime/FlowExecutionNotFound.js +40 -0
  477. package/dist/esm/FlowRuntime/FlowExecutionNotFound.js.map +1 -0
  478. package/dist/esm/FlowRuntime/FlowInstance.d.ts +115 -0
  479. package/dist/esm/FlowRuntime/FlowInstance.d.ts.map +1 -0
  480. package/dist/esm/FlowRuntime/FlowInstance.js +24 -0
  481. package/dist/esm/FlowRuntime/FlowInstance.js.map +1 -0
  482. package/dist/esm/FlowRuntime/FlowRuntime.d.ts +204 -0
  483. package/dist/esm/FlowRuntime/FlowRuntime.d.ts.map +1 -0
  484. package/dist/esm/FlowRuntime/FlowRuntime.js +34 -0
  485. package/dist/esm/FlowRuntime/FlowRuntime.js.map +1 -0
  486. package/dist/esm/FlowRuntime/NodeRecord.d.ts +177 -0
  487. package/dist/esm/FlowRuntime/NodeRecord.d.ts.map +1 -0
  488. package/dist/esm/FlowRuntime/NodeRecord.js +21 -0
  489. package/dist/esm/FlowRuntime/NodeRecord.js.map +1 -0
  490. package/dist/esm/FlowRuntime/WaitingAnnotation.d.ts +69 -0
  491. package/dist/esm/FlowRuntime/WaitingAnnotation.d.ts.map +1 -0
  492. package/dist/esm/FlowRuntime/WaitingAnnotation.js +53 -0
  493. package/dist/esm/FlowRuntime/WaitingAnnotation.js.map +1 -0
  494. package/dist/esm/FlowRuntime/index.d.ts +14 -0
  495. package/dist/esm/FlowRuntime/index.d.ts.map +1 -0
  496. package/dist/esm/FlowRuntime/index.js +15 -0
  497. package/dist/esm/FlowRuntime/index.js.map +1 -0
  498. package/dist/esm/Graph.d.ts +325 -0
  499. package/dist/esm/Graph.d.ts.map +1 -0
  500. package/dist/esm/Graph.js +1485 -0
  501. package/dist/esm/Graph.js.map +1 -0
  502. package/dist/esm/HumanTask.d.ts +442 -0
  503. package/dist/esm/HumanTask.d.ts.map +1 -0
  504. package/dist/esm/HumanTask.js +798 -0
  505. package/dist/esm/HumanTask.js.map +1 -0
  506. package/dist/esm/Interpreter.d.ts +223 -0
  507. package/dist/esm/Interpreter.d.ts.map +1 -0
  508. package/dist/esm/Interpreter.js +1289 -0
  509. package/dist/esm/Interpreter.js.map +1 -0
  510. package/dist/esm/Poll.d.ts +240 -0
  511. package/dist/esm/Poll.d.ts.map +1 -0
  512. package/dist/esm/Poll.js +289 -0
  513. package/dist/esm/Poll.js.map +1 -0
  514. package/dist/esm/RetryPolicy.d.ts +273 -0
  515. package/dist/esm/RetryPolicy.d.ts.map +1 -0
  516. package/dist/esm/RetryPolicy.js +429 -0
  517. package/dist/esm/RetryPolicy.js.map +1 -0
  518. package/dist/esm/Sleep.d.ts +98 -0
  519. package/dist/esm/Sleep.d.ts.map +1 -0
  520. package/dist/esm/Sleep.js +256 -0
  521. package/dist/esm/Sleep.js.map +1 -0
  522. package/dist/esm/Stall.d.ts +173 -0
  523. package/dist/esm/Stall.d.ts.map +1 -0
  524. package/dist/esm/Stall.js +138 -0
  525. package/dist/esm/Stall.js.map +1 -0
  526. package/dist/esm/WaitFor.d.ts +109 -0
  527. package/dist/esm/WaitFor.d.ts.map +1 -0
  528. package/dist/esm/WaitFor.js +184 -0
  529. package/dist/esm/WaitFor.js.map +1 -0
  530. package/dist/esm/index.d.ts +107 -0
  531. package/dist/esm/index.d.ts.map +1 -0
  532. package/dist/esm/index.js +108 -0
  533. package/dist/esm/index.js.map +1 -0
  534. package/dist/esm/internal/BoundedJson.d.ts +48 -0
  535. package/dist/esm/internal/BoundedJson.d.ts.map +1 -0
  536. package/dist/esm/internal/BoundedJson.js +107 -0
  537. package/dist/esm/internal/BoundedJson.js.map +1 -0
  538. package/dist/esm/internal/DeclarationSite.d.ts +135 -0
  539. package/dist/esm/internal/DeclarationSite.d.ts.map +1 -0
  540. package/dist/esm/internal/DeclarationSite.js +196 -0
  541. package/dist/esm/internal/DeclarationSite.js.map +1 -0
  542. package/dist/esm/internal/Declarations.d.ts +35 -0
  543. package/dist/esm/internal/Declarations.d.ts.map +1 -0
  544. package/dist/esm/internal/Declarations.js +43 -0
  545. package/dist/esm/internal/Declarations.js.map +1 -0
  546. package/dist/esm/internal/ExecutionMiddleware.d.ts +21 -0
  547. package/dist/esm/internal/ExecutionMiddleware.d.ts.map +1 -0
  548. package/dist/esm/internal/ExecutionMiddleware.js +13 -0
  549. package/dist/esm/internal/ExecutionMiddleware.js.map +1 -0
  550. package/dist/esm/internal/JsonSchemaSubset.d.ts +133 -0
  551. package/dist/esm/internal/JsonSchemaSubset.d.ts.map +1 -0
  552. package/dist/esm/internal/JsonSchemaSubset.js +363 -0
  553. package/dist/esm/internal/JsonSchemaSubset.js.map +1 -0
  554. package/dist/esm/internal/OutcomeMarker.d.ts +18 -0
  555. package/dist/esm/internal/OutcomeMarker.d.ts.map +1 -0
  556. package/dist/esm/internal/OutcomeMarker.js +18 -0
  557. package/dist/esm/internal/OutcomeMarker.js.map +1 -0
  558. package/docs/README.md +152 -0
  559. package/docs/api.md +440 -0
  560. package/docs/concepts/bodies-and-plans.md +167 -0
  561. package/docs/concepts/execution-identity.md +142 -0
  562. package/docs/concepts/flows-and-actions.md +129 -0
  563. package/docs/concepts/suspension-and-replay.md +130 -0
  564. package/docs/concepts/the-runtime-port.md +110 -0
  565. package/docs/concepts/trampoline-rounds.md +151 -0
  566. package/docs/guides/ask-a-person.md +184 -0
  567. package/docs/guides/build-a-body.md +164 -0
  568. package/docs/guides/cancel-and-roll-back.md +112 -0
  569. package/docs/guides/implement-an-action.md +155 -0
  570. package/docs/guides/inspect-the-plan.md +235 -0
  571. package/docs/guides/poll-until-ready.md +169 -0
  572. package/docs/guides/queue-work-to-a-worker.md +122 -0
  573. package/docs/guides/retry-a-failing-action.md +243 -0
  574. package/docs/guides/reuse-a-recorded-result.md +129 -0
  575. package/docs/guides/run-a-child-flow.md +108 -0
  576. package/docs/guides/run-an-external-job.md +86 -0
  577. package/docs/guides/use-a-prompt.md +38 -0
  578. package/docs/guides/wait-for-a-deadline.md +141 -0
  579. package/docs/guides/wait-for-an-external-signal.md +151 -0
  580. package/docs/installation.md +87 -0
  581. package/docs/quickstart.md +164 -0
  582. package/docs/reference/flow.md +1835 -0
  583. package/docs/testing.md +157 -0
  584. package/docs/troubleshooting.md +286 -0
  585. package/package.json +327 -3
  586. package/src/Action/Action.ts +333 -0
  587. package/src/Action/AttemptTimedOut.ts +37 -0
  588. package/src/Action/BoundaryMode.ts +33 -0
  589. package/src/Action/CacheEnvironment.ts +170 -0
  590. package/src/Action/ConcurrentKeylessDispatch.ts +38 -0
  591. package/src/Action/Context.ts +156 -0
  592. package/src/Action/DuplicateImplementation.ts +24 -0
  593. package/src/Action/FileBoundary.ts +77 -0
  594. package/src/Action/FileInput.ts +42 -0
  595. package/src/Action/Filegroup.ts +16 -0
  596. package/src/Action/Glob.ts +8 -0
  597. package/src/Action/ImplementationVersionMismatch.ts +27 -0
  598. package/src/Action/Implementations.ts +149 -0
  599. package/src/Action/InfraInterrupt.ts +30 -0
  600. package/src/Action/InfraInterruptRetriesExhausted.ts +37 -0
  601. package/src/Action/IrreversibleRetryRequiresIdempotencyKey.ts +32 -0
  602. package/src/Action/StepIdentity.ts +219 -0
  603. package/src/Action/TreeArtifact.ts +8 -0
  604. package/src/Action/TypeId.ts +9 -0
  605. package/src/Action/UncanonicalIdempotencyKey.ts +36 -0
  606. package/src/Action/idempotencyKey.ts +67 -0
  607. package/src/Action/index.ts +31 -0
  608. package/src/Action/make.ts +671 -0
  609. package/src/Action/raceAll.ts +48 -0
  610. package/src/Action/retry.ts +92 -0
  611. package/src/Deadline.ts +201 -0
  612. package/src/DurableClock.ts +176 -0
  613. package/src/DurableDeferred.ts +753 -0
  614. package/src/DurableQueue.ts +519 -0
  615. package/src/ExternalJob.ts +437 -0
  616. package/src/Fault.ts +279 -0
  617. package/src/Flow/Annotations.ts +151 -0
  618. package/src/Flow/CapabilityCeiling.ts +37 -0
  619. package/src/Flow/DeadlineExceeded.ts +40 -0
  620. package/src/Flow/ExecutionIdRequired.ts +36 -0
  621. package/src/Flow/ExecutionIds.ts +133 -0
  622. package/src/Flow/Flow.ts +576 -0
  623. package/src/Flow/MaxRoundsExceeded.ts +39 -0
  624. package/src/Flow/Outcome.ts +179 -0
  625. package/src/Flow/Result.ts +284 -0
  626. package/src/Flow/Runtime.ts +339 -0
  627. package/src/Flow/TypeId.ts +9 -0
  628. package/src/Flow/index.ts +19 -0
  629. package/src/Flow/internal.ts +237 -0
  630. package/src/Flow/make.ts +285 -0
  631. package/src/FlowRuntime/CancelRequestFailed.ts +56 -0
  632. package/src/FlowRuntime/ExecutionIdentityConflict.ts +32 -0
  633. package/src/FlowRuntime/FlowCycleDetected.ts +41 -0
  634. package/src/FlowRuntime/FlowExecutionNotFound.ts +46 -0
  635. package/src/FlowRuntime/FlowInstance.ts +128 -0
  636. package/src/FlowRuntime/FlowRuntime.ts +339 -0
  637. package/src/FlowRuntime/NodeRecord.ts +185 -0
  638. package/src/FlowRuntime/WaitingAnnotation.ts +85 -0
  639. package/src/FlowRuntime/index.ts +17 -0
  640. package/src/Graph.ts +1865 -0
  641. package/src/HumanTask.ts +1007 -0
  642. package/src/Interpreter.ts +1620 -0
  643. package/src/Poll.ts +420 -0
  644. package/src/RetryPolicy.ts +550 -0
  645. package/src/Sleep.ts +296 -0
  646. package/src/Stall.ts +217 -0
  647. package/src/WaitFor.ts +228 -0
  648. package/src/index.ts +125 -0
  649. package/src/internal/BoundedJson.ts +109 -0
  650. package/src/internal/DeclarationSite.ts +214 -0
  651. package/src/internal/Declarations.ts +49 -0
  652. package/src/internal/ExecutionMiddleware.ts +29 -0
  653. package/src/internal/JsonSchemaSubset.ts +392 -0
  654. package/src/internal/OutcomeMarker.ts +19 -0
@@ -0,0 +1,72 @@
1
+ // Deep reviewed and polished by a human on 2026-08-10.
2
+ /**
3
+ * Retries effects while preserving durable action identity.
4
+ *
5
+ * @since 0.1.0
6
+ */
7
+ import * as Effect from "effect/Effect";
8
+ import { dual } from "effect/Function";
9
+ import { CurrentAttempt, CurrentOrdinal } from "./Context.js";
10
+ /**
11
+ * Retries an effect with `Effect.retry` while updating `CurrentAttempt` for
12
+ * each attempt.
13
+ *
14
+ * @category error handling
15
+ * @since 0.1.0
16
+ */
17
+ export const retry = dual(2, (effect, options) => Effect.gen(function* () {
18
+ // A nested retry block shares the enclosing block's slot instead of
19
+ // shadowing it with a fresh one (issue #108): a per-invocation slot was
20
+ // rebuilt on every outer attempt, discarding the pinned `values`, so a
21
+ // completed irreversible inner dispatch drew a brand-new ordinal — a
22
+ // new step key — and re-executed instead of replaying. Sharing the
23
+ // outermost slot keeps every pin alive for the whole outer sequence.
24
+ const enclosing = yield* CurrentOrdinal;
25
+ // One `values` map for the whole retry sequence: the engine fills each
26
+ // action's scope with the ordinal it allocates on the first attempt,
27
+ // and every later attempt of the same sequence reuses those ordinals
28
+ // (issues #73, #84). The `cursors` map, however, is *per block*
29
+ // (issue #116): #108 shared the enclosing block's mutable cursor map
30
+ // wholesale, so a sibling block's attempt boundary — sanctioned to run
31
+ // concurrently under keyed overlap (issue #111) — cleared every
32
+ // scope's cursor and rewound another block's mid-flight dispatch onto
33
+ // an already-consumed pinned ordinal, a duplicate step key. Each block
34
+ // now owns a private cursor view seeded from the enclosing block's
35
+ // cursors at entry, so its attempt boundaries reset only its own view.
36
+ const slot = {
37
+ values: enclosing?.values ?? new Map(),
38
+ cursors: new Map(enclosing?.cursors)
39
+ };
40
+ // Where each scope's dispatch cursor stood when this block was entered.
41
+ // An inner attempt replays the block from its own first dispatch, not
42
+ // from the outer attempt's start, so its cursors rewind to the block
43
+ // entry rather than to zero (issues #100, #108). At the top level the
44
+ // snapshot is empty and rewinding degenerates to a plain reset.
45
+ const entryCursors = new Map(slot.cursors);
46
+ let attempt = 1;
47
+ return yield* Effect.suspend(() => {
48
+ // Every attempt replays the block from its first dispatch, so the
49
+ // per-scope dispatch cursors restart with it (issue #100); the pinned
50
+ // ordinal sequences in `values` persist across attempts.
51
+ slot.cursors.clear();
52
+ for (const [scope, cursor] of entryCursors) {
53
+ slot.cursors.set(scope, cursor);
54
+ }
55
+ return effect.pipe(Effect.provideService(CurrentAttempt, attempt++), Effect.provideService(CurrentOrdinal, slot));
56
+ }).pipe(Effect.retry(options),
57
+ // On exit, fold this block's final cursor positions back into the
58
+ // enclosing block's view (max-merge, so a concurrent sibling's later
59
+ // propagation never rewinds a scope): an enclosing dispatch of a
60
+ // scope this block consumed must take the next pinned position, not
61
+ // re-consume this block's ordinals.
62
+ Effect.onExit(() => Effect.sync(() => {
63
+ if (enclosing === undefined)
64
+ return;
65
+ for (const [scope, cursor] of slot.cursors) {
66
+ const current = enclosing.cursors.get(scope) ?? 0;
67
+ if (cursor > current)
68
+ enclosing.cursors.set(scope, cursor);
69
+ }
70
+ })));
71
+ }));
72
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/Action/retry.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAEtC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAoB,MAAM,cAAc,CAAA;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,KAAK,GAQd,IAAI,CACN,CAAC,EACD,CAAC,MAAoC,EAAE,OAAe,EAAE,EAAE,CACxD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,oEAAoE;IACpE,wEAAwE;IACxE,uEAAuE;IACvE,qEAAqE;IACrE,mEAAmE;IACnE,qEAAqE;IACrE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,cAAc,CAAA;IACvC,uEAAuE;IACvE,qEAAqE;IACrE,qEAAqE;IACrE,gEAAgE;IAChE,qEAAqE;IACrE,uEAAuE;IACvE,gEAAgE;IAChE,sEAAsE;IACtE,uEAAuE;IACvE,mEAAmE;IACnE,uEAAuE;IACvE,MAAM,IAAI,GAAgB;QACxB,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,IAAI,GAAG,EAAE;QACtC,OAAO,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC;KACrC,CAAA;IACD,wEAAwE;IACxE,sEAAsE;IACtE,qEAAqE;IACrE,sEAAsE;IACtE,gEAAgE;IAChE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1C,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;QAChC,kEAAkE;QAClE,sEAAsE;QACtE,yDAAyD;QACzD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;QACpB,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACjC,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAChB,MAAM,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,EAChD,MAAM,CAAC,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,CAC5C,CAAA;IACH,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;IACrB,kEAAkE;IAClE,qEAAqE;IACrE,iEAAiE;IACjE,oEAAoE;IACpE,oCAAoC;IACpC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CACjB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,OAAM;QACnC,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACjD,IAAI,MAAM,GAAG,OAAO;gBAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC,CAAC,CACH,CACF,CAAA;AACH,CAAC,CAAC,CACL,CAAA","sourcesContent":["// Deep reviewed and polished by a human on 2026-08-10.\n\n/**\n * Retries effects while preserving durable action identity.\n *\n * @since 0.1.0\n */\n\nimport * as Effect from \"effect/Effect\"\nimport { dual } from \"effect/Function\"\nimport type * as Types from \"effect/Types\"\nimport { CurrentAttempt, CurrentOrdinal, type OrdinalSlot } from \"./Context.ts\"\n\n/**\n * Retries an effect with `Effect.retry` while updating `CurrentAttempt` for\n * each attempt.\n *\n * @category error handling\n * @since 0.1.0\n */\nexport const retry: {\n <E, O extends Types.NoExcessProperties<Omit<Effect.Retry.Options<E>, \"schedule\">, O>>(\n options: O\n ): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Retry.Return<R, E, A, O>\n <A, E, R, O extends Types.NoExcessProperties<Omit<Effect.Retry.Options<E>, \"schedule\">, O>>(\n self: Effect.Effect<A, E, R>,\n options: O\n ): Effect.Retry.Return<R, E, A, O>\n} = dual(\n 2,\n (effect: Effect.Effect<any, any, any>, options: object) =>\n Effect.gen(function*() {\n // A nested retry block shares the enclosing block's slot instead of\n // shadowing it with a fresh one (issue #108): a per-invocation slot was\n // rebuilt on every outer attempt, discarding the pinned `values`, so a\n // completed irreversible inner dispatch drew a brand-new ordinal — a\n // new step key — and re-executed instead of replaying. Sharing the\n // outermost slot keeps every pin alive for the whole outer sequence.\n const enclosing = yield* CurrentOrdinal\n // One `values` map for the whole retry sequence: the engine fills each\n // action's scope with the ordinal it allocates on the first attempt,\n // and every later attempt of the same sequence reuses those ordinals\n // (issues #73, #84). The `cursors` map, however, is *per block*\n // (issue #116): #108 shared the enclosing block's mutable cursor map\n // wholesale, so a sibling block's attempt boundary — sanctioned to run\n // concurrently under keyed overlap (issue #111) — cleared every\n // scope's cursor and rewound another block's mid-flight dispatch onto\n // an already-consumed pinned ordinal, a duplicate step key. Each block\n // now owns a private cursor view seeded from the enclosing block's\n // cursors at entry, so its attempt boundaries reset only its own view.\n const slot: OrdinalSlot = {\n values: enclosing?.values ?? new Map(),\n cursors: new Map(enclosing?.cursors)\n }\n // Where each scope's dispatch cursor stood when this block was entered.\n // An inner attempt replays the block from its own first dispatch, not\n // from the outer attempt's start, so its cursors rewind to the block\n // entry rather than to zero (issues #100, #108). At the top level the\n // snapshot is empty and rewinding degenerates to a plain reset.\n const entryCursors = new Map(slot.cursors)\n let attempt = 1\n return yield* Effect.suspend(() => {\n // Every attempt replays the block from its first dispatch, so the\n // per-scope dispatch cursors restart with it (issue #100); the pinned\n // ordinal sequences in `values` persist across attempts.\n slot.cursors.clear()\n for (const [scope, cursor] of entryCursors) {\n slot.cursors.set(scope, cursor)\n }\n return effect.pipe(\n Effect.provideService(CurrentAttempt, attempt++),\n Effect.provideService(CurrentOrdinal, slot)\n )\n }).pipe(\n Effect.retry(options),\n // On exit, fold this block's final cursor positions back into the\n // enclosing block's view (max-merge, so a concurrent sibling's later\n // propagation never rewinds a scope): an enclosing dispatch of a\n // scope this block consumed must take the next pinned position, not\n // re-consume this block's ordinals.\n Effect.onExit(() =>\n Effect.sync(() => {\n if (enclosing === undefined) return\n for (const [scope, cursor] of slot.cursors) {\n const current = enclosing.cursors.get(scope) ?? 0\n if (cursor > current) enclosing.cursors.set(scope, cursor)\n }\n })\n )\n )\n })\n)\n"]}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * The wall-clock bound one run of a flow settles by.
3
+ *
4
+ * A deadline counts from the run's FIRST start, which is journaled, so it
5
+ * survives park, resume and process death: a restarted engine honors the
6
+ * original deadline instead of starting a new one. A trampoline lineage is one
7
+ * run, so its rounds share one deadline: the round that hands off stamps the
8
+ * lineage's start and bound on the {@link module:Result.Handoff}, and the next
9
+ * round runs under that stamp rather than starting a clock of its own. Like
10
+ * `maxRounds`, the bound belongs to the lineage originator; a handoff target
11
+ * cannot reset or replace it.
12
+ *
13
+ * The engine applies {@link bound} to every execution of a flow that declares
14
+ * `Flow.make(tag, { deadline })`. A control plane applies it inside a run body
15
+ * to bound a run by an approved envelope's deadline. Both settle an expired
16
+ * run with the same {@link module:DeadlineExceeded.DeadlineExceeded} defect.
17
+ *
18
+ * @since 1.0.0
19
+ */
20
+ import type * as Crypto from "effect/Crypto";
21
+ import * as Duration from "effect/Duration";
22
+ import * as Effect from "effect/Effect";
23
+ import { type LineageDeadline } from "./Flow/Result.ts";
24
+ import { FlowInstance } from "./FlowRuntime/FlowInstance.ts";
25
+ import { FlowRuntime } from "./FlowRuntime/FlowRuntime.ts";
26
+ /**
27
+ * Starts the current execution's deadline: the lineage deadline this round
28
+ * inherited from a handoff, or `deadline` counted from the execution's
29
+ * journaled first start, or from `startedAtMs` when the host supplies a
30
+ * durable start of its own. Answers `undefined` when neither applies, which is
31
+ * an unbounded execution.
32
+ *
33
+ * **Details**
34
+ *
35
+ * The first start is a sealed action, so every later drive of the execution,
36
+ * on this engine or one that resumes it after a restart, reads the same
37
+ * origin. A durable clock is armed at the deadline so a parked execution is
38
+ * driven again when it passes; the clock keeps the due time it was first armed
39
+ * with, so arming it on every drive is idempotent.
40
+ *
41
+ * **Gotchas**
42
+ *
43
+ * Start at most one deadline per execution, before any other dispatch that a
44
+ * replay must line up with: the origin and the clock are addressed by fixed
45
+ * names within the execution.
46
+ *
47
+ * A deadline that is not a positive finite duration, a `startedAtMs` that is
48
+ * not finite, or a bound that would expire after epoch millisecond
49
+ * `Number.MAX_SAFE_INTEGER` dies with a `RangeError`: a durable store records
50
+ * the clock's due time as a safe integer.
51
+ *
52
+ * @category constructors
53
+ * @since 1.0.0
54
+ */
55
+ export declare const start: (options: {
56
+ /** The flow the refusal names. */
57
+ readonly flowName: string;
58
+ /** The bound; a positive finite duration. Absent means unbounded. */
59
+ readonly deadline?: Duration.Input | undefined;
60
+ /**
61
+ * Where the bound counts from, when the host already holds a durable
62
+ * start of its own, such as the time a control plane accepted the run.
63
+ * Absent, the execution's first start is journaled and read back.
64
+ */
65
+ readonly startedAtMs?: number | undefined;
66
+ }) => Effect.Effect<LineageDeadline | undefined, never, FlowRuntime | FlowInstance | Crypto.Crypto>;
67
+ /**
68
+ * The whole milliseconds left before `deadline` passes, as the durable clock
69
+ * row stores its due time; zero or less once it has passed.
70
+ *
71
+ * @category getters
72
+ * @since 1.0.0
73
+ */
74
+ export declare const remainingMs: (deadline: LineageDeadline) => Effect.Effect<number>;
75
+ /**
76
+ * Runs `body` within a started deadline.
77
+ *
78
+ * A body that starts at or past the deadline settles at once, and one that
79
+ * starts before it races the time remaining in this fiber, so a running
80
+ * execution is stopped too. Both settle with the same `DeadlineExceeded`
81
+ * defect. The race is `raceFirst`: a body that parks exits first, so parking
82
+ * still parks. A round that hands off stamps the deadline on its handoff, so
83
+ * the next round of the lineage runs under it. An `undefined` deadline runs
84
+ * `body` unbounded.
85
+ *
86
+ * @category combinators
87
+ * @since 1.0.0
88
+ */
89
+ export declare const within: (deadline: LineageDeadline | undefined, flowName: string) => <A, E, R>(body: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | FlowInstance>;
90
+ /**
91
+ * Bounds the current execution by `deadline`, counted from its journaled first
92
+ * start, or by the lineage deadline this round inherited from a handoff:
93
+ * {@link start}, then {@link within}.
94
+ *
95
+ * A round that inherited a lineage deadline runs under it whatever it
96
+ * declares, so every round of a lineage expires at the originator's time. With
97
+ * no inherited deadline and `deadline` absent, the body runs unbounded.
98
+ *
99
+ * @category combinators
100
+ * @since 1.0.0
101
+ */
102
+ export declare const bound: (options: {
103
+ /** The flow the refusal names. */
104
+ readonly flowName: string;
105
+ /** The bound; a positive finite duration. Absent means unbounded. */
106
+ readonly deadline?: Duration.Input | undefined;
107
+ /** Where the bound counts from; see {@link start}. */
108
+ readonly startedAtMs?: number | undefined;
109
+ }) => <A, E, R>(body: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | FlowRuntime | FlowInstance | Crypto.Crypto>;
110
+ //# sourceMappingURL=Deadline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Deadline.d.ts","sourceRoot":"","sources":["../../src/Deadline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAMvC,OAAO,EAAW,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAgB1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,KAAK,GAAI,SAAS;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1C,KAAG,MAAM,CAAC,MAAM,CAAC,eAAe,GAAG,SAAS,EAAE,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC,MAAM,CAoC5F,CAAA;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,eAAe,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAC+B,CAAA;AAE3G;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM,GAChB,UAAU,eAAe,GAAG,SAAS,EAAE,UAAU,MAAM,MACvD,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,YAAY,CAwBzE,CAAA;AAEN;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,KAAK,GAAI,SAAS;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;IAC9C,sDAAsD;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1C,MACA,CAAC,EAAE,CAAC,EAAE,CAAC,EACN,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC,MAAM,CACmB,CAAA"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * The wall-clock bound one run of a flow settles by.
3
+ *
4
+ * A deadline counts from the run's FIRST start, which is journaled, so it
5
+ * survives park, resume and process death: a restarted engine honors the
6
+ * original deadline instead of starting a new one. A trampoline lineage is one
7
+ * run, so its rounds share one deadline: the round that hands off stamps the
8
+ * lineage's start and bound on the {@link module:Result.Handoff}, and the next
9
+ * round runs under that stamp rather than starting a clock of its own. Like
10
+ * `maxRounds`, the bound belongs to the lineage originator; a handoff target
11
+ * cannot reset or replace it.
12
+ *
13
+ * The engine applies {@link bound} to every execution of a flow that declares
14
+ * `Flow.make(tag, { deadline })`. A control plane applies it inside a run body
15
+ * to bound a run by an approved envelope's deadline. Both settle an expired
16
+ * run with the same {@link module:DeadlineExceeded.DeadlineExceeded} defect.
17
+ *
18
+ * @since 1.0.0
19
+ */
20
+ import * as Clock from "effect/Clock";
21
+ import * as Duration from "effect/Duration";
22
+ import * as Effect from "effect/Effect";
23
+ import * as Option from "effect/Option";
24
+ import * as Schema from "effect/Schema";
25
+ import * as Action from "./Action/index.js";
26
+ import * as DurableClock from "./DurableClock.js";
27
+ import { DeadlineExceeded } from "./Flow/DeadlineExceeded.js";
28
+ import { Handoff } from "./Flow/Result.js";
29
+ import { FlowInstance } from "./FlowRuntime/FlowInstance.js";
30
+ import { FlowRuntime } from "./FlowRuntime/FlowRuntime.js";
31
+ /**
32
+ * The execution's first start, journaled once.
33
+ *
34
+ * A sealed action's result is recorded with its attempt and replayed on every
35
+ * later drive, so the origin a deadline counts from is the time the execution
36
+ * first ran, on this engine or on the one that resumes it after a restart.
37
+ */
38
+ const origin = Action.make({
39
+ name: "@smthrs/engine/deadline-origin",
40
+ tier: "sealed",
41
+ success: Schema.Number,
42
+ execute: Clock.currentTimeMillis.pipe(Effect.map(Math.floor))
43
+ });
44
+ /**
45
+ * Starts the current execution's deadline: the lineage deadline this round
46
+ * inherited from a handoff, or `deadline` counted from the execution's
47
+ * journaled first start, or from `startedAtMs` when the host supplies a
48
+ * durable start of its own. Answers `undefined` when neither applies, which is
49
+ * an unbounded execution.
50
+ *
51
+ * **Details**
52
+ *
53
+ * The first start is a sealed action, so every later drive of the execution,
54
+ * on this engine or one that resumes it after a restart, reads the same
55
+ * origin. A durable clock is armed at the deadline so a parked execution is
56
+ * driven again when it passes; the clock keeps the due time it was first armed
57
+ * with, so arming it on every drive is idempotent.
58
+ *
59
+ * **Gotchas**
60
+ *
61
+ * Start at most one deadline per execution, before any other dispatch that a
62
+ * replay must line up with: the origin and the clock are addressed by fixed
63
+ * names within the execution.
64
+ *
65
+ * A deadline that is not a positive finite duration, a `startedAtMs` that is
66
+ * not finite, or a bound that would expire after epoch millisecond
67
+ * `Number.MAX_SAFE_INTEGER` dies with a `RangeError`: a durable store records
68
+ * the clock's due time as a safe integer.
69
+ *
70
+ * @category constructors
71
+ * @since 1.0.0
72
+ */
73
+ export const start = (options) => Effect.gen(function* () {
74
+ const instance = yield* FlowInstance;
75
+ let lineage = instance.lineageDeadline;
76
+ if (lineage === undefined) {
77
+ if (options.deadline === undefined)
78
+ return undefined;
79
+ const deadlineMs = Option.match(Duration.fromInput(options.deadline), {
80
+ onNone: () => Number.NaN,
81
+ onSome: Duration.toMillis
82
+ });
83
+ if (!Number.isFinite(deadlineMs) || deadlineMs <= 0) {
84
+ return yield* Effect.die(new RangeError(`Deadline.start: "${options.flowName}" deadline must be a positive finite duration`));
85
+ }
86
+ const startedAtMs = options.startedAtMs ?? (yield* origin);
87
+ // The clock armed below is due at `startedAtMs + deadlineMs`, and a
88
+ // durable store records a due time as a safe integer.
89
+ if (!Number.isFinite(startedAtMs) || startedAtMs + deadlineMs > Number.MAX_SAFE_INTEGER) {
90
+ return yield* Effect.die(new RangeError(`Deadline.start: "${options.flowName}" deadline must expire by epoch millisecond ` +
91
+ `${Number.MAX_SAFE_INTEGER}, and a ${deadlineMs} ms deadline from ${startedAtMs} does not`));
92
+ }
93
+ lineage = { startedAtMs, deadlineMs };
94
+ }
95
+ const remaining = yield* remainingMs(lineage);
96
+ if (remaining > 0) {
97
+ yield* (yield* FlowRuntime).scheduleClock(instance.flow, {
98
+ executionId: instance.executionId,
99
+ clock: DurableClock.make({ name: "@smthrs/engine/deadline", duration: remaining })
100
+ });
101
+ }
102
+ return lineage;
103
+ });
104
+ /**
105
+ * The whole milliseconds left before `deadline` passes, as the durable clock
106
+ * row stores its due time; zero or less once it has passed.
107
+ *
108
+ * @category getters
109
+ * @since 1.0.0
110
+ */
111
+ export const remainingMs = (deadline) => Effect.map(Clock.currentTimeMillis, (now) => Math.ceil(deadline.startedAtMs + deadline.deadlineMs - now));
112
+ /**
113
+ * Runs `body` within a started deadline.
114
+ *
115
+ * A body that starts at or past the deadline settles at once, and one that
116
+ * starts before it races the time remaining in this fiber, so a running
117
+ * execution is stopped too. Both settle with the same `DeadlineExceeded`
118
+ * defect. The race is `raceFirst`: a body that parks exits first, so parking
119
+ * still parks. A round that hands off stamps the deadline on its handoff, so
120
+ * the next round of the lineage runs under it. An `undefined` deadline runs
121
+ * `body` unbounded.
122
+ *
123
+ * @category combinators
124
+ * @since 1.0.0
125
+ */
126
+ export const within = (deadline, flowName) => (body) => deadline === undefined ? body : Effect.gen(function* () {
127
+ const instance = yield* FlowInstance;
128
+ const expired = new DeadlineExceeded({
129
+ flowName,
130
+ executionId: instance.executionId,
131
+ deadlineMs: deadline.deadlineMs,
132
+ startedAtMs: deadline.startedAtMs,
133
+ message: `${flowName} execution ${instance.executionId} ran past its ${deadline.deadlineMs} ms deadline, ` +
134
+ `counted from its start at ${new Date(deadline.startedAtMs).toISOString()}`
135
+ });
136
+ const remaining = yield* remainingMs(deadline);
137
+ if (remaining <= 0)
138
+ return yield* Effect.die(expired);
139
+ const value = yield* Effect.raceFirst(body, Effect.andThen(Effect.sleep(remaining), Effect.die(expired)));
140
+ const handoff = instance.handoff;
141
+ if (handoff !== undefined && handoff.deadline === undefined) {
142
+ instance.handoff = new Handoff({
143
+ flow: handoff.flow,
144
+ payload: handoff.payload,
145
+ ...(handoff.capabilityCeilings === undefined ? {} : { capabilityCeilings: handoff.capabilityCeilings }),
146
+ deadline
147
+ });
148
+ }
149
+ return value;
150
+ });
151
+ /**
152
+ * Bounds the current execution by `deadline`, counted from its journaled first
153
+ * start, or by the lineage deadline this round inherited from a handoff:
154
+ * {@link start}, then {@link within}.
155
+ *
156
+ * A round that inherited a lineage deadline runs under it whatever it
157
+ * declares, so every round of a lineage expires at the originator's time. With
158
+ * no inherited deadline and `deadline` absent, the body runs unbounded.
159
+ *
160
+ * @category combinators
161
+ * @since 1.0.0
162
+ */
163
+ export const bound = (options) => (body) => Effect.flatMap(start(options), (deadline) => within(deadline, options.flowName)(body));
164
+ //# sourceMappingURL=Deadline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Deadline.js","sourceRoot":"","sources":["../../src/Deadline.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The wall-clock bound one run of a flow settles by.\n *\n * A deadline counts from the run's FIRST start, which is journaled, so it\n * survives park, resume and process death: a restarted engine honors the\n * original deadline instead of starting a new one. A trampoline lineage is one\n * run, so its rounds share one deadline: the round that hands off stamps the\n * lineage's start and bound on the {@link module:Result.Handoff}, and the next\n * round runs under that stamp rather than starting a clock of its own. Like\n * `maxRounds`, the bound belongs to the lineage originator; a handoff target\n * cannot reset or replace it.\n *\n * The engine applies {@link bound} to every execution of a flow that declares\n * `Flow.make(tag, { deadline })`. A control plane applies it inside a run body\n * to bound a run by an approved envelope's deadline. Both settle an expired\n * run with the same {@link module:DeadlineExceeded.DeadlineExceeded} defect.\n *\n * @since 1.0.0\n */\n\nimport * as Clock from \"effect/Clock\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Duration from \"effect/Duration\"\nimport * as Effect from \"effect/Effect\"\nimport * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\nimport * as Action from \"./Action/index.ts\"\nimport * as DurableClock from \"./DurableClock.ts\"\nimport { DeadlineExceeded } from \"./Flow/DeadlineExceeded.ts\"\nimport { Handoff, type LineageDeadline } from \"./Flow/Result.ts\"\nimport { FlowInstance } from \"./FlowRuntime/FlowInstance.ts\"\nimport { FlowRuntime } from \"./FlowRuntime/FlowRuntime.ts\"\n\n/**\n * The execution's first start, journaled once.\n *\n * A sealed action's result is recorded with its attempt and replayed on every\n * later drive, so the origin a deadline counts from is the time the execution\n * first ran, on this engine or on the one that resumes it after a restart.\n */\nconst origin = Action.make({\n name: \"@smthrs/engine/deadline-origin\",\n tier: \"sealed\",\n success: Schema.Number,\n execute: Clock.currentTimeMillis.pipe(Effect.map(Math.floor))\n})\n\n/**\n * Starts the current execution's deadline: the lineage deadline this round\n * inherited from a handoff, or `deadline` counted from the execution's\n * journaled first start, or from `startedAtMs` when the host supplies a\n * durable start of its own. Answers `undefined` when neither applies, which is\n * an unbounded execution.\n *\n * **Details**\n *\n * The first start is a sealed action, so every later drive of the execution,\n * on this engine or one that resumes it after a restart, reads the same\n * origin. A durable clock is armed at the deadline so a parked execution is\n * driven again when it passes; the clock keeps the due time it was first armed\n * with, so arming it on every drive is idempotent.\n *\n * **Gotchas**\n *\n * Start at most one deadline per execution, before any other dispatch that a\n * replay must line up with: the origin and the clock are addressed by fixed\n * names within the execution.\n *\n * A deadline that is not a positive finite duration, a `startedAtMs` that is\n * not finite, or a bound that would expire after epoch millisecond\n * `Number.MAX_SAFE_INTEGER` dies with a `RangeError`: a durable store records\n * the clock's due time as a safe integer.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const start = (options: {\n /** The flow the refusal names. */\n readonly flowName: string\n /** The bound; a positive finite duration. Absent means unbounded. */\n readonly deadline?: Duration.Input | undefined\n /**\n * Where the bound counts from, when the host already holds a durable\n * start of its own, such as the time a control plane accepted the run.\n * Absent, the execution's first start is journaled and read back.\n */\n readonly startedAtMs?: number | undefined\n}): Effect.Effect<LineageDeadline | undefined, never, FlowRuntime | FlowInstance | Crypto.Crypto> =>\n Effect.gen(function*() {\n const instance = yield* FlowInstance\n let lineage = instance.lineageDeadline\n if (lineage === undefined) {\n if (options.deadline === undefined) return undefined\n const deadlineMs = Option.match(Duration.fromInput(options.deadline), {\n onNone: () => Number.NaN,\n onSome: Duration.toMillis\n })\n if (!Number.isFinite(deadlineMs) || deadlineMs <= 0) {\n return yield* Effect.die(\n new RangeError(`Deadline.start: \"${options.flowName}\" deadline must be a positive finite duration`)\n )\n }\n const startedAtMs = options.startedAtMs ?? (yield* origin)\n // The clock armed below is due at `startedAtMs + deadlineMs`, and a\n // durable store records a due time as a safe integer.\n if (!Number.isFinite(startedAtMs) || startedAtMs + deadlineMs > Number.MAX_SAFE_INTEGER) {\n return yield* Effect.die(\n new RangeError(\n `Deadline.start: \"${options.flowName}\" deadline must expire by epoch millisecond ` +\n `${Number.MAX_SAFE_INTEGER}, and a ${deadlineMs} ms deadline from ${startedAtMs} does not`\n )\n )\n }\n lineage = { startedAtMs, deadlineMs }\n }\n const remaining = yield* remainingMs(lineage)\n if (remaining > 0) {\n yield* (yield* FlowRuntime).scheduleClock(instance.flow, {\n executionId: instance.executionId,\n clock: DurableClock.make({ name: \"@smthrs/engine/deadline\", duration: remaining })\n })\n }\n return lineage\n })\n\n/**\n * The whole milliseconds left before `deadline` passes, as the durable clock\n * row stores its due time; zero or less once it has passed.\n *\n * @category getters\n * @since 1.0.0\n */\nexport const remainingMs = (deadline: LineageDeadline): Effect.Effect<number> =>\n Effect.map(Clock.currentTimeMillis, (now) => Math.ceil(deadline.startedAtMs + deadline.deadlineMs - now))\n\n/**\n * Runs `body` within a started deadline.\n *\n * A body that starts at or past the deadline settles at once, and one that\n * starts before it races the time remaining in this fiber, so a running\n * execution is stopped too. Both settle with the same `DeadlineExceeded`\n * defect. The race is `raceFirst`: a body that parks exits first, so parking\n * still parks. A round that hands off stamps the deadline on its handoff, so\n * the next round of the lineage runs under it. An `undefined` deadline runs\n * `body` unbounded.\n *\n * @category combinators\n * @since 1.0.0\n */\nexport const within =\n (deadline: LineageDeadline | undefined, flowName: string) =>\n <A, E, R>(body: Effect.Effect<A, E, R>): Effect.Effect<A, E, R | FlowInstance> =>\n deadline === undefined ? body : Effect.gen(function*() {\n const instance = yield* FlowInstance\n const expired = new DeadlineExceeded({\n flowName,\n executionId: instance.executionId,\n deadlineMs: deadline.deadlineMs,\n startedAtMs: deadline.startedAtMs,\n message: `${flowName} execution ${instance.executionId} ran past its ${deadline.deadlineMs} ms deadline, ` +\n `counted from its start at ${new Date(deadline.startedAtMs).toISOString()}`\n })\n const remaining = yield* remainingMs(deadline)\n if (remaining <= 0) return yield* Effect.die(expired)\n const value = yield* Effect.raceFirst(body, Effect.andThen(Effect.sleep(remaining), Effect.die(expired)))\n const handoff = instance.handoff\n if (handoff !== undefined && handoff.deadline === undefined) {\n instance.handoff = new Handoff({\n flow: handoff.flow,\n payload: handoff.payload,\n ...(handoff.capabilityCeilings === undefined ? {} : { capabilityCeilings: handoff.capabilityCeilings }),\n deadline\n })\n }\n return value\n })\n\n/**\n * Bounds the current execution by `deadline`, counted from its journaled first\n * start, or by the lineage deadline this round inherited from a handoff:\n * {@link start}, then {@link within}.\n *\n * A round that inherited a lineage deadline runs under it whatever it\n * declares, so every round of a lineage expires at the originator's time. With\n * no inherited deadline and `deadline` absent, the body runs unbounded.\n *\n * @category combinators\n * @since 1.0.0\n */\nexport const bound = (options: {\n /** The flow the refusal names. */\n readonly flowName: string\n /** The bound; a positive finite duration. Absent means unbounded. */\n readonly deadline?: Duration.Input | undefined\n /** Where the bound counts from; see {@link start}. */\n readonly startedAtMs?: number | undefined\n}) =>\n<A, E, R>(\n body: Effect.Effect<A, E, R>\n): Effect.Effect<A, E, R | FlowRuntime | FlowInstance | Crypto.Crypto> =>\n Effect.flatMap(start(options), (deadline) => within(deadline, options.flowName)(body))\n"]}
@@ -0,0 +1,60 @@
1
+ import type * as Crypto from "effect/Crypto";
2
+ import * as Duration from "effect/Duration";
3
+ import * as Effect from "effect/Effect";
4
+ import type * as Schema from "effect/Schema";
5
+ import * as DurableDeferred from "./DurableDeferred.ts";
6
+ import { FlowInstance } from "./FlowRuntime/FlowInstance.ts";
7
+ import { FlowRuntime } from "./FlowRuntime/FlowRuntime.ts";
8
+ declare const TypeId = "@smthrs/flow/DurableClock";
9
+ /**
10
+ * Represents a durable flow timer with a name, duration, and deferred
11
+ * completed when the timer wakes.
12
+ *
13
+ * @category models
14
+ * @since 0.1.0
15
+ */
16
+ export interface DurableClock {
17
+ readonly [TypeId]: typeof TypeId;
18
+ readonly name: string;
19
+ readonly duration: Duration.Duration;
20
+ readonly deferred: DurableDeferred.DurableDeferred<typeof Schema.Void>;
21
+ }
22
+ /**
23
+ * Declares one durable clock after validating its finite nonnegative duration.
24
+ *
25
+ * Throws a `RangeError` for a malformed, infinite or negative duration, or one
26
+ * longer than `Number.MAX_SAFE_INTEGER` milliseconds: a durable store records
27
+ * a clock's due time as a safe integer.
28
+ *
29
+ * @category constructors
30
+ * @since 0.1.0
31
+ */
32
+ export declare const make: (options: {
33
+ readonly name: string;
34
+ readonly duration: Duration.Input;
35
+ }) => DurableClock;
36
+ /**
37
+ * Waits inside a flow, using an in-memory action for durations at or
38
+ * below the threshold and scheduling a durable clock for longer durations.
39
+ *
40
+ * Throws a `RangeError` for the same durations {@link make} refuses, and for
41
+ * a malformed, infinite or negative threshold. A durable sleep that would
42
+ * wake after epoch millisecond `Number.MAX_SAFE_INTEGER` dies with a
43
+ * `RangeError` instead of arming its clock.
44
+ *
45
+ * @category sleeping
46
+ * @since 0.1.0
47
+ */
48
+ export declare const sleep: (options: {
49
+ readonly name: string;
50
+ readonly duration: Duration.Input;
51
+ /**
52
+ * If the duration is less than or equal to this threshold, the clock will
53
+ * be executed in memory.
54
+ *
55
+ * @default 60 seconds
56
+ */
57
+ readonly inMemoryThreshold?: Duration.Input | undefined;
58
+ }) => Effect.Effect<void, never, Crypto.Crypto | FlowRuntime | FlowInstance>;
59
+ export {};
60
+ //# sourceMappingURL=DurableClock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DurableClock.d.ts","sourceRoot":"","sources":["../../src/DurableClock.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAE5C,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAE1D,QAAA,MAAM,MAAM,8BAA8B,CAAA;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,MAAM,CAAA;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,eAAe,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;CACvE;AAkDD;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,GAAI,SAAS;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAA;CAClC,KAAG,YAAwE,CAAA;AAE5E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,KAAK,GAChB,SAAS;IACP,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAA;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;CACxD,KACA,MAAM,CAAC,MAAM,CACd,IAAI,EACJ,KAAK,EACL,MAAM,CAAC,MAAM,GAAG,WAAW,GAAG,YAAY,CA2C3C,CAAA"}
@@ -0,0 +1,122 @@
1
+ // Deep reviewed and polished by a human on 2026-08-10.
2
+ /**
3
+ * Durable timers for flow sleeps.
4
+ *
5
+ * `make` creates a `DurableClock` with a name, duration, and deferred wake-up
6
+ * signal. `sleep` ignores zero durations, runs short sleeps through an
7
+ * in-memory action, and schedules longer sleeps through the `FlowRuntime`
8
+ * before awaiting the durable deferred tied to the clock.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ import * as Clock from "effect/Clock";
13
+ import * as Duration from "effect/Duration";
14
+ import * as Effect from "effect/Effect";
15
+ import * as Option from "effect/Option";
16
+ import * as Action from "./Action/index.js";
17
+ import * as DurableDeferred from "./DurableDeferred.js";
18
+ import { FlowInstance } from "./FlowRuntime/FlowInstance.js";
19
+ import { FlowRuntime } from "./FlowRuntime/FlowRuntime.js";
20
+ const TypeId = "@smthrs/flow/DurableClock";
21
+ /**
22
+ * Parses one author-supplied duration and requires it to be finite and
23
+ * nonnegative. Invalid input throws `RangeError` so the authoring mistake is
24
+ * caught at declaration time, matching `Flow.make` and `Poll.make`.
25
+ *
26
+ * @private
27
+ */
28
+ const durationFromInput = (input, field) => {
29
+ const parsed = Duration.fromInput(input);
30
+ if (Option.isNone(parsed)) {
31
+ throw new RangeError(`DurableClock: "${field}" must be a valid finite duration that is not negative.`);
32
+ }
33
+ const millis = Duration.toMillis(parsed.value);
34
+ if (!Duration.isFinite(parsed.value) || !Number.isFinite(millis) || millis < 0) {
35
+ throw new RangeError(`DurableClock: "${field}" must be a valid finite duration that is not negative.`);
36
+ }
37
+ return parsed.value;
38
+ };
39
+ /**
40
+ * The latest due time a durable timer records, in epoch milliseconds: a store
41
+ * keeps a clock's due time as a safe integer.
42
+ *
43
+ * @private
44
+ */
45
+ const latestDueAtMs = Number.MAX_SAFE_INTEGER;
46
+ /**
47
+ * Parses a clock's own duration, which a store adds to the current time and
48
+ * records, so it is at most {@link latestDueAtMs} milliseconds.
49
+ *
50
+ * @private
51
+ */
52
+ const clockDuration = (input) => {
53
+ const duration = durationFromInput(input, "duration");
54
+ if (Duration.toMillis(duration) > latestDueAtMs) {
55
+ throw new RangeError(`DurableClock: "duration" must be at most ${latestDueAtMs} milliseconds.`);
56
+ }
57
+ return duration;
58
+ };
59
+ const makeClock = (name, duration) => ({
60
+ [TypeId]: TypeId,
61
+ name,
62
+ duration,
63
+ deferred: DurableDeferred.make(`DurableClock/${name}`)
64
+ });
65
+ /**
66
+ * Declares one durable clock after validating its finite nonnegative duration.
67
+ *
68
+ * Throws a `RangeError` for a malformed, infinite or negative duration, or one
69
+ * longer than `Number.MAX_SAFE_INTEGER` milliseconds: a durable store records
70
+ * a clock's due time as a safe integer.
71
+ *
72
+ * @category constructors
73
+ * @since 0.1.0
74
+ */
75
+ export const make = (options) => makeClock(options.name, clockDuration(options.duration));
76
+ /**
77
+ * Waits inside a flow, using an in-memory action for durations at or
78
+ * below the threshold and scheduling a durable clock for longer durations.
79
+ *
80
+ * Throws a `RangeError` for the same durations {@link make} refuses, and for
81
+ * a malformed, infinite or negative threshold. A durable sleep that would
82
+ * wake after epoch millisecond `Number.MAX_SAFE_INTEGER` dies with a
83
+ * `RangeError` instead of arming its clock.
84
+ *
85
+ * @category sleeping
86
+ * @since 0.1.0
87
+ */
88
+ export const sleep = (options) => {
89
+ const name = options.name;
90
+ const duration = clockDuration(options.duration);
91
+ const inMemoryThreshold = durationFromInput(options.inMemoryThreshold ?? defaultInMemoryThreshold, "inMemoryThreshold");
92
+ // Untraced because durable sleeps are recursively resumed by the engine.
93
+ return Effect.fnUntraced(function* () {
94
+ if (Duration.isZero(duration)) {
95
+ return;
96
+ }
97
+ if (Duration.isLessThanOrEqualTo(duration, inMemoryThreshold)) {
98
+ return yield* Action.make({
99
+ name: `DurableClock/${name}`,
100
+ tier: "sealed",
101
+ execute: Effect.sleep(duration)
102
+ });
103
+ }
104
+ // A due time past the latest one a store records would fail the park
105
+ // write deep in the engine, so the sleep refuses it here by name.
106
+ const now = yield* Clock.currentTimeMillis;
107
+ if (now + Duration.toMillis(duration) > latestDueAtMs) {
108
+ return yield* Effect.die(new RangeError(`DurableClock: "${name}" would wake after epoch millisecond ${latestDueAtMs}, ` +
109
+ `the latest due time a durable timer records.`));
110
+ }
111
+ const engine = yield* FlowRuntime;
112
+ const instance = yield* FlowInstance;
113
+ const clock = makeClock(name, duration);
114
+ yield* engine.scheduleClock(instance.flow, {
115
+ executionId: instance.executionId,
116
+ clock
117
+ });
118
+ return yield* DurableDeferred.await(clock.deferred);
119
+ })();
120
+ };
121
+ const defaultInMemoryThreshold = Duration.seconds(60);
122
+ //# sourceMappingURL=DurableClock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DurableClock.js","sourceRoot":"","sources":["../../src/DurableClock.ts"],"names":[],"mappings":"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","sourcesContent":["// Deep reviewed and polished by a human on 2026-08-10.\n\n/**\n * Durable timers for flow sleeps.\n *\n * `make` creates a `DurableClock` with a name, duration, and deferred wake-up\n * signal. `sleep` ignores zero durations, runs short sleeps through an\n * in-memory action, and schedules longer sleeps through the `FlowRuntime`\n * before awaiting the durable deferred tied to the clock.\n *\n * @since 0.1.0\n */\n\nimport * as Clock from \"effect/Clock\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Duration from \"effect/Duration\"\nimport * as Effect from \"effect/Effect\"\nimport * as Option from \"effect/Option\"\nimport type * as Schema from \"effect/Schema\"\nimport * as Action from \"./Action/index.ts\"\nimport * as DurableDeferred from \"./DurableDeferred.ts\"\nimport { FlowInstance } from \"./FlowRuntime/FlowInstance.ts\"\nimport { FlowRuntime } from \"./FlowRuntime/FlowRuntime.ts\"\n\nconst TypeId = \"@smthrs/flow/DurableClock\"\n\n/**\n * Represents a durable flow timer with a name, duration, and deferred\n * completed when the timer wakes.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface DurableClock {\n readonly [TypeId]: typeof TypeId\n readonly name: string\n readonly duration: Duration.Duration\n readonly deferred: DurableDeferred.DurableDeferred<typeof Schema.Void>\n}\n\n/**\n * Parses one author-supplied duration and requires it to be finite and\n * nonnegative. Invalid input throws `RangeError` so the authoring mistake is\n * caught at declaration time, matching `Flow.make` and `Poll.make`.\n *\n * @private\n */\nconst durationFromInput = (input: Duration.Input, field: string): Duration.Duration => {\n const parsed = Duration.fromInput(input)\n if (Option.isNone(parsed)) {\n throw new RangeError(`DurableClock: \"${field}\" must be a valid finite duration that is not negative.`)\n }\n const millis = Duration.toMillis(parsed.value)\n if (!Duration.isFinite(parsed.value) || !Number.isFinite(millis) || millis < 0) {\n throw new RangeError(`DurableClock: \"${field}\" must be a valid finite duration that is not negative.`)\n }\n return parsed.value\n}\n\n/**\n * The latest due time a durable timer records, in epoch milliseconds: a store\n * keeps a clock's due time as a safe integer.\n *\n * @private\n */\nconst latestDueAtMs = Number.MAX_SAFE_INTEGER\n\n/**\n * Parses a clock's own duration, which a store adds to the current time and\n * records, so it is at most {@link latestDueAtMs} milliseconds.\n *\n * @private\n */\nconst clockDuration = (input: Duration.Input): Duration.Duration => {\n const duration = durationFromInput(input, \"duration\")\n if (Duration.toMillis(duration) > latestDueAtMs) {\n throw new RangeError(`DurableClock: \"duration\" must be at most ${latestDueAtMs} milliseconds.`)\n }\n return duration\n}\n\nconst makeClock = (name: string, duration: Duration.Duration): DurableClock => ({\n [TypeId]: TypeId,\n name,\n duration,\n deferred: DurableDeferred.make(`DurableClock/${name}`)\n})\n\n/**\n * Declares one durable clock after validating its finite nonnegative duration.\n *\n * Throws a `RangeError` for a malformed, infinite or negative duration, or one\n * longer than `Number.MAX_SAFE_INTEGER` milliseconds: a durable store records\n * a clock's due time as a safe integer.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make = (options: {\n readonly name: string\n readonly duration: Duration.Input\n}): DurableClock => makeClock(options.name, clockDuration(options.duration))\n\n/**\n * Waits inside a flow, using an in-memory action for durations at or\n * below the threshold and scheduling a durable clock for longer durations.\n *\n * Throws a `RangeError` for the same durations {@link make} refuses, and for\n * a malformed, infinite or negative threshold. A durable sleep that would\n * wake after epoch millisecond `Number.MAX_SAFE_INTEGER` dies with a\n * `RangeError` instead of arming its clock.\n *\n * @category sleeping\n * @since 0.1.0\n */\nexport const sleep = (\n options: {\n readonly name: string\n readonly duration: Duration.Input\n /**\n * If the duration is less than or equal to this threshold, the clock will\n * be executed in memory.\n *\n * @default 60 seconds\n */\n readonly inMemoryThreshold?: Duration.Input | undefined\n }\n): Effect.Effect<\n void,\n never,\n Crypto.Crypto | FlowRuntime | FlowInstance\n> => {\n const name = options.name\n const duration = clockDuration(options.duration)\n const inMemoryThreshold = durationFromInput(\n options.inMemoryThreshold ?? defaultInMemoryThreshold,\n \"inMemoryThreshold\"\n )\n\n // Untraced because durable sleeps are recursively resumed by the engine.\n return Effect.fnUntraced(function*() {\n if (Duration.isZero(duration)) {\n return\n }\n\n if (Duration.isLessThanOrEqualTo(duration, inMemoryThreshold)) {\n return yield* Action.make({\n name: `DurableClock/${name}`,\n tier: \"sealed\",\n execute: Effect.sleep(duration)\n })\n }\n\n // A due time past the latest one a store records would fail the park\n // write deep in the engine, so the sleep refuses it here by name.\n const now = yield* Clock.currentTimeMillis\n if (now + Duration.toMillis(duration) > latestDueAtMs) {\n return yield* Effect.die(\n new RangeError(\n `DurableClock: \"${name}\" would wake after epoch millisecond ${latestDueAtMs}, ` +\n `the latest due time a durable timer records.`\n )\n )\n }\n const engine = yield* FlowRuntime\n const instance = yield* FlowInstance\n const clock = makeClock(name, duration)\n yield* engine.scheduleClock(instance.flow, {\n executionId: instance.executionId,\n clock\n })\n return yield* DurableDeferred.await(clock.deferred)\n })()\n}\n\nconst defaultInMemoryThreshold = Duration.seconds(60)\n"]}