footprintjs 10.0.1 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/CLAUDE.md +61 -7
- package/README.md +136 -312
- package/dist/esm/index.d.ts +62 -2
- package/dist/esm/index.js +13 -6
- package/dist/esm/lib/attempt/anySignal.d.ts +19 -0
- package/dist/esm/lib/attempt/anySignal.js +39 -0
- package/dist/esm/lib/attempt/call.d.ts +88 -0
- package/dist/esm/lib/attempt/call.js +129 -0
- package/dist/esm/lib/attempt/category.d.ts +37 -0
- package/dist/esm/lib/attempt/category.js +131 -0
- package/dist/esm/lib/attempt/correlation.d.ts +95 -0
- package/dist/esm/lib/attempt/correlation.js +178 -0
- package/dist/esm/lib/attempt/deadline.d.ts +44 -0
- package/dist/esm/lib/attempt/deadline.js +101 -0
- package/dist/esm/lib/attempt/decision.d.ts +52 -0
- package/dist/esm/lib/attempt/decision.js +134 -0
- package/dist/esm/lib/attempt/effect.d.ts +76 -0
- package/dist/esm/lib/attempt/effect.js +160 -0
- package/dist/esm/lib/attempt/errors.d.ts +41 -0
- package/dist/esm/lib/attempt/errors.js +44 -0
- package/dist/esm/lib/attempt/index.d.ts +18 -0
- package/dist/esm/lib/attempt/index.js +15 -0
- package/dist/esm/lib/attempt/name.d.ts +21 -0
- package/dist/esm/lib/attempt/name.js +43 -0
- package/dist/esm/lib/attempt/observed.d.ts +66 -0
- package/dist/esm/lib/attempt/observed.js +171 -0
- package/dist/esm/lib/attempt/policy.d.ts +45 -0
- package/dist/esm/lib/attempt/policy.js +83 -0
- package/dist/esm/lib/attempt/record.d.ts +11 -0
- package/dist/esm/lib/attempt/record.js +24 -0
- package/dist/esm/lib/attempt/retryLoopContext.d.ts +18 -0
- package/dist/esm/lib/attempt/retryLoopContext.js +24 -0
- package/dist/esm/lib/attempt/retryLoopTypes.d.ts +18 -0
- package/dist/esm/lib/attempt/retryLoopTypes.js +2 -0
- package/dist/esm/lib/attempt/runner.d.ts +157 -0
- package/dist/esm/lib/attempt/runner.js +523 -0
- package/dist/esm/lib/attempt/standalone.d.ts +47 -0
- package/dist/esm/lib/attempt/standalone.js +126 -0
- package/dist/esm/lib/attempt/types.d.ts +453 -0
- package/dist/esm/lib/attempt/types.js +16 -0
- package/dist/esm/lib/budget/index.d.ts +9 -0
- package/dist/esm/lib/budget/index.js +9 -0
- package/dist/esm/lib/budget/timeBudget.d.ts +136 -0
- package/dist/esm/lib/budget/timeBudget.js +666 -0
- package/dist/esm/lib/builder/FlowChartBuilder.d.ts +88 -3
- package/dist/esm/lib/builder/FlowChartBuilder.js +199 -9
- package/dist/esm/lib/builder/retryLoop.d.ts +56 -0
- package/dist/esm/lib/builder/retryLoop.js +283 -0
- package/dist/esm/lib/builder/types.d.ts +35 -1
- package/dist/esm/lib/builder/types.js +1 -1
- package/dist/esm/lib/decide/decide.js +2 -2
- package/dist/esm/lib/decide/index.d.ts +1 -1
- package/dist/esm/lib/decide/index.js +2 -2
- package/dist/esm/lib/decide/types.d.ts +3 -0
- package/dist/esm/lib/decide/types.js +1 -8
- package/dist/esm/lib/engine/graph/StageNode.d.ts +11 -1
- package/dist/esm/lib/engine/graph/StageNode.js +1 -1
- package/dist/esm/lib/engine/graph/prefixNodeTree.js +5 -1
- package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
- package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
- package/dist/esm/lib/engine/handlers/ResumeEntry.js +3 -1
- package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
- package/dist/esm/lib/engine/handlers/StageRunner.d.ts +8 -1
- package/dist/esm/lib/engine/handlers/StageRunner.js +36 -9
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +24 -5
- package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
- package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
- package/dist/esm/lib/engine/handlers/stageError.d.ts +9 -0
- package/dist/esm/lib/engine/handlers/stageError.js +23 -1
- package/dist/esm/lib/engine/index.d.ts +2 -2
- package/dist/esm/lib/engine/index.js +1 -1
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +68 -40
- package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
- package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
- package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
- package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +61 -9
- package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
- package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
- package/dist/esm/lib/engine/narrative/formatting/sentences.d.ts +23 -0
- package/dist/esm/lib/engine/narrative/formatting/sentences.js +127 -1
- package/dist/esm/lib/engine/narrative/index.d.ts +2 -2
- package/dist/esm/lib/engine/narrative/index.js +1 -1
- package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +27 -21
- package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
- package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
- package/dist/esm/lib/engine/narrative/recorders/index.d.ts +1 -1
- package/dist/esm/lib/engine/narrative/recorders/index.js +1 -1
- package/dist/esm/lib/engine/narrative/types.d.ts +74 -5
- package/dist/esm/lib/engine/narrative/types.js +1 -1
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +194 -118
- package/dist/esm/lib/engine/traversalContext.d.ts +7 -2
- package/dist/esm/lib/engine/traversalContext.js +6 -3
- package/dist/esm/lib/engine/types.d.ts +52 -57
- package/dist/esm/lib/engine/types.js +1 -1
- package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
- package/dist/esm/lib/errors/terminalFailure.js +60 -0
- package/dist/esm/lib/{decide → filter}/evaluator.d.ts +7 -2
- package/dist/esm/lib/filter/evaluator.js +135 -0
- package/dist/esm/lib/ids/idempotencyKey.d.ts +14 -0
- package/dist/esm/lib/ids/idempotencyKey.js +24 -0
- package/dist/esm/lib/memory/StageContext.d.ts +123 -3
- package/dist/esm/lib/memory/StageContext.js +245 -4
- package/dist/esm/lib/memory/attention.d.ts +26 -0
- package/dist/esm/lib/memory/attention.js +171 -0
- package/dist/esm/lib/memory/borrowedMutation.d.ts +8 -0
- package/dist/esm/lib/memory/borrowedMutation.js +14 -1
- package/dist/esm/lib/memory/frameTypes.d.ts +38 -0
- package/dist/esm/lib/memory/frameTypes.js +3 -1
- package/dist/esm/lib/memory/redaction.d.ts +12 -0
- package/dist/esm/lib/memory/redaction.js +54 -5
- package/dist/esm/lib/pause/record.js +10 -1
- package/dist/esm/lib/pause/types.d.ts +19 -0
- package/dist/esm/lib/pause/types.js +17 -1
- package/dist/esm/lib/reactive/createTypedScope.js +3 -1
- package/dist/esm/lib/reactive/types.d.ts +36 -4
- package/dist/esm/lib/reactive/types.js +3 -1
- package/dist/esm/lib/recorder/AttemptRecorder.d.ts +141 -0
- package/dist/esm/lib/recorder/AttemptRecorder.js +412 -0
- package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +36 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.js +50 -2
- package/dist/esm/lib/recorder/EmitRecorder.d.ts +3 -0
- package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
- package/dist/esm/lib/recorder/InOutRecorder.d.ts +37 -1
- package/dist/esm/lib/recorder/InOutRecorder.js +75 -6
- package/dist/esm/lib/recorder/QualityRecorder.d.ts +32 -5
- package/dist/esm/lib/recorder/QualityRecorder.js +87 -29
- package/dist/esm/lib/recorder/TopologyRecorder.d.ts +35 -5
- package/dist/esm/lib/recorder/TopologyRecorder.js +76 -2
- package/dist/esm/lib/recorder/attemptMetricRows.d.ts +11 -0
- package/dist/esm/lib/recorder/attemptMetricRows.js +202 -0
- package/dist/esm/lib/recorder/attemptMetrics.d.ts +7 -0
- package/dist/esm/lib/recorder/attemptMetrics.js +165 -0
- package/dist/esm/lib/recorder/attemptMetricsTypes.d.ts +114 -0
- package/dist/esm/lib/recorder/attemptMetricsTypes.js +2 -0
- package/dist/esm/lib/recorder/attemptOTel.d.ts +78 -0
- package/dist/esm/lib/recorder/attemptOTel.js +107 -0
- package/dist/esm/lib/recorder/attemptSeries.d.ts +81 -0
- package/dist/esm/lib/recorder/attemptSeries.js +103 -0
- package/dist/esm/lib/recorder/hooks.d.ts +9 -0
- package/dist/esm/lib/recorder/hooks.js +4 -1
- package/dist/esm/lib/runner/DeferredObserverTier.js +13 -1
- package/dist/esm/lib/runner/ExecutionRuntime.d.ts +54 -6
- package/dist/esm/lib/runner/ExecutionRuntime.js +57 -5
- package/dist/esm/lib/runner/FlowChartExecutor.d.ts +46 -2
- package/dist/esm/lib/runner/FlowChartExecutor.js +330 -101
- package/dist/esm/lib/runner/RunnableChart.d.ts +6 -0
- package/dist/esm/lib/runner/RunnableChart.js +5 -1
- package/dist/esm/lib/runner/attach.d.ts +2 -1
- package/dist/esm/lib/runner/attach.js +8 -2
- package/dist/esm/lib/runner/checkpoint.js +3 -1
- package/dist/esm/lib/runner/deadline.d.ts +42 -0
- package/dist/esm/lib/runner/deadline.js +90 -0
- package/dist/esm/lib/runner/index.d.ts +3 -1
- package/dist/esm/lib/runner/index.js +2 -1
- package/dist/esm/lib/runner/options.d.ts +17 -0
- package/dist/esm/lib/runner/options.js +3 -1
- package/dist/esm/lib/runner/recordSink.d.ts +128 -0
- package/dist/esm/lib/runner/recordSink.js +296 -0
- package/dist/esm/lib/runner/resume.d.ts +3 -0
- package/dist/esm/lib/runner/resume.js +22 -2
- package/dist/esm/lib/runner/snapshot.d.ts +2 -2
- package/dist/esm/lib/runner/snapshot.js +6 -2
- package/dist/esm/lib/scope/ScopeFacade.d.ts +118 -4
- package/dist/esm/lib/scope/ScopeFacade.js +304 -7
- package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +17 -3
- package/dist/esm/lib/scope/recorders/DebugRecorder.js +79 -13
- package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +10 -0
- package/dist/esm/lib/scope/recorders/MetricRecorder.js +15 -2
- package/dist/esm/lib/scope/runtime.d.ts +3 -0
- package/dist/esm/lib/scope/runtime.js +1 -1
- package/dist/esm/lib/scope/types.d.ts +6 -0
- package/dist/esm/lib/scope/types.js +1 -1
- package/dist/esm/lib/sinks/fileSink.d.ts +135 -0
- package/dist/esm/lib/sinks/fileSink.js +387 -0
- package/dist/esm/recorders.d.ts +8 -2
- package/dist/esm/recorders.js +7 -1
- package/dist/esm/sinks.d.ts +23 -0
- package/dist/esm/sinks.js +23 -0
- package/dist/esm/trace.d.ts +2 -2
- package/dist/esm/trace.js +1 -1
- package/dist/index.js +77 -60
- package/dist/lib/attempt/anySignal.js +43 -0
- package/dist/lib/attempt/call.js +134 -0
- package/dist/lib/attempt/category.js +136 -0
- package/dist/lib/attempt/correlation.js +186 -0
- package/dist/lib/attempt/deadline.js +112 -0
- package/dist/lib/attempt/decision.js +139 -0
- package/dist/lib/attempt/effect.js +174 -0
- package/dist/lib/attempt/errors.js +49 -0
- package/dist/lib/attempt/index.js +26 -0
- package/dist/lib/attempt/name.js +48 -0
- package/dist/lib/attempt/observed.js +177 -0
- package/dist/lib/attempt/policy.js +92 -0
- package/dist/lib/attempt/record.js +29 -0
- package/dist/lib/attempt/retryLoopContext.js +31 -0
- package/dist/lib/attempt/retryLoopTypes.js +3 -0
- package/dist/lib/attempt/runner.js +530 -0
- package/dist/lib/attempt/standalone.js +130 -0
- package/dist/lib/attempt/types.js +17 -0
- package/dist/lib/budget/index.js +17 -0
- package/dist/lib/budget/timeBudget.js +674 -0
- package/dist/lib/builder/FlowChartBuilder.js +199 -9
- package/dist/lib/builder/retryLoop.js +287 -0
- package/dist/lib/builder/types.js +1 -1
- package/dist/lib/decide/decide.js +2 -2
- package/dist/lib/decide/index.js +2 -2
- package/dist/lib/decide/types.js +1 -8
- package/dist/lib/engine/graph/StageNode.js +1 -1
- package/dist/lib/engine/graph/prefixNodeTree.js +5 -1
- package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
- package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
- package/dist/lib/engine/handlers/ResumeEntry.js +3 -1
- package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
- package/dist/lib/engine/handlers/StageRunner.js +36 -9
- package/dist/lib/engine/handlers/SubflowExecutor.js +24 -5
- package/dist/lib/engine/handlers/commitStage.js +24 -5
- package/dist/lib/engine/handlers/stageError.js +26 -2
- package/dist/lib/engine/index.js +1 -1
- package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +67 -39
- package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
- package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +60 -8
- package/dist/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
- package/dist/lib/engine/narrative/formatting/sentences.js +131 -2
- package/dist/lib/engine/narrative/index.js +1 -1
- package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
- package/dist/lib/engine/narrative/recorders/index.js +1 -1
- package/dist/lib/engine/narrative/types.js +1 -1
- package/dist/lib/engine/traversal/FlowchartTraverser.js +192 -116
- package/dist/lib/engine/traversalContext.js +6 -3
- package/dist/lib/engine/types.js +1 -1
- package/dist/lib/errors/terminalFailure.js +64 -0
- package/dist/lib/filter/evaluator.js +139 -0
- package/dist/lib/ids/idempotencyKey.js +28 -0
- package/dist/lib/memory/StageContext.js +246 -5
- package/dist/lib/memory/attention.js +175 -0
- package/dist/lib/memory/borrowedMutation.js +16 -2
- package/dist/lib/memory/frameTypes.js +3 -1
- package/dist/lib/memory/redaction.js +54 -5
- package/dist/lib/pause/record.js +10 -1
- package/dist/lib/pause/types.js +17 -1
- package/dist/lib/reactive/createTypedScope.js +3 -1
- package/dist/lib/reactive/types.js +3 -1
- package/dist/lib/recorder/AttemptRecorder.js +417 -0
- package/dist/lib/recorder/ControlDepRecorder.js +50 -2
- package/dist/lib/recorder/EmitRecorder.js +1 -1
- package/dist/lib/recorder/InOutRecorder.js +75 -6
- package/dist/lib/recorder/QualityRecorder.js +87 -29
- package/dist/lib/recorder/TopologyRecorder.js +76 -2
- package/dist/lib/recorder/attemptMetricRows.js +209 -0
- package/dist/lib/recorder/attemptMetrics.js +174 -0
- package/dist/lib/recorder/attemptMetricsTypes.js +3 -0
- package/dist/lib/recorder/attemptOTel.js +111 -0
- package/dist/lib/recorder/attemptSeries.js +113 -0
- package/dist/lib/recorder/hooks.js +4 -1
- package/dist/lib/runner/DeferredObserverTier.js +13 -1
- package/dist/lib/runner/ExecutionRuntime.js +57 -5
- package/dist/lib/runner/FlowChartExecutor.js +330 -101
- package/dist/lib/runner/RunnableChart.js +5 -1
- package/dist/lib/runner/attach.js +8 -2
- package/dist/lib/runner/checkpoint.js +3 -1
- package/dist/lib/runner/deadline.js +94 -0
- package/dist/lib/runner/index.js +4 -2
- package/dist/lib/runner/options.js +3 -1
- package/dist/lib/runner/recordSink.js +302 -0
- package/dist/lib/runner/resume.js +22 -2
- package/dist/lib/runner/snapshot.js +6 -2
- package/dist/lib/scope/ScopeFacade.js +303 -6
- package/dist/lib/scope/recorders/DebugRecorder.js +79 -13
- package/dist/lib/scope/recorders/MetricRecorder.js +15 -2
- package/dist/lib/scope/runtime.js +1 -1
- package/dist/lib/scope/types.js +1 -1
- package/dist/lib/sinks/fileSink.js +392 -0
- package/dist/recorders.js +10 -2
- package/dist/sinks.js +32 -0
- package/dist/trace.js +1 -1
- package/dist/types/index.d.ts +62 -2
- package/dist/types/lib/attempt/anySignal.d.ts +19 -0
- package/dist/types/lib/attempt/call.d.ts +88 -0
- package/dist/types/lib/attempt/category.d.ts +37 -0
- package/dist/types/lib/attempt/correlation.d.ts +95 -0
- package/dist/types/lib/attempt/deadline.d.ts +44 -0
- package/dist/types/lib/attempt/decision.d.ts +52 -0
- package/dist/types/lib/attempt/effect.d.ts +76 -0
- package/dist/types/lib/attempt/errors.d.ts +41 -0
- package/dist/types/lib/attempt/index.d.ts +18 -0
- package/dist/types/lib/attempt/name.d.ts +21 -0
- package/dist/types/lib/attempt/observed.d.ts +66 -0
- package/dist/types/lib/attempt/policy.d.ts +45 -0
- package/dist/types/lib/attempt/record.d.ts +11 -0
- package/dist/types/lib/attempt/retryLoopContext.d.ts +18 -0
- package/dist/types/lib/attempt/retryLoopTypes.d.ts +18 -0
- package/dist/types/lib/attempt/runner.d.ts +157 -0
- package/dist/types/lib/attempt/standalone.d.ts +47 -0
- package/dist/types/lib/attempt/types.d.ts +453 -0
- package/dist/types/lib/budget/index.d.ts +9 -0
- package/dist/types/lib/budget/timeBudget.d.ts +136 -0
- package/dist/types/lib/builder/FlowChartBuilder.d.ts +88 -3
- package/dist/types/lib/builder/retryLoop.d.ts +56 -0
- package/dist/types/lib/builder/types.d.ts +35 -1
- package/dist/types/lib/decide/index.d.ts +1 -1
- package/dist/types/lib/decide/types.d.ts +3 -0
- package/dist/types/lib/engine/graph/StageNode.d.ts +11 -1
- package/dist/types/lib/engine/handlers/StageRunner.d.ts +8 -1
- package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
- package/dist/types/lib/engine/handlers/stageError.d.ts +9 -0
- package/dist/types/lib/engine/index.d.ts +2 -2
- package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
- package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
- package/dist/types/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
- package/dist/types/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
- package/dist/types/lib/engine/narrative/formatting/sentences.d.ts +23 -0
- package/dist/types/lib/engine/narrative/index.d.ts +2 -2
- package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +27 -21
- package/dist/types/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
- package/dist/types/lib/engine/narrative/recorders/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/types.d.ts +74 -5
- package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
- package/dist/types/lib/engine/traversalContext.d.ts +7 -2
- package/dist/types/lib/engine/types.d.ts +52 -57
- package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
- package/dist/types/lib/{decide → filter}/evaluator.d.ts +7 -2
- package/dist/types/lib/ids/idempotencyKey.d.ts +14 -0
- package/dist/types/lib/memory/StageContext.d.ts +123 -3
- package/dist/types/lib/memory/attention.d.ts +26 -0
- package/dist/types/lib/memory/borrowedMutation.d.ts +8 -0
- package/dist/types/lib/memory/frameTypes.d.ts +38 -0
- package/dist/types/lib/memory/redaction.d.ts +12 -0
- package/dist/types/lib/pause/types.d.ts +19 -0
- package/dist/types/lib/reactive/types.d.ts +36 -4
- package/dist/types/lib/recorder/AttemptRecorder.d.ts +141 -0
- package/dist/types/lib/recorder/ControlDepRecorder.d.ts +36 -2
- package/dist/types/lib/recorder/EmitRecorder.d.ts +3 -0
- package/dist/types/lib/recorder/InOutRecorder.d.ts +37 -1
- package/dist/types/lib/recorder/QualityRecorder.d.ts +32 -5
- package/dist/types/lib/recorder/TopologyRecorder.d.ts +35 -5
- package/dist/types/lib/recorder/attemptMetricRows.d.ts +11 -0
- package/dist/types/lib/recorder/attemptMetrics.d.ts +7 -0
- package/dist/types/lib/recorder/attemptMetricsTypes.d.ts +114 -0
- package/dist/types/lib/recorder/attemptOTel.d.ts +78 -0
- package/dist/types/lib/recorder/attemptSeries.d.ts +81 -0
- package/dist/types/lib/recorder/hooks.d.ts +9 -0
- package/dist/types/lib/runner/ExecutionRuntime.d.ts +54 -6
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +46 -2
- package/dist/types/lib/runner/RunnableChart.d.ts +6 -0
- package/dist/types/lib/runner/attach.d.ts +2 -1
- package/dist/types/lib/runner/deadline.d.ts +42 -0
- package/dist/types/lib/runner/index.d.ts +3 -1
- package/dist/types/lib/runner/options.d.ts +17 -0
- package/dist/types/lib/runner/recordSink.d.ts +128 -0
- package/dist/types/lib/runner/resume.d.ts +3 -0
- package/dist/types/lib/runner/snapshot.d.ts +2 -2
- package/dist/types/lib/scope/ScopeFacade.d.ts +118 -4
- package/dist/types/lib/scope/recorders/DebugRecorder.d.ts +17 -3
- package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +10 -0
- package/dist/types/lib/scope/runtime.d.ts +3 -0
- package/dist/types/lib/scope/types.d.ts +6 -0
- package/dist/types/lib/sinks/fileSink.d.ts +135 -0
- package/dist/types/recorders.d.ts +8 -2
- package/dist/types/sinks.d.ts +23 -0
- package/dist/types/trace.d.ts +2 -2
- package/package.json +20 -6
- package/dist/esm/lib/decide/evaluator.js +0 -130
- package/dist/lib/decide/evaluator.js +0 -134
package/dist/types/index.d.ts
CHANGED
|
@@ -29,6 +29,15 @@ export { flowChart, FlowChartBuilder, flowChartSelector } from './lib/builder/in
|
|
|
29
29
|
export type { BranchChart, ParallelForEachConfig, RetryPolicy } from './lib/builder/index.js';
|
|
30
30
|
/** @category Quick Start — build-time observer (twin of FlowRecorder) */
|
|
31
31
|
export type { StructureDeciderCompleteEvent, StructureEdgeAddedEvent, StructureEdgeKind, StructureLoopEdgeAddedEvent, StructureRecorder, StructureStageAddedEvent, StructureStageTaggedEvent, StructureSubflowMountedEvent, } from './lib/builder/index.js';
|
|
32
|
+
/**
|
|
33
|
+
* @category Time Budget
|
|
34
|
+
*
|
|
35
|
+
* `timeBudget(chart)` — the slowest a chart can take, from its declared retry policies (`attempts × timeoutMs` plus
|
|
36
|
+
* the waits, summed along the slowest path), and every stage that makes a path unbounded, by name. `.budget(ms)`
|
|
37
|
+
* declares the caller's contract; `build()` refuses a chart that cannot keep it. Also `chart.timeBudget()`.
|
|
38
|
+
*/
|
|
39
|
+
export type { BudgetAssumptions, BudgetStep, TimeBudgetOptions, TimeBudgetReport, UnboundedReason, UnboundedStage, } from './lib/budget/index.js';
|
|
40
|
+
export { timeBudget } from './lib/budget/index.js';
|
|
32
41
|
/** @category Quick Start */
|
|
33
42
|
export type { TypedStageFunction } from './lib/builder/typedFlowChart.js';
|
|
34
43
|
/** @category Quick Start */
|
|
@@ -39,10 +48,59 @@ export { narrative } from './recorders.js';
|
|
|
39
48
|
export type { DecideRule, DecisionEvidence, DecisionResult, DefaultBranch, FilterOps, RuleEvidence, SelectionEvidence, SelectionResult, WhenClause, WhereFilter, } from './lib/decide/index.js';
|
|
40
49
|
/** @category Decision Branching */
|
|
41
50
|
export { decide, select } from './lib/decide/index.js';
|
|
51
|
+
/** @category Errors */
|
|
52
|
+
export type { TerminalFailureContext } from './lib/errors/terminalFailure.js';
|
|
53
|
+
/**
|
|
54
|
+
* @category Attempts
|
|
55
|
+
*
|
|
56
|
+
* One `AttemptRecord` per attempt of a stage with a declared `retry` policy, a `timeoutMs`, or a run deadline —
|
|
57
|
+
* timing, outcome, failure category, and the retry-or-stop decision as `DecisionEvidence` — on the stage's
|
|
58
|
+
* execution-tree node (`StageSnapshot.attempts` / `attemptSummary`) and on `FlowRecorder.onAttempt`.
|
|
59
|
+
* A call a stage makes through `scope.$call` is recorded the same way (kind `'call'`), and so is an SDK's own retry
|
|
60
|
+
* an adapter reports through `observed()` (`ObservedAttempt`, kind `'observed'`). `AttemptContext` is what
|
|
61
|
+
* `scope.$attempt()` returns, and what a call's function gets (the attempt's signal, the time left, `observed`);
|
|
62
|
+
* `LateWrite` is a write (or call) an ended attempt tried (`StageSnapshot.lateWrites`). A stage that changes an
|
|
63
|
+
* outside system declares it (`StageTouches`, `.touches()`), and a call does (`CallOptions`): every attempt then
|
|
64
|
+
* carries its `AttemptEffect`, and the key rule is handed an `IdempotencyKeyContext` once per execution.
|
|
65
|
+
*/
|
|
66
|
+
export type { AttemptCategory, AttemptContext, AttemptEffect, AttemptError, AttemptInputs, AttemptKind, AttemptNext, AttemptOptions, AttemptOutcome, AttemptReason, AttemptRecord, AttemptSummary, CallOptions, IdempotencyKeyContext, LateWrite, ObservedAttempt, StageTouches, UnknownEffectInit, } from './lib/attempt/index.js';
|
|
67
|
+
/**
|
|
68
|
+
* @category Attempts
|
|
69
|
+
*
|
|
70
|
+
* An attempt by name (`series` + `attempt`) and per-outcome counts — what recorder rows hold of attempts.
|
|
71
|
+
*/
|
|
72
|
+
export type { AttemptOutcomeCounts, AttemptRef } from './lib/recorder/attemptSeries.js';
|
|
73
|
+
/**
|
|
74
|
+
* @category Attempts
|
|
75
|
+
*
|
|
76
|
+
* `attempt()` — the attempt runner for code that is not a stage (records go to its `onAttempt`); `errorCategory`
|
|
77
|
+
* — the one failure classifier (seven fixed categories); `retryRules` — the one retry rule table, as `decide()`
|
|
78
|
+
* rules; the attempt contract's two errors.
|
|
79
|
+
*/
|
|
80
|
+
export { attempt, AttemptTimeoutError, errorCategory, retryRules, UnknownEffectError } from './lib/attempt/index.js';
|
|
81
|
+
/**
|
|
82
|
+
* @category Correlation
|
|
83
|
+
*
|
|
84
|
+
* The run's correlation (10.1): `env.traceparent` (W3C, parsed strictly) or `env.traceId` + `env.operationId`
|
|
85
|
+
* become ONE frozen `RunCorrelation` per run — on `getSnapshot().correlation`, every flow event's
|
|
86
|
+
* `traversalContext.correlation` and every scope and emit event's `correlation`. `parseTraceparent` /
|
|
87
|
+
* `formatTraceparent` are the W3C codec; a refused header throws `TraceparentError` with a named `reason`.
|
|
88
|
+
*/
|
|
89
|
+
export type { ParsedTraceparent, RunCorrelation, TraceparentFields, TraceparentRefusal } from './lib/attempt/index.js';
|
|
90
|
+
export { formatTraceparent, parseTraceparent, TraceparentError } from './lib/attempt/index.js';
|
|
42
91
|
/** @category Run */
|
|
43
92
|
export type { RunResult } from './lib/runner/index.js';
|
|
44
93
|
/** @category Run */
|
|
45
94
|
export type { FlowChartExecutorOptions } from './lib/runner/index.js';
|
|
95
|
+
/**
|
|
96
|
+
* The crash-safe record (10.1): the executor's `sink` option, its accounting on `getSnapshot().sink`,
|
|
97
|
+
* `executor.flushRecord()`'s result, and the error a run with `onFailure: 'fail'` rejects with. The port
|
|
98
|
+
* (`RecordSink`, `memorySink`) is `foottrace/write`'s; the file adapter is `footprintjs/sinks`.
|
|
99
|
+
* @category Run
|
|
100
|
+
*/
|
|
101
|
+
export type { RecordFlushResult, RecordSinkFailureMode, RecordSinkFlushMode, RecordSinkOption, RecordSinkOptions, RecordSinkStats, } from './lib/runner/index.js';
|
|
102
|
+
/** @category Run */
|
|
103
|
+
export { RecordSinkError } from './lib/runner/index.js';
|
|
46
104
|
/**
|
|
47
105
|
* The four observability dials `FlowChartExecutorOptions` inherits.
|
|
48
106
|
* @category Run
|
|
@@ -101,7 +159,7 @@ export { hasEmitRecorderMethods, hasFlowRecorderMethods, hasRecorderMethods, isF
|
|
|
101
159
|
*/
|
|
102
160
|
export type { EmitEvent, EmitRecorder } from './lib/recorder/index.js';
|
|
103
161
|
/** @category Observe — Flow */
|
|
104
|
-
export type { FlowBreakEvent, FlowDecisionEvent, FlowErrorEvent, FlowForkEvent, FlowLoopEvent, FlowNextEvent, FlowRecorder, FlowRunEvent, FlowRunFailedEvent, FlowSelectedEvent, FlowStageEvent, FlowStageRetryEvent, FlowSubflowEvent, FlowSubflowRegisteredEvent, FlowThrottledEvent, ResumeLink, TraversalContext, } from './lib/engine/index.js';
|
|
162
|
+
export type { FlowAttemptEvent, FlowBreakEvent, FlowDecisionEvent, FlowErrorEvent, FlowForkEvent, FlowLoopEvent, FlowNextEvent, FlowRecorder, FlowRunEvent, FlowRunFailedEvent, FlowSelectedEvent, FlowStageEvent, FlowStageRetryEvent, FlowSubflowEvent, FlowSubflowRegisteredEvent, FlowThrottledEvent, ResumeLink, TraversalContext, } from './lib/engine/index.js';
|
|
105
163
|
/** @category Observe — Flow */
|
|
106
164
|
export type { CombinedNarrativeEntry } from './lib/engine/index.js';
|
|
107
165
|
/**
|
|
@@ -114,7 +172,7 @@ export type { NarrativeFormatter } from './lib/engine/index.js';
|
|
|
114
172
|
/** @category Observe — Flow */
|
|
115
173
|
export { NarrativeFlowRecorder } from './lib/engine/index.js';
|
|
116
174
|
/** @category Observe — Flow */
|
|
117
|
-
export type { ManifestEntry } from './lib/engine/index.js';
|
|
175
|
+
export type { ManifestAttemptRow, ManifestEntry } from './lib/engine/index.js';
|
|
118
176
|
/** @category Observe — Flow */
|
|
119
177
|
export { ManifestFlowRecorder } from './lib/engine/index.js';
|
|
120
178
|
/** @category Observe — Flow */
|
|
@@ -223,4 +281,6 @@ export { extractErrorInfo, formatErrorInfo } from './lib/engine/index.js';
|
|
|
223
281
|
* `enableDevMode` for the full list and usage example.
|
|
224
282
|
*/
|
|
225
283
|
export { disableDevMode, enableDevMode, isDevMode } from './lib/devMode.js';
|
|
284
|
+
export type { RetryLoopCall, RetryLoopDecision, RetryLoopIdentity } from './lib/attempt/retryLoopTypes.js';
|
|
285
|
+
export type { RetryLoopContext, RetryLoopOptions, RetryLoopState } from './lib/builder/retryLoop.js';
|
|
226
286
|
export { stringifySnapshot } from './lib/runner/stringifySnapshot.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/anySignal.ts — one signal that aborts when ANY of its inputs does.
|
|
3
|
+
*
|
|
4
|
+
* The attempt runner gives each attempt its own signal: the run's signal (cancellation, the deadline) composed
|
|
5
|
+
* with the attempt's own time cap. `AbortSignal.any` does this natively, but not in every browser this library
|
|
6
|
+
* runs in (design §3.1), so the composition is ours: small, and leak-free — every listener it adds to an input
|
|
7
|
+
* is removed the moment it aborts or is disposed, so a long run of attempts leaves nothing on the run's signal.
|
|
8
|
+
*/
|
|
9
|
+
/** A composed signal and the one call that releases its inputs. */
|
|
10
|
+
export interface ComposedSignal {
|
|
11
|
+
readonly signal: AbortSignal;
|
|
12
|
+
/** Remove every listener this composition added to its inputs. Idempotent. */
|
|
13
|
+
dispose(): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compose `inputs` (undefined entries ignored): the result aborts with the reason of the first input to abort,
|
|
17
|
+
* or at once with the reason of an input that already has. Call `dispose()` when the attempt ends.
|
|
18
|
+
*/
|
|
19
|
+
export declare function anySignal(inputs: ReadonlyArray<AbortSignal | undefined>): ComposedSignal;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/call.ts — a call made INSIDE a stage attempt: `scope.$call(target, fn, policy?)` (design §3.6, §3.8,
|
|
3
|
+
* packet P2).
|
|
4
|
+
*
|
|
5
|
+
* The same loop as a stage's retry (`runAttempts`, law 1), kind `'call'`, its `target` on every record — and a
|
|
6
|
+
* record even for a single call (`attempts: 1`): timing and outcome evidence with no retry. Its series is the
|
|
7
|
+
* call level of foottrace's attempt-id grammar ({@link callSeries}).
|
|
8
|
+
*
|
|
9
|
+
* THE LAW — a call lives within the attempt that made it. The host (the stage's scope) hands it that attempt's
|
|
10
|
+
* signal and its end as the call's deadline, so the call is capped by the time its stage attempt has left, and is
|
|
11
|
+
* cut when the stage attempt is cut (a time limit, so `'timeout'`; a cancellation, so `'aborted'`); and an `ended`
|
|
12
|
+
* signal that aborts when the attempt is over however it ended (it returned, threw, or its frame committed), so a
|
|
13
|
+
* call never outlives it. Following the P1b fence:
|
|
14
|
+
* - the record of a call attempt cut BY its stage attempt's own abort lands — the cut is evidence;
|
|
15
|
+
* - any other record that arrives once the stage attempt is over is REFUSED: noted by name (`host.refused`), never
|
|
16
|
+
* kept, never fired; the call stops (its in-flight attempt is cut, a wait ends) and no further attempt of an
|
|
17
|
+
* outside call starts — and the library-made rejection of such an orphan never surfaces as an unhandled one;
|
|
18
|
+
* - a call never starts under a signal already aborted, nor past its deadline while that signal is still due (a
|
|
19
|
+
* busy event loop fires timers late): no attempt, no record — the host's signal is its ONE deadline source.
|
|
20
|
+
* What the call's function does after its attempt ended cannot be trapped — it should RETURN its answer, not write
|
|
21
|
+
* the stage's scope (the scope's own fence still refuses a write from an ended stage attempt).
|
|
22
|
+
*
|
|
23
|
+
* A LEAF of the engine (L5): the host is a port, so nothing here names the scope.
|
|
24
|
+
*/
|
|
25
|
+
import type { StructuredErrorInfo } from '../errors/errorInfo.js';
|
|
26
|
+
import type { EffectTarget } from './effect.js';
|
|
27
|
+
import type { AttemptContext, AttemptRecord, ObservedAttempt, RetryPolicy } from './types.js';
|
|
28
|
+
/**
|
|
29
|
+
* The series of the `ordinal`-th call (1-based) made during attempt `stageAttempt` of the stage execution
|
|
30
|
+
* `runtimeStageId`: `<runtimeStageId>@<n>.<k>` — so the id of the call's attempt `m` is `<series>@<m>`, foottrace's
|
|
31
|
+
* `buildAttemptId(runtimeStageId, n, { ordinal: k, attempt: m })` (design §3.4). Written here, in this one place,
|
|
32
|
+
* until the engine adopts foottrace 1.1.0's codec (P6); the bytes are the grammar's.
|
|
33
|
+
*/
|
|
34
|
+
export declare function callSeries(runtimeStageId: string, stageAttempt: number, ordinal: number): string;
|
|
35
|
+
/** What the attempt that makes a call gives it — the scope implements it. */
|
|
36
|
+
export interface CallHost {
|
|
37
|
+
/**
|
|
38
|
+
* The call's series ({@link callSeries}) — asked once, only when the call starts, so a call refused before it
|
|
39
|
+
* starts takes no ordinal and leaves no gap.
|
|
40
|
+
*/
|
|
41
|
+
openSeries(): string;
|
|
42
|
+
/**
|
|
43
|
+
* The stage attempt's signal: the run's cancellation, the run's deadline and the attempt's own cap. When given, it
|
|
44
|
+
* is the call's ONE deadline source — it must abort at {@link deadline}, with a time-limit reason
|
|
45
|
+
* (`deadline.ts · markTimeLimit` / `deadlineReason`); the call arms no timer of its own.
|
|
46
|
+
*/
|
|
47
|
+
readonly signal?: AbortSignal;
|
|
48
|
+
/**
|
|
49
|
+
* When the stage attempt must end, epoch ms — the call's deadline, capping each attempt by the time left. Absent
|
|
50
|
+
* for an uncapped attempt. Without a {@link signal}, the call arms the one timer that ends it here.
|
|
51
|
+
*/
|
|
52
|
+
readonly deadline?: number;
|
|
53
|
+
/** The clock (default `Date.now`). */
|
|
54
|
+
readonly now?: () => number;
|
|
55
|
+
/**
|
|
56
|
+
* Aborts when the attempt that makes the call is over — however it ended — and when its frame commits: the call
|
|
57
|
+
* stops (its in-flight attempt is cut, a wait ends, no attempt follows) and its records are refused. No call
|
|
58
|
+
* outlives the attempt that made it.
|
|
59
|
+
*/
|
|
60
|
+
readonly ended?: AbortSignal;
|
|
61
|
+
/**
|
|
62
|
+
* May a record of the call land on the stage now? `cut`: the call attempt was ended BY the stage attempt's own
|
|
63
|
+
* end, so its record is the evidence of that cut.
|
|
64
|
+
*/
|
|
65
|
+
admits(cut: boolean): boolean;
|
|
66
|
+
/** The served form of an attempt's error — the run's redaction rule. */
|
|
67
|
+
serve(error: unknown): StructuredErrorInfo;
|
|
68
|
+
/** A record that may land: onto the stage, and the run's `onAttempt`. */
|
|
69
|
+
report(record: AttemptRecord, structuredError: StructuredErrorInfo | undefined): void;
|
|
70
|
+
/** A record that may not — the call outlived the attempt that made it. A name is noted; nothing is kept. */
|
|
71
|
+
refused(): void;
|
|
72
|
+
/**
|
|
73
|
+
* The outside system the call touches and its key (P3) — admitted at the call (`effect.ts · callTouches`), the
|
|
74
|
+
* recorded key served under the run's rule. Every record then carries its `effect`, and a series ended without an answer after an attempt of unknown
|
|
75
|
+
* effect rejects with `UnknownEffectError`.
|
|
76
|
+
*/
|
|
77
|
+
readonly effect?: EffectTarget;
|
|
78
|
+
/** An observed report made through the call's own attempt context (`ended`: that call attempt was over). */
|
|
79
|
+
observe(report: ObservedAttempt, at: {
|
|
80
|
+
readonly attempt: number;
|
|
81
|
+
readonly ended: boolean;
|
|
82
|
+
}): void;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Run `fn` as the call `target` under `policy` (already admitted — `policy.ts · admitCallPolicy`) for `host`.
|
|
86
|
+
* Resolves with the answer, or rejects with the last attempt's own error.
|
|
87
|
+
*/
|
|
88
|
+
export declare function runCall<T>(target: string, fn: (attempt: AttemptContext) => Promise<T> | T, policy: RetryPolicy, host: CallHost): Promise<T>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/category.ts — `errorCategory`, the ONE failure classifier (design §3.9).
|
|
3
|
+
*
|
|
4
|
+
* Seven fixed values, so every recorder — the narrative, the metric layer, an agent's own — breaks failures down
|
|
5
|
+
* the same way; a recorder never invents a category of its own. Borrowed from agentfootprint's
|
|
6
|
+
* `classifyRetryReason` and widened, so its decorators adopt this one rather than keep theirs.
|
|
7
|
+
*
|
|
8
|
+
* Category is EVIDENCE, never policy: the default `retryOn` retries every category. A chart that wants "never
|
|
9
|
+
* retry a permanent failure" says so: `retryOn: (e) => errorCategory(e) !== 'permanent'`.
|
|
10
|
+
*
|
|
11
|
+
* Precedence — what the failure LOOKED like wins over what it declares:
|
|
12
|
+
* 1. the attempt's own timer (outcome `'timeout'`, or our `AttemptTimeoutError`) → timeout
|
|
13
|
+
* 2. the run's signal ended it (outcome `'aborted'`) → unknown
|
|
14
|
+
* 3. status 429, or a declared `retryAfterMs` / `retryAfterSeconds` → rate-limited
|
|
15
|
+
* 4. status 5xx → server
|
|
16
|
+
* 5. status 401 / 403 → auth
|
|
17
|
+
* 6. any other 4xx → permanent
|
|
18
|
+
* 7. `retryable: false`, or a validation error → permanent
|
|
19
|
+
* 8. a transport failure (a socket code on the error or its cause, a fetch
|
|
20
|
+
* `TypeError`, an `AbortError` / `TimeoutError` that was not the run's) → network
|
|
21
|
+
* 9. anything else → unknown
|
|
22
|
+
*
|
|
23
|
+
* A status is a NUMBER (`status` or `statusCode`); a numeric string is not read as one. Total: a value whose
|
|
24
|
+
* reads throw (a hostile Proxy) is `'unknown'`, never a second throw from an error path.
|
|
25
|
+
*/
|
|
26
|
+
import type { AttemptCategory, AttemptOutcome } from './types.js';
|
|
27
|
+
/**
|
|
28
|
+
* The category of an attempt's failure. `outcome` is how the attempt ended (default `'failed'`): it decides
|
|
29
|
+
* `'timeout'` (the attempt's own timer) and `'unknown'` (the run's signal) before the error is read.
|
|
30
|
+
*/
|
|
31
|
+
export declare function errorCategory(error: unknown, outcome?: AttemptOutcome): AttemptCategory;
|
|
32
|
+
/**
|
|
33
|
+
* @internal Terminal ownership preserves a producer's known category. An
|
|
34
|
+
* unresolved effect is unknown, never the category of its physical cause.
|
|
35
|
+
* This does not rewrite historical attempt categories or re-read a known one.
|
|
36
|
+
*/
|
|
37
|
+
export declare function terminalCategory(error: unknown, known?: AttemptCategory): AttemptCategory;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/correlation.ts — the run's correlation: the W3C `traceparent` codec and the ONE resolution of the env
|
|
3
|
+
* into a `RunCorrelation` (design docs/design/2026-10-time-and-failure-evidence.md §3.4, packet P4).
|
|
4
|
+
*
|
|
5
|
+
* THREAT MODEL. A `traceparent` comes from whoever sent the request. So:
|
|
6
|
+
* - it is read STRICTLY to the W3C Trace Context grammar (`version-traceid-parentid-flags`, lowercase hex) and
|
|
7
|
+
* anything else is refused by a NAMED reason (`TraceparentError.reason`) — the message never repeats the
|
|
8
|
+
* header, and the error holds no copy of it;
|
|
9
|
+
* - what the run keeps is the canonical form of what was parsed (`formatTraceparent`), never the received
|
|
10
|
+
* bytes — a future version's tail is dropped;
|
|
11
|
+
* - it is correlation only: a name the record carries so a run can be found from a trace. Nothing in the
|
|
12
|
+
* library treats it as identity or authorisation.
|
|
13
|
+
*
|
|
14
|
+
* W3C forward compatibility: a version other than `00` (and never `ff`) is read by its first four fields; a
|
|
15
|
+
* longer header must continue with `-`. Version `00` is exactly 55 characters. A header longer than
|
|
16
|
+
* {@link MAX_HEADER_LENGTH} is refused before it is scanned.
|
|
17
|
+
*/
|
|
18
|
+
import type { RunCorrelation } from './types.js';
|
|
19
|
+
/** Why a `traceparent` was refused — a NAME, so a caller can branch on it without reading a message. */
|
|
20
|
+
export type TraceparentRefusal = 'not-a-string' | 'length' | 'version' | 'characters' | 'zero-trace-id' | 'zero-parent-id';
|
|
21
|
+
/** A parsed `traceparent`: the W3C trace-id, the parent-id (the caller's unit of work), and its trace-flags. */
|
|
22
|
+
export interface ParsedTraceparent {
|
|
23
|
+
/** 32 lowercase hex, not all zeros. */
|
|
24
|
+
readonly traceId: string;
|
|
25
|
+
/** The W3C parent-id — 16 lowercase hex, not all zeros. The library's word for it is "operation". */
|
|
26
|
+
readonly operationId: string;
|
|
27
|
+
/** Bit 0 of `flags`. */
|
|
28
|
+
readonly sampled: boolean;
|
|
29
|
+
/** The trace-flags byte as received — 2 lowercase hex — so a re-format keeps every bit (W3C level 2's random). */
|
|
30
|
+
readonly flags: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* What `formatTraceparent` writes from. `flags` (2 lowercase hex) is the trace-flags byte, `'00'` when absent;
|
|
34
|
+
* `sampled`, when given, sets or clears its bit 0.
|
|
35
|
+
*/
|
|
36
|
+
export interface TraceparentFields {
|
|
37
|
+
readonly traceId: string;
|
|
38
|
+
readonly operationId: string;
|
|
39
|
+
readonly sampled?: boolean;
|
|
40
|
+
readonly flags?: string;
|
|
41
|
+
}
|
|
42
|
+
/** The longest header read at all (a future version may append fields; nothing legitimate is near this). */
|
|
43
|
+
export declare const MAX_HEADER_LENGTH = 256;
|
|
44
|
+
/** A `traceparent` the library will not read. The header itself is never in the message or on the error. */
|
|
45
|
+
export declare class TraceparentError extends Error {
|
|
46
|
+
readonly reason: TraceparentRefusal;
|
|
47
|
+
constructor(reason: TraceparentRefusal);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse a W3C `traceparent` header strictly. Returns a frozen {@link ParsedTraceparent}; throws a
|
|
51
|
+
* {@link TraceparentError} naming the first rule the header breaks.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* parseTraceparent('00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01');
|
|
55
|
+
* // { traceId: '4bf92f3577b34da6a3ce929d0e0e4736', operationId: '00f067aa0ba902b7', sampled: true, flags: '01' }
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseTraceparent(header: unknown): ParsedTraceparent;
|
|
58
|
+
/**
|
|
59
|
+
* Write a version-00 `traceparent` — for an outbound call that continues this run's trace. Both ids must be W3C
|
|
60
|
+
* ids and `flags` a byte of 2 lowercase hex (refused by name otherwise, like a parse); `sampled`, when given,
|
|
61
|
+
* sets or clears bit 0 of the flags. `formatTraceparent(parseTraceparent(h))` is `h` for any valid version-00 `h`.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* formatTraceparent({ traceId, operationId: mySpanId, sampled: true }); // '00-<traceId>-<mySpanId>-01'
|
|
65
|
+
*/
|
|
66
|
+
export declare function formatTraceparent(fields: TraceparentFields): string;
|
|
67
|
+
/** The env fields correlation reads — structural, so this L5 file names nothing of the engine's `ExecutionEnv`. */
|
|
68
|
+
export interface CorrelationEnv {
|
|
69
|
+
readonly traceparent?: unknown;
|
|
70
|
+
readonly traceId?: unknown;
|
|
71
|
+
readonly operationId?: unknown;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Admit a leg's env ONCE (called by `FlowChartExecutor · run` / `resume` before anything moves): a single
|
|
75
|
+
* own-property snapshot of it — every getter runs once, nothing is read off the prototype — and the correlation
|
|
76
|
+
* resolved from that snapshot. In the snapshot the stages see (`$getEnv()`), `traceparent` is exactly
|
|
77
|
+
* `correlation.traceparent` — the canonical header of the effective ids, or no key when the run's correlation has
|
|
78
|
+
* none — so stage code never holds the received bytes, nor a header naming another trace than the record.
|
|
79
|
+
* `env` is `undefined` exactly when none was given.
|
|
80
|
+
*/
|
|
81
|
+
export declare function admitRunEnv<E extends object>(env: E | undefined): {
|
|
82
|
+
readonly env: E | undefined;
|
|
83
|
+
readonly correlation: RunCorrelation | undefined;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* The ONE resolution of a leg's correlation from its env. Only OWN fields count. `traceparent` is parsed once (a
|
|
87
|
+
* bad header refuses the leg — explicit ids do not rescue it); explicit `traceId` / `operationId` win over the
|
|
88
|
+
* header's and must be 1–256 printable ASCII characters (refused by field name, never echoed); an empty one is
|
|
89
|
+
* no id. Everything of the header — its parent-id as the operation, `sampled`, `traceparent` — rides only while
|
|
90
|
+
* the trace IS the header's, and `traceparent` is rebuilt from the EFFECTIVE ids with the header's flags
|
|
91
|
+
* (omitted when the operation is not a W3C parent-id), so the record never names one trace and files or
|
|
92
|
+
* propagates another's. Returns `undefined` when there is no trace id at all — and refuses
|
|
93
|
+
* an `operationId` with no trace to belong to.
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolveCorrelation(env: CorrelationEnv | undefined): RunCorrelation | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/deadline.ts — what the run's deadline IS, to everything that reads time (design §3.1, law 3).
|
|
3
|
+
*
|
|
4
|
+
* The deadline is one number, epoch milliseconds (`env.deadline`); the executor arms the run's signal to abort when
|
|
5
|
+
* it passes (`runner/deadline.ts · armRun`). Reaching it is NOT a cancellation: an attempt the deadline cuts short
|
|
6
|
+
* timed out (it had no answer in the time it had — law 4), and the series stops `no-time-left`, not `aborted`. So
|
|
7
|
+
* the reason the run's signal aborts with at the deadline is BRANDED here, and the attempt runner tells the two
|
|
8
|
+
* apart by the brand — never by the message, never by the clock.
|
|
9
|
+
*
|
|
10
|
+
* The brand is a module-private WeakSet: an ordinary `Error` (same message, same name a run with `timeoutMs` always
|
|
11
|
+
* rejected with), recognisable only by identity.
|
|
12
|
+
*/
|
|
13
|
+
/** The reason the run's signal aborts with when its deadline passes — an `Error`, branded as the deadline's. */
|
|
14
|
+
export declare function deadlineReason(message: string): Error;
|
|
15
|
+
/**
|
|
16
|
+
* Brand `reason` as a time limit — what an attempt's own cap aborts with (P2). An attempt's cap is the deadline of
|
|
17
|
+
* every call made inside it (`attempt/call.ts`), so a call it cuts ran out of time: `'timeout'`, never `'aborted'`.
|
|
18
|
+
* The run's own signal never aborts with it, so a stage attempt reads nothing new.
|
|
19
|
+
*/
|
|
20
|
+
export declare function markTimeLimit<T extends object>(reason: T): T;
|
|
21
|
+
/** Whether `reason` is the run's deadline or an attempt's cap — a time limit, not a cancellation. */
|
|
22
|
+
export declare function isDeadlineReason(reason: unknown): boolean;
|
|
23
|
+
/** Whether the signal aborted for a reason OTHER than a time limit — a cancellation. */
|
|
24
|
+
export declare function isCancelled(signal: AbortSignal | undefined): boolean;
|
|
25
|
+
/** A deadline as the engine reads one: a finite number (epoch ms), else none. */
|
|
26
|
+
export declare function readDeadline(value: unknown): number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* `setTimeout` for any delay: a delay past the host's limit is waited in chunks, so a 30-day deadline does not fire
|
|
29
|
+
* in a millisecond. Returns the one call that cancels it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function setLongTimeout(fn: () => void, ms: number): () => void;
|
|
32
|
+
/** Whether `value` is an AbortSignal (structurally — a signal from another realm counts). */
|
|
33
|
+
export declare function isAbortSignal(value: unknown): value is AbortSignal;
|
|
34
|
+
/** A signal that aborts at a deadline (or with its input), and the one call that releases both. */
|
|
35
|
+
export interface ArmedDeadline {
|
|
36
|
+
readonly signal: AbortSignal | undefined;
|
|
37
|
+
dispose(): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Compose `signal` with a timer that aborts at `deadline` (epoch ms) with a branded {@link deadlineReason} — so the
|
|
41
|
+
* attempt runner's reading holds: the signal it is handed aborts at the deadline, as the run's does (`armRun`). A
|
|
42
|
+
* deadline already past aborts at once; without a deadline the signal is handed back as it is.
|
|
43
|
+
*/
|
|
44
|
+
export declare function armDeadline(signal: AbortSignal | undefined, deadline: number | undefined, message: string, now?: () => number): ArmedDeadline;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/decision.ts — the ONE retry rule table and the runner's evidence builder (design §3.1, §3.8, law 9).
|
|
3
|
+
*
|
|
4
|
+
* `retryRules(policy)` is the retry-or-stop decision as ordinary `decide()` rules over `AttemptInputs`, first
|
|
5
|
+
* match wins, default `retry` ("retryable"):
|
|
6
|
+
*
|
|
7
|
+
* 1 outcome = ok → done succeeded
|
|
8
|
+
* 2 outcome = paused → stop paused
|
|
9
|
+
* 3 aborted = true → stop aborted (the run's signal — the attempt's outcome stays its own)
|
|
10
|
+
* 4 attempt ≥ of → stop exhausted
|
|
11
|
+
* 5 retryOn = false → stop declined (a function rule: it shows the verdict it saw)
|
|
12
|
+
* 6 timeLeftAfterWaitMs ≤ 0 → stop no-time-left
|
|
13
|
+
* default → retry retryable
|
|
14
|
+
*
|
|
15
|
+
* Each rule's `label` IS the reason it names, so `reason` is a projection of the evidence, never a second
|
|
16
|
+
* vocabulary. The ceiling is `attempt/policy.ts · attemptCeiling`, the one reading the engine and the runner
|
|
17
|
+
* share.
|
|
18
|
+
*
|
|
19
|
+
* `decideAttempt` evaluates that table WITHOUT a scope (the runner has none — `decide()` needs a registered
|
|
20
|
+
* one) and builds the evidence `decide()` would build: the filter rows come from `decide()`'s own evaluator
|
|
21
|
+
* (`filter/evaluator.ts · evaluateFilter`), the function rows and the first-match loop mirror
|
|
22
|
+
* `decide/decide.ts` field for field and key for key. A property test pins that both paths give equal evidence
|
|
23
|
+
* for equal inputs (test/lib/attempt/property).
|
|
24
|
+
*
|
|
25
|
+
* Inputs are READ, one key at a time, only when a rule reaches them — so the user's `retryOn` and `backoffMs`
|
|
26
|
+
* run exactly when a retry needs them, as they did before the record existed.
|
|
27
|
+
*/
|
|
28
|
+
import type { DecideRule, DecisionEvidence } from '../decide/types.js';
|
|
29
|
+
import type { AttemptInputs, AttemptNext, AttemptReason, RetryPolicy } from './types.js';
|
|
30
|
+
/** The table's default: no rule stopped the series, so it retries. */
|
|
31
|
+
export declare const RETRY_DEFAULT: Readonly<{
|
|
32
|
+
readonly branch: "retry";
|
|
33
|
+
readonly label: "retryable";
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* The retry rule table for `policy` — six `decide()` rules, then {@link RETRY_DEFAULT}. The ceiling is the
|
|
37
|
+
* whole number of attempts the policy allows, never fewer than one (`attemptCeiling`): a ceiling of `NaN` or
|
|
38
|
+
* `Infinity` cannot make rule 4 unreachable.
|
|
39
|
+
*/
|
|
40
|
+
export declare function retryRules(policy: Pick<RetryPolicy, 'attempts'>): DecideRule<AttemptInputs>[];
|
|
41
|
+
/** A decision: the evidence, and its compact projection. */
|
|
42
|
+
export interface AttemptDecision {
|
|
43
|
+
readonly evidence: DecisionEvidence;
|
|
44
|
+
readonly next: AttemptNext;
|
|
45
|
+
readonly reason: AttemptReason;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Evaluate `rules` (a `retryRules` table) over `read` — first match wins — and build the evidence `decide()`
|
|
49
|
+
* would record with the default {@link RETRY_DEFAULT}. `read(key)` returns one input; it is called only for the
|
|
50
|
+
* keys the evaluated rules touch, in rule order.
|
|
51
|
+
*/
|
|
52
|
+
export declare function decideAttempt(rules: readonly DecideRule<AttemptInputs>[], read: (key: string) => unknown): AttemptDecision;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/effect.ts — side-effect safety (design §3.3, packet P3): the ONE reading of what an attempt did to an
|
|
3
|
+
* outside system, and the ONE rule for a touching target.
|
|
4
|
+
*
|
|
5
|
+
* - `touchesProblem` — the build law, asked at every door a touching declaration enters: the builder
|
|
6
|
+
* (`FlowChartBuilder · applyTouches` / `applyRetryPolicy`), the traverser for a StageNode a stage returns at run
|
|
7
|
+
* time (`FlowchartTraverser · admitDynamicNodes`), and the stage itself (`FlowchartTraverser · executeStage`, for
|
|
8
|
+
* a chart edited after `build()`). A touching target that may retry without an idempotency key is refused: a
|
|
9
|
+
* retry of a non-idempotent effect without one can apply it twice.
|
|
10
|
+
* - `callTouches` — the same law for `scope.$call(target, fn, policy, { touches, idempotencyKey })`.
|
|
11
|
+
* - `admitIdempotencyKey` — the key's format: 1–255 printable ASCII characters, no space. It travels in a request
|
|
12
|
+
* header (`Idempotency-Key`), so a control character could forge one; the refusal names the field, never the
|
|
13
|
+
* value.
|
|
14
|
+
* - `effectOf` — `ok → 'applied'`; a failure whose error declares `effect: 'none'` → `'none'`; anything else →
|
|
15
|
+
* `'unknown'`. A timeout is the absence of an answer (law 4), so it is never `'none'`.
|
|
16
|
+
* - `unknownEffectError` — what a series that ends without an answer after ANY attempt of unknown effect fails
|
|
17
|
+
* with, in place of the attempt's own error (its `cause`).
|
|
18
|
+
* - `interruptProblem` — a keyless touching stage may not be re-run by an `interrupt()` resume.
|
|
19
|
+
*/
|
|
20
|
+
import { UnknownEffectError } from './errors.js';
|
|
21
|
+
import type { AttemptEffect, AttemptOutcome, AttemptRecord, RetryPolicy, StageTouches } from './types.js';
|
|
22
|
+
export { MAX_IDEMPOTENCY_KEY_LENGTH } from '../ids/idempotencyKey.js';
|
|
23
|
+
/**
|
|
24
|
+
* What a touching runner series is told (`AttemptRunOptions.effect`): the system, the REAL key the attempts are made
|
|
25
|
+
* under, and the key as records carry it (the run's served form; the real one when no rule applies).
|
|
26
|
+
*/
|
|
27
|
+
export interface EffectTarget {
|
|
28
|
+
readonly system: string;
|
|
29
|
+
readonly idempotencyKey?: string;
|
|
30
|
+
readonly recordedKey?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Why a touching declaration is refused, or `undefined` when it is admitted: `touches` must be `{ system,
|
|
34
|
+
* idempotencyKey? }` with `system` a name and the key rule a function; and a target that may retry (`retry`'s
|
|
35
|
+
* ceiling above 1) must declare the key rule.
|
|
36
|
+
*/
|
|
37
|
+
export declare function touchesProblem(touches: unknown, retry: Pick<RetryPolicy, 'attempts'> | undefined): string | undefined;
|
|
38
|
+
/** `value` as an idempotency key (`ids/idempotencyKey.ts`, the one rule), or a `TypeError` that names `where`. */
|
|
39
|
+
export declare function admitIdempotencyKey(where: string, value: unknown): string;
|
|
40
|
+
/**
|
|
41
|
+
* A `$call`'s side-effect declaration, admitted: `undefined` when it touches nothing; otherwise the system and the
|
|
42
|
+
* key, refused with a `TypeError` naming `where` when malformed, when a key comes without a system, or when the
|
|
43
|
+
* call may retry with no key — before anything is sent.
|
|
44
|
+
*/
|
|
45
|
+
export declare function callTouches(where: string, options: unknown, policy: Pick<RetryPolicy, 'attempts'>): {
|
|
46
|
+
readonly system: string;
|
|
47
|
+
readonly idempotencyKey?: string;
|
|
48
|
+
} | undefined;
|
|
49
|
+
/** What an attempt that ended `outcome` (with `error`, when it failed) did to the outside system. */
|
|
50
|
+
export declare function effectOf(outcome: AttemptOutcome, error: unknown): AttemptEffect;
|
|
51
|
+
/**
|
|
52
|
+
* What a touching series fails with when any of its attempts left the effect unknown — never the attempt's own error,
|
|
53
|
+
* which a caller would read as a failure and retry. The key is the RECORDED one: under a redaction rule that names
|
|
54
|
+
* it, the error carries the placeholder, as every record does.
|
|
55
|
+
*/
|
|
56
|
+
export declare function unknownEffectError(target: EffectTarget, record: AttemptRecord, cause: unknown): UnknownEffectError;
|
|
57
|
+
/** The key as records carry it: the served form when the caller gave one, else the key itself. */
|
|
58
|
+
export declare function recordedKeyOf(target: EffectTarget): string | undefined;
|
|
59
|
+
/** The runner's refusal of a touching series that may retry with no key — the law, at the last door. */
|
|
60
|
+
export declare function refuseKeylessRetry(target: EffectTarget, attempts: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Why a touching stage may not be RE-RUN by an `interrupt()` resume, or `undefined` when it may (P3). A resume
|
|
63
|
+
* re-runs the stage's function from its top — a second attempt of its effect — so the law that refuses a keyless
|
|
64
|
+
* retry refuses a keyless re-run too. Asked when the stage interrupts (`StageRunner`) and when a checkpoint is
|
|
65
|
+
* resumed (`runner/resume.ts · planResume`, for a checkpoint made by another version of the chart).
|
|
66
|
+
*/
|
|
67
|
+
export declare function interruptProblem(touches: StageTouches | undefined): string | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* The stand-in's declaration on a resume (P3): the paused stage's system, answering the key its checkpoint carried —
|
|
70
|
+
* the OPERATIONAL value, real (checkpoints are exempt from redaction by law). It is marked, so the run serves it
|
|
71
|
+
* like a key of unknown sources: under any state rule the records carry the placeholder (`isCarriedTouches`) — the
|
|
72
|
+
* resumed leg no longer holds the input the key was made of, so it cannot tell whether the key was masked.
|
|
73
|
+
*/
|
|
74
|
+
export declare function carriedTouches(system: string, key: string): StageTouches;
|
|
75
|
+
/** The declaration answers a key a checkpoint carried ({@link carriedTouches}). */
|
|
76
|
+
export declare function isCarriedTouches(touches: unknown): boolean;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/errors.ts — the errors the attempt contract throws (design §3.3).
|
|
3
|
+
*
|
|
4
|
+
* - `AttemptTimeoutError` — the attempt's OWN timer ended it (`RetryPolicy.timeoutMs` / the run's deadline). A
|
|
5
|
+
* timeout is the absence of an answer, not a failure of the outside system (law 4); `errorCategory` reads it
|
|
6
|
+
* as `'timeout'`.
|
|
7
|
+
* - `UnknownEffectError` — a side-effecting target's last attempt ended with no answer, so nobody knows whether
|
|
8
|
+
* the effect happened. "Reconcile, do not retry blindly" is on the error, not in prose.
|
|
9
|
+
*
|
|
10
|
+
* The idempotency key is a VALUE: it rides the error as a field (a redaction rule selects it by name) and is
|
|
11
|
+
* never spelled in a message.
|
|
12
|
+
*/
|
|
13
|
+
/** The attempt's own time cap ran out before it answered. */
|
|
14
|
+
export declare class AttemptTimeoutError extends Error {
|
|
15
|
+
/** The attempt that ran out of time, 1-based. */
|
|
16
|
+
readonly attempt: number;
|
|
17
|
+
/** The cap it ran under, in milliseconds. */
|
|
18
|
+
readonly timeoutMs: number;
|
|
19
|
+
constructor(attempt: number, timeoutMs: number, options?: {
|
|
20
|
+
readonly cause?: unknown;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** What an `UnknownEffectError` names. */
|
|
24
|
+
export interface UnknownEffectInit {
|
|
25
|
+
/** The outside system the stage touches — a name, never a value. */
|
|
26
|
+
readonly system: string;
|
|
27
|
+
/** The key the effect was attempted under — a value, kept as a field and never put in the message. */
|
|
28
|
+
readonly idempotencyKey?: string;
|
|
29
|
+
/** How many attempts ran. */
|
|
30
|
+
readonly attempts: number;
|
|
31
|
+
/** The last attempt's own error. */
|
|
32
|
+
readonly cause?: unknown;
|
|
33
|
+
}
|
|
34
|
+
/** A side-effecting target's last attempt ended with no answer: whether the effect happened is unknown. */
|
|
35
|
+
export declare class UnknownEffectError extends Error {
|
|
36
|
+
readonly system: string;
|
|
37
|
+
/** Absent (not `undefined`) when no key was given — `declare`, so no class field is emitted for it. */
|
|
38
|
+
readonly idempotencyKey?: string;
|
|
39
|
+
readonly attempts: number;
|
|
40
|
+
constructor(init: UnknownEffectInit);
|
|
41
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/ — one runner, one record: every attempt the library runs is an `AttemptRecord` with the
|
|
3
|
+
* retry-or-stop decision that followed it (design docs/design/2026-10-time-and-failure-evidence.md).
|
|
4
|
+
*
|
|
5
|
+
* Public: the record's vocabulary, the one failure classifier, the one rule table, the two errors, and `attempt()`
|
|
6
|
+
* — the runner for code that is not a stage (P2). The loop itself (`runAttempts`), `runCall`, the evidence builder
|
|
7
|
+
* and `anySignal` are the engine's. `RetryPolicy` is declared in
|
|
8
|
+
* `./types.ts` and published through the builder's barrel, where it always was.
|
|
9
|
+
*/
|
|
10
|
+
export { errorCategory } from './category.js';
|
|
11
|
+
export type { ParsedTraceparent, TraceparentFields, TraceparentRefusal } from './correlation.js';
|
|
12
|
+
export { formatTraceparent, parseTraceparent, TraceparentError } from './correlation.js';
|
|
13
|
+
export { retryRules } from './decision.js';
|
|
14
|
+
export type { UnknownEffectInit } from './errors.js';
|
|
15
|
+
export { AttemptTimeoutError, UnknownEffectError } from './errors.js';
|
|
16
|
+
export type { AttemptOptions } from './standalone.js';
|
|
17
|
+
export { attempt } from './standalone.js';
|
|
18
|
+
export type { AttemptCategory, AttemptContext, AttemptEffect, AttemptError, AttemptInputs, AttemptKind, AttemptNext, AttemptOutcome, AttemptReason, AttemptRecord, AttemptSummary, CallOptions, IdempotencyKeyContext, LateWrite, ObservedAttempt, RunCorrelation, StageTouches, } from './types.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* attempt/name.ts — the ONE rule for a name an attempt record carries (design §3.6, threat model, packet P2): the
|
|
3
|
+
* target of a `$call` / `attempt()`, a standalone series, and an observed report's target and source.
|
|
4
|
+
*
|
|
5
|
+
* A target is a NAME from code — `'stripe.quotes.create'` — never from a model and never a value. It rides every
|
|
6
|
+
* record, narrative line, recorder row and metric key exactly as given, so a name is refused unless it is a string
|
|
7
|
+
* of 1–{@link MAX_NAME_LENGTH} characters, not blank, with no control (C0, DEL, C1), format (zero-width, bidi
|
|
8
|
+
* overrides), surrogate, line/paragraph-separator, private-use or noncharacter code point:
|
|
9
|
+
* - an empty or blank name names nothing;
|
|
10
|
+
* - an overlong one is a value, or a flood of one;
|
|
11
|
+
* - a control or separator character forges a narrative line or a log record, and a bidi override hides what a
|
|
12
|
+
* line says.
|
|
13
|
+
* The refusal names the FIELD, never the value (P4's precedent): a rejected name may be exactly what must not be
|
|
14
|
+
* echoed. A `TypeError`, because a malformed name is the caller's code breaking its contract.
|
|
15
|
+
*/
|
|
16
|
+
/** The longest name an attempt record carries. */
|
|
17
|
+
export declare const MAX_NAME_LENGTH = 128;
|
|
18
|
+
/** Why `value` is not a name, or `undefined` when it is one. */
|
|
19
|
+
export declare function attemptNameProblem(value: unknown): string | undefined;
|
|
20
|
+
/** `value` as a name, or a `TypeError` that names `where` and `field` (never the value). */
|
|
21
|
+
export declare function admitAttemptName(where: string, field: string, value: unknown): string;
|