footprintjs 10.0.1 → 10.2.0

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 (368) hide show
  1. package/AGENTS.md +2 -1
  2. package/CLAUDE.md +61 -7
  3. package/README.md +136 -312
  4. package/dist/esm/index.d.ts +62 -2
  5. package/dist/esm/index.js +13 -6
  6. package/dist/esm/lib/attempt/anySignal.d.ts +19 -0
  7. package/dist/esm/lib/attempt/anySignal.js +39 -0
  8. package/dist/esm/lib/attempt/call.d.ts +88 -0
  9. package/dist/esm/lib/attempt/call.js +129 -0
  10. package/dist/esm/lib/attempt/category.d.ts +37 -0
  11. package/dist/esm/lib/attempt/category.js +131 -0
  12. package/dist/esm/lib/attempt/correlation.d.ts +95 -0
  13. package/dist/esm/lib/attempt/correlation.js +178 -0
  14. package/dist/esm/lib/attempt/deadline.d.ts +44 -0
  15. package/dist/esm/lib/attempt/deadline.js +101 -0
  16. package/dist/esm/lib/attempt/decision.d.ts +52 -0
  17. package/dist/esm/lib/attempt/decision.js +134 -0
  18. package/dist/esm/lib/attempt/effect.d.ts +76 -0
  19. package/dist/esm/lib/attempt/effect.js +160 -0
  20. package/dist/esm/lib/attempt/errors.d.ts +41 -0
  21. package/dist/esm/lib/attempt/errors.js +44 -0
  22. package/dist/esm/lib/attempt/index.d.ts +18 -0
  23. package/dist/esm/lib/attempt/index.js +15 -0
  24. package/dist/esm/lib/attempt/name.d.ts +21 -0
  25. package/dist/esm/lib/attempt/name.js +43 -0
  26. package/dist/esm/lib/attempt/observed.d.ts +66 -0
  27. package/dist/esm/lib/attempt/observed.js +171 -0
  28. package/dist/esm/lib/attempt/policy.d.ts +45 -0
  29. package/dist/esm/lib/attempt/policy.js +83 -0
  30. package/dist/esm/lib/attempt/record.d.ts +11 -0
  31. package/dist/esm/lib/attempt/record.js +24 -0
  32. package/dist/esm/lib/attempt/retryLoopContext.d.ts +18 -0
  33. package/dist/esm/lib/attempt/retryLoopContext.js +24 -0
  34. package/dist/esm/lib/attempt/retryLoopTypes.d.ts +18 -0
  35. package/dist/esm/lib/attempt/retryLoopTypes.js +2 -0
  36. package/dist/esm/lib/attempt/runner.d.ts +157 -0
  37. package/dist/esm/lib/attempt/runner.js +523 -0
  38. package/dist/esm/lib/attempt/standalone.d.ts +47 -0
  39. package/dist/esm/lib/attempt/standalone.js +126 -0
  40. package/dist/esm/lib/attempt/types.d.ts +453 -0
  41. package/dist/esm/lib/attempt/types.js +16 -0
  42. package/dist/esm/lib/budget/index.d.ts +9 -0
  43. package/dist/esm/lib/budget/index.js +9 -0
  44. package/dist/esm/lib/budget/timeBudget.d.ts +136 -0
  45. package/dist/esm/lib/budget/timeBudget.js +666 -0
  46. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +88 -3
  47. package/dist/esm/lib/builder/FlowChartBuilder.js +199 -9
  48. package/dist/esm/lib/builder/retryLoop.d.ts +56 -0
  49. package/dist/esm/lib/builder/retryLoop.js +283 -0
  50. package/dist/esm/lib/builder/types.d.ts +35 -1
  51. package/dist/esm/lib/builder/types.js +1 -1
  52. package/dist/esm/lib/decide/decide.js +2 -2
  53. package/dist/esm/lib/decide/index.d.ts +1 -1
  54. package/dist/esm/lib/decide/index.js +2 -2
  55. package/dist/esm/lib/decide/types.d.ts +3 -0
  56. package/dist/esm/lib/decide/types.js +1 -8
  57. package/dist/esm/lib/engine/graph/StageNode.d.ts +11 -1
  58. package/dist/esm/lib/engine/graph/StageNode.js +1 -1
  59. package/dist/esm/lib/engine/graph/prefixNodeTree.js +5 -1
  60. package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
  61. package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
  62. package/dist/esm/lib/engine/handlers/ResumeEntry.js +3 -1
  63. package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
  64. package/dist/esm/lib/engine/handlers/StageRunner.d.ts +8 -1
  65. package/dist/esm/lib/engine/handlers/StageRunner.js +36 -9
  66. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +24 -5
  67. package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
  68. package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
  69. package/dist/esm/lib/engine/handlers/stageError.d.ts +9 -0
  70. package/dist/esm/lib/engine/handlers/stageError.js +23 -1
  71. package/dist/esm/lib/engine/index.d.ts +2 -2
  72. package/dist/esm/lib/engine/index.js +1 -1
  73. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
  74. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +68 -40
  75. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
  76. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
  77. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
  78. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +61 -9
  79. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
  80. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
  81. package/dist/esm/lib/engine/narrative/formatting/sentences.d.ts +23 -0
  82. package/dist/esm/lib/engine/narrative/formatting/sentences.js +127 -1
  83. package/dist/esm/lib/engine/narrative/index.d.ts +2 -2
  84. package/dist/esm/lib/engine/narrative/index.js +1 -1
  85. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +27 -21
  86. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  87. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
  88. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
  89. package/dist/esm/lib/engine/narrative/recorders/index.d.ts +1 -1
  90. package/dist/esm/lib/engine/narrative/recorders/index.js +1 -1
  91. package/dist/esm/lib/engine/narrative/types.d.ts +74 -5
  92. package/dist/esm/lib/engine/narrative/types.js +1 -1
  93. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
  94. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +194 -118
  95. package/dist/esm/lib/engine/traversalContext.d.ts +7 -2
  96. package/dist/esm/lib/engine/traversalContext.js +6 -3
  97. package/dist/esm/lib/engine/types.d.ts +52 -57
  98. package/dist/esm/lib/engine/types.js +1 -1
  99. package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
  100. package/dist/esm/lib/errors/terminalFailure.js +60 -0
  101. package/dist/esm/lib/{decide → filter}/evaluator.d.ts +7 -2
  102. package/dist/esm/lib/filter/evaluator.js +135 -0
  103. package/dist/esm/lib/ids/idempotencyKey.d.ts +14 -0
  104. package/dist/esm/lib/ids/idempotencyKey.js +24 -0
  105. package/dist/esm/lib/memory/StageContext.d.ts +123 -3
  106. package/dist/esm/lib/memory/StageContext.js +245 -4
  107. package/dist/esm/lib/memory/attention.d.ts +26 -0
  108. package/dist/esm/lib/memory/attention.js +171 -0
  109. package/dist/esm/lib/memory/borrowedMutation.d.ts +8 -0
  110. package/dist/esm/lib/memory/borrowedMutation.js +14 -1
  111. package/dist/esm/lib/memory/frameTypes.d.ts +38 -0
  112. package/dist/esm/lib/memory/frameTypes.js +3 -1
  113. package/dist/esm/lib/memory/redaction.d.ts +12 -0
  114. package/dist/esm/lib/memory/redaction.js +54 -5
  115. package/dist/esm/lib/pause/record.js +10 -1
  116. package/dist/esm/lib/pause/types.d.ts +19 -0
  117. package/dist/esm/lib/pause/types.js +17 -1
  118. package/dist/esm/lib/reactive/createTypedScope.js +3 -1
  119. package/dist/esm/lib/reactive/types.d.ts +36 -4
  120. package/dist/esm/lib/reactive/types.js +3 -1
  121. package/dist/esm/lib/recorder/AttemptRecorder.d.ts +141 -0
  122. package/dist/esm/lib/recorder/AttemptRecorder.js +412 -0
  123. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +36 -2
  124. package/dist/esm/lib/recorder/ControlDepRecorder.js +50 -2
  125. package/dist/esm/lib/recorder/EmitRecorder.d.ts +3 -0
  126. package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
  127. package/dist/esm/lib/recorder/InOutRecorder.d.ts +37 -1
  128. package/dist/esm/lib/recorder/InOutRecorder.js +75 -6
  129. package/dist/esm/lib/recorder/QualityRecorder.d.ts +32 -5
  130. package/dist/esm/lib/recorder/QualityRecorder.js +87 -29
  131. package/dist/esm/lib/recorder/TopologyRecorder.d.ts +35 -5
  132. package/dist/esm/lib/recorder/TopologyRecorder.js +76 -2
  133. package/dist/esm/lib/recorder/attemptMetricRows.d.ts +11 -0
  134. package/dist/esm/lib/recorder/attemptMetricRows.js +202 -0
  135. package/dist/esm/lib/recorder/attemptMetrics.d.ts +7 -0
  136. package/dist/esm/lib/recorder/attemptMetrics.js +165 -0
  137. package/dist/esm/lib/recorder/attemptMetricsTypes.d.ts +114 -0
  138. package/dist/esm/lib/recorder/attemptMetricsTypes.js +2 -0
  139. package/dist/esm/lib/recorder/attemptOTel.d.ts +78 -0
  140. package/dist/esm/lib/recorder/attemptOTel.js +107 -0
  141. package/dist/esm/lib/recorder/attemptSeries.d.ts +81 -0
  142. package/dist/esm/lib/recorder/attemptSeries.js +103 -0
  143. package/dist/esm/lib/recorder/hooks.d.ts +9 -0
  144. package/dist/esm/lib/recorder/hooks.js +4 -1
  145. package/dist/esm/lib/runner/DeferredObserverTier.js +13 -1
  146. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +54 -6
  147. package/dist/esm/lib/runner/ExecutionRuntime.js +57 -5
  148. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +46 -2
  149. package/dist/esm/lib/runner/FlowChartExecutor.js +330 -101
  150. package/dist/esm/lib/runner/RunnableChart.d.ts +6 -0
  151. package/dist/esm/lib/runner/RunnableChart.js +5 -1
  152. package/dist/esm/lib/runner/attach.d.ts +2 -1
  153. package/dist/esm/lib/runner/attach.js +8 -2
  154. package/dist/esm/lib/runner/checkpoint.js +3 -1
  155. package/dist/esm/lib/runner/deadline.d.ts +42 -0
  156. package/dist/esm/lib/runner/deadline.js +90 -0
  157. package/dist/esm/lib/runner/index.d.ts +3 -1
  158. package/dist/esm/lib/runner/index.js +2 -1
  159. package/dist/esm/lib/runner/options.d.ts +17 -0
  160. package/dist/esm/lib/runner/options.js +3 -1
  161. package/dist/esm/lib/runner/recordSink.d.ts +128 -0
  162. package/dist/esm/lib/runner/recordSink.js +296 -0
  163. package/dist/esm/lib/runner/resume.d.ts +3 -0
  164. package/dist/esm/lib/runner/resume.js +22 -2
  165. package/dist/esm/lib/runner/snapshot.d.ts +2 -2
  166. package/dist/esm/lib/runner/snapshot.js +6 -2
  167. package/dist/esm/lib/scope/ScopeFacade.d.ts +118 -4
  168. package/dist/esm/lib/scope/ScopeFacade.js +304 -7
  169. package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +17 -3
  170. package/dist/esm/lib/scope/recorders/DebugRecorder.js +79 -13
  171. package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +10 -0
  172. package/dist/esm/lib/scope/recorders/MetricRecorder.js +15 -2
  173. package/dist/esm/lib/scope/runtime.d.ts +3 -0
  174. package/dist/esm/lib/scope/runtime.js +1 -1
  175. package/dist/esm/lib/scope/types.d.ts +6 -0
  176. package/dist/esm/lib/scope/types.js +1 -1
  177. package/dist/esm/lib/sinks/fileSink.d.ts +135 -0
  178. package/dist/esm/lib/sinks/fileSink.js +387 -0
  179. package/dist/esm/recorders.d.ts +8 -2
  180. package/dist/esm/recorders.js +7 -1
  181. package/dist/esm/sinks.d.ts +23 -0
  182. package/dist/esm/sinks.js +23 -0
  183. package/dist/esm/trace.d.ts +2 -2
  184. package/dist/esm/trace.js +1 -1
  185. package/dist/index.js +77 -60
  186. package/dist/lib/attempt/anySignal.js +43 -0
  187. package/dist/lib/attempt/call.js +134 -0
  188. package/dist/lib/attempt/category.js +136 -0
  189. package/dist/lib/attempt/correlation.js +186 -0
  190. package/dist/lib/attempt/deadline.js +112 -0
  191. package/dist/lib/attempt/decision.js +139 -0
  192. package/dist/lib/attempt/effect.js +174 -0
  193. package/dist/lib/attempt/errors.js +49 -0
  194. package/dist/lib/attempt/index.js +26 -0
  195. package/dist/lib/attempt/name.js +48 -0
  196. package/dist/lib/attempt/observed.js +177 -0
  197. package/dist/lib/attempt/policy.js +92 -0
  198. package/dist/lib/attempt/record.js +29 -0
  199. package/dist/lib/attempt/retryLoopContext.js +31 -0
  200. package/dist/lib/attempt/retryLoopTypes.js +3 -0
  201. package/dist/lib/attempt/runner.js +530 -0
  202. package/dist/lib/attempt/standalone.js +130 -0
  203. package/dist/lib/attempt/types.js +17 -0
  204. package/dist/lib/budget/index.js +17 -0
  205. package/dist/lib/budget/timeBudget.js +674 -0
  206. package/dist/lib/builder/FlowChartBuilder.js +199 -9
  207. package/dist/lib/builder/retryLoop.js +287 -0
  208. package/dist/lib/builder/types.js +1 -1
  209. package/dist/lib/decide/decide.js +2 -2
  210. package/dist/lib/decide/index.js +2 -2
  211. package/dist/lib/decide/types.js +1 -8
  212. package/dist/lib/engine/graph/StageNode.js +1 -1
  213. package/dist/lib/engine/graph/prefixNodeTree.js +5 -1
  214. package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
  215. package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
  216. package/dist/lib/engine/handlers/ResumeEntry.js +3 -1
  217. package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
  218. package/dist/lib/engine/handlers/StageRunner.js +36 -9
  219. package/dist/lib/engine/handlers/SubflowExecutor.js +24 -5
  220. package/dist/lib/engine/handlers/commitStage.js +24 -5
  221. package/dist/lib/engine/handlers/stageError.js +26 -2
  222. package/dist/lib/engine/index.js +1 -1
  223. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +67 -39
  224. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
  225. package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +60 -8
  226. package/dist/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
  227. package/dist/lib/engine/narrative/formatting/sentences.js +131 -2
  228. package/dist/lib/engine/narrative/index.js +1 -1
  229. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  230. package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
  231. package/dist/lib/engine/narrative/recorders/index.js +1 -1
  232. package/dist/lib/engine/narrative/types.js +1 -1
  233. package/dist/lib/engine/traversal/FlowchartTraverser.js +192 -116
  234. package/dist/lib/engine/traversalContext.js +6 -3
  235. package/dist/lib/engine/types.js +1 -1
  236. package/dist/lib/errors/terminalFailure.js +64 -0
  237. package/dist/lib/filter/evaluator.js +139 -0
  238. package/dist/lib/ids/idempotencyKey.js +28 -0
  239. package/dist/lib/memory/StageContext.js +246 -5
  240. package/dist/lib/memory/attention.js +175 -0
  241. package/dist/lib/memory/borrowedMutation.js +16 -2
  242. package/dist/lib/memory/frameTypes.js +3 -1
  243. package/dist/lib/memory/redaction.js +54 -5
  244. package/dist/lib/pause/record.js +10 -1
  245. package/dist/lib/pause/types.js +17 -1
  246. package/dist/lib/reactive/createTypedScope.js +3 -1
  247. package/dist/lib/reactive/types.js +3 -1
  248. package/dist/lib/recorder/AttemptRecorder.js +417 -0
  249. package/dist/lib/recorder/ControlDepRecorder.js +50 -2
  250. package/dist/lib/recorder/EmitRecorder.js +1 -1
  251. package/dist/lib/recorder/InOutRecorder.js +75 -6
  252. package/dist/lib/recorder/QualityRecorder.js +87 -29
  253. package/dist/lib/recorder/TopologyRecorder.js +76 -2
  254. package/dist/lib/recorder/attemptMetricRows.js +209 -0
  255. package/dist/lib/recorder/attemptMetrics.js +174 -0
  256. package/dist/lib/recorder/attemptMetricsTypes.js +3 -0
  257. package/dist/lib/recorder/attemptOTel.js +111 -0
  258. package/dist/lib/recorder/attemptSeries.js +113 -0
  259. package/dist/lib/recorder/hooks.js +4 -1
  260. package/dist/lib/runner/DeferredObserverTier.js +13 -1
  261. package/dist/lib/runner/ExecutionRuntime.js +57 -5
  262. package/dist/lib/runner/FlowChartExecutor.js +330 -101
  263. package/dist/lib/runner/RunnableChart.js +5 -1
  264. package/dist/lib/runner/attach.js +8 -2
  265. package/dist/lib/runner/checkpoint.js +3 -1
  266. package/dist/lib/runner/deadline.js +94 -0
  267. package/dist/lib/runner/index.js +4 -2
  268. package/dist/lib/runner/options.js +3 -1
  269. package/dist/lib/runner/recordSink.js +302 -0
  270. package/dist/lib/runner/resume.js +22 -2
  271. package/dist/lib/runner/snapshot.js +6 -2
  272. package/dist/lib/scope/ScopeFacade.js +303 -6
  273. package/dist/lib/scope/recorders/DebugRecorder.js +79 -13
  274. package/dist/lib/scope/recorders/MetricRecorder.js +15 -2
  275. package/dist/lib/scope/runtime.js +1 -1
  276. package/dist/lib/scope/types.js +1 -1
  277. package/dist/lib/sinks/fileSink.js +392 -0
  278. package/dist/recorders.js +10 -2
  279. package/dist/sinks.js +32 -0
  280. package/dist/trace.js +1 -1
  281. package/dist/types/index.d.ts +62 -2
  282. package/dist/types/lib/attempt/anySignal.d.ts +19 -0
  283. package/dist/types/lib/attempt/call.d.ts +88 -0
  284. package/dist/types/lib/attempt/category.d.ts +37 -0
  285. package/dist/types/lib/attempt/correlation.d.ts +95 -0
  286. package/dist/types/lib/attempt/deadline.d.ts +44 -0
  287. package/dist/types/lib/attempt/decision.d.ts +52 -0
  288. package/dist/types/lib/attempt/effect.d.ts +76 -0
  289. package/dist/types/lib/attempt/errors.d.ts +41 -0
  290. package/dist/types/lib/attempt/index.d.ts +18 -0
  291. package/dist/types/lib/attempt/name.d.ts +21 -0
  292. package/dist/types/lib/attempt/observed.d.ts +66 -0
  293. package/dist/types/lib/attempt/policy.d.ts +45 -0
  294. package/dist/types/lib/attempt/record.d.ts +11 -0
  295. package/dist/types/lib/attempt/retryLoopContext.d.ts +18 -0
  296. package/dist/types/lib/attempt/retryLoopTypes.d.ts +18 -0
  297. package/dist/types/lib/attempt/runner.d.ts +157 -0
  298. package/dist/types/lib/attempt/standalone.d.ts +47 -0
  299. package/dist/types/lib/attempt/types.d.ts +453 -0
  300. package/dist/types/lib/budget/index.d.ts +9 -0
  301. package/dist/types/lib/budget/timeBudget.d.ts +136 -0
  302. package/dist/types/lib/builder/FlowChartBuilder.d.ts +88 -3
  303. package/dist/types/lib/builder/retryLoop.d.ts +56 -0
  304. package/dist/types/lib/builder/types.d.ts +35 -1
  305. package/dist/types/lib/decide/index.d.ts +1 -1
  306. package/dist/types/lib/decide/types.d.ts +3 -0
  307. package/dist/types/lib/engine/graph/StageNode.d.ts +11 -1
  308. package/dist/types/lib/engine/handlers/StageRunner.d.ts +8 -1
  309. package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
  310. package/dist/types/lib/engine/handlers/stageError.d.ts +9 -0
  311. package/dist/types/lib/engine/index.d.ts +2 -2
  312. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
  313. package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
  314. package/dist/types/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
  315. package/dist/types/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
  316. package/dist/types/lib/engine/narrative/formatting/sentences.d.ts +23 -0
  317. package/dist/types/lib/engine/narrative/index.d.ts +2 -2
  318. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +27 -21
  319. package/dist/types/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
  320. package/dist/types/lib/engine/narrative/recorders/index.d.ts +1 -1
  321. package/dist/types/lib/engine/narrative/types.d.ts +74 -5
  322. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
  323. package/dist/types/lib/engine/traversalContext.d.ts +7 -2
  324. package/dist/types/lib/engine/types.d.ts +52 -57
  325. package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
  326. package/dist/types/lib/{decide → filter}/evaluator.d.ts +7 -2
  327. package/dist/types/lib/ids/idempotencyKey.d.ts +14 -0
  328. package/dist/types/lib/memory/StageContext.d.ts +123 -3
  329. package/dist/types/lib/memory/attention.d.ts +26 -0
  330. package/dist/types/lib/memory/borrowedMutation.d.ts +8 -0
  331. package/dist/types/lib/memory/frameTypes.d.ts +38 -0
  332. package/dist/types/lib/memory/redaction.d.ts +12 -0
  333. package/dist/types/lib/pause/types.d.ts +19 -0
  334. package/dist/types/lib/reactive/types.d.ts +36 -4
  335. package/dist/types/lib/recorder/AttemptRecorder.d.ts +141 -0
  336. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +36 -2
  337. package/dist/types/lib/recorder/EmitRecorder.d.ts +3 -0
  338. package/dist/types/lib/recorder/InOutRecorder.d.ts +37 -1
  339. package/dist/types/lib/recorder/QualityRecorder.d.ts +32 -5
  340. package/dist/types/lib/recorder/TopologyRecorder.d.ts +35 -5
  341. package/dist/types/lib/recorder/attemptMetricRows.d.ts +11 -0
  342. package/dist/types/lib/recorder/attemptMetrics.d.ts +7 -0
  343. package/dist/types/lib/recorder/attemptMetricsTypes.d.ts +114 -0
  344. package/dist/types/lib/recorder/attemptOTel.d.ts +78 -0
  345. package/dist/types/lib/recorder/attemptSeries.d.ts +81 -0
  346. package/dist/types/lib/recorder/hooks.d.ts +9 -0
  347. package/dist/types/lib/runner/ExecutionRuntime.d.ts +54 -6
  348. package/dist/types/lib/runner/FlowChartExecutor.d.ts +46 -2
  349. package/dist/types/lib/runner/RunnableChart.d.ts +6 -0
  350. package/dist/types/lib/runner/attach.d.ts +2 -1
  351. package/dist/types/lib/runner/deadline.d.ts +42 -0
  352. package/dist/types/lib/runner/index.d.ts +3 -1
  353. package/dist/types/lib/runner/options.d.ts +17 -0
  354. package/dist/types/lib/runner/recordSink.d.ts +128 -0
  355. package/dist/types/lib/runner/resume.d.ts +3 -0
  356. package/dist/types/lib/runner/snapshot.d.ts +2 -2
  357. package/dist/types/lib/scope/ScopeFacade.d.ts +118 -4
  358. package/dist/types/lib/scope/recorders/DebugRecorder.d.ts +17 -3
  359. package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +10 -0
  360. package/dist/types/lib/scope/runtime.d.ts +3 -0
  361. package/dist/types/lib/scope/types.d.ts +6 -0
  362. package/dist/types/lib/sinks/fileSink.d.ts +135 -0
  363. package/dist/types/recorders.d.ts +8 -2
  364. package/dist/types/sinks.d.ts +23 -0
  365. package/dist/types/trace.d.ts +2 -2
  366. package/package.json +20 -6
  367. package/dist/esm/lib/decide/evaluator.js +0 -130
  368. package/dist/lib/decide/evaluator.js +0 -134
@@ -0,0 +1,83 @@
1
+ /**
2
+ * attempt/policy.ts — the ONE reading of a `RetryPolicy`'s ceiling, and the ONE rule for a valid policy.
3
+ *
4
+ * `attemptCeiling` is how many attempts a policy allows. Three readers ask it, so they can never disagree about a
5
+ * stage: the engine's gate (`FlowchartTraverser · executeStage` — does this stage retry at all?), the runner
6
+ * (`runAttempts` — every record's `of`) and the rule table (`retryRules` — rule 4's threshold).
7
+ *
8
+ * `retryPolicyProblem` says why a declared policy is refused. Two doors ask it, with the same words: the builder
9
+ * at build (`FlowChartBuilder · applyRetryPolicy`), and the traverser for a StageNode a stage returns at run time
10
+ * (`FlowchartTraverser · admitDynamicNodes`), which the builder never saw.
11
+ */
12
+ /**
13
+ * The attempts a policy allows: its whole number (a fraction is floored, as the 9.15 loop read it), and never
14
+ * fewer than one. Anything that is not a finite number of at least one — `NaN`, `Infinity`, `0`, a negative, a
15
+ * non-number — is `1`: a broken ceiling never loops.
16
+ */
17
+ export function attemptCeiling(attempts) {
18
+ const whole = typeof attempts === 'number' ? Math.floor(attempts) : NaN;
19
+ return Number.isFinite(whole) && whole >= 1 ? whole : 1;
20
+ }
21
+ /**
22
+ * Why `retry` is refused, or `undefined` when it is a valid policy: `attempts` must be a whole number ≥ 1, a
23
+ * declared `timeoutMs` a finite number > 0, and a declared `maxBackoffMs` a finite number ≥ 0. `attempts: 1` is
24
+ * valid on purpose — a policy declared but switched off (or, with a `timeoutMs`, a timeout with no retry).
25
+ */
26
+ export function retryPolicyProblem(retry) {
27
+ const { attempts, timeoutMs, maxBackoffMs } = retry;
28
+ if (!(typeof attempts === 'number' && Number.isInteger(attempts) && attempts >= 1)) {
29
+ return (`retry.attempts must be a whole number >= 1 (got ${String(attempts)}). ` +
30
+ 'It counts TOTAL runs including the first, so `attempts: 3` means one run plus up to two retries; ' +
31
+ '`attempts: 1` means the policy is declared but currently off.');
32
+ }
33
+ if (timeoutMs !== undefined && attemptTimeoutMs(timeoutMs) === undefined) {
34
+ return (`retry.timeoutMs must be a finite number of milliseconds > 0 (got ${String(timeoutMs)}). ` +
35
+ 'It caps ONE attempt; leave it out for an uncapped attempt.');
36
+ }
37
+ if (maxBackoffMs !== undefined && backoffCeilingMs(maxBackoffMs) === undefined) {
38
+ return (`retry.maxBackoffMs must be a finite number of milliseconds >= 0 (got ${String(maxBackoffMs)}). ` +
39
+ 'It caps every wait between attempts; leave it out for an uncapped wait.');
40
+ }
41
+ return undefined;
42
+ }
43
+ /**
44
+ * The ceiling a policy puts on ONE wait (`maxBackoffMs`): a finite number ≥ 0, else none. The runner caps every
45
+ * wait at it (`waitAfter`), and the static budget check counts each wait at it — one reading, so the check's bound
46
+ * is the runner's law.
47
+ */
48
+ export function backoffCeilingMs(maxBackoffMs) {
49
+ return typeof maxBackoffMs === 'number' && Number.isFinite(maxBackoffMs) && maxBackoffMs >= 0
50
+ ? maxBackoffMs
51
+ : undefined;
52
+ }
53
+ /** A wait the policy's `backoffMs` answered (already defended, `resolveBackoffMs`), capped at its declared ceiling. */
54
+ export function cappedWaitMs(waitMs, maxBackoffMs) {
55
+ const ceiling = backoffCeilingMs(maxBackoffMs);
56
+ return ceiling === undefined ? waitMs : Math.min(waitMs, ceiling);
57
+ }
58
+ /**
59
+ * The cap a policy puts on one attempt: a finite number > 0, else none. The one reading the engine's gate and the
60
+ * runner share (the builder refuses any other declared value, `retryPolicyProblem`).
61
+ */
62
+ export function attemptTimeoutMs(timeoutMs) {
63
+ return typeof timeoutMs === 'number' && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : undefined;
64
+ }
65
+ /** The policy of a call made with none: one attempt — still recorded (a single call is evidence too). */
66
+ export const SINGLE_CALL = Object.freeze({ attempts: 1 });
67
+ /**
68
+ * A `$call` / `attempt()` policy as the caller handed it: absent means {@link SINGLE_CALL}; anything else must be a
69
+ * valid `RetryPolicy` (`retryPolicyProblem`) or it is refused with a `TypeError` naming `where` — at the call,
70
+ * before anything runs.
71
+ */
72
+ export function admitCallPolicy(where, policy) {
73
+ if (policy === undefined)
74
+ return SINGLE_CALL;
75
+ if (policy === null || typeof policy !== 'object') {
76
+ throw new TypeError(`${where}: the policy must be a RetryPolicy object ({ attempts, timeoutMs?, backoffMs?, retryOn? })`);
77
+ }
78
+ const problem = retryPolicyProblem(policy);
79
+ if (problem !== undefined)
80
+ throw new TypeError(`${where}: ${problem}`);
81
+ return policy;
82
+ }
83
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9hdHRlbXB0L3BvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBSUg7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsUUFBaUI7SUFDOUMsTUFBTSxLQUFLLEdBQUcsT0FBTyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDeEUsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxLQUFtRTtJQUVuRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDcEQsSUFBSSxDQUFDLENBQUMsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksUUFBUSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDbkYsT0FBTyxDQUNMLG1EQUFtRCxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUs7WUFDeEUsbUdBQW1HO1lBQ25HLCtEQUErRCxDQUNoRSxDQUFDO0lBQ0osQ0FBQztJQUNELElBQUksU0FBUyxLQUFLLFNBQVMsSUFBSSxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN6RSxPQUFPLENBQ0wsb0VBQW9FLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSztZQUMxRiw0REFBNEQsQ0FDN0QsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLFlBQVksS0FBSyxTQUFTLElBQUksZ0JBQWdCLENBQUMsWUFBWSxDQUFDLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDL0UsT0FBTyxDQUNMLHdFQUF3RSxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUs7WUFDakcseUVBQXlFLENBQzFFLENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsWUFBcUI7SUFDcEQsT0FBTyxPQUFPLFlBQVksS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxZQUFZLElBQUksQ0FBQztRQUMzRixDQUFDLENBQUMsWUFBWTtRQUNkLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDaEIsQ0FBQztBQUVELHVIQUF1SDtBQUN2SCxNQUFNLFVBQVUsWUFBWSxDQUFDLE1BQWMsRUFBRSxZQUFxQjtJQUNoRSxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMvQyxPQUFPLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDcEUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxTQUFrQjtJQUNqRCxPQUFPLE9BQU8sU0FBUyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzlHLENBQUM7QUFFRCx5R0FBeUc7QUFDekcsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFnQixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFdkU7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBYSxFQUFFLE1BQWU7SUFDNUQsSUFBSSxNQUFNLEtBQUssU0FBUztRQUFFLE9BQU8sV0FBVyxDQUFDO0lBQzdDLElBQUksTUFBTSxLQUFLLElBQUksSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNsRCxNQUFNLElBQUksU0FBUyxDQUNqQixHQUFHLEtBQUssNEZBQTRGLENBQ3JHLENBQUM7SUFDSixDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsTUFBcUIsQ0FBQyxDQUFDO0lBQzFELElBQUksT0FBTyxLQUFLLFNBQVM7UUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsS0FBSyxLQUFLLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdkUsT0FBTyxNQUFxQixDQUFDO0FBQy9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvcG9saWN5LnRzIOKAlCB0aGUgT05FIHJlYWRpbmcgb2YgYSBgUmV0cnlQb2xpY3lgJ3MgY2VpbGluZywgYW5kIHRoZSBPTkUgcnVsZSBmb3IgYSB2YWxpZCBwb2xpY3kuXG4gKlxuICogYGF0dGVtcHRDZWlsaW5nYCBpcyBob3cgbWFueSBhdHRlbXB0cyBhIHBvbGljeSBhbGxvd3MuIFRocmVlIHJlYWRlcnMgYXNrIGl0LCBzbyB0aGV5IGNhbiBuZXZlciBkaXNhZ3JlZSBhYm91dCBhXG4gKiBzdGFnZTogdGhlIGVuZ2luZSdzIGdhdGUgKGBGbG93Y2hhcnRUcmF2ZXJzZXIgwrcgZXhlY3V0ZVN0YWdlYCDigJQgZG9lcyB0aGlzIHN0YWdlIHJldHJ5IGF0IGFsbD8pLCB0aGUgcnVubmVyXG4gKiAoYHJ1bkF0dGVtcHRzYCDigJQgZXZlcnkgcmVjb3JkJ3MgYG9mYCkgYW5kIHRoZSBydWxlIHRhYmxlIChgcmV0cnlSdWxlc2Ag4oCUIHJ1bGUgNCdzIHRocmVzaG9sZCkuXG4gKlxuICogYHJldHJ5UG9saWN5UHJvYmxlbWAgc2F5cyB3aHkgYSBkZWNsYXJlZCBwb2xpY3kgaXMgcmVmdXNlZC4gVHdvIGRvb3JzIGFzayBpdCwgd2l0aCB0aGUgc2FtZSB3b3JkczogdGhlIGJ1aWxkZXJcbiAqIGF0IGJ1aWxkIChgRmxvd0NoYXJ0QnVpbGRlciDCtyBhcHBseVJldHJ5UG9saWN5YCksIGFuZCB0aGUgdHJhdmVyc2VyIGZvciBhIFN0YWdlTm9kZSBhIHN0YWdlIHJldHVybnMgYXQgcnVuIHRpbWVcbiAqIChgRmxvd2NoYXJ0VHJhdmVyc2VyIMK3IGFkbWl0RHluYW1pY05vZGVzYCksIHdoaWNoIHRoZSBidWlsZGVyIG5ldmVyIHNhdy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFJldHJ5UG9saWN5IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKlxuICogVGhlIGF0dGVtcHRzIGEgcG9saWN5IGFsbG93czogaXRzIHdob2xlIG51bWJlciAoYSBmcmFjdGlvbiBpcyBmbG9vcmVkLCBhcyB0aGUgOS4xNSBsb29wIHJlYWQgaXQpLCBhbmQgbmV2ZXJcbiAqIGZld2VyIHRoYW4gb25lLiBBbnl0aGluZyB0aGF0IGlzIG5vdCBhIGZpbml0ZSBudW1iZXIgb2YgYXQgbGVhc3Qgb25lIOKAlCBgTmFOYCwgYEluZmluaXR5YCwgYDBgLCBhIG5lZ2F0aXZlLCBhXG4gKiBub24tbnVtYmVyIOKAlCBpcyBgMWA6IGEgYnJva2VuIGNlaWxpbmcgbmV2ZXIgbG9vcHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdHRlbXB0Q2VpbGluZyhhdHRlbXB0czogdW5rbm93bik6IG51bWJlciB7XG4gIGNvbnN0IHdob2xlID0gdHlwZW9mIGF0dGVtcHRzID09PSAnbnVtYmVyJyA/IE1hdGguZmxvb3IoYXR0ZW1wdHMpIDogTmFOO1xuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHdob2xlKSAmJiB3aG9sZSA+PSAxID8gd2hvbGUgOiAxO1xufVxuXG4vKipcbiAqIFdoeSBgcmV0cnlgIGlzIHJlZnVzZWQsIG9yIGB1bmRlZmluZWRgIHdoZW4gaXQgaXMgYSB2YWxpZCBwb2xpY3k6IGBhdHRlbXB0c2AgbXVzdCBiZSBhIHdob2xlIG51bWJlciDiiaUgMSwgYVxuICogZGVjbGFyZWQgYHRpbWVvdXRNc2AgYSBmaW5pdGUgbnVtYmVyID4gMCwgYW5kIGEgZGVjbGFyZWQgYG1heEJhY2tvZmZNc2AgYSBmaW5pdGUgbnVtYmVyIOKJpSAwLiBgYXR0ZW1wdHM6IDFgIGlzXG4gKiB2YWxpZCBvbiBwdXJwb3NlIOKAlCBhIHBvbGljeSBkZWNsYXJlZCBidXQgc3dpdGNoZWQgb2ZmIChvciwgd2l0aCBhIGB0aW1lb3V0TXNgLCBhIHRpbWVvdXQgd2l0aCBubyByZXRyeSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXRyeVBvbGljeVByb2JsZW0oXG4gIHJldHJ5OiBQaWNrPFJldHJ5UG9saWN5LCAnYXR0ZW1wdHMnIHwgJ3RpbWVvdXRNcycgfCAnbWF4QmFja29mZk1zJz4sXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCB7IGF0dGVtcHRzLCB0aW1lb3V0TXMsIG1heEJhY2tvZmZNcyB9ID0gcmV0cnk7XG4gIGlmICghKHR5cGVvZiBhdHRlbXB0cyA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzSW50ZWdlcihhdHRlbXB0cykgJiYgYXR0ZW1wdHMgPj0gMSkpIHtcbiAgICByZXR1cm4gKFxuICAgICAgYHJldHJ5LmF0dGVtcHRzIG11c3QgYmUgYSB3aG9sZSBudW1iZXIgPj0gMSAoZ290ICR7U3RyaW5nKGF0dGVtcHRzKX0pLiBgICtcbiAgICAgICdJdCBjb3VudHMgVE9UQUwgcnVucyBpbmNsdWRpbmcgdGhlIGZpcnN0LCBzbyBgYXR0ZW1wdHM6IDNgIG1lYW5zIG9uZSBydW4gcGx1cyB1cCB0byB0d28gcmV0cmllczsgJyArXG4gICAgICAnYGF0dGVtcHRzOiAxYCBtZWFucyB0aGUgcG9saWN5IGlzIGRlY2xhcmVkIGJ1dCBjdXJyZW50bHkgb2ZmLidcbiAgICApO1xuICB9XG4gIGlmICh0aW1lb3V0TXMgIT09IHVuZGVmaW5lZCAmJiBhdHRlbXB0VGltZW91dE1zKHRpbWVvdXRNcykgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAoXG4gICAgICBgcmV0cnkudGltZW91dE1zIG11c3QgYmUgYSBmaW5pdGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyA+IDAgKGdvdCAke1N0cmluZyh0aW1lb3V0TXMpfSkuIGAgK1xuICAgICAgJ0l0IGNhcHMgT05FIGF0dGVtcHQ7IGxlYXZlIGl0IG91dCBmb3IgYW4gdW5jYXBwZWQgYXR0ZW1wdC4nXG4gICAgKTtcbiAgfVxuICBpZiAobWF4QmFja29mZk1zICE9PSB1bmRlZmluZWQgJiYgYmFja29mZkNlaWxpbmdNcyhtYXhCYWNrb2ZmTXMpID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gKFxuICAgICAgYHJldHJ5Lm1heEJhY2tvZmZNcyBtdXN0IGJlIGEgZmluaXRlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgPj0gMCAoZ290ICR7U3RyaW5nKG1heEJhY2tvZmZNcyl9KS4gYCArXG4gICAgICAnSXQgY2FwcyBldmVyeSB3YWl0IGJldHdlZW4gYXR0ZW1wdHM7IGxlYXZlIGl0IG91dCBmb3IgYW4gdW5jYXBwZWQgd2FpdC4nXG4gICAgKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRoZSBjZWlsaW5nIGEgcG9saWN5IHB1dHMgb24gT05FIHdhaXQgKGBtYXhCYWNrb2ZmTXNgKTogYSBmaW5pdGUgbnVtYmVyIOKJpSAwLCBlbHNlIG5vbmUuIFRoZSBydW5uZXIgY2FwcyBldmVyeVxuICogd2FpdCBhdCBpdCAoYHdhaXRBZnRlcmApLCBhbmQgdGhlIHN0YXRpYyBidWRnZXQgY2hlY2sgY291bnRzIGVhY2ggd2FpdCBhdCBpdCDigJQgb25lIHJlYWRpbmcsIHNvIHRoZSBjaGVjaydzIGJvdW5kXG4gKiBpcyB0aGUgcnVubmVyJ3MgbGF3LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmFja29mZkNlaWxpbmdNcyhtYXhCYWNrb2ZmTXM6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHlwZW9mIG1heEJhY2tvZmZNcyA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG1heEJhY2tvZmZNcykgJiYgbWF4QmFja29mZk1zID49IDBcbiAgICA/IG1heEJhY2tvZmZNc1xuICAgIDogdW5kZWZpbmVkO1xufVxuXG4vKiogQSB3YWl0IHRoZSBwb2xpY3kncyBgYmFja29mZk1zYCBhbnN3ZXJlZCAoYWxyZWFkeSBkZWZlbmRlZCwgYHJlc29sdmVCYWNrb2ZmTXNgKSwgY2FwcGVkIGF0IGl0cyBkZWNsYXJlZCBjZWlsaW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhcHBlZFdhaXRNcyh3YWl0TXM6IG51bWJlciwgbWF4QmFja29mZk1zOiB1bmtub3duKTogbnVtYmVyIHtcbiAgY29uc3QgY2VpbGluZyA9IGJhY2tvZmZDZWlsaW5nTXMobWF4QmFja29mZk1zKTtcbiAgcmV0dXJuIGNlaWxpbmcgPT09IHVuZGVmaW5lZCA/IHdhaXRNcyA6IE1hdGgubWluKHdhaXRNcywgY2VpbGluZyk7XG59XG5cbi8qKlxuICogVGhlIGNhcCBhIHBvbGljeSBwdXRzIG9uIG9uZSBhdHRlbXB0OiBhIGZpbml0ZSBudW1iZXIgPiAwLCBlbHNlIG5vbmUuIFRoZSBvbmUgcmVhZGluZyB0aGUgZW5naW5lJ3MgZ2F0ZSBhbmQgdGhlXG4gKiBydW5uZXIgc2hhcmUgKHRoZSBidWlsZGVyIHJlZnVzZXMgYW55IG90aGVyIGRlY2xhcmVkIHZhbHVlLCBgcmV0cnlQb2xpY3lQcm9ibGVtYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdHRlbXB0VGltZW91dE1zKHRpbWVvdXRNczogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0eXBlb2YgdGltZW91dE1zID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodGltZW91dE1zKSAmJiB0aW1lb3V0TXMgPiAwID8gdGltZW91dE1zIDogdW5kZWZpbmVkO1xufVxuXG4vKiogVGhlIHBvbGljeSBvZiBhIGNhbGwgbWFkZSB3aXRoIG5vbmU6IG9uZSBhdHRlbXB0IOKAlCBzdGlsbCByZWNvcmRlZCAoYSBzaW5nbGUgY2FsbCBpcyBldmlkZW5jZSB0b28pLiAqL1xuZXhwb3J0IGNvbnN0IFNJTkdMRV9DQUxMOiBSZXRyeVBvbGljeSA9IE9iamVjdC5mcmVlemUoeyBhdHRlbXB0czogMSB9KTtcblxuLyoqXG4gKiBBIGAkY2FsbGAgLyBgYXR0ZW1wdCgpYCBwb2xpY3kgYXMgdGhlIGNhbGxlciBoYW5kZWQgaXQ6IGFic2VudCBtZWFucyB7QGxpbmsgU0lOR0xFX0NBTEx9OyBhbnl0aGluZyBlbHNlIG11c3QgYmUgYVxuICogdmFsaWQgYFJldHJ5UG9saWN5YCAoYHJldHJ5UG9saWN5UHJvYmxlbWApIG9yIGl0IGlzIHJlZnVzZWQgd2l0aCBhIGBUeXBlRXJyb3JgIG5hbWluZyBgd2hlcmVgIOKAlCBhdCB0aGUgY2FsbCxcbiAqIGJlZm9yZSBhbnl0aGluZyBydW5zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRtaXRDYWxsUG9saWN5KHdoZXJlOiBzdHJpbmcsIHBvbGljeTogdW5rbm93bik6IFJldHJ5UG9saWN5IHtcbiAgaWYgKHBvbGljeSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gU0lOR0xFX0NBTEw7XG4gIGlmIChwb2xpY3kgPT09IG51bGwgfHwgdHlwZW9mIHBvbGljeSAhPT0gJ29iamVjdCcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgYCR7d2hlcmV9OiB0aGUgcG9saWN5IG11c3QgYmUgYSBSZXRyeVBvbGljeSBvYmplY3QgKHsgYXR0ZW1wdHMsIHRpbWVvdXRNcz8sIGJhY2tvZmZNcz8sIHJldHJ5T24/IH0pYCxcbiAgICApO1xuICB9XG4gIGNvbnN0IHByb2JsZW0gPSByZXRyeVBvbGljeVByb2JsZW0ocG9saWN5IGFzIFJldHJ5UG9saWN5KTtcbiAgaWYgKHByb2JsZW0gIT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHt3aGVyZX06ICR7cHJvYmxlbX1gKTtcbiAgcmV0dXJuIHBvbGljeSBhcyBSZXRyeVBvbGljeTtcbn1cbiJdfQ==
@@ -0,0 +1,11 @@
1
+ /**
2
+ * attempt/record.ts — how an `AttemptRecord` holds what it holds: frozen to its leaves, and an error only as the run
3
+ * SERVES it, named fields only. One owner, so a record the runner makes (`runner.ts`) and a record an adapter
4
+ * reports (`observed.ts`) can never differ in what they keep.
5
+ */
6
+ import type { StructuredErrorInfo } from '../errors/errorInfo.js';
7
+ import type { AttemptError } from './types.js';
8
+ /** The record's copy of a served error: its named fields only — never `raw`, never an extra own key. */
9
+ export declare function recordedError(served: StructuredErrorInfo): AttemptError;
10
+ /** Freeze a record built of plain objects and arrays, to its leaves. */
11
+ export declare function freezeDeep<T>(value: T): T;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * attempt/record.ts — how an `AttemptRecord` holds what it holds: frozen to its leaves, and an error only as the run
3
+ * SERVES it, named fields only. One owner, so a record the runner makes (`runner.ts`) and a record an adapter
4
+ * reports (`observed.ts`) can never differ in what they keep.
5
+ */
6
+ /** The record's copy of a served error: its named fields only — never `raw`, never an extra own key. */
7
+ export function recordedError(served) {
8
+ return {
9
+ message: served.message,
10
+ ...(served.name !== undefined && { name: served.name }),
11
+ ...(served.code !== undefined && { code: served.code }),
12
+ ...(served.issues !== undefined && { issues: served.issues.map((issue) => ({ ...issue, path: [...issue.path] })) }),
13
+ };
14
+ }
15
+ /** Freeze a record built of plain objects and arrays, to its leaves. */
16
+ export function freezeDeep(value) {
17
+ if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
18
+ Object.freeze(value);
19
+ for (const key of Object.keys(value))
20
+ freezeDeep(value[key]);
21
+ }
22
+ return value;
23
+ }
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9hdHRlbXB0L3JlY29yZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBS0gsd0dBQXdHO0FBQ3hHLE1BQU0sVUFBVSxhQUFhLENBQUMsTUFBMkI7SUFDdkQsT0FBTztRQUNMLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztRQUN2QixHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZELEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNwSCxDQUFDO0FBQ0osQ0FBQztBQUVELHdFQUF3RTtBQUN4RSxNQUFNLFVBQVUsVUFBVSxDQUFJLEtBQVE7SUFDcEMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMzRSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JCLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFBRSxVQUFVLENBQUUsS0FBaUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzVGLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvcmVjb3JkLnRzIOKAlCBob3cgYW4gYEF0dGVtcHRSZWNvcmRgIGhvbGRzIHdoYXQgaXQgaG9sZHM6IGZyb3plbiB0byBpdHMgbGVhdmVzLCBhbmQgYW4gZXJyb3Igb25seSBhcyB0aGUgcnVuXG4gKiBTRVJWRVMgaXQsIG5hbWVkIGZpZWxkcyBvbmx5LiBPbmUgb3duZXIsIHNvIGEgcmVjb3JkIHRoZSBydW5uZXIgbWFrZXMgKGBydW5uZXIudHNgKSBhbmQgYSByZWNvcmQgYW4gYWRhcHRlclxuICogcmVwb3J0cyAoYG9ic2VydmVkLnRzYCkgY2FuIG5ldmVyIGRpZmZlciBpbiB3aGF0IHRoZXkga2VlcC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFN0cnVjdHVyZWRFcnJvckluZm8gfSBmcm9tICcuLi9lcnJvcnMvZXJyb3JJbmZvLmpzJztcbmltcG9ydCB0eXBlIHsgQXR0ZW1wdEVycm9yIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKiBUaGUgcmVjb3JkJ3MgY29weSBvZiBhIHNlcnZlZCBlcnJvcjogaXRzIG5hbWVkIGZpZWxkcyBvbmx5IOKAlCBuZXZlciBgcmF3YCwgbmV2ZXIgYW4gZXh0cmEgb3duIGtleS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRlZEVycm9yKHNlcnZlZDogU3RydWN0dXJlZEVycm9ySW5mbyk6IEF0dGVtcHRFcnJvciB7XG4gIHJldHVybiB7XG4gICAgbWVzc2FnZTogc2VydmVkLm1lc3NhZ2UsXG4gICAgLi4uKHNlcnZlZC5uYW1lICE9PSB1bmRlZmluZWQgJiYgeyBuYW1lOiBzZXJ2ZWQubmFtZSB9KSxcbiAgICAuLi4oc2VydmVkLmNvZGUgIT09IHVuZGVmaW5lZCAmJiB7IGNvZGU6IHNlcnZlZC5jb2RlIH0pLFxuICAgIC4uLihzZXJ2ZWQuaXNzdWVzICE9PSB1bmRlZmluZWQgJiYgeyBpc3N1ZXM6IHNlcnZlZC5pc3N1ZXMubWFwKChpc3N1ZSkgPT4gKHsgLi4uaXNzdWUsIHBhdGg6IFsuLi5pc3N1ZS5wYXRoXSB9KSkgfSksXG4gIH07XG59XG5cbi8qKiBGcmVlemUgYSByZWNvcmQgYnVpbHQgb2YgcGxhaW4gb2JqZWN0cyBhbmQgYXJyYXlzLCB0byBpdHMgbGVhdmVzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyZWV6ZURlZXA8VD4odmFsdWU6IFQpOiBUIHtcbiAgaWYgKHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgIU9iamVjdC5pc0Zyb3plbih2YWx1ZSkpIHtcbiAgICBPYmplY3QuZnJlZXplKHZhbHVlKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh2YWx1ZSkpIGZyZWV6ZURlZXAoKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtrZXldKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG4iXX0=
@@ -0,0 +1,18 @@
1
+ /** Internal one-call port: the builder declares logical identity; the call owner stamps it before dispatch. */
2
+ import type { RetryLoopCall } from './retryLoopTypes.js';
3
+ import type { AttemptRecord } from './types.js';
4
+ export interface RetryLoopCallPort {
5
+ readonly identity: RetryLoopCall;
6
+ readonly record: (record: AttemptRecord) => void;
7
+ }
8
+ export declare function registerRetryLoopCall(target: object, port: RetryLoopCallPort): () => void;
9
+ /** Claimed once, so nested calls made by the user's callback do not inherit the outer call's logical identity. */
10
+ export declare function takeRetryLoopCall(target: object): RetryLoopCallPort | undefined;
11
+ export interface RetryLoopBudget {
12
+ readonly passes?: number;
13
+ readonly role: 'callback' | 'control' | 'wait';
14
+ readonly timeoutMs?: number;
15
+ readonly waitMs?: number;
16
+ }
17
+ export declare function declareRetryLoopBudget(node: object, budget: RetryLoopBudget): void;
18
+ export declare function retryLoopBudget(node: object): RetryLoopBudget | undefined;
@@ -0,0 +1,24 @@
1
+ const calls = new WeakMap();
2
+ export function registerRetryLoopCall(target, port) {
3
+ if (calls.has(target))
4
+ throw new Error('retry loop: another call is already being prepared on this scope');
5
+ calls.set(target, port);
6
+ return () => {
7
+ if (calls.get(target) === port)
8
+ calls.delete(target);
9
+ };
10
+ }
11
+ /** Claimed once, so nested calls made by the user's callback do not inherit the outer call's logical identity. */
12
+ export function takeRetryLoopCall(target) {
13
+ const port = calls.get(target);
14
+ calls.delete(target);
15
+ return port;
16
+ }
17
+ const budgets = new WeakMap();
18
+ export function declareRetryLoopBudget(node, budget) {
19
+ budgets.set(node, Object.freeze({ ...budget }));
20
+ }
21
+ export function retryLoopBudget(node) {
22
+ return budgets.get(node);
23
+ }
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0cnlMb29wQ29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvYXR0ZW1wdC9yZXRyeUxvb3BDb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE1BQU0sS0FBSyxHQUFHLElBQUksT0FBTyxFQUE2QixDQUFDO0FBRXZELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxNQUFjLEVBQUUsSUFBdUI7SUFDM0UsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQztJQUMzRyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN4QixPQUFPLEdBQUcsRUFBRTtRQUNWLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJO1lBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2RCxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsa0hBQWtIO0FBQ2xILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxNQUFjO0lBQzlDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyQixPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFTRCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBMkIsQ0FBQztBQUN2RCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsSUFBWSxFQUFFLE1BQXVCO0lBQzFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNsRCxDQUFDO0FBQ0QsTUFBTSxVQUFVLGVBQWUsQ0FBQyxJQUFZO0lBQzFDLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMzQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEludGVybmFsIG9uZS1jYWxsIHBvcnQ6IHRoZSBidWlsZGVyIGRlY2xhcmVzIGxvZ2ljYWwgaWRlbnRpdHk7IHRoZSBjYWxsIG93bmVyIHN0YW1wcyBpdCBiZWZvcmUgZGlzcGF0Y2guICovXG5pbXBvcnQgdHlwZSB7IFJldHJ5TG9vcENhbGwgfSBmcm9tICcuL3JldHJ5TG9vcFR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgQXR0ZW1wdFJlY29yZCB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJldHJ5TG9vcENhbGxQb3J0IHtcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IFJldHJ5TG9vcENhbGw7XG4gIHJlYWRvbmx5IHJlY29yZDogKHJlY29yZDogQXR0ZW1wdFJlY29yZCkgPT4gdm9pZDtcbn1cblxuY29uc3QgY2FsbHMgPSBuZXcgV2Vha01hcDxvYmplY3QsIFJldHJ5TG9vcENhbGxQb3J0PigpO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJSZXRyeUxvb3BDYWxsKHRhcmdldDogb2JqZWN0LCBwb3J0OiBSZXRyeUxvb3BDYWxsUG9ydCk6ICgpID0+IHZvaWQge1xuICBpZiAoY2FsbHMuaGFzKHRhcmdldCkpIHRocm93IG5ldyBFcnJvcigncmV0cnkgbG9vcDogYW5vdGhlciBjYWxsIGlzIGFscmVhZHkgYmVpbmcgcHJlcGFyZWQgb24gdGhpcyBzY29wZScpO1xuICBjYWxscy5zZXQodGFyZ2V0LCBwb3J0KTtcbiAgcmV0dXJuICgpID0+IHtcbiAgICBpZiAoY2FsbHMuZ2V0KHRhcmdldCkgPT09IHBvcnQpIGNhbGxzLmRlbGV0ZSh0YXJnZXQpO1xuICB9O1xufVxuXG4vKiogQ2xhaW1lZCBvbmNlLCBzbyBuZXN0ZWQgY2FsbHMgbWFkZSBieSB0aGUgdXNlcidzIGNhbGxiYWNrIGRvIG5vdCBpbmhlcml0IHRoZSBvdXRlciBjYWxsJ3MgbG9naWNhbCBpZGVudGl0eS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0YWtlUmV0cnlMb29wQ2FsbCh0YXJnZXQ6IG9iamVjdCk6IFJldHJ5TG9vcENhbGxQb3J0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcG9ydCA9IGNhbGxzLmdldCh0YXJnZXQpO1xuICBjYWxscy5kZWxldGUodGFyZ2V0KTtcbiAgcmV0dXJuIHBvcnQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlMb29wQnVkZ2V0IHtcbiAgcmVhZG9ubHkgcGFzc2VzPzogbnVtYmVyO1xuICByZWFkb25seSByb2xlOiAnY2FsbGJhY2snIHwgJ2NvbnRyb2wnIHwgJ3dhaXQnO1xuICByZWFkb25seSB0aW1lb3V0TXM/OiBudW1iZXI7XG4gIHJlYWRvbmx5IHdhaXRNcz86IG51bWJlcjtcbn1cblxuY29uc3QgYnVkZ2V0cyA9IG5ldyBXZWFrTWFwPG9iamVjdCwgUmV0cnlMb29wQnVkZ2V0PigpO1xuZXhwb3J0IGZ1bmN0aW9uIGRlY2xhcmVSZXRyeUxvb3BCdWRnZXQobm9kZTogb2JqZWN0LCBidWRnZXQ6IFJldHJ5TG9vcEJ1ZGdldCk6IHZvaWQge1xuICBidWRnZXRzLnNldChub2RlLCBPYmplY3QuZnJlZXplKHsgLi4uYnVkZ2V0IH0pKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiByZXRyeUxvb3BCdWRnZXQobm9kZTogb2JqZWN0KTogUmV0cnlMb29wQnVkZ2V0IHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIGJ1ZGdldHMuZ2V0KG5vZGUpO1xufVxuIl19
@@ -0,0 +1,18 @@
1
+ /** Logical identity of an explicit retry workflow. Physical attempt identities remain unchanged. */
2
+ export interface RetryLoopIdentity {
3
+ readonly id: string;
4
+ readonly series: string;
5
+ readonly attempt: number;
6
+ readonly of: number;
7
+ }
8
+ /** The role of one physical call inside a logical pass. */
9
+ export interface RetryLoopCall extends RetryLoopIdentity {
10
+ readonly phase: 'attempt' | 'reconcile';
11
+ }
12
+ /** The explicit chart decision, after reconciliation; never rewrites a physical call's outcome. */
13
+ export interface RetryLoopDecision extends RetryLoopIdentity {
14
+ readonly effect: 'applied' | 'none' | 'unknown';
15
+ readonly reconciled: boolean;
16
+ readonly next: 'retry' | 'done' | 'stop';
17
+ readonly reason: string;
18
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV0cnlMb29wVHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2F0dGVtcHQvcmV0cnlMb29wVHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBMb2dpY2FsIGlkZW50aXR5IG9mIGFuIGV4cGxpY2l0IHJldHJ5IHdvcmtmbG93LiBQaHlzaWNhbCBhdHRlbXB0IGlkZW50aXRpZXMgcmVtYWluIHVuY2hhbmdlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlMb29wSWRlbnRpdHkge1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuICByZWFkb25seSBzZXJpZXM6IHN0cmluZztcbiAgcmVhZG9ubHkgYXR0ZW1wdDogbnVtYmVyO1xuICByZWFkb25seSBvZjogbnVtYmVyO1xufVxuXG4vKiogVGhlIHJvbGUgb2Ygb25lIHBoeXNpY2FsIGNhbGwgaW5zaWRlIGEgbG9naWNhbCBwYXNzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXRyeUxvb3BDYWxsIGV4dGVuZHMgUmV0cnlMb29wSWRlbnRpdHkge1xuICByZWFkb25seSBwaGFzZTogJ2F0dGVtcHQnIHwgJ3JlY29uY2lsZSc7XG59XG5cbi8qKiBUaGUgZXhwbGljaXQgY2hhcnQgZGVjaXNpb24sIGFmdGVyIHJlY29uY2lsaWF0aW9uOyBuZXZlciByZXdyaXRlcyBhIHBoeXNpY2FsIGNhbGwncyBvdXRjb21lLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXRyeUxvb3BEZWNpc2lvbiBleHRlbmRzIFJldHJ5TG9vcElkZW50aXR5IHtcbiAgcmVhZG9ubHkgZWZmZWN0OiAnYXBwbGllZCcgfCAnbm9uZScgfCAndW5rbm93bic7XG4gIHJlYWRvbmx5IHJlY29uY2lsZWQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5leHQ6ICdyZXRyeScgfCAnZG9uZScgfCAnc3RvcCc7XG4gIHJlYWRvbmx5IHJlYXNvbjogc3RyaW5nO1xufVxuIl19
@@ -0,0 +1,157 @@
1
+ /**
2
+ * attempt/runner.ts — `runAttempts`, THE retry loop (design §3.1, law 1: one runner, one record).
3
+ *
4
+ * Runs a function under a policy and records every try: one frozen `AttemptRecord` per attempt, carrying its
5
+ * timing, outcome, failure category and the retry-or-stop decision (`attempt/decision.ts`), and one
6
+ * `AttemptSummary` when the series ends. The engine's stage retry (`FlowchartTraverser · executeStage`) runs on
7
+ * it; later packets run in-stage calls and standalone `attempt()` on it too.
8
+ *
9
+ * The loop, per attempt n — for a failed attempt, the 9.15 loop's order, step for step:
10
+ *
11
+ * start → run(n) → outcome (ok | failed | aborted [it threw the run's abort reason] | paused [a PauseSignal])
12
+ * → decide over the inputs, first match wins (`retryRules`) — retryOn is asked here (rule 5)
13
+ * → the run's signal aborted inside retryOn? decide again: rule 3 stops the series here, before the
14
+ * discard and before backoffMs, as the 9.15 abort check did
15
+ * → retry: between(n) — the discard — and THEN backoffMs(n), the wait's length
16
+ * → the error's served form and category, read after retryOn and backoffMs ran → the record
17
+ * → onEnd(summary) only when the series ends here
18
+ * → onAttempt(record, served error)
19
+ * → done: return the value · stop: rethrow the attempt's OWN error
20
+ * → retry: onRetry(n, of, delay, served error) → wait (cut short by the signal) → aborted? stop
21
+ *
22
+ * WHAT IT PRESERVES (the 9.15 loop's behaviour, moved here unchanged): the function runs the same number of
23
+ * times; `retryOn` is asked only for a failed, non-final attempt; `backoffMs` only when a retry follows, after
24
+ * the discard; a throwing predicate is "do not retry", a throwing or non-finite backoff is "no wait"; a pause is
25
+ * never retried; the attempt's own error is rethrown, never a wrapper; and a failed attempt's order —
26
+ * `retryOn` → the abort check → the discard (`between`) → `backoffMs` → the served error → the retry event →
27
+ * the wait → the abort check. So an abort inside `retryOn` stops before the discard and never asks `backoffMs`;
28
+ * an abort inside `backoffMs` comes after the discard, still fires the retry event, then ends at the wait; and
29
+ * the served error shows what `retryOn` did to the thrown value. The one difference: when the run's signal has
30
+ * ALREADY aborted as the attempt fails, the series stops without asking `retryOn` (the abort decides first —
31
+ * rule 3 before rule 5).
32
+ *
33
+ * WHAT IT ADDS: the record and the summary. A record is frozen to its leaves and holds only clone-safe data —
34
+ * the error as the run SERVES it (`serve`, the redaction rule's form) without `raw`. The hook gets the served
35
+ * `StructuredErrorInfo` whole, `raw` included, as `onStageRetry` always has. A record never rewrites what the
36
+ * attempt did: an attempt that threw its own error is `failed`, with its category, even when the run aborted
37
+ * around it — the abort is the series' stop reason (`reason: 'aborted'`); a throwing `retryOn` is `declined`
38
+ * with `retryOnThrew: true`, apart from a real `false`.
39
+ *
40
+ * TIME (P1b). Each attempt runs under `min(policy.timeoutMs, time left before options.deadline)` and gets an
41
+ * `AttemptContext` — its signal, composed from the run's and its own cap's timer (`LiveAttempt`). The cap's timer
42
+ * aborts with an `AttemptTimeoutError`; the run's deadline aborts the run's signal with a branded reason
43
+ * (`attempt/deadline.ts`). Either way the attempt is `'timeout'`, never `'aborted'`: the deadline is not a
44
+ * cancellation, so rule 3 does not match and rule 6 (`timeLeftAfterWaitMs ≤ 0`) stops a series whose next wait
45
+ * would outlast it. Under a deadline rule 6 needs the wait's length, so `backoffMs(n, error)` is asked DURING the
46
+ * decision — before the discard; without one the 9.15 order above holds unchanged. No attempt starts at or past
47
+ * the deadline: a wait the deadline cut ends the series `no-time-left`, recording no further attempt.
48
+ *
49
+ * THE FENCE. The moment an attempt ends without an answer — its signal aborts (synchronously, before any listener
50
+ * the function added) or it throws — `onAbandon(n)` fires once, and the engine closes that attempt's scope: the
51
+ * function may still be running, and nothing it does afterwards may land beside a later attempt.
52
+ *
53
+ * ONE async frame with ONE await per attempt: the engine relies on that to keep a retried stage's microtask
54
+ * shape, so parallel siblings settle in the order they always did. The engine races the attempt's signal itself,
55
+ * at the stage boundary (`raced: true`); any other caller gets the race here, so the series never waits on an
56
+ * attempt past its cap.
57
+ *
58
+ * CALLS (P2). The same loop runs a call a stage makes (`attempt/call.ts · runCall`, kind `'call'`, its `target` on
59
+ * every record) and the standalone `attempt()`. An attempt's cap is the DEADLINE of every call made inside it, so
60
+ * the cap's reason is branded a time limit (`attempt/deadline.ts · markTimeLimit`): a call cut by its stage
61
+ * attempt's cap timed out, it was not cancelled. `attemptEndsAt` says when an attempt must end; an `interrupt()`
62
+ * thrown inside a call is a pause, like a `PauseSignal` — never retried.
63
+ */
64
+ import type { StructuredErrorInfo } from '../errors/errorInfo.js';
65
+ import type { EffectTarget } from './effect.js';
66
+ import type { AttemptCategory, AttemptContext, AttemptKind, AttemptRecord, AttemptSummary, ObservedAttempt, RetryPolicy } from './types.js';
67
+ /** What a series reports, and the engine's between-attempt step. Every member is optional. */
68
+ export interface AttemptRunOptions {
69
+ /** The series every record names — for a stage attempt, its execution's `runtimeStageId`. */
70
+ readonly series: string;
71
+ /** Default `'stage'`. */
72
+ readonly kind?: AttemptKind;
73
+ /** The outside target every record names — a call's (`$call`, `attempt()`); absent for a stage attempt. */
74
+ readonly target?: string;
75
+ /**
76
+ * The run's signal. Once it has aborted (other than at the deadline), rule 3 stops the series
77
+ * (`reason: 'aborted'`); it cuts a wait short. An attempt that threw its reason is recorded `'aborted'` — or
78
+ * `'timeout'` when the reason is the deadline's (`attempt/deadline.ts`).
79
+ */
80
+ readonly signal?: AbortSignal;
81
+ /**
82
+ * The run's deadline, epoch milliseconds. Every attempt is capped by the time left; rule 6 stops a series whose
83
+ * next wait would outlast it (`no-time-left`). Absent (or not finite) = no deadline: the time left is `Infinity`.
84
+ */
85
+ readonly deadline?: number;
86
+ /** The clock, epoch milliseconds. Default `Date.now`. */
87
+ readonly now?: () => number;
88
+ /** The served form of a failed attempt's error. Default `extractErrorInfo` (no redaction rule). */
89
+ readonly serve?: (error: unknown) => StructuredErrorInfo;
90
+ /** Between a failed attempt and the next, before `backoffMs`: the engine discards the attempt's staged writes. */
91
+ readonly between?: (attempt: number) => void;
92
+ /** Every attempt, at its end, with its served error (`undefined` for `'ok'` and `'paused'`). */
93
+ readonly onAttempt?: (record: AttemptRecord, structuredError: StructuredErrorInfo | undefined) => void;
94
+ /** A failed attempt that WILL be retried — after `between` and `onAttempt`, before the wait. */
95
+ readonly onRetry?: (attempt: number, of: number, delayMs: number, structuredError: StructuredErrorInfo) => void;
96
+ /** The series ended: called once, before the last `onAttempt` (or after a wait the run's signal cut). */
97
+ readonly onEnd?: (summary: AttemptSummary) => void;
98
+ /** @internal Native owner only: the exact escaping value and category, before its stage serves the error. */
99
+ readonly onFailure?: (error: unknown, category: AttemptCategory) => void;
100
+ /** `retryOn` threw — the attempt is treated as declined; the engine logs the throw here. */
101
+ readonly onRetryOnThrew?: (thrown: unknown) => void;
102
+ /**
103
+ * The attempt ended without an answer — called SYNCHRONOUSLY the moment its signal aborts (its cap, the deadline,
104
+ * a cancellation), else as soon as it failed. Whatever the abandoned function does afterwards is not this
105
+ * series': the engine fences its scope here. Once per attempt; never for `'ok'` or `'paused'` — except an attempt
106
+ * that STARTED under an already-aborted signal, fenced once its synchronous part has run (nobody waits for it).
107
+ */
108
+ readonly onAbandon?: (attempt: number) => void;
109
+ /**
110
+ * The caller races `run`'s promise against the attempt's signal itself — the engine does, at the stage boundary
111
+ * (`StageRunner`), so a stage keeps its one await per attempt. Otherwise the runner races it: the series never
112
+ * waits on an attempt past its cap.
113
+ */
114
+ readonly raced?: boolean;
115
+ /**
116
+ * What an attempt's `observed(report)` does (P2) — the owner of the attempt records the report: `runCall` hands
117
+ * a call's reports to the scope, `attempt()` keeps its own. `ended` says the attempt had already ended when the
118
+ * report came (the owner drops it). Absent — a stage attempt's context, whose `observed` the scope's
119
+ * `$attempt()` replaces — `observed` is refused with a `TypeError`.
120
+ */
121
+ readonly observe?: (report: ObservedAttempt, at: {
122
+ readonly attempt: number;
123
+ readonly ended: boolean;
124
+ }) => void;
125
+ /**
126
+ * The outside system the target touches (P3, design §3.3). Every record then says what its attempt did to it
127
+ * (`effect`) and names the system and the RECORDED key; every attempt's context carries the REAL key. A series
128
+ * that ends without an answer after any attempt of unknown effect fails with `UnknownEffectError` (its `cause` the attempt's own error) —
129
+ * except a pause, which stays a pause. A touching series that may retry without a key is refused before anything
130
+ * runs: the law's last door.
131
+ */
132
+ readonly effect?: EffectTarget;
133
+ }
134
+ /**
135
+ * When the attempt behind `context` must end, epoch milliseconds — its start plus its cap (`min(timeoutMs, time
136
+ * left)`, so never past the run's deadline) — or `undefined` for an uncapped attempt. A call made inside the
137
+ * attempt runs under it as its deadline (`attempt/call.ts`). Only the runner's own contexts are known.
138
+ */
139
+ export declare function attemptEndsAt(context: AttemptContext | undefined): number | undefined;
140
+ /**
141
+ * Run `run` until it succeeds or the policy stops it; resolve with its value or reject with the LAST attempt's
142
+ * own error. `run(n)` is called with the attempt number, 1-based.
143
+ */
144
+ export declare function runAttempts<T>(run: (attempt: number, context: AttemptContext) => Promise<T> | T, policy: RetryPolicy, options: AttemptRunOptions): Promise<T>;
145
+ /**
146
+ * Resolve a policy's `backoffMs` for the attempt that just failed (1-based) and its error. Anything that is not a finite,
147
+ * positive number — a missing dial, a negative value, a `NaN` from a consumer's arithmetic, or a throwing
148
+ * function — becomes `0`, i.e. retry immediately. A backoff dial must never be able to crash a run or park it
149
+ * forever.
150
+ */
151
+ export declare function resolveBackoffMs(backoffMs: RetryPolicy['backoffMs'], attempt: number, error?: unknown): number;
152
+ /**
153
+ * Await `ms`, cut short by an abort. Resolves either way — the caller re-checks `signal.aborted` and rethrows
154
+ * the attempt's own error, so a cancelled run never sits out a long backoff and never loses the failure that
155
+ * caused it. The timer and the listener are always cleaned up.
156
+ */
157
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;