@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,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "The runtime port"
|
|
3
|
+
description: "FlowRuntime is the service the authoring APIs are written against, what it must provide, and why this package depends on nothing that implements it."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 6
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`FlowRuntime` is the smallest service a `Flow`, an `Action`, a `DurableDeferred`,
|
|
9
|
+
or a `DurableClock` needs in order to be executed, polled, suspended, and
|
|
10
|
+
resumed. This package declares that port and depends on nothing that implements
|
|
11
|
+
it. The dependency runs one way:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
@smthrs/flow declares FlowRuntime
|
|
15
|
+
↓
|
|
16
|
+
@smthrs/engine implements it
|
|
17
|
+
↓
|
|
18
|
+
@smthrs/engine-store makes the implementation durable
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
There is deliberately no dependency, type-only or otherwise, from
|
|
22
|
+
`@smthrs/flow` back to `@smthrs/engine`. That is what lets the authoring model
|
|
23
|
+
bundle for a browser, and what lets a test swap a whole engine for a fixture
|
|
24
|
+
without touching a declaration.
|
|
25
|
+
|
|
26
|
+
## What the port provides
|
|
27
|
+
|
|
28
|
+
| Method | What it does |
|
|
29
|
+
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
30
|
+
| `register` | Binds a flow tag to the behavior that drives it. `Interpreter.layer` is the only public caller. |
|
|
31
|
+
| `execute` | Starts or joins an execution under a given id, optionally discarding the result. |
|
|
32
|
+
| `poll` | Answers the current `Result` of an execution, or nothing when it is known and unsettled. |
|
|
33
|
+
| `interrupt`, `interruptUnsafe` | Requests cancellation. A durable engine records the request before interrupting anything. |
|
|
34
|
+
| `resume` | Re-drives a suspended execution. |
|
|
35
|
+
| `actionExecute` | Dispatches one action attempt and records its exit. |
|
|
36
|
+
| `deferredResult`, `deferredDone`, `deferredDoneIfWaiting` | Reads and writes durable deferred completions. |
|
|
37
|
+
| `scheduleClock` | Arms a durable timer. |
|
|
38
|
+
| `recordNode` | Optional. Records the graph a run was driven from, and how each node settled. |
|
|
39
|
+
|
|
40
|
+
Every method takes a flow whatever its requirement channel says and demands none
|
|
41
|
+
of it. The channel is a compile-time statement about which action implementations
|
|
42
|
+
a body names, and the port sits below where that statement is settled: a runtime
|
|
43
|
+
resolves each call by the tag the node carries, which is the only thing left of a
|
|
44
|
+
plan read back out of a journal. `Flow.execute`, one level up, is where the
|
|
45
|
+
requirements are collected.
|
|
46
|
+
|
|
47
|
+
`deferredDoneIfWaiting` answers a `DeferredDoneIfWaitingOutcome` of `Completed`,
|
|
48
|
+
`Existing`, or `NotWaiting`. It exists so a completion can be admitted as one
|
|
49
|
+
mutation only while its run is actually parked on that wait, which is what stops
|
|
50
|
+
a guessed or stale token from pre-answering a run. It does not authorize the
|
|
51
|
+
caller: a token is an unsigned address, so the host authorizes whoever
|
|
52
|
+
completes an open wait.
|
|
53
|
+
|
|
54
|
+
`recordNode` is the one optional method, and optional in the strong sense: a
|
|
55
|
+
runtime that keeps no history leaves it absent and the walk is unchanged, so no
|
|
56
|
+
interpreter behavior may depend on whether one is there. An engine with a
|
|
57
|
+
journal implements it by writing the record. Each record carries its own
|
|
58
|
+
replay-stable `sourceId`, and an implementation must use that as the record's
|
|
59
|
+
producer identity rather than minting one per observation: that is what makes a
|
|
60
|
+
resumed walk collapse onto the rows the first walk wrote instead of recording
|
|
61
|
+
every node twice. It is separate from `actionExecute` because a node is not an
|
|
62
|
+
action, and three of the four records describe nodes no action ever dispatched.
|
|
63
|
+
|
|
64
|
+
## The per-execution instance
|
|
65
|
+
|
|
66
|
+
`FlowRuntime.FlowInstance` is one execution's frontier state: its `executionId`,
|
|
67
|
+
`lineageId`, `flow`, a `scope` closed only when the execution fully completes,
|
|
68
|
+
the mutable `suspended`, `interrupted`, `waiting`, `handoff`, and `cause` fields,
|
|
69
|
+
and `actionState`. This package declares the contract; a runtime constructs the
|
|
70
|
+
value. A completion wakes a parked run through `FlowRuntime.resume`.
|
|
71
|
+
|
|
72
|
+
## Declaring a wait
|
|
73
|
+
|
|
74
|
+
`FlowRuntime.annotateWaiting(annotation)` is how an implementation tells a
|
|
75
|
+
durable driver what kind of wait is about to happen, so the run parks under that
|
|
76
|
+
reason and token rather than a derived default. A `WaitingAnnotation` is
|
|
77
|
+
`{ reason, wakeAt?, token? }`. `Sleep` declares `timer` with the deadline,
|
|
78
|
+
`WaitFor` declares `event` with the wake token, and `HumanTask` declares
|
|
79
|
+
`approval` with the current attempt's token.
|
|
80
|
+
|
|
81
|
+
## Failures the port defines
|
|
82
|
+
|
|
83
|
+
| Failure | Raised when |
|
|
84
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
85
|
+
| `FlowCycleDetected` | Executing a flow would close a cycle in the persisted parent-execution chain. `path` holds the ordered execution ids from the cycle's target back to itself. |
|
|
86
|
+
| `FlowExecutionNotFound` | `poll` or `resume` names an execution id the runtime never recorded. |
|
|
87
|
+
| `CancelRequestFailed` | A durable runtime could not record a cancellation. `cancel_request_failed` is a storage failure; `unsafe_interrupt_unsupported` is the durable engine refusing `interruptUnsafe`, which it does not implement. |
|
|
88
|
+
|
|
89
|
+
`CancelRequestFailed` is the reason `interrupt` is not fire and forget: the
|
|
90
|
+
request is recorded before anything is interrupted, so a caller that cannot
|
|
91
|
+
record it learns the run is still going instead of being told it stopped.
|
|
92
|
+
|
|
93
|
+
## Implementing the port
|
|
94
|
+
|
|
95
|
+
Two implementations ship:
|
|
96
|
+
|
|
97
|
+
- `FlowEngine.layerMemory` from [`@smthrs/engine`](/api/engine) keeps every
|
|
98
|
+
recorded step in the process. Use it for tests and local development.
|
|
99
|
+
- The durable engine from [`@smthrs/engine-store`](/api/engine-store) backs the
|
|
100
|
+
same port with SQLite, which is what turns a suspended run into one a later
|
|
101
|
+
process resumes.
|
|
102
|
+
|
|
103
|
+
A third implementation is an ordinary exercise: satisfy the port and every
|
|
104
|
+
declaration in this package runs against it unchanged.
|
|
105
|
+
|
|
106
|
+
## Related pages
|
|
107
|
+
|
|
108
|
+
- [Suspension and replay](./suspension-and-replay.md): what the port's park and
|
|
109
|
+
resume mean to a body.
|
|
110
|
+
- [Testing](../testing.md): running flows against the in-memory implementation.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Trampoline rounds"
|
|
3
|
+
description: "How a flow loops: one round settles with Done, To, or Park, the engine follows a handoff to the next round, and maxRounds bounds the lineage."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 5
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
A body builds one round. Loops that depend on a runtime value are not written
|
|
9
|
+
inside a round; they are written as a **lineage** of rounds, where each round
|
|
10
|
+
ends by naming the next one. That is a trampoline, and it is why the plan can
|
|
11
|
+
stay static while the loop count cannot.
|
|
12
|
+
|
|
13
|
+
## The three settlements
|
|
14
|
+
|
|
15
|
+
A body may settle a round with an ordinary success value, or with one of three
|
|
16
|
+
outcomes:
|
|
17
|
+
|
|
18
|
+
| Outcome | Constructor | What it means |
|
|
19
|
+
| ------- | ------------------------------ | ------------------------------------------------------- |
|
|
20
|
+
| `Done` | `Flow.done(value)` | End the lineage with this value. |
|
|
21
|
+
| `To` | `someFlow.to(payload)` | End this round and open the next one with this payload. |
|
|
22
|
+
| `Park` | `Flow.park({ reason, token })` | Park this round durably under a waiting reason. |
|
|
23
|
+
|
|
24
|
+
A round that hands off settles as `Flow.Handoff`, beside `Complete` and
|
|
25
|
+
`Suspended`. Following the handoff is the engine's job: this package produces the
|
|
26
|
+
settlement, and [`@smthrs/engine`](/api/engine) opens the next round.
|
|
27
|
+
|
|
28
|
+
A handoff completes the round successfully and discards its `withRollback` registrations.
|
|
29
|
+
It closes the current round's scope with a success exit, running its exit
|
|
30
|
+
finalizers. The next round has a fresh scope, so its failure cannot roll back
|
|
31
|
+
effects from earlier rounds. The engine does not provide lineage-scoped
|
|
32
|
+
compensation; compensation across rounds requires an explicit durable design.
|
|
33
|
+
Suspension keeps the current round's scope open instead. See
|
|
34
|
+
[Scope and cleanup](./suspension-and-replay.md#scope-and-cleanup).
|
|
35
|
+
|
|
36
|
+
Values are passed in their author-facing form. The engine encodes a `Done` value
|
|
37
|
+
with the settling flow's success schema and a `To` payload with the target flow's
|
|
38
|
+
payload schema, at the settlement boundary. Callers do not pre-encode.
|
|
39
|
+
|
|
40
|
+
## A loop that counts
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { Action, Flow } from "@smthrs/flow"
|
|
44
|
+
import { Node } from "@smthrs/plan"
|
|
45
|
+
import * as Schema from "effect/Schema"
|
|
46
|
+
|
|
47
|
+
const Increment = Action.make("trampoline/increment", {
|
|
48
|
+
payload: { value: Schema.Number },
|
|
49
|
+
success: Schema.Number
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
type CounterFlow = Flow.Flow<
|
|
53
|
+
"trampoline/counter",
|
|
54
|
+
Schema.Struct<{ value: typeof Schema.Number; target: typeof Schema.Number }>,
|
|
55
|
+
typeof Schema.Number,
|
|
56
|
+
typeof Schema.Never,
|
|
57
|
+
Action.Requirement<"trampoline/increment">
|
|
58
|
+
>
|
|
59
|
+
|
|
60
|
+
const Counter: CounterFlow = Flow.make("trampoline/counter", {
|
|
61
|
+
payload: { value: Schema.Number, target: Schema.Number },
|
|
62
|
+
success: Schema.Number,
|
|
63
|
+
body: ({ target, value }: { readonly value: number; readonly target: number }) =>
|
|
64
|
+
Increment.call({ value }).pipe(
|
|
65
|
+
Node.branch({
|
|
66
|
+
if: (next) => next >= target,
|
|
67
|
+
then: (next) => Flow.done(next),
|
|
68
|
+
else: (next) => Counter.to({ value: next, target })
|
|
69
|
+
})
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Two things about that declaration are load bearing.
|
|
75
|
+
|
|
76
|
+
The body names the flow it is the body of. That is legal because a body is read
|
|
77
|
+
when a round is planned, long after `Flow.make` returned, so the binding is
|
|
78
|
+
initialized by then. The explicit `CounterFlow` type annotation is what breaks
|
|
79
|
+
the circularity for the compiler.
|
|
80
|
+
|
|
81
|
+
`.to()` **drops** the requirement channel. A self-handoff that propagated its
|
|
82
|
+
requirements would have to name its own requirements inside them, and the type
|
|
83
|
+
would not be finite. Dropping it is sound because a handoff ends this execution
|
|
84
|
+
and the next round runs under its own driver's context.
|
|
85
|
+
|
|
86
|
+
## Cancelling a logical run
|
|
87
|
+
|
|
88
|
+
Keep the execution ID returned at admission. `flow.interrupt(id)` requests
|
|
89
|
+
cancellation across the logical run, even after that round has handed off;
|
|
90
|
+
using a later round ID reaches the same lineage. A completed predecessor is
|
|
91
|
+
historical evidence, not proof the whole job is complete. Its recorded handoff
|
|
92
|
+
is not rewritten as a cancellation.
|
|
93
|
+
|
|
94
|
+
Cancellation reaches linked children, including children created by earlier
|
|
95
|
+
rounds and their handoff successors. A fork's ancestry does not, by itself,
|
|
96
|
+
create a cancellation link. The durable engine serializes intent with handoff
|
|
97
|
+
admission; the memory engine retains intent before admitting a later round.
|
|
98
|
+
Returning from `interrupt` means the request was recorded, not that user cleanup
|
|
99
|
+
or an owner in another process has finished. It is permanent; `resume` does not
|
|
100
|
+
undo it. Low-level `poll(id)` still reads the named round's result, not a
|
|
101
|
+
consolidated logical-run observation.
|
|
102
|
+
|
|
103
|
+
## The round budget
|
|
104
|
+
|
|
105
|
+
`Flow.make`'s `maxRounds` bounds one lineage. It is a budget, not loop detection:
|
|
106
|
+
identical consecutive rounds are legal, so a runaway lineage is stopped by
|
|
107
|
+
counting rounds rather than by comparing them. Absent means unbounded, which is
|
|
108
|
+
the right default for a lineage whose exit condition is its own branch.
|
|
109
|
+
|
|
110
|
+
`maxRounds` must be a positive safe integer; `Flow.make` throws a `RangeError`
|
|
111
|
+
otherwise. Exceeding it terminates the lineage with a `Flow.MaxRoundsExceeded`
|
|
112
|
+
defect recorded in the execution result. It is not a typed `execute` failure,
|
|
113
|
+
because a lineage that ran away is a declaration bug rather than an outcome a
|
|
114
|
+
caller was told to expect.
|
|
115
|
+
|
|
116
|
+
## The lineage deadline
|
|
117
|
+
|
|
118
|
+
A lineage is one run, so `Flow.make`'s `deadline` bounds the whole lineage, not
|
|
119
|
+
each round. The originating round journals its first start; each round that
|
|
120
|
+
hands off stamps that start and the bound on its `Flow.Handoff`, and the next
|
|
121
|
+
round runs under the stamp whatever it declares. Every round therefore expires
|
|
122
|
+
at the originator's start plus the originator's deadline, and settles with
|
|
123
|
+
`Flow.DeadlineExceeded` when it passes.
|
|
124
|
+
|
|
125
|
+
## Recognizing an outcome
|
|
126
|
+
|
|
127
|
+
`Flow.isOutcome` does not work by shape. Ordinary success data may carry the same
|
|
128
|
+
`_tag` fields, and treating it as control would let a payload steer a run. Graph
|
|
129
|
+
construction carries a non-enumerable marker from the authoring node to its
|
|
130
|
+
hydrated value, and the guard reads that marker, so
|
|
131
|
+
`{ _tag: "Done", value: 1 }` written by hand is not an outcome.
|
|
132
|
+
|
|
133
|
+
## What trampolines are for
|
|
134
|
+
|
|
135
|
+
- **Fan out over discovered data.** `Node.all` fixes its width at plan time. When
|
|
136
|
+
the width comes from a step result, end the round and carry the list in the
|
|
137
|
+
next round's payload, where it is real data.
|
|
138
|
+
- **Loop until a runtime condition holds.** `Poll.make` is exactly this,
|
|
139
|
+
packaged: its body is one attempt that either settles the lineage or sleeps and
|
|
140
|
+
hands off with the attempt counter raised. See
|
|
141
|
+
[Poll until something is ready](../guides/poll-until-ready.md).
|
|
142
|
+
- **Park a round for something outside the run** without pretending the wait is a
|
|
143
|
+
step, with `Flow.park`.
|
|
144
|
+
|
|
145
|
+
## Related pages
|
|
146
|
+
|
|
147
|
+
- [Bodies are plans](./bodies-and-plans.md): why width is fixed inside a round.
|
|
148
|
+
- [Suspension and replay](./suspension-and-replay.md): the other two results and
|
|
149
|
+
what a re-drive does.
|
|
150
|
+
- [Run a flow as a child execution](../guides/run-a-child-flow.md): the other
|
|
151
|
+
boundary that drops requirements, and how it differs from a handoff.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Ask a person for a decision"
|
|
3
|
+
description: "Park a run on a typed question, record an answer against the attempt's token, re-ask a refused answer, and give the question a deadline."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 6
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`HumanTask.action` is a question as a plan node. The run parks under the
|
|
9
|
+
`approval` waiting reason, someone records an answer against the token it parked
|
|
10
|
+
with, and the node settles with that answer. Validation, re-asking, and a
|
|
11
|
+
deadline are part of the declaration rather than something the caller builds.
|
|
12
|
+
|
|
13
|
+
## Ask the question
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Action, Flow, HumanTask, Interpreter } from "@smthrs/flow"
|
|
17
|
+
import * as Layer from "effect/Layer"
|
|
18
|
+
import * as Schema from "effect/Schema"
|
|
19
|
+
|
|
20
|
+
export const Release = Flow.make("release/Release", {
|
|
21
|
+
payload: { build: Schema.String },
|
|
22
|
+
success: Schema.Json,
|
|
23
|
+
error: HumanTask.HumanTaskFailed,
|
|
24
|
+
body: ({ build }) =>
|
|
25
|
+
HumanTask.action.call({
|
|
26
|
+
name: "release",
|
|
27
|
+
kind: "confirm",
|
|
28
|
+
prompt: `Ship ${build}?`,
|
|
29
|
+
maxAttempts: 3
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
export const layer = Layer.mergeAll(
|
|
34
|
+
HumanTask.layer,
|
|
35
|
+
Interpreter.layer(Release)
|
|
36
|
+
).pipe(Layer.provideMerge(Action.layerImplementations))
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`name` addresses the question. Two calls naming one question in one execution
|
|
40
|
+
await one answer.
|
|
41
|
+
|
|
42
|
+
## Choose the shape of the answer
|
|
43
|
+
|
|
44
|
+
| `kind` | What the person supplies | Other fields |
|
|
45
|
+
| --------- | --------------------------------------- | ------------ |
|
|
46
|
+
| `ask` | Prose. | none |
|
|
47
|
+
| `confirm` | A boolean. | none |
|
|
48
|
+
| `select` | One of the strings in `options`. | `options` |
|
|
49
|
+
| `json` | A value the task's JSON Schema accepts. | `schema` |
|
|
50
|
+
|
|
51
|
+
A `schema` supplied with any kind other than `json` is refused, because nothing
|
|
52
|
+
would check it. The bounded schema subset is `type` (`object`, `array`, `string`,
|
|
53
|
+
`number`, `integer`, `boolean`, `null`), `enum`, `properties`, `required`,
|
|
54
|
+
`items`, `nullable`, `description`, and `title`. `enum` members may be any JSON
|
|
55
|
+
value, including objects and arrays, and membership is compared structurally
|
|
56
|
+
rather than by reference.
|
|
57
|
+
|
|
58
|
+
## Give the answer a type
|
|
59
|
+
|
|
60
|
+
`HumanTask.action` succeeds with `Schema.Json`. `HumanTask.decode` gives that
|
|
61
|
+
answer your own type:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const Decision = Schema.Struct({ decision: Schema.Literals(["ship", "hold"]) })
|
|
65
|
+
|
|
66
|
+
const asked = HumanTask.action.call({
|
|
67
|
+
name: "release",
|
|
68
|
+
kind: "json",
|
|
69
|
+
prompt: "Ship the release?",
|
|
70
|
+
schema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
required: ["decision"],
|
|
73
|
+
properties: { decision: { enum: ["ship", "hold"] } }
|
|
74
|
+
},
|
|
75
|
+
maxAttempts: 3,
|
|
76
|
+
timeoutMs: 6 * 60 * 60 * 1000
|
|
77
|
+
}).pipe(HumanTask.decode(Decision))
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The schema you pass to `decode` and the question's own schema description must
|
|
81
|
+
agree. A disagreement surfaces as a defect rather than as a failure a body could
|
|
82
|
+
catch, because the two descriptions are the same claim written twice.
|
|
83
|
+
|
|
84
|
+
## Record an answer
|
|
85
|
+
|
|
86
|
+
The run parks carrying the current attempt's token. Whoever collects the answer
|
|
87
|
+
records it against that token:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { DurableDeferred } from "@smthrs/flow"
|
|
91
|
+
|
|
92
|
+
const tokenFor = (executionId: string, attempt: number): DurableDeferred.Token =>
|
|
93
|
+
DurableDeferred.tokenFromExecutionId(HumanTask.deferred("release", attempt), {
|
|
94
|
+
flow: Release,
|
|
95
|
+
executionId
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
export const answer = (executionId: string, attempt: number) =>
|
|
99
|
+
HumanTask.answer({ token: tokenFor(executionId, attempt), value: true })
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Each attempt is its own durable wait point, named `WaitFor/<name>#<attempt>`,
|
|
103
|
+
because a durable deferred records the first completion and replays it forever.
|
|
104
|
+
The runtime admits an answer only while the run is parked on that exact approval
|
|
105
|
+
wait, and records the completion as one mutation, so a guessed, unopened, or
|
|
106
|
+
stale token cannot pre-answer a run. A token whose deferred name
|
|
107
|
+
`HumanTask.deferred` could not have written fails with
|
|
108
|
+
`DurableDeferred.TokenInvalid` carrying `deferred_mismatch`.
|
|
109
|
+
|
|
110
|
+
These checks bound when an answer lands, not who sends it. A token is an
|
|
111
|
+
unsigned address the execution id and attempt rebuild, so the endpoint that
|
|
112
|
+
calls `HumanTask.answer` must authorize the person first.
|
|
113
|
+
|
|
114
|
+
Do not track the attempt number in your own process. Read it back from the
|
|
115
|
+
engine's waiting row, which carries the `approval` reason and the token of the
|
|
116
|
+
one attempt that is open.
|
|
117
|
+
|
|
118
|
+
## Refuse an answer before it is sent
|
|
119
|
+
|
|
120
|
+
`HumanTask.validate(value, request)` returns the reason an answer would be
|
|
121
|
+
refused, or `undefined`. Run it in the interface, so a typo is refused while the
|
|
122
|
+
person is still looking at it:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
const problem = HumanTask.validate(candidate, { kind: "select", options: ["ship", "hold"] })
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`HumanTask.validateSchema(schema)` checks that a JSON Schema stays inside the
|
|
129
|
+
bounded subset at every depth, and returns the first reason it does not.
|
|
130
|
+
|
|
131
|
+
## When the question ends without an answer
|
|
132
|
+
|
|
133
|
+
A refused answer is recorded under the attempt that refused it, as a sealed step
|
|
134
|
+
named `HumanTask/<name>#<attempt>/rejected` carrying the task, the attempt, and
|
|
135
|
+
the reason. The run then parks on the next attempt's token. A re-driven round
|
|
136
|
+
replays every answer it already has and parks on the first attempt that has none,
|
|
137
|
+
so a restart between the park and the answer resumes on the same token.
|
|
138
|
+
|
|
139
|
+
`HumanTask.HumanTaskFailed` carries `code`, `task`, `attempts`, the `rejections`
|
|
140
|
+
it collected, and a message:
|
|
141
|
+
|
|
142
|
+
| Code | Meaning |
|
|
143
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
144
|
+
| `request_invalid` | The question was unanswerable before anyone was asked: a `select` with no options, an attempt budget below one or above `HumanTask.maxAttemptBudget`, a `timeoutMs` that is not a length of time, or a schema outside the subset or past its depth or node bound. |
|
|
145
|
+
| `rejected` | The attempt budget was spent on answers the task refused. |
|
|
146
|
+
| `timeout` | The deadline passed with the question still open. |
|
|
147
|
+
|
|
148
|
+
`HumanTask.HumanAnswerInvalid` is the separate refusal an answer earns before it
|
|
149
|
+
can consume durable storage, with `answer_invalid` for an answer outside the
|
|
150
|
+
durable JSON boundary and `answer_not_open` for an attempt that is not waiting.
|
|
151
|
+
|
|
152
|
+
`maxAttempts` defaults to `HumanTask.defaultMaxAttempts`, which is `10`.
|
|
153
|
+
|
|
154
|
+
## Put a deadline on it
|
|
155
|
+
|
|
156
|
+
`timeoutMs` is how long the question stays open across every attempt. It races
|
|
157
|
+
the answer against one `DurableClock` per task through
|
|
158
|
+
`DurableDeferred.raceAll`, and the race parks and settles on whichever arrives
|
|
159
|
+
first. Both shipped engines re-enter a parked race on the next drive,
|
|
160
|
+
re-registering the raced deferreds against their persisted completions, so a
|
|
161
|
+
deadline settles under the in-process engine and the SQLite engine store alike.
|
|
162
|
+
|
|
163
|
+
A parked dispatch keeps its attempt row and its attempt number, so a question
|
|
164
|
+
that waits out a person costs nothing against the action's retry budget.
|
|
165
|
+
|
|
166
|
+
## Bounded by construction
|
|
167
|
+
|
|
168
|
+
One question cannot grow a durable record without limit. The module exports every
|
|
169
|
+
bound as a constant, including `maxAttemptBudget` (1000), `maxSchemaDepth` (32),
|
|
170
|
+
`maxSchemaNodes` (512), `maxAnswerNodes` (10,000), `maxAnswerBytes` (256 KiB),
|
|
171
|
+
`maxPromptBytes` (64 KiB), `maxOptions` (256), `maxDiagnosticChars` (512), and
|
|
172
|
+
`maxRetainedRejectionChars` (8192).
|
|
173
|
+
|
|
174
|
+
A value echoed into a rejection message is truncated with an explicit marker, and
|
|
175
|
+
the retained `rejections` array records how many further rejections it omitted.
|
|
176
|
+
Only the accumulated array is capped: each per-attempt journal step still records
|
|
177
|
+
its own full reason, so the record shows what was actually said.
|
|
178
|
+
|
|
179
|
+
## Related pages
|
|
180
|
+
|
|
181
|
+
- [Wait for an external signal](./wait-for-an-external-signal.md): the wait point
|
|
182
|
+
and token machinery this is built on.
|
|
183
|
+
- [Suspension and replay](../concepts/suspension-and-replay.md): what the
|
|
184
|
+
`approval` park does to the run.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Compose a body from branches and fan-out"
|
|
3
|
+
description: "Sequence steps, fan out and join, bound concurrency, decide between two continuations, and recover from a typed failure, all as static topology."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
A body is written in [`@smthrs/plan`](/api/plan)'s `Node` combinators. This guide
|
|
9
|
+
builds one release gate out of them: two checks in parallel, a report that joins
|
|
10
|
+
them, a decision, and a recovery arm.
|
|
11
|
+
|
|
12
|
+
Every combinator here is evaluated once, at plan time. Nothing in this file runs
|
|
13
|
+
a step.
|
|
14
|
+
|
|
15
|
+
## Declare the steps
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Action, Flow } from "@smthrs/flow"
|
|
19
|
+
import { Node } from "@smthrs/plan"
|
|
20
|
+
import * as Schema from "effect/Schema"
|
|
21
|
+
|
|
22
|
+
export class GateFailed extends Schema.TaggedError<GateFailed>()(
|
|
23
|
+
"release/GateFailed",
|
|
24
|
+
{ reason: Schema.String }
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
const Lint = Action.make("release/Lint", {
|
|
28
|
+
payload: { target: Schema.String },
|
|
29
|
+
success: Schema.String,
|
|
30
|
+
error: GateFailed
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const Types = Action.make("release/Types", {
|
|
34
|
+
payload: { target: Schema.String },
|
|
35
|
+
success: Schema.String,
|
|
36
|
+
error: GateFailed
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const Report = Action.make("release/Report", {
|
|
40
|
+
payload: { lint: Schema.String, types: Schema.String },
|
|
41
|
+
success: Schema.String
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const Ship = Action.make("release/Ship", {
|
|
45
|
+
payload: { report: Schema.String },
|
|
46
|
+
success: Schema.String
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const Explain = Action.make("release/Explain", {
|
|
50
|
+
payload: { reason: Schema.String },
|
|
51
|
+
success: Schema.String
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Fan out, then join
|
|
56
|
+
|
|
57
|
+
`Node.all` settles its members concurrently and answers a record keyed by member
|
|
58
|
+
name. Reading a field off the result records a reference path, so the join is an
|
|
59
|
+
ordinary step that receives real strings:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const checks = (target: string) =>
|
|
63
|
+
Node.all({
|
|
64
|
+
lint: Lint.call({ target }),
|
|
65
|
+
types: Types.call({ target })
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const report = (target: string) =>
|
|
69
|
+
checks(target).pipe(
|
|
70
|
+
Node.bindPlanned((settled) => Report.call({ lint: settled.lint, types: settled.types }))
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`settled.lint` is a `Planned<string>`, not a string. Pass it into a payload;
|
|
75
|
+
never build a message out of it. The fan-in is a step for that reason: an action
|
|
76
|
+
that receives two strings, not a function in the body that tries to concatenate
|
|
77
|
+
placeholders.
|
|
78
|
+
|
|
79
|
+
`Node.all` fixes its width at plan time. To bound concurrency, use one `Node.all`
|
|
80
|
+
per batch and give the next batch the previous batch's result as payload. The
|
|
81
|
+
reference is what sequences them, and an operator reading the plan sees exactly
|
|
82
|
+
how many steps can be in flight.
|
|
83
|
+
|
|
84
|
+
## Decide between two continuations
|
|
85
|
+
|
|
86
|
+
`Node.branch` stores both arms. The predicate is digested and evaluated at run
|
|
87
|
+
time on the real value; the arms are built once, here:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const gate = (target: string) =>
|
|
91
|
+
report(target).pipe(
|
|
92
|
+
Node.branch({
|
|
93
|
+
if: (text) => text.includes("clean"),
|
|
94
|
+
then: (text) => Ship.call({ report: text }),
|
|
95
|
+
else: (text) => Explain.call({ reason: text })
|
|
96
|
+
})
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Both arms contribute their requirements to the node, because both are topology
|
|
101
|
+
the plan carries. A run takes one of them, but which one is not known until the
|
|
102
|
+
predicate sees the real value.
|
|
103
|
+
|
|
104
|
+
Write the decision as a `branch`, not as an `if` in the body. An `if` on a
|
|
105
|
+
planned value cannot read it, and an `if` on the payload is fine but produces a
|
|
106
|
+
plan that no longer describes the alternative.
|
|
107
|
+
|
|
108
|
+
## Recover from a typed failure
|
|
109
|
+
|
|
110
|
+
`Node.catch` is failure topology. With an `error` schema it handles only the
|
|
111
|
+
failures the schema accepts and leaves the rest in the node's error type:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
export const Gate = Flow.make("release/Gate", {
|
|
115
|
+
payload: { target: Schema.String },
|
|
116
|
+
success: Schema.String,
|
|
117
|
+
body: ({ target }) =>
|
|
118
|
+
gate(target).pipe(
|
|
119
|
+
Node.catch({
|
|
120
|
+
error: GateFailed,
|
|
121
|
+
onFailure: (failure) => Explain.call({ reason: failure.reason })
|
|
122
|
+
})
|
|
123
|
+
)
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Without an `error` schema the whole domain error channel is handled and the
|
|
128
|
+
resulting node has no declared error type. Interpreter refusals still propagate.
|
|
129
|
+
The failure arm is built once at plan time against a planned error placeholder,
|
|
130
|
+
so `failure.reason` is a reference, like every other planned field.
|
|
131
|
+
|
|
132
|
+
## Compute, and order
|
|
133
|
+
|
|
134
|
+
Two smaller combinators finish the vocabulary:
|
|
135
|
+
|
|
136
|
+
- `Node.map(node, f)` computes on a step result. The function is digested and
|
|
137
|
+
runs later, on the real value. This is where computation belongs, and only
|
|
138
|
+
computation: a `map` that decides what happens next is a `branch` written
|
|
139
|
+
wrongly.
|
|
140
|
+
- `Node.priority(node, n)` orders ready work, higher first. It changes latency
|
|
141
|
+
and nothing else, and it never enters key material, so raising it cannot
|
|
142
|
+
invalidate a recorded result. Children inherit it lexically, and a child that
|
|
143
|
+
states its own keeps it.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const urgent = Node.priority(Lint.call({ target: "release" }), 9)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## When the shape depends on a result
|
|
150
|
+
|
|
151
|
+
Every combinator above fixes its topology before the run. When the shape itself
|
|
152
|
+
depends on something a step produced, that is a new round: settle this one and
|
|
153
|
+
carry the data in the next round's payload. See
|
|
154
|
+
[Trampoline rounds](../concepts/trampoline-rounds.md).
|
|
155
|
+
|
|
156
|
+
## Related pages
|
|
157
|
+
|
|
158
|
+
- [Bodies are plans](../concepts/bodies-and-plans.md): the rules behind the
|
|
159
|
+
vocabulary, and the refusals a bad body earns.
|
|
160
|
+
- [Inspect the plan a body builds](./inspect-the-plan.md): read the nodes and
|
|
161
|
+
edges this body produces without running it.
|