@smthrs/flow 0.0.0-stage → 1.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +161 -0
- package/LICENSE +21 -0
- package/README.md +212 -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 +387 -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 +110 -0
- package/dist/cjs/Deadline.d.ts.map +1 -0
- package/dist/cjs/Deadline.js +112 -0
- package/dist/cjs/Deadline.js.map +7 -0
- package/dist/cjs/DurableClock.d.ts +60 -0
- package/dist/cjs/DurableClock.d.ts.map +1 -0
- package/dist/cjs/DurableClock.js +107 -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 +339 -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 +186 -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 +135 -0
- package/dist/cjs/Flow/make.d.ts.map +1 -0
- package/dist/cjs/Flow/make.js +107 -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 +204 -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 +177 -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 +1020 -0
- package/dist/cjs/Graph.js.map +7 -0
- package/dist/cjs/HumanTask.d.ts +442 -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 +223 -0
- package/dist/cjs/Interpreter.d.ts.map +1 -0
- package/dist/cjs/Interpreter.js +908 -0
- package/dist/cjs/Interpreter.js.map +7 -0
- package/dist/cjs/Poll.d.ts +240 -0
- package/dist/cjs/Poll.d.ts.map +1 -0
- package/dist/cjs/Poll.js +154 -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 +141 -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 +413 -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 +110 -0
- package/dist/esm/Deadline.d.ts.map +1 -0
- package/dist/esm/Deadline.js +164 -0
- package/dist/esm/Deadline.js.map +1 -0
- package/dist/esm/DurableClock.d.ts +60 -0
- package/dist/esm/DurableClock.d.ts.map +1 -0
- package/dist/esm/DurableClock.js +122 -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 +252 -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 +135 -0
- package/dist/esm/Flow/make.d.ts.map +1 -0
- package/dist/esm/Flow/make.js +111 -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 +204 -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 +177 -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 +1485 -0
- package/dist/esm/Graph.js.map +1 -0
- package/dist/esm/HumanTask.d.ts +442 -0
- package/dist/esm/HumanTask.d.ts.map +1 -0
- package/dist/esm/HumanTask.js +798 -0
- package/dist/esm/HumanTask.js.map +1 -0
- package/dist/esm/Interpreter.d.ts +223 -0
- package/dist/esm/Interpreter.d.ts.map +1 -0
- package/dist/esm/Interpreter.js +1289 -0
- package/dist/esm/Interpreter.js.map +1 -0
- package/dist/esm/Poll.d.ts +240 -0
- package/dist/esm/Poll.d.ts.map +1 -0
- package/dist/esm/Poll.js +289 -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 +256 -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 +152 -0
- package/docs/api.md +440 -0
- package/docs/concepts/bodies-and-plans.md +167 -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 +164 -0
- package/docs/guides/cancel-and-roll-back.md +112 -0
- package/docs/guides/implement-an-action.md +155 -0
- package/docs/guides/inspect-the-plan.md +235 -0
- package/docs/guides/poll-until-ready.md +169 -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 +129 -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 +87 -0
- package/docs/quickstart.md +164 -0
- package/docs/reference/flow.md +1835 -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 +671 -0
- package/src/Action/raceAll.ts +48 -0
- package/src/Action/retry.ts +92 -0
- package/src/Deadline.ts +201 -0
- package/src/DurableClock.ts +176 -0
- package/src/DurableDeferred.ts +753 -0
- package/src/DurableQueue.ts +519 -0
- package/src/ExternalJob.ts +437 -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 +339 -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 +285 -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 +339 -0
- package/src/FlowRuntime/NodeRecord.ts +185 -0
- package/src/FlowRuntime/WaitingAnnotation.ts +85 -0
- package/src/FlowRuntime/index.ts +17 -0
- package/src/Graph.ts +1865 -0
- package/src/HumanTask.ts +1007 -0
- package/src/Interpreter.ts +1620 -0
- package/src/Poll.ts +420 -0
- package/src/RetryPolicy.ts +550 -0
- package/src/Sleep.ts +296 -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
package/dist/esm/Poll.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polling as a durable lineage: one attempt per round, a durable wait between
|
|
3
|
+
* attempts, and a bound the lineage settles on.
|
|
4
|
+
*
|
|
5
|
+
* Smithers 0.x had a `Poller` component — a check, an interval, a backoff, an
|
|
6
|
+
* attempt bound, and what to do at that bound. The pieces it was built from
|
|
7
|
+
* already exist here: {@link module:Sleep.action} is the durable wait, and
|
|
8
|
+
* `Flow.to` opens the next round. What was missing is the shape that puts them
|
|
9
|
+
* together, and that is this module.
|
|
10
|
+
*
|
|
11
|
+
* A poll is a flow whose body is ONE attempt. It runs the check, and branches:
|
|
12
|
+
* a satisfied check settles the lineage with the check's own output, an
|
|
13
|
+
* unsatisfied one sleeps for this attempt's delay and hands off to the next
|
|
14
|
+
* round with the attempt counter raised. The last attempt has no sleep and no
|
|
15
|
+
* handoff — it either answers with the output it just read (`return-last`) or
|
|
16
|
+
* fails {@link PollExhausted} (`fail`).
|
|
17
|
+
*
|
|
18
|
+
* Everything durable about it is durable for the ordinary reason. Each attempt
|
|
19
|
+
* is a round with its own keyed plan nodes, so a check that already ran replays
|
|
20
|
+
* from its recorded outcome instead of running again; the wait between attempts
|
|
21
|
+
* is a durable timer, so a process that dies during it resumes on the round it
|
|
22
|
+
* left rather than starting the poll over; and the attempt counter travels in
|
|
23
|
+
* the payload, so nothing about "which attempt is this" lives in memory.
|
|
24
|
+
*
|
|
25
|
+
* The bound is stated twice on purpose. The body ends the lineage on the last
|
|
26
|
+
* attempt, and `maxAttempts` is also the flow's `maxRounds` budget, so a
|
|
27
|
+
* lineage that somehow opened another round is refused by the engine rather
|
|
28
|
+
* than polling forever.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
*/
|
|
32
|
+
import * as Node from "@smthrs/plan/Node";
|
|
33
|
+
import * as Effect from "effect/Effect";
|
|
34
|
+
import * as Schema from "effect/Schema";
|
|
35
|
+
import * as Action from "./Action/index.js";
|
|
36
|
+
import * as Flow from "./Flow/index.js";
|
|
37
|
+
import * as Sleep from "./Sleep.js";
|
|
38
|
+
/**
|
|
39
|
+
* The success schema a check action declares.
|
|
40
|
+
*
|
|
41
|
+
* @category schemas
|
|
42
|
+
* @since 0.1.0
|
|
43
|
+
*/
|
|
44
|
+
export const CheckResult = (result) => Schema.Struct({ satisfied: Schema.Boolean, output: result });
|
|
45
|
+
/**
|
|
46
|
+
* A poll that used its last attempt without a satisfied check.
|
|
47
|
+
*
|
|
48
|
+
* It is a typed failure rather than a defect: running out of attempts is an
|
|
49
|
+
* expected outcome of polling something that may never become ready, so a
|
|
50
|
+
* caller recovers from it through `Node.catch` like any other declared failure.
|
|
51
|
+
*
|
|
52
|
+
* @category errors
|
|
53
|
+
* @since 0.1.0
|
|
54
|
+
*/
|
|
55
|
+
export class PollExhausted extends Schema.TaggedError()("@smthrs/flow/PollExhausted", {
|
|
56
|
+
// This wire shape freezes at 1.0.0-rc.0.
|
|
57
|
+
code: Schema.Literal("poll_exhausted").pipe(Schema.withConstructorDefault(Effect.succeed("poll_exhausted"))),
|
|
58
|
+
poll: Schema.String,
|
|
59
|
+
attempts: Schema.Number,
|
|
60
|
+
message: Schema.String
|
|
61
|
+
}) {
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The tag the exhaustion step is catalogued and resolved under.
|
|
65
|
+
*
|
|
66
|
+
* @category constructors
|
|
67
|
+
* @since 0.1.0
|
|
68
|
+
*/
|
|
69
|
+
export const exhaustedTag = "system/poll-exhausted";
|
|
70
|
+
/**
|
|
71
|
+
* The declared step a poll takes when its last attempt was not satisfied.
|
|
72
|
+
*
|
|
73
|
+
* Running out of attempts is a step rather than a bare `Effect.fail` so the
|
|
74
|
+
* exhaustion is in the plan and in the journal: the round that gave up shows
|
|
75
|
+
* which poll gave up and after how many attempts, exactly like every other node
|
|
76
|
+
* a body drove.
|
|
77
|
+
*
|
|
78
|
+
* @category constructors
|
|
79
|
+
* @since 0.1.0
|
|
80
|
+
*/
|
|
81
|
+
export const exhausted = Action.makeSystem(exhaustedTag, {
|
|
82
|
+
payload: { poll: Schema.String, attempts: Schema.Number },
|
|
83
|
+
success: Schema.Never,
|
|
84
|
+
error: PollExhausted,
|
|
85
|
+
tier: "sealed"
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* The wait before the attempt after this one, in milliseconds.
|
|
89
|
+
*
|
|
90
|
+
* @category combinators
|
|
91
|
+
* @since 0.1.0
|
|
92
|
+
*/
|
|
93
|
+
export const delayMillis = (options) =>
|
|
94
|
+
// A zero interval is zero under every backoff. Multiplying it by a factor
|
|
95
|
+
// that has overflowed to `Infinity` would make it `NaN`.
|
|
96
|
+
options.intervalMs === 0 ? 0 : options.intervalMs *
|
|
97
|
+
(options.backoff === "fixed" ? 1 : options.backoff === "linear" ? options.attempt : 2 ** (options.attempt - 1));
|
|
98
|
+
/**
|
|
99
|
+
* What a poll round can fail with.
|
|
100
|
+
*
|
|
101
|
+
* {@link PollExhausted} is the poll's own failure. `SleepRequestInvalid` is the
|
|
102
|
+
* wait node's, declared because the wait between attempts is an ordinary
|
|
103
|
+
* {@link module:Sleep.action} node and its typed refusal is part of the
|
|
104
|
+
* topology a poll carries. Its codes cover a payload that names no deadline,
|
|
105
|
+
* names two deadlines, or names a value that is not a deadline. {@link make}
|
|
106
|
+
* refuses invalid author schedules at construction. A caller-visible round
|
|
107
|
+
* payload can still carry an invalid attempt that produces an invalid derived
|
|
108
|
+
* wait, so `Sleep` refuses that wait before the round parks.
|
|
109
|
+
*
|
|
110
|
+
* @category schemas
|
|
111
|
+
* @since 0.1.0
|
|
112
|
+
*/
|
|
113
|
+
export const Failure = Schema.Union([PollExhausted, Sleep.SleepRequestInvalid]);
|
|
114
|
+
/**
|
|
115
|
+
* The payload schema one round is opened with: the author's fields, plus the
|
|
116
|
+
* attempt counter the lineage carries between them.
|
|
117
|
+
*
|
|
118
|
+
* @private
|
|
119
|
+
*/
|
|
120
|
+
const payloadSchema = (input, maxAttempts) => Schema.Struct({
|
|
121
|
+
...input,
|
|
122
|
+
attempt: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1), Schema.isLessThanOrEqualTo(maxAttempts)))
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
125
|
+
* The attempt a round payload carries, defaulting to the first.
|
|
126
|
+
*
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
const attemptOf = (payload) => {
|
|
130
|
+
const attempt = payload.attempt;
|
|
131
|
+
return typeof attempt === "number" ? attempt : 1;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Rebuilds a round payload with an explicit attempt.
|
|
135
|
+
*
|
|
136
|
+
* The two views of one round payload — what the check reads, and what the next
|
|
137
|
+
* round is opened with — are the same fields with `attempt` resolved. TypeScript
|
|
138
|
+
* cannot reduce a mapped type over an unresolved generic field set, so the
|
|
139
|
+
* shape is stated once here instead of at each use.
|
|
140
|
+
*
|
|
141
|
+
* @private
|
|
142
|
+
*/
|
|
143
|
+
const withAttempt = (payload, attempt) => ({ ...payload, attempt });
|
|
144
|
+
/**
|
|
145
|
+
* Declares a durable poller.
|
|
146
|
+
*
|
|
147
|
+
* **When to use**
|
|
148
|
+
*
|
|
149
|
+
* Use it wherever a run has to keep asking until something is ready — a build
|
|
150
|
+
* that finishes, a deployment that goes live, a review that lands — and the
|
|
151
|
+
* waiting has to survive a restart. `check` is the one thing an author writes:
|
|
152
|
+
* a body fragment that reads whatever it polls and reports a {@link Check}.
|
|
153
|
+
* Everything else is schedule. Under stable callback admission (the default of
|
|
154
|
+
* `Interpreter.layerWithImplementations`), wrap `check` in `Node.capture` with
|
|
155
|
+
* every semantic capture, including a version for imported behavior. An
|
|
156
|
+
* uncaptured check keeps the poll process-local. The helper captures its own
|
|
157
|
+
* callbacks using the schedule and the check's identity.
|
|
158
|
+
*
|
|
159
|
+
* ```ts
|
|
160
|
+
* const Deployment = Poll.make("deploy/wait", {
|
|
161
|
+
* input: { id: Schema.String },
|
|
162
|
+
* result: Schema.String,
|
|
163
|
+
* intervalMs: 5_000,
|
|
164
|
+
* backoff: "exponential",
|
|
165
|
+
* maxAttempts: 8,
|
|
166
|
+
* onTimeout: "fail",
|
|
167
|
+
* check: Node.capture(
|
|
168
|
+
* { action: Status.name, implementationVersion: "deploy/status-check/v1" },
|
|
169
|
+
* ({ attempt, id }) => Status.call({ attempt, id })
|
|
170
|
+
* )
|
|
171
|
+
* })
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* The check may not fail. A check that can fail states what a failure means for
|
|
175
|
+
* the poll — give up, or treat it as "not ready yet" — with `Node.catch` inside
|
|
176
|
+
* the fragment, rather than leaving the poll to guess.
|
|
177
|
+
*
|
|
178
|
+
* A per-attempt time limit on the check itself is NOT a poll option. A plan
|
|
179
|
+
* node's duration is not something the body around it can bound; that bound
|
|
180
|
+
* belongs in the check's own implementation, where `DurableDeferred.raceAll`
|
|
181
|
+
* races the work against a durable clock and stays replayable.
|
|
182
|
+
*
|
|
183
|
+
* A schedule no clock can be armed with is refused here, with a `RangeError`
|
|
184
|
+
* naming the option that is wrong. `intervalMs` becomes the `millis` of a
|
|
185
|
+
* {@link module:Sleep.action} node, and a wait of `Infinity`, `NaN`, or a
|
|
186
|
+
* negative length arms a timer that never fires — a poll that hangs forever
|
|
187
|
+
* with a plan that looks correct. The check is on the schedule, not only on the
|
|
188
|
+
* interval: `{ intervalMs: 1000, maxAttempts: 2000, backoff: "exponential" }`
|
|
189
|
+
* states three finite options and asks for an infinite wait, so the LAST wait
|
|
190
|
+
* the poll can arm has to be a length too, and no longer than
|
|
191
|
+
* `Number.MAX_SAFE_INTEGER` milliseconds, the latest deadline a durable timer
|
|
192
|
+
* records. `maxAttempts` is the lineage's round
|
|
193
|
+
* budget, and a budget below one attempt reaches `Flow.make` as a `maxRounds`
|
|
194
|
+
* complaint about an option the author never wrote.
|
|
195
|
+
*
|
|
196
|
+
* @throws A `RangeError` when `intervalMs` is not a duration a clock accepts,
|
|
197
|
+
* when `maxAttempts` is not a whole number of attempts of at least one, or when
|
|
198
|
+
* the interval under the declared backoff reaches a wait no clock can be armed
|
|
199
|
+
* with before the budget is spent.
|
|
200
|
+
* @category constructors
|
|
201
|
+
* @since 0.1.0
|
|
202
|
+
*/
|
|
203
|
+
export const make = (tag, options) => {
|
|
204
|
+
if (Object.prototype.hasOwnProperty.call(options.input, "attempt")) {
|
|
205
|
+
throw new TypeError(`Poll.make: "${tag}" input cannot declare the reserved "attempt" field. ` +
|
|
206
|
+
"Poll owns that counter across durable rounds.");
|
|
207
|
+
}
|
|
208
|
+
const input = Object.freeze({ ...options.input });
|
|
209
|
+
const result = options.result;
|
|
210
|
+
const check = options.check;
|
|
211
|
+
const intervalMs = options.intervalMs;
|
|
212
|
+
const maxAttempts = options.maxAttempts;
|
|
213
|
+
if (!Number.isFinite(intervalMs) || intervalMs < 0) {
|
|
214
|
+
throw new RangeError(`Poll.make: "${tag}" intervalMs must be a finite number of milliseconds that is not negative, ` +
|
|
215
|
+
`and was ${intervalMs}. The interval is the length of a durable wait, and a wait of ` +
|
|
216
|
+
"that length never ends.");
|
|
217
|
+
}
|
|
218
|
+
if (!Number.isSafeInteger(maxAttempts) || maxAttempts < 1) {
|
|
219
|
+
throw new RangeError(`Poll.make: "${tag}" maxAttempts must be a whole number of attempts of at least one, and was ` +
|
|
220
|
+
`${maxAttempts}. A poll checks at least once.`);
|
|
221
|
+
}
|
|
222
|
+
const backoff = options.backoff ?? "fixed";
|
|
223
|
+
// The wait a poll arms is not `intervalMs`. {@link delayMillis} multiplies it
|
|
224
|
+
// by the backoff, so a schedule whose options are each finite can still ask
|
|
225
|
+
// for a wait that is not a length — and that wait arms the same timer that
|
|
226
|
+
// never fires the interval guard above exists to refuse. The last wait is the
|
|
227
|
+
// one before the final attempt, because the attempt at the budget gives up
|
|
228
|
+
// rather than sleeps, and the schedule never shrinks, so the last wait is
|
|
229
|
+
// also the longest: checking it checks all of them.
|
|
230
|
+
const longestWaitMs = maxAttempts > 1
|
|
231
|
+
? delayMillis({ intervalMs, backoff, attempt: maxAttempts - 1 })
|
|
232
|
+
: 0;
|
|
233
|
+
// A durable timer records its deadline as a safe integer of milliseconds,
|
|
234
|
+
// so `Sleep` refuses a longer wait on the round that reaches it.
|
|
235
|
+
if (!Number.isFinite(longestWaitMs) || longestWaitMs > Number.MAX_SAFE_INTEGER) {
|
|
236
|
+
throw new RangeError(`Poll.make: "${tag}" asks for a wait of ${longestWaitMs} ms before its last attempt. An ` +
|
|
237
|
+
`intervalMs of ${intervalMs} under the "${backoff}" backoff reaches a length no clock ` +
|
|
238
|
+
`can be armed with by attempt ${maxAttempts - 1} of ${maxAttempts}. Lower ` +
|
|
239
|
+
"maxAttempts, shorten the interval, or slow the backoff.");
|
|
240
|
+
}
|
|
241
|
+
const onTimeout = options.onTimeout ?? "fail";
|
|
242
|
+
const captures = { tag, intervalMs, backoff, maxAttempts, onTimeout, check: Node.functionIdentity(check) };
|
|
243
|
+
const body = (payload) => {
|
|
244
|
+
const attempt = attemptOf(payload);
|
|
245
|
+
const last = attempt >= maxAttempts;
|
|
246
|
+
return check(withAttempt(payload, attempt)).pipe(Node.branch({
|
|
247
|
+
if: Node.capture(captures, (checked) => checked.satisfied),
|
|
248
|
+
then: (checked) => Flow.done(checked.output),
|
|
249
|
+
else: (checked) => last
|
|
250
|
+
? onTimeout === "return-last"
|
|
251
|
+
? Flow.done(checked.output)
|
|
252
|
+
: exhausted.call({ poll: tag, attempts: attempt })
|
|
253
|
+
: Sleep.action.call({
|
|
254
|
+
millis: delayMillis({ intervalMs, backoff, attempt })
|
|
255
|
+
}).pipe(Node.andThen(self.to(withAttempt(payload, attempt + 1))))
|
|
256
|
+
}));
|
|
257
|
+
};
|
|
258
|
+
// The body names the flow it is the body of, which is what makes one round
|
|
259
|
+
// open the next. It is read when a round is planned, long after `Flow.make`
|
|
260
|
+
// has returned, so the binding is initialized by then.
|
|
261
|
+
const self = Flow.make(tag, {
|
|
262
|
+
payload: payloadSchema(input, maxAttempts),
|
|
263
|
+
success: result,
|
|
264
|
+
error: Failure,
|
|
265
|
+
maxRounds: maxAttempts,
|
|
266
|
+
// A captured wrapper must not admit a process-local check as stable.
|
|
267
|
+
body: captures.check.algorithm === "sha256-source-ephemeral/v4" ? body : Node.capture(captures, body)
|
|
268
|
+
});
|
|
269
|
+
return self;
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* The exhaustion implementation, provided beside the other action layers a
|
|
273
|
+
* poll's rounds call.
|
|
274
|
+
*
|
|
275
|
+
* ```ts
|
|
276
|
+
* Layer.mergeAll(Poll.layer, Sleep.layer, Interpreter.layer(Deployment)).pipe(
|
|
277
|
+
* Layer.provideMerge(Action.layerImplementations)
|
|
278
|
+
* )
|
|
279
|
+
* ```
|
|
280
|
+
*
|
|
281
|
+
* @category layers
|
|
282
|
+
* @since 0.1.0
|
|
283
|
+
*/
|
|
284
|
+
export const layer = exhausted.toLayer(({ attempts, poll }) => Effect.fail(new PollExhausted({
|
|
285
|
+
poll,
|
|
286
|
+
attempts,
|
|
287
|
+
message: `Poll "${poll}" used all ${attempts} attempts without a satisfied check.`
|
|
288
|
+
})));
|
|
289
|
+
//# sourceMappingURL=Poll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Poll.js","sourceRoot":"","sources":["../../src/Poll.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Polling as a durable lineage: one attempt per round, a durable wait between\n * attempts, and a bound the lineage settles on.\n *\n * Smithers 0.x had a `Poller` component — a check, an interval, a backoff, an\n * attempt bound, and what to do at that bound. The pieces it was built from\n * already exist here: {@link module:Sleep.action} is the durable wait, and\n * `Flow.to` opens the next round. What was missing is the shape that puts them\n * together, and that is this module.\n *\n * A poll is a flow whose body is ONE attempt. It runs the check, and branches:\n * a satisfied check settles the lineage with the check's own output, an\n * unsatisfied one sleeps for this attempt's delay and hands off to the next\n * round with the attempt counter raised. The last attempt has no sleep and no\n * handoff — it either answers with the output it just read (`return-last`) or\n * fails {@link PollExhausted} (`fail`).\n *\n * Everything durable about it is durable for the ordinary reason. Each attempt\n * is a round with its own keyed plan nodes, so a check that already ran replays\n * from its recorded outcome instead of running again; the wait between attempts\n * is a durable timer, so a process that dies during it resumes on the round it\n * left rather than starting the poll over; and the attempt counter travels in\n * the payload, so nothing about \"which attempt is this\" lives in memory.\n *\n * The bound is stated twice on purpose. The body ends the lineage on the last\n * attempt, and `maxAttempts` is also the flow's `maxRounds` budget, so a\n * lineage that somehow opened another round is refused by the engine rather\n * than polling forever.\n *\n * @since 0.1.0\n */\n\nimport * as Node from \"@smthrs/plan/Node\"\nimport type * as Repetition from \"@smthrs/plan/Repetition\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Effect from \"effect/Effect\"\nimport type * as Layer from \"effect/Layer\"\nimport * as Schema from \"effect/Schema\"\nimport * as Action from \"./Action/index.ts\"\nimport * as Flow from \"./Flow/index.ts\"\nimport type { FlowRuntime } from \"./FlowRuntime/FlowRuntime.ts\"\nimport * as Sleep from \"./Sleep.ts\"\n\n/**\n * How the wait between attempts grows.\n *\n * `fixed` waits the interval every time, `linear` waits the interval times the\n * attempt, and `exponential` doubles the interval on every attempt.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Backoff = \"fixed\" | \"linear\" | \"exponential\"\n\n/**\n * What a check reports: whether the poll is over, and the value this attempt\n * read.\n *\n * The output travels on every attempt, satisfied or not, because it is also\n * the answer a `return-last` poll settles with when it runs out of attempts.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface Check<out Result> {\n readonly satisfied: boolean\n readonly output: Result\n}\n\n/**\n * The success schema a check action declares.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const CheckResult = <Result extends Schema.Top>(\n result: Result\n): Schema.Struct<{\n readonly satisfied: typeof Schema.Boolean\n readonly output: Result\n}> => Schema.Struct({ satisfied: Schema.Boolean, output: result })\n\n/**\n * A poll that used its last attempt without a satisfied check.\n *\n * It is a typed failure rather than a defect: running out of attempts is an\n * expected outcome of polling something that may never become ready, so a\n * caller recovers from it through `Node.catch` like any other declared failure.\n *\n * @category errors\n * @since 0.1.0\n */\nexport class PollExhausted extends Schema.TaggedError<PollExhausted>()(\n \"@smthrs/flow/PollExhausted\",\n {\n // This wire shape freezes at 1.0.0-rc.0.\n code: Schema.Literal(\"poll_exhausted\").pipe(\n Schema.withConstructorDefault(Effect.succeed(\"poll_exhausted\"))\n ),\n poll: Schema.String,\n attempts: Schema.Number,\n message: Schema.String\n }\n) {}\n\n/**\n * The tag the exhaustion step is catalogued and resolved under.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const exhaustedTag = \"system/poll-exhausted\"\n\n/**\n * The declared step a poll takes when its last attempt was not satisfied.\n *\n * Running out of attempts is a step rather than a bare `Effect.fail` so the\n * exhaustion is in the plan and in the journal: the round that gave up shows\n * which poll gave up and after how many attempts, exactly like every other node\n * a body drove.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const exhausted: Action.Declared<\n typeof exhaustedTag,\n Schema.Struct<{\n readonly poll: typeof Schema.String\n readonly attempts: typeof Schema.Number\n }>,\n typeof Schema.Never,\n typeof PollExhausted,\n never\n> = Action.makeSystem(exhaustedTag, {\n payload: { poll: Schema.String, attempts: Schema.Number },\n success: Schema.Never,\n error: PollExhausted,\n tier: \"sealed\"\n})\n\n/**\n * The wait before the attempt after this one, in milliseconds.\n *\n * @category combinators\n * @since 0.1.0\n */\nexport const delayMillis = (options: {\n readonly intervalMs: number\n readonly backoff: Backoff\n readonly attempt: number\n}): number =>\n // A zero interval is zero under every backoff. Multiplying it by a factor\n // that has overflowed to `Infinity` would make it `NaN`.\n options.intervalMs === 0 ? 0 : options.intervalMs *\n (options.backoff === \"fixed\" ? 1 : options.backoff === \"linear\" ? options.attempt : 2 ** (options.attempt - 1))\n\n/**\n * What a poll round can fail with.\n *\n * {@link PollExhausted} is the poll's own failure. `SleepRequestInvalid` is the\n * wait node's, declared because the wait between attempts is an ordinary\n * {@link module:Sleep.action} node and its typed refusal is part of the\n * topology a poll carries. Its codes cover a payload that names no deadline,\n * names two deadlines, or names a value that is not a deadline. {@link make}\n * refuses invalid author schedules at construction. A caller-visible round\n * payload can still carry an invalid attempt that produces an invalid derived\n * wait, so `Sleep` refuses that wait before the round parks.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Failure: Schema.Union<\n readonly [typeof PollExhausted, typeof Sleep.SleepRequestInvalid]\n> = Schema.Union([PollExhausted, Sleep.SleepRequestInvalid])\n\n/**\n * The payload schema {@link make} derives from an author's input fields: the\n * author's own fields, plus the attempt this round is.\n *\n * `attempt` is optional so a caller starts a poll with its own fields alone;\n * the first round reads it as one.\n *\n * @category models\n * @since 0.1.0\n */\nexport type PayloadSchema<Input extends Schema.Struct.Fields> = Schema.Struct<\n Input & { readonly attempt: Schema.optional<typeof Schema.Number> }\n>\n\n/**\n * The payload schema one round is opened with: the author's fields, plus the\n * attempt counter the lineage carries between them.\n *\n * @private\n */\nconst payloadSchema = <Input extends Schema.Struct.Fields>(\n input: Input,\n maxAttempts: number\n): PayloadSchema<Input> =>\n Schema.Struct({\n ...input,\n attempt: Schema.optional(\n Schema.Int.check(\n Schema.isGreaterThanOrEqualTo(1),\n Schema.isLessThanOrEqualTo(maxAttempts)\n )\n )\n })\n\n/**\n * The attempt a round payload carries, defaulting to the first.\n *\n * @private\n */\nconst attemptOf = (payload: object): number => {\n const attempt = (payload as { readonly attempt?: unknown }).attempt\n return typeof attempt === \"number\" ? attempt : 1\n}\n\n/**\n * Rebuilds a round payload with an explicit attempt.\n *\n * The two views of one round payload — what the check reads, and what the next\n * round is opened with — are the same fields with `attempt` resolved. TypeScript\n * cannot reduce a mapped type over an unresolved generic field set, so the\n * shape is stated once here instead of at each use.\n *\n * @private\n */\nconst withAttempt = <Payload>(payload: object, attempt: number): Payload =>\n ({ ...payload, attempt }) as unknown as Payload\n\n/**\n * Declares a durable poller.\n *\n * **When to use**\n *\n * Use it wherever a run has to keep asking until something is ready — a build\n * that finishes, a deployment that goes live, a review that lands — and the\n * waiting has to survive a restart. `check` is the one thing an author writes:\n * a body fragment that reads whatever it polls and reports a {@link Check}.\n * Everything else is schedule. Under stable callback admission (the default of\n * `Interpreter.layerWithImplementations`), wrap `check` in `Node.capture` with\n * every semantic capture, including a version for imported behavior. An\n * uncaptured check keeps the poll process-local. The helper captures its own\n * callbacks using the schedule and the check's identity.\n *\n * ```ts\n * const Deployment = Poll.make(\"deploy/wait\", {\n * input: { id: Schema.String },\n * result: Schema.String,\n * intervalMs: 5_000,\n * backoff: \"exponential\",\n * maxAttempts: 8,\n * onTimeout: \"fail\",\n * check: Node.capture(\n * { action: Status.name, implementationVersion: \"deploy/status-check/v1\" },\n * ({ attempt, id }) => Status.call({ attempt, id })\n * )\n * })\n * ```\n *\n * The check may not fail. A check that can fail states what a failure means for\n * the poll — give up, or treat it as \"not ready yet\" — with `Node.catch` inside\n * the fragment, rather than leaving the poll to guess.\n *\n * A per-attempt time limit on the check itself is NOT a poll option. A plan\n * node's duration is not something the body around it can bound; that bound\n * belongs in the check's own implementation, where `DurableDeferred.raceAll`\n * races the work against a durable clock and stays replayable.\n *\n * A schedule no clock can be armed with is refused here, with a `RangeError`\n * naming the option that is wrong. `intervalMs` becomes the `millis` of a\n * {@link module:Sleep.action} node, and a wait of `Infinity`, `NaN`, or a\n * negative length arms a timer that never fires — a poll that hangs forever\n * with a plan that looks correct. The check is on the schedule, not only on the\n * interval: `{ intervalMs: 1000, maxAttempts: 2000, backoff: \"exponential\" }`\n * states three finite options and asks for an infinite wait, so the LAST wait\n * the poll can arm has to be a length too, and no longer than\n * `Number.MAX_SAFE_INTEGER` milliseconds, the latest deadline a durable timer\n * records. `maxAttempts` is the lineage's round\n * budget, and a budget below one attempt reaches `Flow.make` as a `maxRounds`\n * complaint about an option the author never wrote.\n *\n * @throws A `RangeError` when `intervalMs` is not a duration a clock accepts,\n * when `maxAttempts` is not a whole number of attempts of at least one, or when\n * the interval under the declared backoff reaches a wait no clock can be armed\n * with before the budget is spent.\n * @category constructors\n * @since 0.1.0\n */\nexport const make = <\n const Tag extends string,\n Input extends Schema.Struct.Fields,\n Result extends Schema.Top,\n R = never\n>(\n tag: Tag,\n options: {\n readonly input: Input\n readonly result: Result\n readonly check: (\n payload: Schema.Struct.Type<Input> & { readonly attempt: number }\n ) => Node.Node<Check<Result[\"Type\"]>, never, R>\n readonly intervalMs: number\n readonly maxAttempts: number\n readonly backoff?: Backoff | undefined\n readonly onTimeout?: Repetition.AtCeiling | undefined\n }\n): Flow.Flow<Tag, PayloadSchema<Input>, Result, typeof Failure, R> => {\n type Round = Flow.Flow<Tag, PayloadSchema<Input>, Result, typeof Failure, R>\n type RoundPayload = PayloadSchema<Input>[\"Type\"]\n if (Object.prototype.hasOwnProperty.call(options.input, \"attempt\")) {\n throw new TypeError(\n `Poll.make: \"${tag}\" input cannot declare the reserved \"attempt\" field. ` +\n \"Poll owns that counter across durable rounds.\"\n )\n }\n const input = Object.freeze({ ...options.input }) as Input\n const result = options.result\n const check = options.check\n const intervalMs = options.intervalMs\n const maxAttempts = options.maxAttempts\n if (!Number.isFinite(intervalMs) || intervalMs < 0) {\n throw new RangeError(\n `Poll.make: \"${tag}\" intervalMs must be a finite number of milliseconds that is not negative, ` +\n `and was ${intervalMs}. The interval is the length of a durable wait, and a wait of ` +\n \"that length never ends.\"\n )\n }\n if (!Number.isSafeInteger(maxAttempts) || maxAttempts < 1) {\n throw new RangeError(\n `Poll.make: \"${tag}\" maxAttempts must be a whole number of attempts of at least one, and was ` +\n `${maxAttempts}. A poll checks at least once.`\n )\n }\n const backoff = options.backoff ?? \"fixed\"\n // The wait a poll arms is not `intervalMs`. {@link delayMillis} multiplies it\n // by the backoff, so a schedule whose options are each finite can still ask\n // for a wait that is not a length — and that wait arms the same timer that\n // never fires the interval guard above exists to refuse. The last wait is the\n // one before the final attempt, because the attempt at the budget gives up\n // rather than sleeps, and the schedule never shrinks, so the last wait is\n // also the longest: checking it checks all of them.\n const longestWaitMs = maxAttempts > 1\n ? delayMillis({ intervalMs, backoff, attempt: maxAttempts - 1 })\n : 0\n // A durable timer records its deadline as a safe integer of milliseconds,\n // so `Sleep` refuses a longer wait on the round that reaches it.\n if (!Number.isFinite(longestWaitMs) || longestWaitMs > Number.MAX_SAFE_INTEGER) {\n throw new RangeError(\n `Poll.make: \"${tag}\" asks for a wait of ${longestWaitMs} ms before its last attempt. An ` +\n `intervalMs of ${intervalMs} under the \"${backoff}\" backoff reaches a length no clock ` +\n `can be armed with by attempt ${maxAttempts - 1} of ${maxAttempts}. Lower ` +\n \"maxAttempts, shorten the interval, or slow the backoff.\"\n )\n }\n const onTimeout = options.onTimeout ?? \"fail\"\n const captures = { tag, intervalMs, backoff, maxAttempts, onTimeout, check: Node.functionIdentity(check) }\n const body = (\n payload: RoundPayload\n ): Node.Node<Flow.BodySuccess<Result[\"Type\"]>, typeof Failure.Type, R> => {\n const attempt = attemptOf(payload)\n const last = attempt >= maxAttempts\n return check(withAttempt(payload, attempt)).pipe(\n Node.branch({\n if: Node.capture(captures, (checked) => checked.satisfied),\n then: (checked) => Flow.done(checked.output),\n else: (checked): Node.Node<Flow.BodySuccess<Result[\"Type\"]>, typeof Failure.Type> =>\n last\n ? onTimeout === \"return-last\"\n ? Flow.done(checked.output)\n : exhausted.call({ poll: tag, attempts: attempt })\n : Sleep.action.call({\n millis: delayMillis({ intervalMs, backoff, attempt })\n }).pipe(\n Node.andThen(\n self.to(withAttempt<Parameters<Round[\"to\"]>[0]>(payload, attempt + 1))\n )\n )\n })\n )\n }\n // The body names the flow it is the body of, which is what makes one round\n // open the next. It is read when a round is planned, long after `Flow.make`\n // has returned, so the binding is initialized by then.\n const self: Round = Flow.make(tag, {\n payload: payloadSchema(input, maxAttempts),\n success: result,\n error: Failure,\n maxRounds: maxAttempts,\n // A captured wrapper must not admit a process-local check as stable.\n body: captures.check.algorithm === \"sha256-source-ephemeral/v4\" ? body : Node.capture(captures, body)\n })\n return self\n}\n\n/**\n * The exhaustion implementation, provided beside the other action layers a\n * poll's rounds call.\n *\n * ```ts\n * Layer.mergeAll(Poll.layer, Sleep.layer, Interpreter.layer(Deployment)).pipe(\n * Layer.provideMerge(Action.layerImplementations)\n * )\n * ```\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer: Layer.Layer<never, never, Crypto.Crypto | FlowRuntime> = exhausted.toLayer(\n ({ attempts, poll }) =>\n Effect.fail(\n new PollExhausted({\n poll,\n attempts,\n message: `Poll \"${poll}\" used all ${attempts} attempts without a satisfied check.`\n })\n )\n)\n"]}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines data-shaped retry policies for durable action retries.
|
|
3
|
+
*
|
|
4
|
+
* A `RetryPolicy` is a plain value — initial interval, backoff factor, cap,
|
|
5
|
+
* optional maximum attempts, optional jitter, and optional non-retryable
|
|
6
|
+
* error tags — so the next retry delay can be derived from a persisted
|
|
7
|
+
* attempt count instead of fiber-local `Schedule` state. `nextDelay` mirrors
|
|
8
|
+
* Temporal's `ExponentialRetryPolicy.ComputeNextDelay` formula, and `decide`
|
|
9
|
+
* is the engine's single retry decision point: the core default a pluggable
|
|
10
|
+
* `resolveRetry` resolution can later dispatch in front of.
|
|
11
|
+
*
|
|
12
|
+
* The historical terminal-failure schemas below use the `@smthrs/flow/` tags settled for
|
|
13
|
+
* 1.0.0-rc.0. The release candidate makes no compatibility promise to 0.x
|
|
14
|
+
* journals, and these tags freeze at the RC. Current action dispatch preserves
|
|
15
|
+
* the final declared failure when a retry policy is spent.
|
|
16
|
+
*
|
|
17
|
+
* See `docs/guides/retry-a-failing-action.md`; its "Infrastructure
|
|
18
|
+
* interrupts" section covers the interrupt retry schedule.
|
|
19
|
+
*
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
*/
|
|
22
|
+
import * as Effect from "effect/Effect";
|
|
23
|
+
import * as Option from "effect/Option";
|
|
24
|
+
import * as Schema from "effect/Schema";
|
|
25
|
+
/**
|
|
26
|
+
* Data-shaped retry policy schema. Decoding enforces the same relational
|
|
27
|
+
* contract as {@link make}; persisted data cannot bypass constructor checks.
|
|
28
|
+
*
|
|
29
|
+
* @category models
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
*/
|
|
32
|
+
export declare const RetryPolicy: Schema.Struct<{
|
|
33
|
+
readonly initialMs: Schema.Number;
|
|
34
|
+
readonly factor: Schema.Number;
|
|
35
|
+
readonly maxMs: Schema.Number;
|
|
36
|
+
readonly maxAttempts: Schema.optional<Schema.Number>;
|
|
37
|
+
readonly expirationMs: Schema.optional<Schema.Number>;
|
|
38
|
+
readonly jitterRatio: Schema.optional<Schema.Number>;
|
|
39
|
+
readonly nonRetryable: Schema.optional<Schema.$Array<Schema.String>>;
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* The value form of a {@link RetryPolicy}.
|
|
43
|
+
*
|
|
44
|
+
* @category models
|
|
45
|
+
* @since 0.1.0
|
|
46
|
+
*/
|
|
47
|
+
export type RetryPolicy = typeof RetryPolicy.Type;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a `RetryPolicy` value after checking every numeric bound.
|
|
50
|
+
* `initialMs` must be greater than zero: a zero initial interval would
|
|
51
|
+
* compute a zero delay for every attempt, which {@link nextDelay} reads as
|
|
52
|
+
* exhausted, so the policy would never retry. `jitterRatio` must be between
|
|
53
|
+
* zero and one, inclusive, and `jitterRatio: 0` disables jitter.
|
|
54
|
+
*
|
|
55
|
+
* @category constructors
|
|
56
|
+
* @since 0.1.0
|
|
57
|
+
*/
|
|
58
|
+
export declare const make: (options: {
|
|
59
|
+
readonly initialMs: number;
|
|
60
|
+
readonly factor: number;
|
|
61
|
+
readonly maxMs: number;
|
|
62
|
+
readonly maxAttempts?: number | undefined;
|
|
63
|
+
readonly expirationMs?: number | undefined;
|
|
64
|
+
readonly jitterRatio?: number | undefined;
|
|
65
|
+
readonly nonRetryable?: ReadonlyArray<string> | undefined;
|
|
66
|
+
}) => RetryPolicy;
|
|
67
|
+
/**
|
|
68
|
+
* The default engine retry policy.
|
|
69
|
+
*
|
|
70
|
+
* Uses a 200ms initial delay growing by 1.5x, capped at 30s, and never gives
|
|
71
|
+
* up: it declares neither `maxAttempts` nor `expirationMs`. Bound long-lived
|
|
72
|
+
* retries with `make({ ..., expirationMs })` when a wall-clock give-up is
|
|
73
|
+
* required.
|
|
74
|
+
*
|
|
75
|
+
* @category constructors
|
|
76
|
+
* @since 0.1.0
|
|
77
|
+
*/
|
|
78
|
+
export declare const defaultRetryPolicy: RetryPolicy;
|
|
79
|
+
/**
|
|
80
|
+
* Bounded infrastructure retry: 5 seconds doubling to 5 minutes, for 2 hours.
|
|
81
|
+
*
|
|
82
|
+
* @category constructors
|
|
83
|
+
* @since 1.0.0
|
|
84
|
+
*/
|
|
85
|
+
export declare const transient: RetryPolicy;
|
|
86
|
+
/**
|
|
87
|
+
* A retry decision: wait `delayMs` before the next attempt.
|
|
88
|
+
*
|
|
89
|
+
* @category models
|
|
90
|
+
* @since 0.1.0
|
|
91
|
+
*/
|
|
92
|
+
export interface RetryAfter {
|
|
93
|
+
readonly _tag: "RetryAfter";
|
|
94
|
+
readonly delayMs: number;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A retry decision: stop retrying.
|
|
98
|
+
*
|
|
99
|
+
* @category models
|
|
100
|
+
* @since 0.1.0
|
|
101
|
+
*/
|
|
102
|
+
export interface GiveUp {
|
|
103
|
+
readonly _tag: "GiveUp";
|
|
104
|
+
readonly reason: "nonRetryable" | "exhausted" | "expired";
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The outcome of the engine's retry decision point.
|
|
108
|
+
*
|
|
109
|
+
* @category models
|
|
110
|
+
* @since 0.1.0
|
|
111
|
+
*/
|
|
112
|
+
export type RetryDecision = RetryAfter | GiveUp;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a `RetryAfter` decision.
|
|
115
|
+
*
|
|
116
|
+
* @category constructors
|
|
117
|
+
* @since 0.1.0
|
|
118
|
+
*/
|
|
119
|
+
export declare const retryAfter: (delayMs: number) => RetryDecision;
|
|
120
|
+
/**
|
|
121
|
+
* Creates a `GiveUp` decision.
|
|
122
|
+
*
|
|
123
|
+
* @category constructors
|
|
124
|
+
* @since 0.1.0
|
|
125
|
+
*/
|
|
126
|
+
export declare const giveUp: (reason: GiveUp["reason"]) => RetryDecision;
|
|
127
|
+
declare const RetryPolicyExpired_base: Schema.Class<RetryPolicyExpired, Schema.TaggedStruct<"@smthrs/flow/RetryPolicyExpired", {
|
|
128
|
+
readonly code: Schema.withConstructorDefault<Schema.Literal<"retry_policy_expired">>;
|
|
129
|
+
readonly actionName: Schema.String;
|
|
130
|
+
readonly attempt: Schema.Number;
|
|
131
|
+
readonly expirationMs: Schema.Number;
|
|
132
|
+
readonly lastError: Schema.optional<Schema.Unknown>;
|
|
133
|
+
}>, import("effect/Cause").YieldableError>;
|
|
134
|
+
/**
|
|
135
|
+
* A historical retry sequence crossed its `expirationMs` wall-clock bound.
|
|
136
|
+
* Current dispatch preserves the final declared failure instead of emitting this defect.
|
|
137
|
+
*
|
|
138
|
+
* @category errors
|
|
139
|
+
* @since 0.1.0
|
|
140
|
+
*/
|
|
141
|
+
export declare class RetryPolicyExpired extends RetryPolicyExpired_base {
|
|
142
|
+
}
|
|
143
|
+
declare const RetryAttemptsExhausted_base: Schema.Class<RetryAttemptsExhausted, Schema.TaggedStruct<"@smthrs/flow/RetryAttemptsExhausted", {
|
|
144
|
+
readonly code: Schema.withConstructorDefault<Schema.Literal<"retry_attempts_exhausted">>;
|
|
145
|
+
readonly actionName: Schema.String;
|
|
146
|
+
readonly attempt: Schema.Number;
|
|
147
|
+
readonly maxAttempts: Schema.Number;
|
|
148
|
+
readonly lastError: Schema.optional<Schema.Unknown>;
|
|
149
|
+
}>, import("effect/Cause").YieldableError>;
|
|
150
|
+
/**
|
|
151
|
+
* A historical retry sequence exhausted its `maxAttempts` bound.
|
|
152
|
+
* Current dispatch preserves the final declared failure instead of emitting this defect.
|
|
153
|
+
*
|
|
154
|
+
* @category errors
|
|
155
|
+
* @since 0.1.0
|
|
156
|
+
*/
|
|
157
|
+
export declare class RetryAttemptsExhausted extends RetryAttemptsExhausted_base {
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Computes the delay before attempt `attempt + 1` from the persisted attempt
|
|
161
|
+
* count, mirroring Temporal's `ComputeNextDelay`
|
|
162
|
+
* (`common/backoff/retrypolicy.go`).
|
|
163
|
+
*
|
|
164
|
+
* `attempt` is the 1-based attempt that just failed. Returns `None` when the
|
|
165
|
+
* policy gives up: `maxAttempts` reached, a non-positive computed interval,
|
|
166
|
+
* a cap below the initial interval, or — when the policy declares
|
|
167
|
+
* `expirationMs` and the caller supplies `elapsedMs` — an elapsed duration
|
|
168
|
+
* past the expiration bound. Otherwise the delay is capped to the remaining
|
|
169
|
+
* expiration window, expiring only when that window cannot fit one more
|
|
170
|
+
* full-value (`initialMs`) attempt.
|
|
171
|
+
*
|
|
172
|
+
* Jitter is deterministic-friendly: `options.random` is a `[0, 1]` sample
|
|
173
|
+
* supplied by the caller and defaults to `1`, which leaves the delay at its
|
|
174
|
+
* un-jittered value. Use {@link nextDelayEffect} to sample the `Random`
|
|
175
|
+
* service instead. A sample outside `[0, 1]`, or a persisted `jitterRatio`
|
|
176
|
+
* above one, gives up rather than returning a delay the policy never
|
|
177
|
+
* declared. A sample of zero under `jitterRatio: 1` is a delay of zero, which
|
|
178
|
+
* retries immediately.
|
|
179
|
+
*
|
|
180
|
+
* @category attempts
|
|
181
|
+
* @since 0.1.0
|
|
182
|
+
*/
|
|
183
|
+
export declare const nextDelay: (policy: RetryPolicy, attempt: number, options?: {
|
|
184
|
+
readonly random?: number | undefined;
|
|
185
|
+
readonly elapsedMs?: number | undefined;
|
|
186
|
+
}) => Option.Option<number>;
|
|
187
|
+
/**
|
|
188
|
+
* Computes the next retry delay, sampling the `Random` service for jitter.
|
|
189
|
+
*
|
|
190
|
+
* Deterministic under `Random.withSeed`. Policies without a `jitterRatio`
|
|
191
|
+
* never touch the service.
|
|
192
|
+
*
|
|
193
|
+
* @category attempts
|
|
194
|
+
* @since 0.1.0
|
|
195
|
+
*/
|
|
196
|
+
export declare const nextDelayEffect: (policy: RetryPolicy, attempt: number, options?: {
|
|
197
|
+
readonly elapsedMs?: number | undefined;
|
|
198
|
+
}) => Effect.Effect<Option.Option<number>>;
|
|
199
|
+
/**
|
|
200
|
+
* Extracts the stable identity tag of an error for non-retryable matching:
|
|
201
|
+
* an own string `_tag` when present, otherwise the first own `name` descriptor
|
|
202
|
+
* found while walking a bounded prototype chain. That first descriptor decides
|
|
203
|
+
* the result: only a string data value is a tag.
|
|
204
|
+
*
|
|
205
|
+
* Descriptors keep accessors inert instead of running author code through a
|
|
206
|
+
* property read. A bounded walk also terminates when a hostile proxy reports a
|
|
207
|
+
* cyclic prototype chain; any proxy trap that throws leaves the error untagged.
|
|
208
|
+
*
|
|
209
|
+
* @category attempts
|
|
210
|
+
* @since 0.1.0
|
|
211
|
+
*/
|
|
212
|
+
export declare const errorTag: (error: unknown) => string | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Error tags that are non-retryable by type, under every policy (issue #156).
|
|
215
|
+
*
|
|
216
|
+
* These failures are integrity verdicts that must reach the driver without an
|
|
217
|
+
* action-level retry hiding the first detection. Their persistence seams
|
|
218
|
+
* take a quarantine state action before raising them, so a later dispatch can
|
|
219
|
+
* heal, but the detecting dispatch remains a non-retryable failure. No
|
|
220
|
+
* per-callsite or per-policy opt-out exists; the tags are matched by string so
|
|
221
|
+
* the classification does not invert the package dependency direction.
|
|
222
|
+
*
|
|
223
|
+
* `AttemptEvidenceQuarantined` (issue #171) is the succeeded-attempt-row
|
|
224
|
+
* counterpart: the corrupt boundary evidence is removed while the completed
|
|
225
|
+
* outcome stays durable. It reaches the driver unretried, which parks the
|
|
226
|
+
* first detection in the `quarantine` waiting state; the next explicit resume
|
|
227
|
+
* returns the recorded outcome without re-executing the action.
|
|
228
|
+
*
|
|
229
|
+
* @category attempts
|
|
230
|
+
* @since 0.1.0
|
|
231
|
+
*/
|
|
232
|
+
export declare const defaultNonRetryable: ReadonlyArray<string>;
|
|
233
|
+
/**
|
|
234
|
+
* Whether an error is classified non-retryable, either by type (see
|
|
235
|
+
* {@link defaultNonRetryable}) or by the policy's declared tag list.
|
|
236
|
+
*
|
|
237
|
+
* @category attempts
|
|
238
|
+
* @since 0.1.0
|
|
239
|
+
*/
|
|
240
|
+
export declare const isNonRetryable: (policy: RetryPolicy, error: unknown) => boolean;
|
|
241
|
+
/**
|
|
242
|
+
* The pure core of the engine's single retry decision point.
|
|
243
|
+
*
|
|
244
|
+
* Non-retryable classification is evaluated here and nowhere else. This is
|
|
245
|
+
* the default a pluggable `resolveRetry` resolution falls back to when no
|
|
246
|
+
* plugin claims the decision.
|
|
247
|
+
*
|
|
248
|
+
* @category attempts
|
|
249
|
+
* @since 0.1.0
|
|
250
|
+
*/
|
|
251
|
+
export declare const decide: (policy: RetryPolicy, options: {
|
|
252
|
+
readonly attempt: number;
|
|
253
|
+
readonly error: unknown;
|
|
254
|
+
readonly random?: number | undefined;
|
|
255
|
+
readonly elapsedMs?: number | undefined;
|
|
256
|
+
}) => RetryDecision;
|
|
257
|
+
/**
|
|
258
|
+
* Effect form of {@link decide}, sampling the `Random` service for jitter.
|
|
259
|
+
*
|
|
260
|
+
* This is the engine-facing decision function: keep calls to it behind a
|
|
261
|
+
* single decision point so a plugin hook dispatch can later be inserted in
|
|
262
|
+
* front of it without touching call sites.
|
|
263
|
+
*
|
|
264
|
+
* @category attempts
|
|
265
|
+
* @since 0.1.0
|
|
266
|
+
*/
|
|
267
|
+
export declare const decideEffect: (policy: RetryPolicy, options: {
|
|
268
|
+
readonly attempt: number;
|
|
269
|
+
readonly error: unknown;
|
|
270
|
+
readonly elapsedMs?: number | undefined;
|
|
271
|
+
}) => Effect.Effect<RetryDecision>;
|
|
272
|
+
export {};
|
|
273
|
+
//# sourceMappingURL=RetryPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RetryPolicy.d.ts","sourceRoot":"","sources":["../../src/RetryPolicy.ts"],"names":[],"mappings":"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"}
|