@smthrs/flow 0.0.0-stage → 1.0.0-rc.4
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.
- package/CHANGELOG.md +160 -0
- package/LICENSE +21 -0
- package/README.md +210 -2
- package/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/cjs/Action/Action.d.ts +250 -0
- package/dist/cjs/Action/Action.d.ts.map +1 -0
- package/dist/cjs/Action/Action.js +42 -0
- package/dist/cjs/Action/Action.js.map +7 -0
- package/dist/cjs/Action/AttemptTimedOut.d.ts +33 -0
- package/dist/cjs/Action/AttemptTimedOut.d.ts.map +1 -0
- package/dist/cjs/Action/AttemptTimedOut.js +51 -0
- package/dist/cjs/Action/AttemptTimedOut.js.map +7 -0
- package/dist/cjs/Action/BoundaryMode.d.ts +29 -0
- package/dist/cjs/Action/BoundaryMode.d.ts.map +1 -0
- package/dist/cjs/Action/BoundaryMode.js +36 -0
- package/dist/cjs/Action/BoundaryMode.js.map +7 -0
- package/dist/cjs/Action/CacheEnvironment.d.ts +158 -0
- package/dist/cjs/Action/CacheEnvironment.d.ts.map +1 -0
- package/dist/cjs/Action/CacheEnvironment.js +57 -0
- package/dist/cjs/Action/CacheEnvironment.js.map +7 -0
- package/dist/cjs/Action/ConcurrentKeylessDispatch.d.ts +34 -0
- package/dist/cjs/Action/ConcurrentKeylessDispatch.d.ts.map +1 -0
- package/dist/cjs/Action/ConcurrentKeylessDispatch.js +46 -0
- package/dist/cjs/Action/ConcurrentKeylessDispatch.js.map +7 -0
- package/dist/cjs/Action/Context.d.ts +131 -0
- package/dist/cjs/Action/Context.d.ts.map +1 -0
- package/dist/cjs/Action/Context.js +68 -0
- package/dist/cjs/Action/Context.js.map +7 -0
- package/dist/cjs/Action/DuplicateImplementation.d.ts +20 -0
- package/dist/cjs/Action/DuplicateImplementation.d.ts.map +1 -0
- package/dist/cjs/Action/DuplicateImplementation.js +46 -0
- package/dist/cjs/Action/DuplicateImplementation.js.map +7 -0
- package/dist/cjs/Action/FileBoundary.d.ts +59 -0
- package/dist/cjs/Action/FileBoundary.d.ts.map +1 -0
- package/dist/cjs/Action/FileBoundary.js +81 -0
- package/dist/cjs/Action/FileBoundary.js.map +7 -0
- package/dist/cjs/Action/FileInput.d.ts +28 -0
- package/dist/cjs/Action/FileInput.d.ts.map +1 -0
- package/dist/cjs/Action/FileInput.js +42 -0
- package/dist/cjs/Action/FileInput.js.map +7 -0
- package/dist/cjs/Action/Filegroup.d.ts +16 -0
- package/dist/cjs/Action/Filegroup.d.ts.map +1 -0
- package/dist/cjs/Action/Filegroup.js +27 -0
- package/dist/cjs/Action/Filegroup.js.map +7 -0
- package/dist/cjs/Action/Glob.d.ts +8 -0
- package/dist/cjs/Action/Glob.d.ts.map +1 -0
- package/dist/cjs/Action/Glob.js +28 -0
- package/dist/cjs/Action/Glob.js.map +7 -0
- package/dist/cjs/Action/ImplementationVersionMismatch.d.ts +26 -0
- package/dist/cjs/Action/ImplementationVersionMismatch.d.ts.map +1 -0
- package/dist/cjs/Action/ImplementationVersionMismatch.js +45 -0
- package/dist/cjs/Action/ImplementationVersionMismatch.js.map +7 -0
- package/dist/cjs/Action/Implementations.d.ts +114 -0
- package/dist/cjs/Action/Implementations.d.ts.map +1 -0
- package/dist/cjs/Action/Implementations.js +65 -0
- package/dist/cjs/Action/Implementations.js.map +7 -0
- package/dist/cjs/Action/InfraInterrupt.d.ts +26 -0
- package/dist/cjs/Action/InfraInterrupt.d.ts.map +1 -0
- package/dist/cjs/Action/InfraInterrupt.js +46 -0
- package/dist/cjs/Action/InfraInterrupt.js.map +7 -0
- package/dist/cjs/Action/InfraInterruptRetriesExhausted.d.ts +33 -0
- package/dist/cjs/Action/InfraInterruptRetriesExhausted.d.ts.map +1 -0
- package/dist/cjs/Action/InfraInterruptRetriesExhausted.js +54 -0
- package/dist/cjs/Action/InfraInterruptRetriesExhausted.js.map +7 -0
- package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts +26 -0
- package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts.map +1 -0
- package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.js +47 -0
- package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.js.map +7 -0
- package/dist/cjs/Action/StepIdentity.d.ts +153 -0
- package/dist/cjs/Action/StepIdentity.d.ts.map +1 -0
- package/dist/cjs/Action/StepIdentity.js +75 -0
- package/dist/cjs/Action/StepIdentity.js.map +7 -0
- package/dist/cjs/Action/TreeArtifact.d.ts +8 -0
- package/dist/cjs/Action/TreeArtifact.d.ts.map +1 -0
- package/dist/cjs/Action/TreeArtifact.js +25 -0
- package/dist/cjs/Action/TreeArtifact.js.map +7 -0
- package/dist/cjs/Action/TypeId.d.ts +8 -0
- package/dist/cjs/Action/TypeId.d.ts.map +1 -0
- package/dist/cjs/Action/TypeId.js +25 -0
- package/dist/cjs/Action/TypeId.js.map +7 -0
- package/dist/cjs/Action/UncanonicalIdempotencyKey.d.ts +32 -0
- package/dist/cjs/Action/UncanonicalIdempotencyKey.d.ts.map +1 -0
- package/dist/cjs/Action/UncanonicalIdempotencyKey.js +51 -0
- package/dist/cjs/Action/UncanonicalIdempotencyKey.js.map +7 -0
- package/dist/cjs/Action/idempotencyKey.d.ts +21 -0
- package/dist/cjs/Action/idempotencyKey.d.ts.map +1 -0
- package/dist/cjs/Action/idempotencyKey.js +59 -0
- package/dist/cjs/Action/idempotencyKey.js.map +7 -0
- package/dist/cjs/Action/index.d.ts +29 -0
- package/dist/cjs/Action/index.d.ts.map +1 -0
- package/dist/cjs/Action/index.js +60 -0
- package/dist/cjs/Action/index.js.map +7 -0
- package/dist/cjs/Action/make.d.ts +128 -0
- package/dist/cjs/Action/make.d.ts.map +1 -0
- package/dist/cjs/Action/make.js +373 -0
- package/dist/cjs/Action/make.js.map +7 -0
- package/dist/cjs/Action/raceAll.d.ts +21 -0
- package/dist/cjs/Action/raceAll.d.ts.map +1 -0
- package/dist/cjs/Action/raceAll.js +46 -0
- package/dist/cjs/Action/raceAll.js.map +7 -0
- package/dist/cjs/Action/retry.d.ts +19 -0
- package/dist/cjs/Action/retry.d.ts.map +1 -0
- package/dist/cjs/Action/retry.js +75 -0
- package/dist/cjs/Action/retry.js.map +7 -0
- package/dist/cjs/Deadline.d.ts +105 -0
- package/dist/cjs/Deadline.d.ts.map +1 -0
- package/dist/cjs/Deadline.js +104 -0
- package/dist/cjs/Deadline.js.map +7 -0
- package/dist/cjs/DurableClock.d.ts +61 -0
- package/dist/cjs/DurableClock.d.ts.map +1 -0
- package/dist/cjs/DurableClock.js +90 -0
- package/dist/cjs/DurableClock.js.map +7 -0
- package/dist/cjs/DurableDeferred.d.ts +311 -0
- package/dist/cjs/DurableDeferred.d.ts.map +1 -0
- package/dist/cjs/DurableDeferred.js +322 -0
- package/dist/cjs/DurableDeferred.js.map +7 -0
- package/dist/cjs/DurableQueue.d.ts +160 -0
- package/dist/cjs/DurableQueue.d.ts.map +1 -0
- package/dist/cjs/DurableQueue.js +229 -0
- package/dist/cjs/DurableQueue.js.map +7 -0
- package/dist/cjs/ExternalJob.d.ts +179 -0
- package/dist/cjs/ExternalJob.d.ts.map +1 -0
- package/dist/cjs/ExternalJob.js +338 -0
- package/dist/cjs/ExternalJob.js.map +7 -0
- package/dist/cjs/Fault.d.ts +131 -0
- package/dist/cjs/Fault.d.ts.map +1 -0
- package/dist/cjs/Fault.js +157 -0
- package/dist/cjs/Fault.js.map +7 -0
- package/dist/cjs/Flow/Annotations.d.ts +245 -0
- package/dist/cjs/Flow/Annotations.d.ts.map +1 -0
- package/dist/cjs/Flow/Annotations.js +72 -0
- package/dist/cjs/Flow/Annotations.js.map +7 -0
- package/dist/cjs/Flow/CapabilityCeiling.d.ts +21 -0
- package/dist/cjs/Flow/CapabilityCeiling.d.ts.map +1 -0
- package/dist/cjs/Flow/CapabilityCeiling.js +49 -0
- package/dist/cjs/Flow/CapabilityCeiling.js.map +7 -0
- package/dist/cjs/Flow/DeadlineExceeded.d.ts +33 -0
- package/dist/cjs/Flow/DeadlineExceeded.d.ts.map +1 -0
- package/dist/cjs/Flow/DeadlineExceeded.js +52 -0
- package/dist/cjs/Flow/DeadlineExceeded.js.map +7 -0
- package/dist/cjs/Flow/ExecutionIdRequired.d.ts +25 -0
- package/dist/cjs/Flow/ExecutionIdRequired.d.ts.map +1 -0
- package/dist/cjs/Flow/ExecutionIdRequired.js +46 -0
- package/dist/cjs/Flow/ExecutionIdRequired.js.map +7 -0
- package/dist/cjs/Flow/ExecutionIds.d.ts +80 -0
- package/dist/cjs/Flow/ExecutionIds.d.ts.map +1 -0
- package/dist/cjs/Flow/ExecutionIds.js +66 -0
- package/dist/cjs/Flow/ExecutionIds.js.map +7 -0
- package/dist/cjs/Flow/Flow.d.ts +422 -0
- package/dist/cjs/Flow/Flow.d.ts.map +1 -0
- package/dist/cjs/Flow/Flow.js +17 -0
- package/dist/cjs/Flow/Flow.js.map +7 -0
- package/dist/cjs/Flow/MaxRoundsExceeded.d.ts +35 -0
- package/dist/cjs/Flow/MaxRoundsExceeded.d.ts.map +1 -0
- package/dist/cjs/Flow/MaxRoundsExceeded.js +50 -0
- package/dist/cjs/Flow/MaxRoundsExceeded.js.map +7 -0
- package/dist/cjs/Flow/Outcome.d.ts +162 -0
- package/dist/cjs/Flow/Outcome.d.ts.map +1 -0
- package/dist/cjs/Flow/Outcome.js +80 -0
- package/dist/cjs/Flow/Outcome.js.map +7 -0
- package/dist/cjs/Flow/Result.d.ts +186 -0
- package/dist/cjs/Flow/Result.d.ts.map +1 -0
- package/dist/cjs/Flow/Result.js +159 -0
- package/dist/cjs/Flow/Result.js.map +7 -0
- package/dist/cjs/Flow/Runtime.d.ts +98 -0
- package/dist/cjs/Flow/Runtime.d.ts.map +1 -0
- package/dist/cjs/Flow/Runtime.js +160 -0
- package/dist/cjs/Flow/Runtime.js.map +7 -0
- package/dist/cjs/Flow/TypeId.d.ts +8 -0
- package/dist/cjs/Flow/TypeId.d.ts.map +1 -0
- package/dist/cjs/Flow/TypeId.js +25 -0
- package/dist/cjs/Flow/TypeId.js.map +7 -0
- package/dist/cjs/Flow/index.d.ts +17 -0
- package/dist/cjs/Flow/index.d.ts.map +1 -0
- package/dist/cjs/Flow/index.js +29 -0
- package/dist/cjs/Flow/index.js.map +7 -0
- package/dist/cjs/Flow/internal.d.ts +34 -0
- package/dist/cjs/Flow/internal.d.ts.map +1 -0
- package/dist/cjs/Flow/internal.js +187 -0
- package/dist/cjs/Flow/internal.js.map +7 -0
- package/dist/cjs/Flow/make.d.ts +134 -0
- package/dist/cjs/Flow/make.d.ts.map +1 -0
- package/dist/cjs/Flow/make.js +104 -0
- package/dist/cjs/Flow/make.js.map +7 -0
- package/dist/cjs/FlowRuntime/CancelRequestFailed.d.ts +55 -0
- package/dist/cjs/FlowRuntime/CancelRequestFailed.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/CancelRequestFailed.js +51 -0
- package/dist/cjs/FlowRuntime/CancelRequestFailed.js.map +7 -0
- package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.d.ts +23 -0
- package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.js +55 -0
- package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.js.map +7 -0
- package/dist/cjs/FlowRuntime/FlowCycleDetected.d.ts +28 -0
- package/dist/cjs/FlowRuntime/FlowCycleDetected.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/FlowCycleDetected.js +49 -0
- package/dist/cjs/FlowRuntime/FlowCycleDetected.js.map +7 -0
- package/dist/cjs/FlowRuntime/FlowExecutionNotFound.d.ts +38 -0
- package/dist/cjs/FlowRuntime/FlowExecutionNotFound.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/FlowExecutionNotFound.js +53 -0
- package/dist/cjs/FlowRuntime/FlowExecutionNotFound.js.map +7 -0
- package/dist/cjs/FlowRuntime/FlowInstance.d.ts +115 -0
- package/dist/cjs/FlowRuntime/FlowInstance.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/FlowInstance.js +37 -0
- package/dist/cjs/FlowRuntime/FlowInstance.js.map +7 -0
- package/dist/cjs/FlowRuntime/FlowRuntime.d.ts +198 -0
- package/dist/cjs/FlowRuntime/FlowRuntime.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/FlowRuntime.js +37 -0
- package/dist/cjs/FlowRuntime/FlowRuntime.js.map +7 -0
- package/dist/cjs/FlowRuntime/NodeRecord.d.ts +175 -0
- package/dist/cjs/FlowRuntime/NodeRecord.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/NodeRecord.js +17 -0
- package/dist/cjs/FlowRuntime/NodeRecord.js.map +7 -0
- package/dist/cjs/FlowRuntime/WaitingAnnotation.d.ts +69 -0
- package/dist/cjs/FlowRuntime/WaitingAnnotation.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/WaitingAnnotation.js +53 -0
- package/dist/cjs/FlowRuntime/WaitingAnnotation.js.map +7 -0
- package/dist/cjs/FlowRuntime/index.d.ts +14 -0
- package/dist/cjs/FlowRuntime/index.d.ts.map +1 -0
- package/dist/cjs/FlowRuntime/index.js +26 -0
- package/dist/cjs/FlowRuntime/index.js.map +7 -0
- package/dist/cjs/Graph.d.ts +325 -0
- package/dist/cjs/Graph.d.ts.map +1 -0
- package/dist/cjs/Graph.js +1021 -0
- package/dist/cjs/Graph.js.map +7 -0
- package/dist/cjs/HumanTask.d.ts +440 -0
- package/dist/cjs/HumanTask.d.ts.map +1 -0
- package/dist/cjs/HumanTask.js +413 -0
- package/dist/cjs/HumanTask.js.map +7 -0
- package/dist/cjs/Interpreter.d.ts +222 -0
- package/dist/cjs/Interpreter.d.ts.map +1 -0
- package/dist/cjs/Interpreter.js +888 -0
- package/dist/cjs/Interpreter.js.map +7 -0
- package/dist/cjs/Poll.d.ts +238 -0
- package/dist/cjs/Poll.d.ts.map +1 -0
- package/dist/cjs/Poll.js +150 -0
- package/dist/cjs/Poll.js.map +7 -0
- package/dist/cjs/RetryPolicy.d.ts +273 -0
- package/dist/cjs/RetryPolicy.d.ts.map +1 -0
- package/dist/cjs/RetryPolicy.js +251 -0
- package/dist/cjs/RetryPolicy.js.map +7 -0
- package/dist/cjs/Sleep.d.ts +98 -0
- package/dist/cjs/Sleep.d.ts.map +1 -0
- package/dist/cjs/Sleep.js +133 -0
- package/dist/cjs/Sleep.js.map +7 -0
- package/dist/cjs/Stall.d.ts +173 -0
- package/dist/cjs/Stall.d.ts.map +1 -0
- package/dist/cjs/Stall.js +92 -0
- package/dist/cjs/Stall.js.map +7 -0
- package/dist/cjs/WaitFor.d.ts +109 -0
- package/dist/cjs/WaitFor.d.ts.map +1 -0
- package/dist/cjs/WaitFor.js +117 -0
- package/dist/cjs/WaitFor.js.map +7 -0
- package/dist/cjs/index.d.ts +107 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +69 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/BoundedJson.d.ts +48 -0
- package/dist/cjs/internal/BoundedJson.d.ts.map +1 -0
- package/dist/cjs/internal/BoundedJson.js +96 -0
- package/dist/cjs/internal/BoundedJson.js.map +7 -0
- package/dist/cjs/internal/DeclarationSite.d.ts +135 -0
- package/dist/cjs/internal/DeclarationSite.d.ts.map +1 -0
- package/dist/cjs/internal/DeclarationSite.js +89 -0
- package/dist/cjs/internal/DeclarationSite.js.map +7 -0
- package/dist/cjs/internal/Declarations.d.ts +35 -0
- package/dist/cjs/internal/Declarations.d.ts.map +1 -0
- package/dist/cjs/internal/Declarations.js +50 -0
- package/dist/cjs/internal/Declarations.js.map +7 -0
- package/dist/cjs/internal/ExecutionMiddleware.d.ts +21 -0
- package/dist/cjs/internal/ExecutionMiddleware.d.ts.map +1 -0
- package/dist/cjs/internal/ExecutionMiddleware.js +39 -0
- package/dist/cjs/internal/ExecutionMiddleware.js.map +7 -0
- package/dist/cjs/internal/JsonSchemaSubset.d.ts +133 -0
- package/dist/cjs/internal/JsonSchemaSubset.d.ts.map +1 -0
- package/dist/cjs/internal/JsonSchemaSubset.js +229 -0
- package/dist/cjs/internal/JsonSchemaSubset.js.map +7 -0
- package/dist/cjs/internal/OutcomeMarker.d.ts +18 -0
- package/dist/cjs/internal/OutcomeMarker.d.ts.map +1 -0
- package/dist/cjs/internal/OutcomeMarker.js +27 -0
- package/dist/cjs/internal/OutcomeMarker.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/Action/Action.d.ts +250 -0
- package/dist/esm/Action/Action.d.ts.map +1 -0
- package/dist/esm/Action/Action.js +30 -0
- package/dist/esm/Action/Action.js.map +1 -0
- package/dist/esm/Action/AttemptTimedOut.d.ts +33 -0
- package/dist/esm/Action/AttemptTimedOut.d.ts.map +1 -0
- package/dist/esm/Action/AttemptTimedOut.js +32 -0
- package/dist/esm/Action/AttemptTimedOut.js.map +1 -0
- package/dist/esm/Action/BoundaryMode.d.ts +29 -0
- package/dist/esm/Action/BoundaryMode.d.ts.map +1 -0
- package/dist/esm/Action/BoundaryMode.js +23 -0
- package/dist/esm/Action/BoundaryMode.js.map +1 -0
- package/dist/esm/Action/CacheEnvironment.d.ts +158 -0
- package/dist/esm/Action/CacheEnvironment.d.ts.map +1 -0
- package/dist/esm/Action/CacheEnvironment.js +130 -0
- package/dist/esm/Action/CacheEnvironment.js.map +1 -0
- package/dist/esm/Action/ConcurrentKeylessDispatch.d.ts +34 -0
- package/dist/esm/Action/ConcurrentKeylessDispatch.d.ts.map +1 -0
- package/dist/esm/Action/ConcurrentKeylessDispatch.js +33 -0
- package/dist/esm/Action/ConcurrentKeylessDispatch.js.map +1 -0
- package/dist/esm/Action/Context.d.ts +131 -0
- package/dist/esm/Action/Context.d.ts.map +1 -0
- package/dist/esm/Action/Context.js +99 -0
- package/dist/esm/Action/Context.js.map +1 -0
- package/dist/esm/Action/DuplicateImplementation.d.ts +20 -0
- package/dist/esm/Action/DuplicateImplementation.d.ts.map +1 -0
- package/dist/esm/Action/DuplicateImplementation.js +20 -0
- package/dist/esm/Action/DuplicateImplementation.js.map +1 -0
- package/dist/esm/Action/FileBoundary.d.ts +59 -0
- package/dist/esm/Action/FileBoundary.d.ts.map +1 -0
- package/dist/esm/Action/FileBoundary.js +60 -0
- package/dist/esm/Action/FileBoundary.js.map +1 -0
- package/dist/esm/Action/FileInput.d.ts +28 -0
- package/dist/esm/Action/FileInput.d.ts.map +1 -0
- package/dist/esm/Action/FileInput.js +32 -0
- package/dist/esm/Action/FileInput.js.map +1 -0
- package/dist/esm/Action/Filegroup.d.ts +16 -0
- package/dist/esm/Action/Filegroup.d.ts.map +1 -0
- package/dist/esm/Action/Filegroup.js +15 -0
- package/dist/esm/Action/Filegroup.js.map +1 -0
- package/dist/esm/Action/Glob.d.ts +8 -0
- package/dist/esm/Action/Glob.d.ts.map +1 -0
- package/dist/esm/Action/Glob.js +7 -0
- package/dist/esm/Action/Glob.js.map +1 -0
- package/dist/esm/Action/ImplementationVersionMismatch.d.ts +26 -0
- package/dist/esm/Action/ImplementationVersionMismatch.d.ts.map +1 -0
- package/dist/esm/Action/ImplementationVersionMismatch.js +24 -0
- package/dist/esm/Action/ImplementationVersionMismatch.js.map +1 -0
- package/dist/esm/Action/Implementations.d.ts +114 -0
- package/dist/esm/Action/Implementations.d.ts.map +1 -0
- package/dist/esm/Action/Implementations.js +94 -0
- package/dist/esm/Action/Implementations.js.map +1 -0
- package/dist/esm/Action/InfraInterrupt.d.ts +26 -0
- package/dist/esm/Action/InfraInterrupt.d.ts.map +1 -0
- package/dist/esm/Action/InfraInterrupt.js +25 -0
- package/dist/esm/Action/InfraInterrupt.js.map +1 -0
- package/dist/esm/Action/InfraInterruptRetriesExhausted.d.ts +33 -0
- package/dist/esm/Action/InfraInterruptRetriesExhausted.d.ts.map +1 -0
- package/dist/esm/Action/InfraInterruptRetriesExhausted.js +32 -0
- package/dist/esm/Action/InfraInterruptRetriesExhausted.js.map +1 -0
- package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts +26 -0
- package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts.map +1 -0
- package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.js +25 -0
- package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.js.map +1 -0
- package/dist/esm/Action/StepIdentity.d.ts +153 -0
- package/dist/esm/Action/StepIdentity.d.ts.map +1 -0
- package/dist/esm/Action/StepIdentity.js +139 -0
- package/dist/esm/Action/StepIdentity.js.map +1 -0
- package/dist/esm/Action/TreeArtifact.d.ts +8 -0
- package/dist/esm/Action/TreeArtifact.d.ts.map +1 -0
- package/dist/esm/Action/TreeArtifact.js +7 -0
- package/dist/esm/Action/TreeArtifact.js.map +1 -0
- package/dist/esm/Action/TypeId.d.ts +8 -0
- package/dist/esm/Action/TypeId.d.ts.map +1 -0
- package/dist/esm/Action/TypeId.js +9 -0
- package/dist/esm/Action/TypeId.js.map +1 -0
- package/dist/esm/Action/UncanonicalIdempotencyKey.d.ts +32 -0
- package/dist/esm/Action/UncanonicalIdempotencyKey.d.ts.map +1 -0
- package/dist/esm/Action/UncanonicalIdempotencyKey.js +31 -0
- package/dist/esm/Action/UncanonicalIdempotencyKey.js.map +1 -0
- package/dist/esm/Action/idempotencyKey.d.ts +21 -0
- package/dist/esm/Action/idempotencyKey.d.ts.map +1 -0
- package/dist/esm/Action/idempotencyKey.js +50 -0
- package/dist/esm/Action/idempotencyKey.js.map +1 -0
- package/dist/esm/Action/index.d.ts +29 -0
- package/dist/esm/Action/index.d.ts.map +1 -0
- package/dist/esm/Action/index.js +30 -0
- package/dist/esm/Action/index.js.map +1 -0
- package/dist/esm/Action/make.d.ts +128 -0
- package/dist/esm/Action/make.d.ts.map +1 -0
- package/dist/esm/Action/make.js +405 -0
- package/dist/esm/Action/make.js.map +1 -0
- package/dist/esm/Action/raceAll.d.ts +21 -0
- package/dist/esm/Action/raceAll.d.ts.map +1 -0
- package/dist/esm/Action/raceAll.js +20 -0
- package/dist/esm/Action/raceAll.js.map +1 -0
- package/dist/esm/Action/retry.d.ts +19 -0
- package/dist/esm/Action/retry.d.ts.map +1 -0
- package/dist/esm/Action/retry.js +72 -0
- package/dist/esm/Action/retry.js.map +1 -0
- package/dist/esm/Deadline.d.ts +105 -0
- package/dist/esm/Deadline.d.ts.map +1 -0
- package/dist/esm/Deadline.js +152 -0
- package/dist/esm/Deadline.js.map +1 -0
- package/dist/esm/DurableClock.d.ts +61 -0
- package/dist/esm/DurableClock.d.ts.map +1 -0
- package/dist/esm/DurableClock.js +75 -0
- package/dist/esm/DurableClock.js.map +1 -0
- package/dist/esm/DurableDeferred.d.ts +311 -0
- package/dist/esm/DurableDeferred.d.ts.map +1 -0
- package/dist/esm/DurableDeferred.js +357 -0
- package/dist/esm/DurableDeferred.js.map +1 -0
- package/dist/esm/DurableQueue.d.ts +160 -0
- package/dist/esm/DurableQueue.d.ts.map +1 -0
- package/dist/esm/DurableQueue.js +303 -0
- package/dist/esm/DurableQueue.js.map +1 -0
- package/dist/esm/ExternalJob.d.ts +179 -0
- package/dist/esm/ExternalJob.d.ts.map +1 -0
- package/dist/esm/ExternalJob.js +296 -0
- package/dist/esm/ExternalJob.js.map +1 -0
- package/dist/esm/Fault.d.ts +131 -0
- package/dist/esm/Fault.d.ts.map +1 -0
- package/dist/esm/Fault.js +198 -0
- package/dist/esm/Fault.js.map +1 -0
- package/dist/esm/Flow/Annotations.d.ts +245 -0
- package/dist/esm/Flow/Annotations.d.ts.map +1 -0
- package/dist/esm/Flow/Annotations.js +110 -0
- package/dist/esm/Flow/Annotations.js.map +1 -0
- package/dist/esm/Flow/CapabilityCeiling.d.ts +21 -0
- package/dist/esm/Flow/CapabilityCeiling.d.ts.map +1 -0
- package/dist/esm/Flow/CapabilityCeiling.js +27 -0
- package/dist/esm/Flow/CapabilityCeiling.js.map +1 -0
- package/dist/esm/Flow/DeadlineExceeded.d.ts +33 -0
- package/dist/esm/Flow/DeadlineExceeded.d.ts.map +1 -0
- package/dist/esm/Flow/DeadlineExceeded.js +34 -0
- package/dist/esm/Flow/DeadlineExceeded.js.map +1 -0
- package/dist/esm/Flow/ExecutionIdRequired.d.ts +25 -0
- package/dist/esm/Flow/ExecutionIdRequired.d.ts.map +1 -0
- package/dist/esm/Flow/ExecutionIdRequired.js +30 -0
- package/dist/esm/Flow/ExecutionIdRequired.js.map +1 -0
- package/dist/esm/Flow/ExecutionIds.d.ts +80 -0
- package/dist/esm/Flow/ExecutionIds.d.ts.map +1 -0
- package/dist/esm/Flow/ExecutionIds.js +91 -0
- package/dist/esm/Flow/ExecutionIds.js.map +1 -0
- package/dist/esm/Flow/Flow.d.ts +422 -0
- package/dist/esm/Flow/Flow.d.ts.map +1 -0
- package/dist/esm/Flow/Flow.js +3 -0
- package/dist/esm/Flow/Flow.js.map +1 -0
- package/dist/esm/Flow/MaxRoundsExceeded.d.ts +35 -0
- package/dist/esm/Flow/MaxRoundsExceeded.d.ts.map +1 -0
- package/dist/esm/Flow/MaxRoundsExceeded.js +34 -0
- package/dist/esm/Flow/MaxRoundsExceeded.js.map +1 -0
- package/dist/esm/Flow/Outcome.d.ts +162 -0
- package/dist/esm/Flow/Outcome.d.ts.map +1 -0
- package/dist/esm/Flow/Outcome.js +115 -0
- package/dist/esm/Flow/Outcome.js.map +1 -0
- package/dist/esm/Flow/Result.d.ts +186 -0
- package/dist/esm/Flow/Result.d.ts.map +1 -0
- package/dist/esm/Flow/Result.js +171 -0
- package/dist/esm/Flow/Result.js.map +1 -0
- package/dist/esm/Flow/Runtime.d.ts +98 -0
- package/dist/esm/Flow/Runtime.d.ts.map +1 -0
- package/dist/esm/Flow/Runtime.js +231 -0
- package/dist/esm/Flow/Runtime.js.map +1 -0
- package/dist/esm/Flow/TypeId.d.ts +8 -0
- package/dist/esm/Flow/TypeId.d.ts.map +1 -0
- package/dist/esm/Flow/TypeId.js +9 -0
- package/dist/esm/Flow/TypeId.js.map +1 -0
- package/dist/esm/Flow/index.d.ts +17 -0
- package/dist/esm/Flow/index.d.ts.map +1 -0
- package/dist/esm/Flow/index.js +18 -0
- package/dist/esm/Flow/index.js.map +1 -0
- package/dist/esm/Flow/internal.d.ts +34 -0
- package/dist/esm/Flow/internal.d.ts.map +1 -0
- package/dist/esm/Flow/internal.js +149 -0
- package/dist/esm/Flow/internal.js.map +1 -0
- package/dist/esm/Flow/make.d.ts +134 -0
- package/dist/esm/Flow/make.d.ts.map +1 -0
- package/dist/esm/Flow/make.js +106 -0
- package/dist/esm/Flow/make.js.map +1 -0
- package/dist/esm/FlowRuntime/CancelRequestFailed.d.ts +55 -0
- package/dist/esm/FlowRuntime/CancelRequestFailed.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/CancelRequestFailed.js +53 -0
- package/dist/esm/FlowRuntime/CancelRequestFailed.js.map +1 -0
- package/dist/esm/FlowRuntime/ExecutionIdentityConflict.d.ts +23 -0
- package/dist/esm/FlowRuntime/ExecutionIdentityConflict.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/ExecutionIdentityConflict.js +24 -0
- package/dist/esm/FlowRuntime/ExecutionIdentityConflict.js.map +1 -0
- package/dist/esm/FlowRuntime/FlowCycleDetected.d.ts +28 -0
- package/dist/esm/FlowRuntime/FlowCycleDetected.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/FlowCycleDetected.js +35 -0
- package/dist/esm/FlowRuntime/FlowCycleDetected.js.map +1 -0
- package/dist/esm/FlowRuntime/FlowExecutionNotFound.d.ts +38 -0
- package/dist/esm/FlowRuntime/FlowExecutionNotFound.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/FlowExecutionNotFound.js +40 -0
- package/dist/esm/FlowRuntime/FlowExecutionNotFound.js.map +1 -0
- package/dist/esm/FlowRuntime/FlowInstance.d.ts +115 -0
- package/dist/esm/FlowRuntime/FlowInstance.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/FlowInstance.js +24 -0
- package/dist/esm/FlowRuntime/FlowInstance.js.map +1 -0
- package/dist/esm/FlowRuntime/FlowRuntime.d.ts +198 -0
- package/dist/esm/FlowRuntime/FlowRuntime.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/FlowRuntime.js +34 -0
- package/dist/esm/FlowRuntime/FlowRuntime.js.map +1 -0
- package/dist/esm/FlowRuntime/NodeRecord.d.ts +175 -0
- package/dist/esm/FlowRuntime/NodeRecord.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/NodeRecord.js +21 -0
- package/dist/esm/FlowRuntime/NodeRecord.js.map +1 -0
- package/dist/esm/FlowRuntime/WaitingAnnotation.d.ts +69 -0
- package/dist/esm/FlowRuntime/WaitingAnnotation.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/WaitingAnnotation.js +53 -0
- package/dist/esm/FlowRuntime/WaitingAnnotation.js.map +1 -0
- package/dist/esm/FlowRuntime/index.d.ts +14 -0
- package/dist/esm/FlowRuntime/index.d.ts.map +1 -0
- package/dist/esm/FlowRuntime/index.js +15 -0
- package/dist/esm/FlowRuntime/index.js.map +1 -0
- package/dist/esm/Graph.d.ts +325 -0
- package/dist/esm/Graph.d.ts.map +1 -0
- package/dist/esm/Graph.js +1483 -0
- package/dist/esm/Graph.js.map +1 -0
- package/dist/esm/HumanTask.d.ts +440 -0
- package/dist/esm/HumanTask.d.ts.map +1 -0
- package/dist/esm/HumanTask.js +794 -0
- package/dist/esm/HumanTask.js.map +1 -0
- package/dist/esm/Interpreter.d.ts +222 -0
- package/dist/esm/Interpreter.d.ts.map +1 -0
- package/dist/esm/Interpreter.js +1269 -0
- package/dist/esm/Interpreter.js.map +1 -0
- package/dist/esm/Poll.d.ts +238 -0
- package/dist/esm/Poll.d.ts.map +1 -0
- package/dist/esm/Poll.js +282 -0
- package/dist/esm/Poll.js.map +1 -0
- package/dist/esm/RetryPolicy.d.ts +273 -0
- package/dist/esm/RetryPolicy.d.ts.map +1 -0
- package/dist/esm/RetryPolicy.js +429 -0
- package/dist/esm/RetryPolicy.js.map +1 -0
- package/dist/esm/Sleep.d.ts +98 -0
- package/dist/esm/Sleep.d.ts.map +1 -0
- package/dist/esm/Sleep.js +230 -0
- package/dist/esm/Sleep.js.map +1 -0
- package/dist/esm/Stall.d.ts +173 -0
- package/dist/esm/Stall.d.ts.map +1 -0
- package/dist/esm/Stall.js +138 -0
- package/dist/esm/Stall.js.map +1 -0
- package/dist/esm/WaitFor.d.ts +109 -0
- package/dist/esm/WaitFor.d.ts.map +1 -0
- package/dist/esm/WaitFor.js +184 -0
- package/dist/esm/WaitFor.js.map +1 -0
- package/dist/esm/index.d.ts +107 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +108 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/BoundedJson.d.ts +48 -0
- package/dist/esm/internal/BoundedJson.d.ts.map +1 -0
- package/dist/esm/internal/BoundedJson.js +107 -0
- package/dist/esm/internal/BoundedJson.js.map +1 -0
- package/dist/esm/internal/DeclarationSite.d.ts +135 -0
- package/dist/esm/internal/DeclarationSite.d.ts.map +1 -0
- package/dist/esm/internal/DeclarationSite.js +196 -0
- package/dist/esm/internal/DeclarationSite.js.map +1 -0
- package/dist/esm/internal/Declarations.d.ts +35 -0
- package/dist/esm/internal/Declarations.d.ts.map +1 -0
- package/dist/esm/internal/Declarations.js +43 -0
- package/dist/esm/internal/Declarations.js.map +1 -0
- package/dist/esm/internal/ExecutionMiddleware.d.ts +21 -0
- package/dist/esm/internal/ExecutionMiddleware.d.ts.map +1 -0
- package/dist/esm/internal/ExecutionMiddleware.js +13 -0
- package/dist/esm/internal/ExecutionMiddleware.js.map +1 -0
- package/dist/esm/internal/JsonSchemaSubset.d.ts +133 -0
- package/dist/esm/internal/JsonSchemaSubset.d.ts.map +1 -0
- package/dist/esm/internal/JsonSchemaSubset.js +363 -0
- package/dist/esm/internal/JsonSchemaSubset.js.map +1 -0
- package/dist/esm/internal/OutcomeMarker.d.ts +18 -0
- package/dist/esm/internal/OutcomeMarker.d.ts.map +1 -0
- package/dist/esm/internal/OutcomeMarker.js +18 -0
- package/dist/esm/internal/OutcomeMarker.js.map +1 -0
- package/docs/README.md +150 -0
- package/docs/api.md +436 -0
- package/docs/concepts/bodies-and-plans.md +157 -0
- package/docs/concepts/execution-identity.md +142 -0
- package/docs/concepts/flows-and-actions.md +129 -0
- package/docs/concepts/suspension-and-replay.md +130 -0
- package/docs/concepts/the-runtime-port.md +110 -0
- package/docs/concepts/trampoline-rounds.md +151 -0
- package/docs/guides/ask-a-person.md +184 -0
- package/docs/guides/build-a-body.md +161 -0
- package/docs/guides/cancel-and-roll-back.md +112 -0
- package/docs/guides/implement-an-action.md +147 -0
- package/docs/guides/inspect-the-plan.md +154 -0
- package/docs/guides/poll-until-ready.md +167 -0
- package/docs/guides/queue-work-to-a-worker.md +122 -0
- package/docs/guides/retry-a-failing-action.md +243 -0
- package/docs/guides/reuse-a-recorded-result.md +122 -0
- package/docs/guides/run-a-child-flow.md +108 -0
- package/docs/guides/run-an-external-job.md +86 -0
- package/docs/guides/use-a-prompt.md +38 -0
- package/docs/guides/wait-for-a-deadline.md +141 -0
- package/docs/guides/wait-for-an-external-signal.md +151 -0
- package/docs/installation.md +82 -0
- package/docs/quickstart.md +155 -0
- package/docs/reference/flow.md +1831 -0
- package/docs/testing.md +157 -0
- package/docs/troubleshooting.md +286 -0
- package/package.json +327 -3
- package/src/Action/Action.ts +333 -0
- package/src/Action/AttemptTimedOut.ts +37 -0
- package/src/Action/BoundaryMode.ts +33 -0
- package/src/Action/CacheEnvironment.ts +170 -0
- package/src/Action/ConcurrentKeylessDispatch.ts +38 -0
- package/src/Action/Context.ts +156 -0
- package/src/Action/DuplicateImplementation.ts +24 -0
- package/src/Action/FileBoundary.ts +77 -0
- package/src/Action/FileInput.ts +42 -0
- package/src/Action/Filegroup.ts +16 -0
- package/src/Action/Glob.ts +8 -0
- package/src/Action/ImplementationVersionMismatch.ts +27 -0
- package/src/Action/Implementations.ts +149 -0
- package/src/Action/InfraInterrupt.ts +30 -0
- package/src/Action/InfraInterruptRetriesExhausted.ts +37 -0
- package/src/Action/IrreversibleRetryRequiresIdempotencyKey.ts +32 -0
- package/src/Action/StepIdentity.ts +219 -0
- package/src/Action/TreeArtifact.ts +8 -0
- package/src/Action/TypeId.ts +9 -0
- package/src/Action/UncanonicalIdempotencyKey.ts +36 -0
- package/src/Action/idempotencyKey.ts +67 -0
- package/src/Action/index.ts +31 -0
- package/src/Action/make.ts +657 -0
- package/src/Action/raceAll.ts +48 -0
- package/src/Action/retry.ts +92 -0
- package/src/Deadline.ts +185 -0
- package/src/DurableClock.ts +133 -0
- package/src/DurableDeferred.ts +753 -0
- package/src/DurableQueue.ts +519 -0
- package/src/ExternalJob.ts +432 -0
- package/src/Fault.ts +279 -0
- package/src/Flow/Annotations.ts +151 -0
- package/src/Flow/CapabilityCeiling.ts +37 -0
- package/src/Flow/DeadlineExceeded.ts +40 -0
- package/src/Flow/ExecutionIdRequired.ts +36 -0
- package/src/Flow/ExecutionIds.ts +133 -0
- package/src/Flow/Flow.ts +576 -0
- package/src/Flow/MaxRoundsExceeded.ts +39 -0
- package/src/Flow/Outcome.ts +179 -0
- package/src/Flow/Result.ts +284 -0
- package/src/Flow/Runtime.ts +309 -0
- package/src/Flow/TypeId.ts +9 -0
- package/src/Flow/index.ts +19 -0
- package/src/Flow/internal.ts +237 -0
- package/src/Flow/make.ts +279 -0
- package/src/FlowRuntime/CancelRequestFailed.ts +56 -0
- package/src/FlowRuntime/ExecutionIdentityConflict.ts +32 -0
- package/src/FlowRuntime/FlowCycleDetected.ts +41 -0
- package/src/FlowRuntime/FlowExecutionNotFound.ts +46 -0
- package/src/FlowRuntime/FlowInstance.ts +128 -0
- package/src/FlowRuntime/FlowRuntime.ts +333 -0
- package/src/FlowRuntime/NodeRecord.ts +183 -0
- package/src/FlowRuntime/WaitingAnnotation.ts +85 -0
- package/src/FlowRuntime/index.ts +17 -0
- package/src/Graph.ts +1862 -0
- package/src/HumanTask.ts +1003 -0
- package/src/Interpreter.ts +1593 -0
- package/src/Poll.ts +414 -0
- package/src/RetryPolicy.ts +550 -0
- package/src/Sleep.ts +267 -0
- package/src/Stall.ts +217 -0
- package/src/WaitFor.ts +228 -0
- package/src/index.ts +125 -0
- package/src/internal/BoundedJson.ts +109 -0
- package/src/internal/DeclarationSite.ts +214 -0
- package/src/internal/Declarations.ts +49 -0
- package/src/internal/ExecutionMiddleware.ts +29 -0
- package/src/internal/JsonSchemaSubset.ts +392 -0
- package/src/internal/OutcomeMarker.ts +19 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
// Deep reviewed and polished by a human on 2026-08-10.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Defines data-shaped retry policies for durable action retries.
|
|
5
|
+
*
|
|
6
|
+
* A `RetryPolicy` is a plain value — initial interval, backoff factor, cap,
|
|
7
|
+
* optional maximum attempts, optional jitter, and optional non-retryable
|
|
8
|
+
* error tags — so the next retry delay can be derived from a persisted
|
|
9
|
+
* attempt count instead of fiber-local `Schedule` state. `nextDelay` mirrors
|
|
10
|
+
* Temporal's `ExponentialRetryPolicy.ComputeNextDelay` formula, and `decide`
|
|
11
|
+
* is the engine's single retry decision point: the core default a pluggable
|
|
12
|
+
* `resolveRetry` resolution can later dispatch in front of.
|
|
13
|
+
*
|
|
14
|
+
* The historical terminal-failure schemas below use the `@smthrs/flow/` tags settled for
|
|
15
|
+
* 1.0.0-rc.0. The release candidate makes no compatibility promise to 0.x
|
|
16
|
+
* journals, and these tags freeze at the RC. Current action dispatch preserves
|
|
17
|
+
* the final declared failure when a retry policy is spent.
|
|
18
|
+
*
|
|
19
|
+
* See `docs/guides/retry-a-failing-action.md`; its "Infrastructure
|
|
20
|
+
* interrupts" section covers the interrupt retry schedule.
|
|
21
|
+
*
|
|
22
|
+
* @since 0.1.0
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import * as Effect from "effect/Effect"
|
|
26
|
+
import * as Option from "effect/Option"
|
|
27
|
+
import * as Random from "effect/Random"
|
|
28
|
+
import * as Schema from "effect/Schema"
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Data-shaped retry policy schema.
|
|
32
|
+
*
|
|
33
|
+
* The delay before attempt `n + 1` is
|
|
34
|
+
* `min(initialMs * factor^(n - 1), maxMs)`, where `n` is the attempt that
|
|
35
|
+
* just failed. `maxAttempts` bounds the total number of attempts;
|
|
36
|
+
* `expirationMs` bounds the total wall-clock retry duration
|
|
37
|
+
* (schedule-to-close, mirroring Temporal's `expirationInterval`);
|
|
38
|
+
* `jitterRatio` spreads the final portion of each delay uniformly;
|
|
39
|
+
* `nonRetryable` lists error tags that must never be retried.
|
|
40
|
+
*
|
|
41
|
+
* The bounds are per STEP KEY, which is what makes them the provider-retry
|
|
42
|
+
* budget for one agent ask rather than a budget for the exchange the ask
|
|
43
|
+
* belongs to. A structured-output correction re-prompts under a NEW session,
|
|
44
|
+
* so the corrected ask is a different sealed step with its own attempt
|
|
45
|
+
* sequence: `maxAttempts` bounds the provider retries inside one correction
|
|
46
|
+
* session and does not bound the correction ladder, which `AgentAction`
|
|
47
|
+
* bounds separately with its own `corrections` budget.
|
|
48
|
+
*
|
|
49
|
+
* @category models
|
|
50
|
+
* @since 0.1.0
|
|
51
|
+
*/
|
|
52
|
+
const RetryPolicyFields = Schema.Struct({
|
|
53
|
+
initialMs: Schema.Number,
|
|
54
|
+
factor: Schema.Number,
|
|
55
|
+
maxMs: Schema.Number,
|
|
56
|
+
maxAttempts: Schema.optional(Schema.Number),
|
|
57
|
+
expirationMs: Schema.optional(Schema.Number),
|
|
58
|
+
jitterRatio: Schema.optional(Schema.Number),
|
|
59
|
+
nonRetryable: Schema.optional(Schema.Array(Schema.String))
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
type RetryPolicyFields = typeof RetryPolicyFields.Type
|
|
63
|
+
|
|
64
|
+
/** Returns the first contract violation shared by decoding and construction. */
|
|
65
|
+
const validationIssue = (policy: RetryPolicyFields): string | undefined => {
|
|
66
|
+
// Zero is refused rather than read as "retry immediately": every computed
|
|
67
|
+
// delay would be zero, so such a policy would give up on its first failure
|
|
68
|
+
// no matter what `maxAttempts` promised. Use `initialMs: 1` for a
|
|
69
|
+
// near-immediate retry.
|
|
70
|
+
if (!Number.isFinite(policy.initialMs) || policy.initialMs <= 0) {
|
|
71
|
+
return `"initialMs" must be a finite number of milliseconds greater than zero, and was ${policy.initialMs}.`
|
|
72
|
+
}
|
|
73
|
+
if (!Number.isFinite(policy.factor) || policy.factor <= 0) {
|
|
74
|
+
return `"factor" must be a finite number greater than zero, and was ${policy.factor}.`
|
|
75
|
+
}
|
|
76
|
+
if (!Number.isFinite(policy.maxMs) || policy.maxMs < policy.initialMs) {
|
|
77
|
+
return `"maxMs" must be a finite number of milliseconds at least as large as initialMs, and was ${policy.maxMs}.`
|
|
78
|
+
}
|
|
79
|
+
if (
|
|
80
|
+
policy.maxAttempts !== undefined &&
|
|
81
|
+
(!Number.isSafeInteger(policy.maxAttempts) || policy.maxAttempts < 1)
|
|
82
|
+
) {
|
|
83
|
+
return `"maxAttempts" must be a safe integer of at least one, and was ${policy.maxAttempts}.`
|
|
84
|
+
}
|
|
85
|
+
if (
|
|
86
|
+
policy.expirationMs !== undefined &&
|
|
87
|
+
(!Number.isFinite(policy.expirationMs) || policy.expirationMs <= 0)
|
|
88
|
+
) {
|
|
89
|
+
return `"expirationMs" must be a finite number of milliseconds greater than zero, and was ${policy.expirationMs}.`
|
|
90
|
+
}
|
|
91
|
+
if (
|
|
92
|
+
policy.jitterRatio !== undefined &&
|
|
93
|
+
(!Number.isFinite(policy.jitterRatio) || policy.jitterRatio < 0 || policy.jitterRatio > 1)
|
|
94
|
+
) {
|
|
95
|
+
return `"jitterRatio" must be a finite number between zero and one, inclusive, and was ${policy.jitterRatio}.`
|
|
96
|
+
}
|
|
97
|
+
return undefined
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Data-shaped retry policy schema. Decoding enforces the same relational
|
|
102
|
+
* contract as {@link make}; persisted data cannot bypass constructor checks.
|
|
103
|
+
*
|
|
104
|
+
* @category models
|
|
105
|
+
* @since 0.1.0
|
|
106
|
+
*/
|
|
107
|
+
export const RetryPolicy = RetryPolicyFields.check(
|
|
108
|
+
Schema.makeFilter(
|
|
109
|
+
(policy) => validationIssue(policy) ?? true,
|
|
110
|
+
{ title: "validRetryPolicy" }
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The value form of a {@link RetryPolicy}.
|
|
116
|
+
*
|
|
117
|
+
* @category models
|
|
118
|
+
* @since 0.1.0
|
|
119
|
+
*/
|
|
120
|
+
export type RetryPolicy = typeof RetryPolicy.Type
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Creates a `RetryPolicy` value after checking every numeric bound.
|
|
124
|
+
* `initialMs` must be greater than zero: a zero initial interval would
|
|
125
|
+
* compute a zero delay for every attempt, which {@link nextDelay} reads as
|
|
126
|
+
* exhausted, so the policy would never retry. `jitterRatio` must be between
|
|
127
|
+
* zero and one, inclusive, and `jitterRatio: 0` disables jitter.
|
|
128
|
+
*
|
|
129
|
+
* @category constructors
|
|
130
|
+
* @since 0.1.0
|
|
131
|
+
*/
|
|
132
|
+
export const make = (options: {
|
|
133
|
+
readonly initialMs: number
|
|
134
|
+
readonly factor: number
|
|
135
|
+
readonly maxMs: number
|
|
136
|
+
readonly maxAttempts?: number | undefined
|
|
137
|
+
readonly expirationMs?: number | undefined
|
|
138
|
+
readonly jitterRatio?: number | undefined
|
|
139
|
+
readonly nonRetryable?: ReadonlyArray<string> | undefined
|
|
140
|
+
}): RetryPolicy => {
|
|
141
|
+
const issue = validationIssue(options)
|
|
142
|
+
if (issue !== undefined) throw new RangeError(`RetryPolicy.make: ${issue}`)
|
|
143
|
+
return Object.freeze({
|
|
144
|
+
initialMs: options.initialMs,
|
|
145
|
+
factor: options.factor,
|
|
146
|
+
maxMs: options.maxMs,
|
|
147
|
+
...(options.maxAttempts !== undefined ? { maxAttempts: options.maxAttempts } : {}),
|
|
148
|
+
...(options.expirationMs !== undefined ? { expirationMs: options.expirationMs } : {}),
|
|
149
|
+
...(options.jitterRatio !== undefined ? { jitterRatio: options.jitterRatio } : {}),
|
|
150
|
+
...(options.nonRetryable !== undefined
|
|
151
|
+
? { nonRetryable: Object.freeze([...options.nonRetryable]) }
|
|
152
|
+
: {})
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* The default engine retry policy.
|
|
158
|
+
*
|
|
159
|
+
* Uses a 200ms initial delay growing by 1.5x, capped at 30s, and never gives
|
|
160
|
+
* up: it declares neither `maxAttempts` nor `expirationMs`. Bound long-lived
|
|
161
|
+
* retries with `make({ ..., expirationMs })` when a wall-clock give-up is
|
|
162
|
+
* required.
|
|
163
|
+
*
|
|
164
|
+
* @category constructors
|
|
165
|
+
* @since 0.1.0
|
|
166
|
+
*/
|
|
167
|
+
export const defaultRetryPolicy: RetryPolicy = Object.freeze(
|
|
168
|
+
make({
|
|
169
|
+
initialMs: 200,
|
|
170
|
+
factor: 1.5,
|
|
171
|
+
maxMs: 30000
|
|
172
|
+
})
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Bounded infrastructure retry: 5 seconds doubling to 5 minutes, for 2 hours.
|
|
177
|
+
*
|
|
178
|
+
* @category constructors
|
|
179
|
+
* @since 1.0.0
|
|
180
|
+
*/
|
|
181
|
+
export const transient: RetryPolicy = make({
|
|
182
|
+
initialMs: 5000,
|
|
183
|
+
factor: 2,
|
|
184
|
+
maxMs: 300000,
|
|
185
|
+
expirationMs: 7200000
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* A retry decision: wait `delayMs` before the next attempt.
|
|
190
|
+
*
|
|
191
|
+
* @category models
|
|
192
|
+
* @since 0.1.0
|
|
193
|
+
*/
|
|
194
|
+
export interface RetryAfter {
|
|
195
|
+
readonly _tag: "RetryAfter"
|
|
196
|
+
readonly delayMs: number
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* A retry decision: stop retrying.
|
|
201
|
+
*
|
|
202
|
+
* @category models
|
|
203
|
+
* @since 0.1.0
|
|
204
|
+
*/
|
|
205
|
+
export interface GiveUp {
|
|
206
|
+
readonly _tag: "GiveUp"
|
|
207
|
+
readonly reason: "nonRetryable" | "exhausted" | "expired"
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The outcome of the engine's retry decision point.
|
|
212
|
+
*
|
|
213
|
+
* @category models
|
|
214
|
+
* @since 0.1.0
|
|
215
|
+
*/
|
|
216
|
+
export type RetryDecision = RetryAfter | GiveUp
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Creates a `RetryAfter` decision.
|
|
220
|
+
*
|
|
221
|
+
* @category constructors
|
|
222
|
+
* @since 0.1.0
|
|
223
|
+
*/
|
|
224
|
+
export const retryAfter = (delayMs: number): RetryDecision => ({
|
|
225
|
+
_tag: "RetryAfter",
|
|
226
|
+
delayMs
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Creates a `GiveUp` decision.
|
|
231
|
+
*
|
|
232
|
+
* @category constructors
|
|
233
|
+
* @since 0.1.0
|
|
234
|
+
*/
|
|
235
|
+
export const giveUp = (reason: GiveUp["reason"]): RetryDecision => ({
|
|
236
|
+
_tag: "GiveUp",
|
|
237
|
+
reason
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* A historical retry sequence crossed its `expirationMs` wall-clock bound.
|
|
242
|
+
* Current dispatch preserves the final declared failure instead of emitting this defect.
|
|
243
|
+
*
|
|
244
|
+
* @category errors
|
|
245
|
+
* @since 0.1.0
|
|
246
|
+
*/
|
|
247
|
+
export class RetryPolicyExpired extends Schema.TaggedError<RetryPolicyExpired>()(
|
|
248
|
+
"@smthrs/flow/RetryPolicyExpired",
|
|
249
|
+
{
|
|
250
|
+
code: Schema.Literal("retry_policy_expired").pipe(
|
|
251
|
+
Schema.withConstructorDefault(Effect.succeed("retry_policy_expired"))
|
|
252
|
+
),
|
|
253
|
+
actionName: Schema.String,
|
|
254
|
+
attempt: Schema.Number,
|
|
255
|
+
expirationMs: Schema.Number,
|
|
256
|
+
lastError: Schema.optional(Schema.Unknown)
|
|
257
|
+
}
|
|
258
|
+
) {}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* A historical retry sequence exhausted its `maxAttempts` bound.
|
|
262
|
+
* Current dispatch preserves the final declared failure instead of emitting this defect.
|
|
263
|
+
*
|
|
264
|
+
* @category errors
|
|
265
|
+
* @since 0.1.0
|
|
266
|
+
*/
|
|
267
|
+
export class RetryAttemptsExhausted extends Schema.TaggedError<RetryAttemptsExhausted>()(
|
|
268
|
+
"@smthrs/flow/RetryAttemptsExhausted",
|
|
269
|
+
{
|
|
270
|
+
code: Schema.Literal("retry_attempts_exhausted").pipe(
|
|
271
|
+
Schema.withConstructorDefault(Effect.succeed("retry_attempts_exhausted"))
|
|
272
|
+
),
|
|
273
|
+
actionName: Schema.String,
|
|
274
|
+
attempt: Schema.Number,
|
|
275
|
+
maxAttempts: Schema.Number,
|
|
276
|
+
lastError: Schema.optional(Schema.Unknown)
|
|
277
|
+
}
|
|
278
|
+
) {}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Computes the delay before attempt `attempt + 1` from the persisted attempt
|
|
282
|
+
* count, mirroring Temporal's `ComputeNextDelay`
|
|
283
|
+
* (`common/backoff/retrypolicy.go`).
|
|
284
|
+
*
|
|
285
|
+
* `attempt` is the 1-based attempt that just failed. Returns `None` when the
|
|
286
|
+
* policy gives up: `maxAttempts` reached, a non-positive computed interval,
|
|
287
|
+
* a cap below the initial interval, or — when the policy declares
|
|
288
|
+
* `expirationMs` and the caller supplies `elapsedMs` — an elapsed duration
|
|
289
|
+
* past the expiration bound. Otherwise the delay is capped to the remaining
|
|
290
|
+
* expiration window, expiring only when that window cannot fit one more
|
|
291
|
+
* full-value (`initialMs`) attempt.
|
|
292
|
+
*
|
|
293
|
+
* Jitter is deterministic-friendly: `options.random` is a `[0, 1]` sample
|
|
294
|
+
* supplied by the caller and defaults to `1`, which leaves the delay at its
|
|
295
|
+
* un-jittered value. Use {@link nextDelayEffect} to sample the `Random`
|
|
296
|
+
* service instead. A sample outside `[0, 1]`, or a persisted `jitterRatio`
|
|
297
|
+
* above one, gives up rather than returning a delay the policy never
|
|
298
|
+
* declared. A sample of zero under `jitterRatio: 1` is a delay of zero, which
|
|
299
|
+
* retries immediately.
|
|
300
|
+
*
|
|
301
|
+
* @category attempts
|
|
302
|
+
* @since 0.1.0
|
|
303
|
+
*/
|
|
304
|
+
export const nextDelay = (
|
|
305
|
+
policy: RetryPolicy,
|
|
306
|
+
attempt: number,
|
|
307
|
+
options?: {
|
|
308
|
+
readonly random?: number | undefined
|
|
309
|
+
readonly elapsedMs?: number | undefined
|
|
310
|
+
}
|
|
311
|
+
): Option.Option<number> => {
|
|
312
|
+
// Persisted policies can be decoded without `make`, so these guards treat a
|
|
313
|
+
// corrupt row as terminal instead of sending an invalid delay to the engine.
|
|
314
|
+
if (validationIssue(policy) !== undefined || !Number.isSafeInteger(attempt) || attempt < 1) {
|
|
315
|
+
return Option.none()
|
|
316
|
+
}
|
|
317
|
+
if (
|
|
318
|
+
options?.elapsedMs !== undefined &&
|
|
319
|
+
(!Number.isFinite(options.elapsedMs) || options.elapsedMs < 0)
|
|
320
|
+
) {
|
|
321
|
+
return Option.none()
|
|
322
|
+
}
|
|
323
|
+
if (policy.maxAttempts !== undefined && attempt >= policy.maxAttempts) {
|
|
324
|
+
return Option.none()
|
|
325
|
+
}
|
|
326
|
+
if (
|
|
327
|
+
policy.expirationMs !== undefined &&
|
|
328
|
+
options?.elapsedMs !== undefined &&
|
|
329
|
+
options.elapsedMs > policy.expirationMs
|
|
330
|
+
) {
|
|
331
|
+
return Option.none()
|
|
332
|
+
}
|
|
333
|
+
const raw = policy.initialMs * Math.pow(policy.factor, attempt - 1)
|
|
334
|
+
if (!(raw > 0)) {
|
|
335
|
+
return Option.none()
|
|
336
|
+
}
|
|
337
|
+
let delay = Math.min(raw, policy.maxMs)
|
|
338
|
+
// Temporal caps the delay to the remaining expiration window rather than
|
|
339
|
+
// refusing outright; the below-initial check then expires sequences whose
|
|
340
|
+
// remaining window cannot fit one more full-value attempt.
|
|
341
|
+
if (policy.expirationMs !== undefined && options?.elapsedMs !== undefined) {
|
|
342
|
+
delay = Math.min(delay, Math.max(0, policy.expirationMs - options.elapsedMs))
|
|
343
|
+
}
|
|
344
|
+
if (delay < policy.initialMs) {
|
|
345
|
+
return Option.none()
|
|
346
|
+
}
|
|
347
|
+
// `validationIssue` established finite `maxMs`, so `Math.min` made the
|
|
348
|
+
// un-jittered delay finite even when the exponential itself overflowed.
|
|
349
|
+
// This check belongs before jitter conceptually: a full-jitter sample of
|
|
350
|
+
// zero is a legitimate immediate retry rather than a give-up.
|
|
351
|
+
if (policy.jitterRatio !== undefined && policy.jitterRatio > 0) {
|
|
352
|
+
// Both jitter inputs are bounded to [0, 1] where they are accepted --
|
|
353
|
+
// `make` for `jitterRatio` and this function's contract for `random` --
|
|
354
|
+
// while `random` is a public option that still needs checking here.
|
|
355
|
+
const random = options?.random ?? 1
|
|
356
|
+
if (!(random >= 0 && random <= 1)) {
|
|
357
|
+
return Option.none()
|
|
358
|
+
}
|
|
359
|
+
// In range, the result is between `delay * (1 - jitterRatio)` and `delay`,
|
|
360
|
+
// so it is finite and never negative. A jittered value of zero retries
|
|
361
|
+
// immediately; it does not exhaust the sequence.
|
|
362
|
+
//
|
|
363
|
+
// The two terms do not sum to exactly `delay` at `random: 1`: at
|
|
364
|
+
// `jitterRatio: 0.000002` a delay of 100 rounds up to 100.00000000000001,
|
|
365
|
+
// above the policy's own cap and above the remaining expiration window.
|
|
366
|
+
// Clamping down to the un-jittered delay is what makes the upper bound
|
|
367
|
+
// stated above exact rather than approximate.
|
|
368
|
+
const jittered = delay * (1 - policy.jitterRatio) + random * delay * policy.jitterRatio
|
|
369
|
+
delay = Math.min(delay, jittered)
|
|
370
|
+
}
|
|
371
|
+
return Option.some(delay)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Computes the next retry delay, sampling the `Random` service for jitter.
|
|
376
|
+
*
|
|
377
|
+
* Deterministic under `Random.withSeed`. Policies without a `jitterRatio`
|
|
378
|
+
* never touch the service.
|
|
379
|
+
*
|
|
380
|
+
* @category attempts
|
|
381
|
+
* @since 0.1.0
|
|
382
|
+
*/
|
|
383
|
+
export const nextDelayEffect = (
|
|
384
|
+
policy: RetryPolicy,
|
|
385
|
+
attempt: number,
|
|
386
|
+
options?: { readonly elapsedMs?: number | undefined }
|
|
387
|
+
): Effect.Effect<Option.Option<number>> =>
|
|
388
|
+
policy.jitterRatio === undefined || policy.jitterRatio <= 0
|
|
389
|
+
? Effect.sync(() => nextDelay(policy, attempt, { elapsedMs: options?.elapsedMs }))
|
|
390
|
+
: Effect.map(Random.next, (random) => nextDelay(policy, attempt, { random, elapsedMs: options?.elapsedMs }))
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Extracts the stable identity tag of an error for non-retryable matching:
|
|
394
|
+
* an own string `_tag` when present, otherwise the first own `name` descriptor
|
|
395
|
+
* found while walking a bounded prototype chain. That first descriptor decides
|
|
396
|
+
* the result: only a string data value is a tag.
|
|
397
|
+
*
|
|
398
|
+
* Descriptors keep accessors inert instead of running author code through a
|
|
399
|
+
* property read. A bounded walk also terminates when a hostile proxy reports a
|
|
400
|
+
* cyclic prototype chain; any proxy trap that throws leaves the error untagged.
|
|
401
|
+
*
|
|
402
|
+
* @category attempts
|
|
403
|
+
* @since 0.1.0
|
|
404
|
+
*/
|
|
405
|
+
export const errorTag = (error: unknown): string | undefined => {
|
|
406
|
+
if (typeof error !== "object" || error === null) return undefined
|
|
407
|
+
try {
|
|
408
|
+
const tag = Object.getOwnPropertyDescriptor(error, "_tag")
|
|
409
|
+
if (tag !== undefined && "value" in tag && typeof tag.value === "string") return tag.value
|
|
410
|
+
|
|
411
|
+
let current: object | null = error
|
|
412
|
+
for (let depth = 0; current !== null && depth < 64; depth++) {
|
|
413
|
+
const name = Object.getOwnPropertyDescriptor(current, "name")
|
|
414
|
+
if (name !== undefined) {
|
|
415
|
+
return "value" in name && typeof name.value === "string" ? name.value : undefined
|
|
416
|
+
}
|
|
417
|
+
current = Object.getPrototypeOf(current)
|
|
418
|
+
}
|
|
419
|
+
} catch {
|
|
420
|
+
// Proxies and hostile accessors are untrusted failure payloads. An error
|
|
421
|
+
// that cannot be inspected inertly simply has no stable retry tag.
|
|
422
|
+
}
|
|
423
|
+
return undefined
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Error tags that are non-retryable by type, under every policy (issue #156).
|
|
428
|
+
*
|
|
429
|
+
* These failures are integrity verdicts that must reach the driver without an
|
|
430
|
+
* action-level retry hiding the first detection. Their persistence seams
|
|
431
|
+
* take a quarantine state action before raising them, so a later dispatch can
|
|
432
|
+
* heal, but the detecting dispatch remains a non-retryable failure. No
|
|
433
|
+
* per-callsite or per-policy opt-out exists; the tags are matched by string so
|
|
434
|
+
* the classification does not invert the package dependency direction.
|
|
435
|
+
*
|
|
436
|
+
* `AttemptEvidenceQuarantined` (issue #171) is the succeeded-attempt-row
|
|
437
|
+
* counterpart: the corrupt boundary evidence is removed while the completed
|
|
438
|
+
* outcome stays durable. It reaches the driver unretried, which parks the
|
|
439
|
+
* first detection in the `quarantine` waiting state; the next explicit resume
|
|
440
|
+
* returns the recorded outcome without re-executing the action.
|
|
441
|
+
*
|
|
442
|
+
* @category attempts
|
|
443
|
+
* @since 0.1.0
|
|
444
|
+
*/
|
|
445
|
+
export const defaultNonRetryable: ReadonlyArray<string> = [
|
|
446
|
+
"@smthrs/engine-store/CacheCorruptionDetected",
|
|
447
|
+
"@smthrs/engine-store/AttemptEvidenceQuarantined"
|
|
448
|
+
]
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Whether an error is classified non-retryable, either by type (see
|
|
452
|
+
* {@link defaultNonRetryable}) or by the policy's declared tag list.
|
|
453
|
+
*
|
|
454
|
+
* @category attempts
|
|
455
|
+
* @since 0.1.0
|
|
456
|
+
*/
|
|
457
|
+
export const isNonRetryable = (policy: RetryPolicy, error: unknown): boolean => {
|
|
458
|
+
const tag = errorTag(error)
|
|
459
|
+
if (tag === undefined) {
|
|
460
|
+
return false
|
|
461
|
+
}
|
|
462
|
+
if (defaultNonRetryable.includes(tag)) {
|
|
463
|
+
return true
|
|
464
|
+
}
|
|
465
|
+
return policy.nonRetryable !== undefined && policy.nonRetryable.includes(tag)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* The pure core of the engine's single retry decision point.
|
|
470
|
+
*
|
|
471
|
+
* Non-retryable classification is evaluated here and nowhere else. This is
|
|
472
|
+
* the default a pluggable `resolveRetry` resolution falls back to when no
|
|
473
|
+
* plugin claims the decision.
|
|
474
|
+
*
|
|
475
|
+
* @category attempts
|
|
476
|
+
* @since 0.1.0
|
|
477
|
+
*/
|
|
478
|
+
export const decide = (
|
|
479
|
+
policy: RetryPolicy,
|
|
480
|
+
options: {
|
|
481
|
+
readonly attempt: number
|
|
482
|
+
readonly error: unknown
|
|
483
|
+
readonly random?: number | undefined
|
|
484
|
+
readonly elapsedMs?: number | undefined
|
|
485
|
+
}
|
|
486
|
+
): RetryDecision => {
|
|
487
|
+
if (isNonRetryable(policy, options.error)) {
|
|
488
|
+
return giveUp("nonRetryable")
|
|
489
|
+
}
|
|
490
|
+
return Option.match(
|
|
491
|
+
nextDelay(policy, options.attempt, { random: options.random, elapsedMs: options.elapsedMs }),
|
|
492
|
+
{
|
|
493
|
+
onNone: () =>
|
|
494
|
+
// A policy can report `expired` only when it declares an expiration
|
|
495
|
+
// bound and dropping elapsed time would have allowed another attempt.
|
|
496
|
+
// A malformed elapsed value still gives up because the sequence cannot
|
|
497
|
+
// continue without a trustworthy clock reading; without an expiration
|
|
498
|
+
// bound, the public terminal reason for that refusal is `exhausted`.
|
|
499
|
+
policy.expirationMs !== undefined &&
|
|
500
|
+
Option.isSome(nextDelay(policy, options.attempt, { random: options.random }))
|
|
501
|
+
? giveUp("expired")
|
|
502
|
+
: giveUp("exhausted"),
|
|
503
|
+
onSome: (delay) => {
|
|
504
|
+
// Tool failures may supply a delay instead of using policy backoff.
|
|
505
|
+
// Inspect only an own data property: failure payloads can be untrusted.
|
|
506
|
+
let hint: unknown
|
|
507
|
+
if (typeof options.error === "object" && options.error !== null) {
|
|
508
|
+
try {
|
|
509
|
+
const descriptor = Object.getOwnPropertyDescriptor(options.error, "retryAfterMs")
|
|
510
|
+
if (descriptor !== undefined && "value" in descriptor) hint = descriptor.value
|
|
511
|
+
} catch {
|
|
512
|
+
// An uninspectable failure falls back to the policy delay.
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (typeof hint !== "number" || !Number.isFinite(hint) || hint < 0) {
|
|
516
|
+
return retryAfter(delay)
|
|
517
|
+
}
|
|
518
|
+
return retryAfter(Math.min(
|
|
519
|
+
hint,
|
|
520
|
+
policy.maxMs,
|
|
521
|
+
policy.expirationMs !== undefined && options.elapsedMs !== undefined
|
|
522
|
+
? Math.max(0, policy.expirationMs - options.elapsedMs)
|
|
523
|
+
: policy.maxMs
|
|
524
|
+
))
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Effect form of {@link decide}, sampling the `Random` service for jitter.
|
|
532
|
+
*
|
|
533
|
+
* This is the engine-facing decision function: keep calls to it behind a
|
|
534
|
+
* single decision point so a plugin hook dispatch can later be inserted in
|
|
535
|
+
* front of it without touching call sites.
|
|
536
|
+
*
|
|
537
|
+
* @category attempts
|
|
538
|
+
* @since 0.1.0
|
|
539
|
+
*/
|
|
540
|
+
export const decideEffect = (
|
|
541
|
+
policy: RetryPolicy,
|
|
542
|
+
options: {
|
|
543
|
+
readonly attempt: number
|
|
544
|
+
readonly error: unknown
|
|
545
|
+
readonly elapsedMs?: number | undefined
|
|
546
|
+
}
|
|
547
|
+
): Effect.Effect<RetryDecision> =>
|
|
548
|
+
policy.jitterRatio === undefined || policy.jitterRatio <= 0
|
|
549
|
+
? Effect.sync(() => decide(policy, options))
|
|
550
|
+
: Effect.map(Random.next, (random) => decide(policy, { ...options, random }))
|