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
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* attempt/call.ts — a call made INSIDE a stage attempt: `scope.$call(target, fn, policy?)` (design §3.6, §3.8,
|
|
4
|
+
* packet P2).
|
|
5
|
+
*
|
|
6
|
+
* The same loop as a stage's retry (`runAttempts`, law 1), kind `'call'`, its `target` on every record — and a
|
|
7
|
+
* record even for a single call (`attempts: 1`): timing and outcome evidence with no retry. Its series is the
|
|
8
|
+
* call level of foottrace's attempt-id grammar ({@link callSeries}).
|
|
9
|
+
*
|
|
10
|
+
* THE LAW — a call lives within the attempt that made it. The host (the stage's scope) hands it that attempt's
|
|
11
|
+
* signal and its end as the call's deadline, so the call is capped by the time its stage attempt has left, and is
|
|
12
|
+
* cut when the stage attempt is cut (a time limit, so `'timeout'`; a cancellation, so `'aborted'`); and an `ended`
|
|
13
|
+
* signal that aborts when the attempt is over however it ended (it returned, threw, or its frame committed), so a
|
|
14
|
+
* call never outlives it. Following the P1b fence:
|
|
15
|
+
* - the record of a call attempt cut BY its stage attempt's own abort lands — the cut is evidence;
|
|
16
|
+
* - any other record that arrives once the stage attempt is over is REFUSED: noted by name (`host.refused`), never
|
|
17
|
+
* kept, never fired; the call stops (its in-flight attempt is cut, a wait ends) and no further attempt of an
|
|
18
|
+
* outside call starts — and the library-made rejection of such an orphan never surfaces as an unhandled one;
|
|
19
|
+
* - a call never starts under a signal already aborted, nor past its deadline while that signal is still due (a
|
|
20
|
+
* busy event loop fires timers late): no attempt, no record — the host's signal is its ONE deadline source.
|
|
21
|
+
* What the call's function does after its attempt ended cannot be trapped — it should RETURN its answer, not write
|
|
22
|
+
* the stage's scope (the scope's own fence still refuses a write from an ended stage attempt).
|
|
23
|
+
*
|
|
24
|
+
* A LEAF of the engine (L5): the host is a port, so nothing here names the scope.
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.runCall = exports.callSeries = void 0;
|
|
28
|
+
const anySignal_js_1 = require("./anySignal.js");
|
|
29
|
+
const deadline_js_1 = require("./deadline.js");
|
|
30
|
+
const runner_js_1 = require("./runner.js");
|
|
31
|
+
/**
|
|
32
|
+
* The series of the `ordinal`-th call (1-based) made during attempt `stageAttempt` of the stage execution
|
|
33
|
+
* `runtimeStageId`: `<runtimeStageId>@<n>.<k>` — so the id of the call's attempt `m` is `<series>@<m>`, foottrace's
|
|
34
|
+
* `buildAttemptId(runtimeStageId, n, { ordinal: k, attempt: m })` (design §3.4). Written here, in this one place,
|
|
35
|
+
* until the engine adopts foottrace 1.1.0's codec (P6); the bytes are the grammar's.
|
|
36
|
+
*/
|
|
37
|
+
function callSeries(runtimeStageId, stageAttempt, ordinal) {
|
|
38
|
+
return `${runtimeStageId}@${stageAttempt}.${ordinal}`;
|
|
39
|
+
}
|
|
40
|
+
exports.callSeries = callSeries;
|
|
41
|
+
/**
|
|
42
|
+
* Run `fn` as the call `target` under `policy` (already admitted — `policy.ts · admitCallPolicy`) for `host`.
|
|
43
|
+
* Resolves with the answer, or rejects with the last attempt's own error.
|
|
44
|
+
*/
|
|
45
|
+
function runCall(target, fn, policy, host) {
|
|
46
|
+
const hostSignal = host.signal;
|
|
47
|
+
const now = host.now ?? Date.now;
|
|
48
|
+
// Started under an aborted signal, or after the attempt that makes it ended: no attempt, no record.
|
|
49
|
+
for (const signal of [hostSignal, host.ended])
|
|
50
|
+
if (signal?.aborted)
|
|
51
|
+
return Promise.reject(signal.reason);
|
|
52
|
+
const stop = new AbortController();
|
|
53
|
+
// ONE deadline source. A host's signal aborts at the host's deadline (its attempt's cap, or the run's deadline),
|
|
54
|
+
// so a second timer for the same instant could only race it — and, firing first, end the call with a reason of
|
|
55
|
+
// its own and fail the stage instead of timing it out. A host with a deadline and no signal gets the one timer.
|
|
56
|
+
const own = hostSignal === undefined
|
|
57
|
+
? (0, deadline_js_1.armDeadline)(undefined, host.deadline, lateCallMessage(target, undefined, 'ran out of time'), now)
|
|
58
|
+
: undefined;
|
|
59
|
+
const composed = (0, anySignal_js_1.anySignal)([hostSignal, host.ended, own?.signal, stop.signal]);
|
|
60
|
+
// An orphan — a call still running when the attempt that made it ended — is stopped by the library, so its
|
|
61
|
+
// rejection must not surface as an unhandled one; whoever awaits it still gets it.
|
|
62
|
+
let result;
|
|
63
|
+
const quiet = () => {
|
|
64
|
+
result?.catch(() => undefined);
|
|
65
|
+
};
|
|
66
|
+
host.ended?.addEventListener('abort', quiet, { once: true });
|
|
67
|
+
const release = () => {
|
|
68
|
+
host.ended?.removeEventListener('abort', quiet);
|
|
69
|
+
own?.dispose();
|
|
70
|
+
composed.dispose();
|
|
71
|
+
};
|
|
72
|
+
if (composed.signal.aborted) {
|
|
73
|
+
release();
|
|
74
|
+
return Promise.reject(composed.signal.reason);
|
|
75
|
+
}
|
|
76
|
+
// Past the deadline while its signal is still due (a busy event loop fires timers late): nothing is sent — the
|
|
77
|
+
// call ends, with no record, when that signal aborts.
|
|
78
|
+
if (host.deadline !== undefined && now() >= host.deadline) {
|
|
79
|
+
result = new Promise((_resolve, reject) => {
|
|
80
|
+
composed.signal.addEventListener('abort', () => {
|
|
81
|
+
release();
|
|
82
|
+
reject(composed.signal.reason);
|
|
83
|
+
}, { once: true });
|
|
84
|
+
});
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
const seriesName = host.openSeries();
|
|
88
|
+
/** Call attempts ended BY the stage attempt's end — their records are the evidence of the cut. */
|
|
89
|
+
const cut = new Set();
|
|
90
|
+
const ended = () => new Error(lateCallMessage(target, seriesName, 'cannot continue'));
|
|
91
|
+
const series = (0, runner_js_1.runAttempts)((_attempt, context) => {
|
|
92
|
+
// The attempt that made this call is over: no further attempt of an outside call starts.
|
|
93
|
+
if (!host.admits(false)) {
|
|
94
|
+
const reason = ended();
|
|
95
|
+
stop.abort(reason);
|
|
96
|
+
throw reason;
|
|
97
|
+
}
|
|
98
|
+
return fn(context);
|
|
99
|
+
}, policy, {
|
|
100
|
+
series: seriesName,
|
|
101
|
+
kind: 'call',
|
|
102
|
+
target,
|
|
103
|
+
...(host.effect !== undefined && { effect: host.effect }),
|
|
104
|
+
signal: composed.signal,
|
|
105
|
+
...(host.deadline !== undefined && { deadline: host.deadline }),
|
|
106
|
+
now,
|
|
107
|
+
serve: (error) => host.serve(error),
|
|
108
|
+
// Synchronous at the abort: the stage attempt's signal aborting is what cut this call attempt.
|
|
109
|
+
onAbandon: (attempt) => {
|
|
110
|
+
if (hostSignal?.aborted)
|
|
111
|
+
cut.add(attempt);
|
|
112
|
+
},
|
|
113
|
+
onAttempt: (record, structuredError) => {
|
|
114
|
+
if (host.admits(cut.has(record.attempt))) {
|
|
115
|
+
host.report(record, structuredError);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
host.refused();
|
|
119
|
+
// Nothing follows a refused record: a wait ends now and the series stops `aborted`.
|
|
120
|
+
if (!stop.signal.aborted)
|
|
121
|
+
stop.abort(ended());
|
|
122
|
+
},
|
|
123
|
+
observe: (report, at) => host.observe(report, at),
|
|
124
|
+
});
|
|
125
|
+
result = series.finally(release);
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
exports.runCall = runCall;
|
|
129
|
+
/** Why a call stopped or could not go on — its target and series are names; no value is in the message. */
|
|
130
|
+
function lateCallMessage(target, series, what) {
|
|
131
|
+
return (`[footprint] $call "${target}"${series === undefined ? '' : ` (${series})`} ${what}: the attempt that made this ` +
|
|
132
|
+
'call has ended — no further attempt of it starts, and nothing it records lands on the stage.');
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvYXR0ZW1wdC9jYWxsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7OztBQUdILGlEQUEyQztBQUMzQywrQ0FBNEM7QUFFNUMsMkNBQTBDO0FBRzFDOzs7OztHQUtHO0FBQ0gsU0FBZ0IsVUFBVSxDQUFDLGNBQXNCLEVBQUUsWUFBb0IsRUFBRSxPQUFlO0lBQ3RGLE9BQU8sR0FBRyxjQUFjLElBQUksWUFBWSxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ3hELENBQUM7QUFGRCxnQ0FFQztBQWlERDs7O0dBR0c7QUFDSCxTQUFnQixPQUFPLENBQ3JCLE1BQWMsRUFDZCxFQUErQyxFQUMvQyxNQUFtQixFQUNuQixJQUFjO0lBRWQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUMvQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDakMsb0dBQW9HO0lBQ3BHLEtBQUssTUFBTSxNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUFFLElBQUksTUFBTSxFQUFFLE9BQU87WUFBRSxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pHLE1BQU0sSUFBSSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDbkMsaUhBQWlIO0lBQ2pILCtHQUErRztJQUMvRyxnSEFBZ0g7SUFDaEgsTUFBTSxHQUFHLEdBQ1AsVUFBVSxLQUFLLFNBQVM7UUFDdEIsQ0FBQyxDQUFDLElBQUEseUJBQVcsRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLEdBQUcsQ0FBQztRQUNuRyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2hCLE1BQU0sUUFBUSxHQUFHLElBQUEsd0JBQVMsRUFBQyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDL0UsMkdBQTJHO0lBQzNHLG1GQUFtRjtJQUNuRixJQUFJLE1BQThCLENBQUM7SUFDbkMsTUFBTSxLQUFLLEdBQUcsR0FBRyxFQUFFO1FBQ2pCLE1BQU0sRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakMsQ0FBQyxDQUFDO0lBQ0YsSUFBSSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0QsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFO1FBQ25CLElBQUksQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hELEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNmLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNyQixDQUFDLENBQUM7SUFDRixJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDNUIsT0FBTyxFQUFFLENBQUM7UUFDVixPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsK0dBQStHO0lBQy9HLHNEQUFzRDtJQUN0RCxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxJQUFJLEdBQUcsRUFBRSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMxRCxNQUFNLEdBQUcsSUFBSSxPQUFPLENBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDM0MsUUFBUSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FDOUIsT0FBTyxFQUNQLEdBQUcsRUFBRTtnQkFDSCxPQUFPLEVBQUUsQ0FBQztnQkFDVixNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNqQyxDQUFDLEVBQ0QsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQ2YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNyQyxrR0FBa0c7SUFDbEcsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUM5QixNQUFNLEtBQUssR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7SUFDdEYsTUFBTSxNQUFNLEdBQUcsSUFBQSx1QkFBVyxFQUN4QixDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUNwQix5RkFBeUY7UUFDekYsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixNQUFNLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ25CLE1BQU0sTUFBTSxDQUFDO1FBQ2YsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3JCLENBQUMsRUFDRCxNQUFNLEVBQ047UUFDRSxNQUFNLEVBQUUsVUFBVTtRQUNsQixJQUFJLEVBQUUsTUFBTTtRQUNaLE1BQU07UUFDTixHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3pELE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtRQUN2QixHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQy9ELEdBQUc7UUFDSCxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ25DLCtGQUErRjtRQUMvRixTQUFTLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLFVBQVUsRUFBRSxPQUFPO2dCQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUMsQ0FBQztRQUNELFNBQVMsRUFBRSxDQUFDLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRTtZQUNyQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQztnQkFDckMsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixvRkFBb0Y7WUFDcEYsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztLQUNsRCxDQUNGLENBQUM7SUFDRixNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBN0ZELDBCQTZGQztBQUVELDJHQUEyRztBQUMzRyxTQUFTLGVBQWUsQ0FBQyxNQUFjLEVBQUUsTUFBMEIsRUFBRSxJQUFZO0lBQy9FLE9BQU8sQ0FDTCxzQkFBc0IsTUFBTSxJQUFJLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLCtCQUErQjtRQUNqSCw4RkFBOEYsQ0FDL0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvY2FsbC50cyDigJQgYSBjYWxsIG1hZGUgSU5TSURFIGEgc3RhZ2UgYXR0ZW1wdDogYHNjb3BlLiRjYWxsKHRhcmdldCwgZm4sIHBvbGljeT8pYCAoZGVzaWduIMKnMy42LCDCpzMuOCxcbiAqIHBhY2tldCBQMikuXG4gKlxuICogVGhlIHNhbWUgbG9vcCBhcyBhIHN0YWdlJ3MgcmV0cnkgKGBydW5BdHRlbXB0c2AsIGxhdyAxKSwga2luZCBgJ2NhbGwnYCwgaXRzIGB0YXJnZXRgIG9uIGV2ZXJ5IHJlY29yZCDigJQgYW5kIGFcbiAqIHJlY29yZCBldmVuIGZvciBhIHNpbmdsZSBjYWxsIChgYXR0ZW1wdHM6IDFgKTogdGltaW5nIGFuZCBvdXRjb21lIGV2aWRlbmNlIHdpdGggbm8gcmV0cnkuIEl0cyBzZXJpZXMgaXMgdGhlXG4gKiBjYWxsIGxldmVsIG9mIGZvb3R0cmFjZSdzIGF0dGVtcHQtaWQgZ3JhbW1hciAoe0BsaW5rIGNhbGxTZXJpZXN9KS5cbiAqXG4gKiBUSEUgTEFXIOKAlCBhIGNhbGwgbGl2ZXMgd2l0aGluIHRoZSBhdHRlbXB0IHRoYXQgbWFkZSBpdC4gVGhlIGhvc3QgKHRoZSBzdGFnZSdzIHNjb3BlKSBoYW5kcyBpdCB0aGF0IGF0dGVtcHQnc1xuICogc2lnbmFsIGFuZCBpdHMgZW5kIGFzIHRoZSBjYWxsJ3MgZGVhZGxpbmUsIHNvIHRoZSBjYWxsIGlzIGNhcHBlZCBieSB0aGUgdGltZSBpdHMgc3RhZ2UgYXR0ZW1wdCBoYXMgbGVmdCwgYW5kIGlzXG4gKiBjdXQgd2hlbiB0aGUgc3RhZ2UgYXR0ZW1wdCBpcyBjdXQgKGEgdGltZSBsaW1pdCwgc28gYCd0aW1lb3V0J2A7IGEgY2FuY2VsbGF0aW9uLCBzbyBgJ2Fib3J0ZWQnYCk7IGFuZCBhbiBgZW5kZWRgXG4gKiBzaWduYWwgdGhhdCBhYm9ydHMgd2hlbiB0aGUgYXR0ZW1wdCBpcyBvdmVyIGhvd2V2ZXIgaXQgZW5kZWQgKGl0IHJldHVybmVkLCB0aHJldywgb3IgaXRzIGZyYW1lIGNvbW1pdHRlZCksIHNvIGFcbiAqIGNhbGwgbmV2ZXIgb3V0bGl2ZXMgaXQuIEZvbGxvd2luZyB0aGUgUDFiIGZlbmNlOlxuICogICAtIHRoZSByZWNvcmQgb2YgYSBjYWxsIGF0dGVtcHQgY3V0IEJZIGl0cyBzdGFnZSBhdHRlbXB0J3Mgb3duIGFib3J0IGxhbmRzIOKAlCB0aGUgY3V0IGlzIGV2aWRlbmNlO1xuICogICAtIGFueSBvdGhlciByZWNvcmQgdGhhdCBhcnJpdmVzIG9uY2UgdGhlIHN0YWdlIGF0dGVtcHQgaXMgb3ZlciBpcyBSRUZVU0VEOiBub3RlZCBieSBuYW1lIChgaG9zdC5yZWZ1c2VkYCksIG5ldmVyXG4gKiAgICAga2VwdCwgbmV2ZXIgZmlyZWQ7IHRoZSBjYWxsIHN0b3BzIChpdHMgaW4tZmxpZ2h0IGF0dGVtcHQgaXMgY3V0LCBhIHdhaXQgZW5kcykgYW5kIG5vIGZ1cnRoZXIgYXR0ZW1wdCBvZiBhblxuICogICAgIG91dHNpZGUgY2FsbCBzdGFydHMg4oCUIGFuZCB0aGUgbGlicmFyeS1tYWRlIHJlamVjdGlvbiBvZiBzdWNoIGFuIG9ycGhhbiBuZXZlciBzdXJmYWNlcyBhcyBhbiB1bmhhbmRsZWQgb25lO1xuICogICAtIGEgY2FsbCBuZXZlciBzdGFydHMgdW5kZXIgYSBzaWduYWwgYWxyZWFkeSBhYm9ydGVkLCBub3IgcGFzdCBpdHMgZGVhZGxpbmUgd2hpbGUgdGhhdCBzaWduYWwgaXMgc3RpbGwgZHVlIChhXG4gKiAgICAgYnVzeSBldmVudCBsb29wIGZpcmVzIHRpbWVycyBsYXRlKTogbm8gYXR0ZW1wdCwgbm8gcmVjb3JkIOKAlCB0aGUgaG9zdCdzIHNpZ25hbCBpcyBpdHMgT05FIGRlYWRsaW5lIHNvdXJjZS5cbiAqIFdoYXQgdGhlIGNhbGwncyBmdW5jdGlvbiBkb2VzIGFmdGVyIGl0cyBhdHRlbXB0IGVuZGVkIGNhbm5vdCBiZSB0cmFwcGVkIOKAlCBpdCBzaG91bGQgUkVUVVJOIGl0cyBhbnN3ZXIsIG5vdCB3cml0ZVxuICogdGhlIHN0YWdlJ3Mgc2NvcGUgKHRoZSBzY29wZSdzIG93biBmZW5jZSBzdGlsbCByZWZ1c2VzIGEgd3JpdGUgZnJvbSBhbiBlbmRlZCBzdGFnZSBhdHRlbXB0KS5cbiAqXG4gKiBBIExFQUYgb2YgdGhlIGVuZ2luZSAoTDUpOiB0aGUgaG9zdCBpcyBhIHBvcnQsIHNvIG5vdGhpbmcgaGVyZSBuYW1lcyB0aGUgc2NvcGUuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBTdHJ1Y3R1cmVkRXJyb3JJbmZvIH0gZnJvbSAnLi4vZXJyb3JzL2Vycm9ySW5mby5qcyc7XG5pbXBvcnQgeyBhbnlTaWduYWwgfSBmcm9tICcuL2FueVNpZ25hbC5qcyc7XG5pbXBvcnQgeyBhcm1EZWFkbGluZSB9IGZyb20gJy4vZGVhZGxpbmUuanMnO1xuaW1wb3J0IHR5cGUgeyBFZmZlY3RUYXJnZXQgfSBmcm9tICcuL2VmZmVjdC5qcyc7XG5pbXBvcnQgeyBydW5BdHRlbXB0cyB9IGZyb20gJy4vcnVubmVyLmpzJztcbmltcG9ydCB0eXBlIHsgQXR0ZW1wdENvbnRleHQsIEF0dGVtcHRSZWNvcmQsIE9ic2VydmVkQXR0ZW1wdCwgUmV0cnlQb2xpY3kgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBUaGUgc2VyaWVzIG9mIHRoZSBgb3JkaW5hbGAtdGggY2FsbCAoMS1iYXNlZCkgbWFkZSBkdXJpbmcgYXR0ZW1wdCBgc3RhZ2VBdHRlbXB0YCBvZiB0aGUgc3RhZ2UgZXhlY3V0aW9uXG4gKiBgcnVudGltZVN0YWdlSWRgOiBgPHJ1bnRpbWVTdGFnZUlkPkA8bj4uPGs+YCDigJQgc28gdGhlIGlkIG9mIHRoZSBjYWxsJ3MgYXR0ZW1wdCBgbWAgaXMgYDxzZXJpZXM+QDxtPmAsIGZvb3R0cmFjZSdzXG4gKiBgYnVpbGRBdHRlbXB0SWQocnVudGltZVN0YWdlSWQsIG4sIHsgb3JkaW5hbDogaywgYXR0ZW1wdDogbSB9KWAgKGRlc2lnbiDCpzMuNCkuIFdyaXR0ZW4gaGVyZSwgaW4gdGhpcyBvbmUgcGxhY2UsXG4gKiB1bnRpbCB0aGUgZW5naW5lIGFkb3B0cyBmb290dHJhY2UgMS4xLjAncyBjb2RlYyAoUDYpOyB0aGUgYnl0ZXMgYXJlIHRoZSBncmFtbWFyJ3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxsU2VyaWVzKHJ1bnRpbWVTdGFnZUlkOiBzdHJpbmcsIHN0YWdlQXR0ZW1wdDogbnVtYmVyLCBvcmRpbmFsOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7cnVudGltZVN0YWdlSWR9QCR7c3RhZ2VBdHRlbXB0fS4ke29yZGluYWx9YDtcbn1cblxuLyoqIFdoYXQgdGhlIGF0dGVtcHQgdGhhdCBtYWtlcyBhIGNhbGwgZ2l2ZXMgaXQg4oCUIHRoZSBzY29wZSBpbXBsZW1lbnRzIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBDYWxsSG9zdCB7XG4gIC8qKlxuICAgKiBUaGUgY2FsbCdzIHNlcmllcyAoe0BsaW5rIGNhbGxTZXJpZXN9KSDigJQgYXNrZWQgb25jZSwgb25seSB3aGVuIHRoZSBjYWxsIHN0YXJ0cywgc28gYSBjYWxsIHJlZnVzZWQgYmVmb3JlIGl0XG4gICAqIHN0YXJ0cyB0YWtlcyBubyBvcmRpbmFsIGFuZCBsZWF2ZXMgbm8gZ2FwLlxuICAgKi9cbiAgb3BlblNlcmllcygpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgc3RhZ2UgYXR0ZW1wdCdzIHNpZ25hbDogdGhlIHJ1bidzIGNhbmNlbGxhdGlvbiwgdGhlIHJ1bidzIGRlYWRsaW5lIGFuZCB0aGUgYXR0ZW1wdCdzIG93biBjYXAuIFdoZW4gZ2l2ZW4sIGl0XG4gICAqIGlzIHRoZSBjYWxsJ3MgT05FIGRlYWRsaW5lIHNvdXJjZSDigJQgaXQgbXVzdCBhYm9ydCBhdCB7QGxpbmsgZGVhZGxpbmV9LCB3aXRoIGEgdGltZS1saW1pdCByZWFzb25cbiAgICogKGBkZWFkbGluZS50cyDCtyBtYXJrVGltZUxpbWl0YCAvIGBkZWFkbGluZVJlYXNvbmApOyB0aGUgY2FsbCBhcm1zIG5vIHRpbWVyIG9mIGl0cyBvd24uXG4gICAqL1xuICByZWFkb25seSBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgLyoqXG4gICAqIFdoZW4gdGhlIHN0YWdlIGF0dGVtcHQgbXVzdCBlbmQsIGVwb2NoIG1zIOKAlCB0aGUgY2FsbCdzIGRlYWRsaW5lLCBjYXBwaW5nIGVhY2ggYXR0ZW1wdCBieSB0aGUgdGltZSBsZWZ0LiBBYnNlbnRcbiAgICogZm9yIGFuIHVuY2FwcGVkIGF0dGVtcHQuIFdpdGhvdXQgYSB7QGxpbmsgc2lnbmFsfSwgdGhlIGNhbGwgYXJtcyB0aGUgb25lIHRpbWVyIHRoYXQgZW5kcyBpdCBoZXJlLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVhZGxpbmU/OiBudW1iZXI7XG4gIC8qKiBUaGUgY2xvY2sgKGRlZmF1bHQgYERhdGUubm93YCkuICovXG4gIHJlYWRvbmx5IG5vdz86ICgpID0+IG51bWJlcjtcbiAgLyoqXG4gICAqIEFib3J0cyB3aGVuIHRoZSBhdHRlbXB0IHRoYXQgbWFrZXMgdGhlIGNhbGwgaXMgb3ZlciDigJQgaG93ZXZlciBpdCBlbmRlZCDigJQgYW5kIHdoZW4gaXRzIGZyYW1lIGNvbW1pdHM6IHRoZSBjYWxsXG4gICAqIHN0b3BzIChpdHMgaW4tZmxpZ2h0IGF0dGVtcHQgaXMgY3V0LCBhIHdhaXQgZW5kcywgbm8gYXR0ZW1wdCBmb2xsb3dzKSBhbmQgaXRzIHJlY29yZHMgYXJlIHJlZnVzZWQuIE5vIGNhbGxcbiAgICogb3V0bGl2ZXMgdGhlIGF0dGVtcHQgdGhhdCBtYWRlIGl0LlxuICAgKi9cbiAgcmVhZG9ubHkgZW5kZWQ/OiBBYm9ydFNpZ25hbDtcbiAgLyoqXG4gICAqIE1heSBhIHJlY29yZCBvZiB0aGUgY2FsbCBsYW5kIG9uIHRoZSBzdGFnZSBub3c/IGBjdXRgOiB0aGUgY2FsbCBhdHRlbXB0IHdhcyBlbmRlZCBCWSB0aGUgc3RhZ2UgYXR0ZW1wdCdzIG93blxuICAgKiBlbmQsIHNvIGl0cyByZWNvcmQgaXMgdGhlIGV2aWRlbmNlIG9mIHRoYXQgY3V0LlxuICAgKi9cbiAgYWRtaXRzKGN1dDogYm9vbGVhbik6IGJvb2xlYW47XG4gIC8qKiBUaGUgc2VydmVkIGZvcm0gb2YgYW4gYXR0ZW1wdCdzIGVycm9yIOKAlCB0aGUgcnVuJ3MgcmVkYWN0aW9uIHJ1bGUuICovXG4gIHNlcnZlKGVycm9yOiB1bmtub3duKTogU3RydWN0dXJlZEVycm9ySW5mbztcbiAgLyoqIEEgcmVjb3JkIHRoYXQgbWF5IGxhbmQ6IG9udG8gdGhlIHN0YWdlLCBhbmQgdGhlIHJ1bidzIGBvbkF0dGVtcHRgLiAqL1xuICByZXBvcnQocmVjb3JkOiBBdHRlbXB0UmVjb3JkLCBzdHJ1Y3R1cmVkRXJyb3I6IFN0cnVjdHVyZWRFcnJvckluZm8gfCB1bmRlZmluZWQpOiB2b2lkO1xuICAvKiogQSByZWNvcmQgdGhhdCBtYXkgbm90IOKAlCB0aGUgY2FsbCBvdXRsaXZlZCB0aGUgYXR0ZW1wdCB0aGF0IG1hZGUgaXQuIEEgbmFtZSBpcyBub3RlZDsgbm90aGluZyBpcyBrZXB0LiAqL1xuICByZWZ1c2VkKCk6IHZvaWQ7XG4gIC8qKlxuICAgKiBUaGUgb3V0c2lkZSBzeXN0ZW0gdGhlIGNhbGwgdG91Y2hlcyBhbmQgaXRzIGtleSAoUDMpIOKAlCBhZG1pdHRlZCBhdCB0aGUgY2FsbCAoYGVmZmVjdC50cyDCtyBjYWxsVG91Y2hlc2ApLCB0aGVcbiAgICogcmVjb3JkZWQga2V5IHNlcnZlZCB1bmRlciB0aGUgcnVuJ3MgcnVsZS4gRXZlcnkgcmVjb3JkIHRoZW4gY2FycmllcyBpdHMgYGVmZmVjdGAsIGFuZCBhIHNlcmllcyBlbmRlZCB3aXRob3V0IGFuIGFuc3dlciBhZnRlciBhbiBhdHRlbXB0IG9mIHVua25vd25cbiAgICogZWZmZWN0IHJlamVjdHMgd2l0aCBgVW5rbm93bkVmZmVjdEVycm9yYC5cbiAgICovXG4gIHJlYWRvbmx5IGVmZmVjdD86IEVmZmVjdFRhcmdldDtcbiAgLyoqIEFuIG9ic2VydmVkIHJlcG9ydCBtYWRlIHRocm91Z2ggdGhlIGNhbGwncyBvd24gYXR0ZW1wdCBjb250ZXh0IChgZW5kZWRgOiB0aGF0IGNhbGwgYXR0ZW1wdCB3YXMgb3ZlcikuICovXG4gIG9ic2VydmUocmVwb3J0OiBPYnNlcnZlZEF0dGVtcHQsIGF0OiB7IHJlYWRvbmx5IGF0dGVtcHQ6IG51bWJlcjsgcmVhZG9ubHkgZW5kZWQ6IGJvb2xlYW4gfSk6IHZvaWQ7XG59XG5cbi8qKlxuICogUnVuIGBmbmAgYXMgdGhlIGNhbGwgYHRhcmdldGAgdW5kZXIgYHBvbGljeWAgKGFscmVhZHkgYWRtaXR0ZWQg4oCUIGBwb2xpY3kudHMgwrcgYWRtaXRDYWxsUG9saWN5YCkgZm9yIGBob3N0YC5cbiAqIFJlc29sdmVzIHdpdGggdGhlIGFuc3dlciwgb3IgcmVqZWN0cyB3aXRoIHRoZSBsYXN0IGF0dGVtcHQncyBvd24gZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5DYWxsPFQ+KFxuICB0YXJnZXQ6IHN0cmluZyxcbiAgZm46IChhdHRlbXB0OiBBdHRlbXB0Q29udGV4dCkgPT4gUHJvbWlzZTxUPiB8IFQsXG4gIHBvbGljeTogUmV0cnlQb2xpY3ksXG4gIGhvc3Q6IENhbGxIb3N0LFxuKTogUHJvbWlzZTxUPiB7XG4gIGNvbnN0IGhvc3RTaWduYWwgPSBob3N0LnNpZ25hbDtcbiAgY29uc3Qgbm93ID0gaG9zdC5ub3cgPz8gRGF0ZS5ub3c7XG4gIC8vIFN0YXJ0ZWQgdW5kZXIgYW4gYWJvcnRlZCBzaWduYWwsIG9yIGFmdGVyIHRoZSBhdHRlbXB0IHRoYXQgbWFrZXMgaXQgZW5kZWQ6IG5vIGF0dGVtcHQsIG5vIHJlY29yZC5cbiAgZm9yIChjb25zdCBzaWduYWwgb2YgW2hvc3RTaWduYWwsIGhvc3QuZW5kZWRdKSBpZiAoc2lnbmFsPy5hYm9ydGVkKSByZXR1cm4gUHJvbWlzZS5yZWplY3Qoc2lnbmFsLnJlYXNvbik7XG4gIGNvbnN0IHN0b3AgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIC8vIE9ORSBkZWFkbGluZSBzb3VyY2UuIEEgaG9zdCdzIHNpZ25hbCBhYm9ydHMgYXQgdGhlIGhvc3QncyBkZWFkbGluZSAoaXRzIGF0dGVtcHQncyBjYXAsIG9yIHRoZSBydW4ncyBkZWFkbGluZSksXG4gIC8vIHNvIGEgc2Vjb25kIHRpbWVyIGZvciB0aGUgc2FtZSBpbnN0YW50IGNvdWxkIG9ubHkgcmFjZSBpdCDigJQgYW5kLCBmaXJpbmcgZmlyc3QsIGVuZCB0aGUgY2FsbCB3aXRoIGEgcmVhc29uIG9mXG4gIC8vIGl0cyBvd24gYW5kIGZhaWwgdGhlIHN0YWdlIGluc3RlYWQgb2YgdGltaW5nIGl0IG91dC4gQSBob3N0IHdpdGggYSBkZWFkbGluZSBhbmQgbm8gc2lnbmFsIGdldHMgdGhlIG9uZSB0aW1lci5cbiAgY29uc3Qgb3duID1cbiAgICBob3N0U2lnbmFsID09PSB1bmRlZmluZWRcbiAgICAgID8gYXJtRGVhZGxpbmUodW5kZWZpbmVkLCBob3N0LmRlYWRsaW5lLCBsYXRlQ2FsbE1lc3NhZ2UodGFyZ2V0LCB1bmRlZmluZWQsICdyYW4gb3V0IG9mIHRpbWUnKSwgbm93KVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGNvbXBvc2VkID0gYW55U2lnbmFsKFtob3N0U2lnbmFsLCBob3N0LmVuZGVkLCBvd24/LnNpZ25hbCwgc3RvcC5zaWduYWxdKTtcbiAgLy8gQW4gb3JwaGFuIOKAlCBhIGNhbGwgc3RpbGwgcnVubmluZyB3aGVuIHRoZSBhdHRlbXB0IHRoYXQgbWFkZSBpdCBlbmRlZCDigJQgaXMgc3RvcHBlZCBieSB0aGUgbGlicmFyeSwgc28gaXRzXG4gIC8vIHJlamVjdGlvbiBtdXN0IG5vdCBzdXJmYWNlIGFzIGFuIHVuaGFuZGxlZCBvbmU7IHdob2V2ZXIgYXdhaXRzIGl0IHN0aWxsIGdldHMgaXQuXG4gIGxldCByZXN1bHQ6IFByb21pc2U8VD4gfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHF1aWV0ID0gKCkgPT4ge1xuICAgIHJlc3VsdD8uY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgfTtcbiAgaG9zdC5lbmRlZD8uYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBxdWlldCwgeyBvbmNlOiB0cnVlIH0pO1xuICBjb25zdCByZWxlYXNlID0gKCkgPT4ge1xuICAgIGhvc3QuZW5kZWQ/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgcXVpZXQpO1xuICAgIG93bj8uZGlzcG9zZSgpO1xuICAgIGNvbXBvc2VkLmRpc3Bvc2UoKTtcbiAgfTtcbiAgaWYgKGNvbXBvc2VkLnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgcmVsZWFzZSgpO1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChjb21wb3NlZC5zaWduYWwucmVhc29uKTtcbiAgfVxuICAvLyBQYXN0IHRoZSBkZWFkbGluZSB3aGlsZSBpdHMgc2lnbmFsIGlzIHN0aWxsIGR1ZSAoYSBidXN5IGV2ZW50IGxvb3AgZmlyZXMgdGltZXJzIGxhdGUpOiBub3RoaW5nIGlzIHNlbnQg4oCUIHRoZVxuICAvLyBjYWxsIGVuZHMsIHdpdGggbm8gcmVjb3JkLCB3aGVuIHRoYXQgc2lnbmFsIGFib3J0cy5cbiAgaWYgKGhvc3QuZGVhZGxpbmUgIT09IHVuZGVmaW5lZCAmJiBub3coKSA+PSBob3N0LmRlYWRsaW5lKSB7XG4gICAgcmVzdWx0ID0gbmV3IFByb21pc2U8VD4oKF9yZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbXBvc2VkLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAnYWJvcnQnLFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgcmVsZWFzZSgpO1xuICAgICAgICAgIHJlamVjdChjb21wb3NlZC5zaWduYWwucmVhc29uKTtcbiAgICAgICAgfSxcbiAgICAgICAgeyBvbmNlOiB0cnVlIH0sXG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBjb25zdCBzZXJpZXNOYW1lID0gaG9zdC5vcGVuU2VyaWVzKCk7XG4gIC8qKiBDYWxsIGF0dGVtcHRzIGVuZGVkIEJZIHRoZSBzdGFnZSBhdHRlbXB0J3MgZW5kIOKAlCB0aGVpciByZWNvcmRzIGFyZSB0aGUgZXZpZGVuY2Ugb2YgdGhlIGN1dC4gKi9cbiAgY29uc3QgY3V0ID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIGNvbnN0IGVuZGVkID0gKCkgPT4gbmV3IEVycm9yKGxhdGVDYWxsTWVzc2FnZSh0YXJnZXQsIHNlcmllc05hbWUsICdjYW5ub3QgY29udGludWUnKSk7XG4gIGNvbnN0IHNlcmllcyA9IHJ1bkF0dGVtcHRzPFQ+KFxuICAgIChfYXR0ZW1wdCwgY29udGV4dCkgPT4ge1xuICAgICAgLy8gVGhlIGF0dGVtcHQgdGhhdCBtYWRlIHRoaXMgY2FsbCBpcyBvdmVyOiBubyBmdXJ0aGVyIGF0dGVtcHQgb2YgYW4gb3V0c2lkZSBjYWxsIHN0YXJ0cy5cbiAgICAgIGlmICghaG9zdC5hZG1pdHMoZmFsc2UpKSB7XG4gICAgICAgIGNvbnN0IHJlYXNvbiA9IGVuZGVkKCk7XG4gICAgICAgIHN0b3AuYWJvcnQocmVhc29uKTtcbiAgICAgICAgdGhyb3cgcmVhc29uO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZuKGNvbnRleHQpO1xuICAgIH0sXG4gICAgcG9saWN5LFxuICAgIHtcbiAgICAgIHNlcmllczogc2VyaWVzTmFtZSxcbiAgICAgIGtpbmQ6ICdjYWxsJyxcbiAgICAgIHRhcmdldCxcbiAgICAgIC4uLihob3N0LmVmZmVjdCAhPT0gdW5kZWZpbmVkICYmIHsgZWZmZWN0OiBob3N0LmVmZmVjdCB9KSxcbiAgICAgIHNpZ25hbDogY29tcG9zZWQuc2lnbmFsLFxuICAgICAgLi4uKGhvc3QuZGVhZGxpbmUgIT09IHVuZGVmaW5lZCAmJiB7IGRlYWRsaW5lOiBob3N0LmRlYWRsaW5lIH0pLFxuICAgICAgbm93LFxuICAgICAgc2VydmU6IChlcnJvcikgPT4gaG9zdC5zZXJ2ZShlcnJvciksXG4gICAgICAvLyBTeW5jaHJvbm91cyBhdCB0aGUgYWJvcnQ6IHRoZSBzdGFnZSBhdHRlbXB0J3Mgc2lnbmFsIGFib3J0aW5nIGlzIHdoYXQgY3V0IHRoaXMgY2FsbCBhdHRlbXB0LlxuICAgICAgb25BYmFuZG9uOiAoYXR0ZW1wdCkgPT4ge1xuICAgICAgICBpZiAoaG9zdFNpZ25hbD8uYWJvcnRlZCkgY3V0LmFkZChhdHRlbXB0KTtcbiAgICAgIH0sXG4gICAgICBvbkF0dGVtcHQ6IChyZWNvcmQsIHN0cnVjdHVyZWRFcnJvcikgPT4ge1xuICAgICAgICBpZiAoaG9zdC5hZG1pdHMoY3V0LmhhcyhyZWNvcmQuYXR0ZW1wdCkpKSB7XG4gICAgICAgICAgaG9zdC5yZXBvcnQocmVjb3JkLCBzdHJ1Y3R1cmVkRXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBob3N0LnJlZnVzZWQoKTtcbiAgICAgICAgLy8gTm90aGluZyBmb2xsb3dzIGEgcmVmdXNlZCByZWNvcmQ6IGEgd2FpdCBlbmRzIG5vdyBhbmQgdGhlIHNlcmllcyBzdG9wcyBgYWJvcnRlZGAuXG4gICAgICAgIGlmICghc3RvcC5zaWduYWwuYWJvcnRlZCkgc3RvcC5hYm9ydChlbmRlZCgpKTtcbiAgICAgIH0sXG4gICAgICBvYnNlcnZlOiAocmVwb3J0LCBhdCkgPT4gaG9zdC5vYnNlcnZlKHJlcG9ydCwgYXQpLFxuICAgIH0sXG4gICk7XG4gIHJlc3VsdCA9IHNlcmllcy5maW5hbGx5KHJlbGVhc2UpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKiogV2h5IGEgY2FsbCBzdG9wcGVkIG9yIGNvdWxkIG5vdCBnbyBvbiDigJQgaXRzIHRhcmdldCBhbmQgc2VyaWVzIGFyZSBuYW1lczsgbm8gdmFsdWUgaXMgaW4gdGhlIG1lc3NhZ2UuICovXG5mdW5jdGlvbiBsYXRlQ2FsbE1lc3NhZ2UodGFyZ2V0OiBzdHJpbmcsIHNlcmllczogc3RyaW5nIHwgdW5kZWZpbmVkLCB3aGF0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gKFxuICAgIGBbZm9vdHByaW50XSAkY2FsbCBcIiR7dGFyZ2V0fVwiJHtzZXJpZXMgPT09IHVuZGVmaW5lZCA/ICcnIDogYCAoJHtzZXJpZXN9KWB9ICR7d2hhdH06IHRoZSBhdHRlbXB0IHRoYXQgbWFkZSB0aGlzIGAgK1xuICAgICdjYWxsIGhhcyBlbmRlZCDigJQgbm8gZnVydGhlciBhdHRlbXB0IG9mIGl0IHN0YXJ0cywgYW5kIG5vdGhpbmcgaXQgcmVjb3JkcyBsYW5kcyBvbiB0aGUgc3RhZ2UuJ1xuICApO1xufVxuIl19
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* attempt/category.ts — `errorCategory`, the ONE failure classifier (design §3.9).
|
|
4
|
+
*
|
|
5
|
+
* Seven fixed values, so every recorder — the narrative, the metric layer, an agent's own — breaks failures down
|
|
6
|
+
* the same way; a recorder never invents a category of its own. Borrowed from agentfootprint's
|
|
7
|
+
* `classifyRetryReason` and widened, so its decorators adopt this one rather than keep theirs.
|
|
8
|
+
*
|
|
9
|
+
* Category is EVIDENCE, never policy: the default `retryOn` retries every category. A chart that wants "never
|
|
10
|
+
* retry a permanent failure" says so: `retryOn: (e) => errorCategory(e) !== 'permanent'`.
|
|
11
|
+
*
|
|
12
|
+
* Precedence — what the failure LOOKED like wins over what it declares:
|
|
13
|
+
* 1. the attempt's own timer (outcome `'timeout'`, or our `AttemptTimeoutError`) → timeout
|
|
14
|
+
* 2. the run's signal ended it (outcome `'aborted'`) → unknown
|
|
15
|
+
* 3. status 429, or a declared `retryAfterMs` / `retryAfterSeconds` → rate-limited
|
|
16
|
+
* 4. status 5xx → server
|
|
17
|
+
* 5. status 401 / 403 → auth
|
|
18
|
+
* 6. any other 4xx → permanent
|
|
19
|
+
* 7. `retryable: false`, or a validation error → permanent
|
|
20
|
+
* 8. a transport failure (a socket code on the error or its cause, a fetch
|
|
21
|
+
* `TypeError`, an `AbortError` / `TimeoutError` that was not the run's) → network
|
|
22
|
+
* 9. anything else → unknown
|
|
23
|
+
*
|
|
24
|
+
* A status is a NUMBER (`status` or `statusCode`); a numeric string is not read as one. Total: a value whose
|
|
25
|
+
* reads throw (a hostile Proxy) is `'unknown'`, never a second throw from an error path.
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.terminalCategory = exports.errorCategory = void 0;
|
|
29
|
+
const errors_js_1 = require("../schema/errors.js");
|
|
30
|
+
const errors_js_2 = require("./errors.js");
|
|
31
|
+
/** Socket-level codes a transport failure carries (Node's `errno` names). */
|
|
32
|
+
const NETWORK_CODES = new Set([
|
|
33
|
+
'ECONNRESET',
|
|
34
|
+
'ECONNREFUSED',
|
|
35
|
+
'ENOTFOUND',
|
|
36
|
+
'ETIMEDOUT',
|
|
37
|
+
'EAI_AGAIN',
|
|
38
|
+
'EPIPE',
|
|
39
|
+
]);
|
|
40
|
+
/** The messages runtimes give a `fetch` that never reached the server (Node, Chromium, Firefox, Safari). */
|
|
41
|
+
const FETCH_FAILURE = /^(fetch failed|failed to fetch|networkerror when attempting to fetch resource\.?|load failed)$/i;
|
|
42
|
+
/** Error names that say a validation failed — retrying the same input cannot succeed. */
|
|
43
|
+
const VALIDATION_NAMES = new Set(['ValidationError', 'ZodError', 'InputValidationError']);
|
|
44
|
+
/** Error names of an abort or a timeout that some OTHER signal raised (the run's own ends as outcome `'aborted'`). */
|
|
45
|
+
const TRANSPORT_ABORT_NAMES = new Set(['AbortError', 'TimeoutError']);
|
|
46
|
+
/**
|
|
47
|
+
* The category of an attempt's failure. `outcome` is how the attempt ended (default `'failed'`): it decides
|
|
48
|
+
* `'timeout'` (the attempt's own timer) and `'unknown'` (the run's signal) before the error is read.
|
|
49
|
+
*/
|
|
50
|
+
function errorCategory(error, outcome = 'failed') {
|
|
51
|
+
if (outcome === 'timeout')
|
|
52
|
+
return 'timeout';
|
|
53
|
+
if (outcome === 'aborted')
|
|
54
|
+
return 'unknown';
|
|
55
|
+
try {
|
|
56
|
+
return categoryOf(error);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return 'unknown';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.errorCategory = errorCategory;
|
|
63
|
+
/**
|
|
64
|
+
* @internal Terminal ownership preserves a producer's known category. An
|
|
65
|
+
* unresolved effect is unknown, never the category of its physical cause.
|
|
66
|
+
* This does not rewrite historical attempt categories or re-read a known one.
|
|
67
|
+
*/
|
|
68
|
+
function terminalCategory(error, known) {
|
|
69
|
+
try {
|
|
70
|
+
if (error instanceof errors_js_2.UnknownEffectError)
|
|
71
|
+
return 'unknown';
|
|
72
|
+
// CJS and ESM have distinct constructors. A declared own DATA name may
|
|
73
|
+
// only reduce certainty to unknown; never execute an error's name getter
|
|
74
|
+
// or promote its physical cause to a known outcome across module copies.
|
|
75
|
+
if (error !== null && (typeof error === 'object' || typeof error === 'function')) {
|
|
76
|
+
const name = Object.getOwnPropertyDescriptor(error, 'name');
|
|
77
|
+
if (name && Object.prototype.hasOwnProperty.call(name, 'value') && name.value === 'UnknownEffectError') {
|
|
78
|
+
return 'unknown';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return known ?? 'unknown';
|
|
84
|
+
}
|
|
85
|
+
return known ?? errorCategory(error);
|
|
86
|
+
}
|
|
87
|
+
exports.terminalCategory = terminalCategory;
|
|
88
|
+
function categoryOf(error) {
|
|
89
|
+
if (error instanceof errors_js_2.AttemptTimeoutError)
|
|
90
|
+
return 'timeout';
|
|
91
|
+
if (error === null || (typeof error !== 'object' && typeof error !== 'function'))
|
|
92
|
+
return 'unknown';
|
|
93
|
+
const fields = error;
|
|
94
|
+
const status = numberField(fields, 'status') ?? numberField(fields, 'statusCode');
|
|
95
|
+
const declaresRetryAfter = isWait(fields.retryAfterMs) || isWait(fields.retryAfterSeconds);
|
|
96
|
+
if (status === 429 || declaresRetryAfter)
|
|
97
|
+
return 'rate-limited';
|
|
98
|
+
if (status !== undefined && status >= 500 && status <= 599)
|
|
99
|
+
return 'server';
|
|
100
|
+
if (status === 401 || status === 403)
|
|
101
|
+
return 'auth';
|
|
102
|
+
if (status !== undefined && status >= 400 && status <= 499)
|
|
103
|
+
return 'permanent';
|
|
104
|
+
if (fields.retryable === false)
|
|
105
|
+
return 'permanent';
|
|
106
|
+
if (error instanceof errors_js_1.InputValidationError)
|
|
107
|
+
return 'permanent';
|
|
108
|
+
const name = typeof fields.name === 'string' ? fields.name : undefined;
|
|
109
|
+
if (name !== undefined && VALIDATION_NAMES.has(name))
|
|
110
|
+
return 'permanent';
|
|
111
|
+
if (status === undefined && isTransportFailure(fields, name))
|
|
112
|
+
return 'network';
|
|
113
|
+
return 'unknown';
|
|
114
|
+
}
|
|
115
|
+
function isTransportFailure(fields, name) {
|
|
116
|
+
if (hasNetworkCode(fields.code))
|
|
117
|
+
return true;
|
|
118
|
+
const cause = fields.cause;
|
|
119
|
+
if (cause !== null && typeof cause === 'object' && hasNetworkCode(cause.code)) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (name !== undefined && TRANSPORT_ABORT_NAMES.has(name))
|
|
123
|
+
return true;
|
|
124
|
+
return fields instanceof TypeError && typeof fields.message === 'string' && FETCH_FAILURE.test(fields.message);
|
|
125
|
+
}
|
|
126
|
+
function hasNetworkCode(code) {
|
|
127
|
+
return typeof code === 'string' && NETWORK_CODES.has(code);
|
|
128
|
+
}
|
|
129
|
+
function numberField(fields, key) {
|
|
130
|
+
const value = fields[key];
|
|
131
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
132
|
+
}
|
|
133
|
+
function isWait(value) {
|
|
134
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0ZWdvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2F0dGVtcHQvY2F0ZWdvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7OztBQUVILG1EQUEyRDtBQUMzRCwyQ0FBc0U7QUFHdEUsNkVBQTZFO0FBQzdFLE1BQU0sYUFBYSxHQUF3QixJQUFJLEdBQUcsQ0FBQztJQUNqRCxZQUFZO0lBQ1osY0FBYztJQUNkLFdBQVc7SUFDWCxXQUFXO0lBQ1gsV0FBVztJQUNYLE9BQU87Q0FDUixDQUFDLENBQUM7QUFFSCw0R0FBNEc7QUFDNUcsTUFBTSxhQUFhLEdBQUcsaUdBQWlHLENBQUM7QUFFeEgseUZBQXlGO0FBQ3pGLE1BQU0sZ0JBQWdCLEdBQXdCLElBQUksR0FBRyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsVUFBVSxFQUFFLHNCQUFzQixDQUFDLENBQUMsQ0FBQztBQUUvRyxzSEFBc0g7QUFDdEgsTUFBTSxxQkFBcUIsR0FBd0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQztBQUUzRjs7O0dBR0c7QUFDSCxTQUFnQixhQUFhLENBQUMsS0FBYyxFQUFFLFVBQTBCLFFBQVE7SUFDOUUsSUFBSSxPQUFPLEtBQUssU0FBUztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzVDLElBQUksT0FBTyxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM1QyxJQUFJLENBQUM7UUFDSCxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUM7QUFSRCxzQ0FRQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxLQUFjLEVBQUUsS0FBdUI7SUFDdEUsSUFBSSxDQUFDO1FBQ0gsSUFBSSxL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QUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxjQUFjLENBQUUsS0FBaUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzNHLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELElBQUksSUFBSSxLQUFLLFNBQVMsSUFBSSxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkUsT0FBTyxNQUFNLFlBQVksU0FBUyxJQUFJLE9BQU8sTUFBTSxDQUFDLE9BQU8sS0FBSyxRQUFRLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDakgsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLElBQWE7SUFDbkMsT0FBTyxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsTUFBK0IsRUFBRSxHQUE0QjtJQUNoRixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUIsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDakYsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFDLEtBQWM7SUFDNUIsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDO0FBQzNFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvY2F0ZWdvcnkudHMg4oCUIGBlcnJvckNhdGVnb3J5YCwgdGhlIE9ORSBmYWlsdXJlIGNsYXNzaWZpZXIgKGRlc2lnbiDCpzMuOSkuXG4gKlxuICogU2V2ZW4gZml4ZWQgdmFsdWVzLCBzbyBldmVyeSByZWNvcmRlciDigJQgdGhlIG5hcnJhdGl2ZSwgdGhlIG1ldHJpYyBsYXllciwgYW4gYWdlbnQncyBvd24g4oCUIGJyZWFrcyBmYWlsdXJlcyBkb3duXG4gKiB0aGUgc2FtZSB3YXk7IGEgcmVjb3JkZXIgbmV2ZXIgaW52ZW50cyBhIGNhdGVnb3J5IG9mIGl0cyBvd24uIEJvcnJvd2VkIGZyb20gYWdlbnRmb290cHJpbnQnc1xuICogYGNsYXNzaWZ5UmV0cnlSZWFzb25gIGFuZCB3aWRlbmVkLCBzbyBpdHMgZGVjb3JhdG9ycyBhZG9wdCB0aGlzIG9uZSByYXRoZXIgdGhhbiBrZWVwIHRoZWlycy5cbiAqXG4gKiBDYXRlZ29yeSBpcyBFVklERU5DRSwgbmV2ZXIgcG9saWN5OiB0aGUgZGVmYXVsdCBgcmV0cnlPbmAgcmV0cmllcyBldmVyeSBjYXRlZ29yeS4gQSBjaGFydCB0aGF0IHdhbnRzIFwibmV2ZXJcbiAqIHJldHJ5IGEgcGVybWFuZW50IGZhaWx1cmVcIiBzYXlzIHNvOiBgcmV0cnlPbjogKGUpID0+IGVycm9yQ2F0ZWdvcnkoZSkgIT09ICdwZXJtYW5lbnQnYC5cbiAqXG4gKiBQcmVjZWRlbmNlIOKAlCB3aGF0IHRoZSBmYWlsdXJlIExPT0tFRCBsaWtlIHdpbnMgb3ZlciB3aGF0IGl0IGRlY2xhcmVzOlxuICogICAxLiB0aGUgYXR0ZW1wdCdzIG93biB0aW1lciAob3V0Y29tZSBgJ3RpbWVvdXQnYCwgb3Igb3VyIGBBdHRlbXB0VGltZW91dEVycm9yYCkgIOKGkiB0aW1lb3V0XG4gKiAgIDIuIHRoZSBydW4ncyBzaWduYWwgZW5kZWQgaXQgKG91dGNvbWUgYCdhYm9ydGVkJ2ApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4oaSIHVua25vd25cbiAqICAgMy4gc3RhdHVzIDQyOSwgb3IgYSBkZWNsYXJlZCBgcmV0cnlBZnRlck1zYCAvIGByZXRyeUFmdGVyU2Vjb25kc2AgICAgICAgICAgICAgICDihpIgcmF0ZS1saW1pdGVkXG4gKiAgIDQuIHN0YXR1cyA1eHggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4oaSIHNlcnZlclxuICogICA1LiBzdGF0dXMgNDAxIC8gNDAzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKGkiBhdXRoXG4gKiAgIDYuIGFueSBvdGhlciA0eHggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4oaSIHBlcm1hbmVudFxuICogICA3LiBgcmV0cnlhYmxlOiBmYWxzZWAsIG9yIGEgdmFsaWRhdGlvbiBlcnJvciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKGkiBwZXJtYW5lbnRcbiAqICAgOC4gYSB0cmFuc3BvcnQgZmFpbHVyZSAoYSBzb2NrZXQgY29kZSBvbiB0aGUgZXJyb3Igb3IgaXRzIGNhdXNlLCBhIGZldGNoXG4gKiAgICAgIGBUeXBlRXJyb3JgLCBhbiBgQWJvcnRFcnJvcmAgLyBgVGltZW91dEVycm9yYCB0aGF0IHdhcyBub3QgdGhlIHJ1bidzKSAgICAgICAg4oaSIG5ldHdvcmtcbiAqICAgOS4gYW55dGhpbmcgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDihpIgdW5rbm93blxuICpcbiAqIEEgc3RhdHVzIGlzIGEgTlVNQkVSIChgc3RhdHVzYCBvciBgc3RhdHVzQ29kZWApOyBhIG51bWVyaWMgc3RyaW5nIGlzIG5vdCByZWFkIGFzIG9uZS4gVG90YWw6IGEgdmFsdWUgd2hvc2VcbiAqIHJlYWRzIHRocm93IChhIGhvc3RpbGUgUHJveHkpIGlzIGAndW5rbm93bidgLCBuZXZlciBhIHNlY29uZCB0aHJvdyBmcm9tIGFuIGVycm9yIHBhdGguXG4gKi9cblxuaW1wb3J0IHsgSW5wdXRWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuLi9zY2hlbWEvZXJyb3JzLmpzJztcbmltcG9ydCB7IEF0dGVtcHRUaW1lb3V0RXJyb3IsIFVua25vd25FZmZlY3RFcnJvciB9IGZyb20gJy4vZXJyb3JzLmpzJztcbmltcG9ydCB0eXBlIHsgQXR0ZW1wdENhdGVnb3J5LCBBdHRlbXB0T3V0Y29tZSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKiogU29ja2V0LWxldmVsIGNvZGVzIGEgdHJhbnNwb3J0IGZhaWx1cmUgY2FycmllcyAoTm9kZSdzIGBlcnJub2AgbmFtZXMpLiAqL1xuY29uc3QgTkVUV09SS19DT0RFUzogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoW1xuICAnRUNPTk5SRVNFVCcsXG4gICdFQ09OTlJFRlVTRUQnLFxuICAnRU5PVEZPVU5EJyxcbiAgJ0VUSU1FRE9VVCcsXG4gICdFQUlfQUdBSU4nLFxuICAnRVBJUEUnLFxuXSk7XG5cbi8qKiBUaGUgbWVzc2FnZXMgcnVudGltZXMgZ2l2ZSBhIGBmZXRjaGAgdGhhdCBuZXZlciByZWFjaGVkIHRoZSBzZXJ2ZXIgKE5vZGUsIENocm9taXVtLCBGaXJlZm94LCBTYWZhcmkpLiAqL1xuY29uc3QgRkVUQ0hfRkFJTFVSRSA9IC9eKGZldGNoIGZhaWxlZHxmYWlsZWQgdG8gZmV0Y2h8bmV0d29ya2Vycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBmZXRjaCByZXNvdXJjZVxcLj98bG9hZCBmYWlsZWQpJC9pO1xuXG4vKiogRXJyb3IgbmFtZXMgdGhhdCBzYXkgYSB2YWxpZGF0aW9uIGZhaWxlZCDigJQgcmV0cnlpbmcgdGhlIHNhbWUgaW5wdXQgY2Fubm90IHN1Y2NlZWQuICovXG5jb25zdCBWQUxJREFUSU9OX05BTUVTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldChbJ1ZhbGlkYXRpb25FcnJvcicsICdab2RFcnJvcicsICdJbnB1dFZhbGlkYXRpb25FcnJvciddKTtcblxuLyoqIEVycm9yIG5hbWVzIG9mIGFuIGFib3J0IG9yIGEgdGltZW91dCB0aGF0IHNvbWUgT1RIRVIgc2lnbmFsIHJhaXNlZCAodGhlIHJ1bidzIG93biBlbmRzIGFzIG91dGNvbWUgYCdhYm9ydGVkJ2ApLiAqL1xuY29uc3QgVFJBTlNQT1JUX0FCT1JUX05BTUVTOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldChbJ0Fib3J0RXJyb3InLCAnVGltZW91dEVycm9yJ10pO1xuXG4vKipcbiAqIFRoZSBjYXRlZ29yeSBvZiBhbiBhdHRlbXB0J3MgZmFpbHVyZS4gYG91dGNvbWVgIGlzIGhvdyB0aGUgYXR0ZW1wdCBlbmRlZCAoZGVmYXVsdCBgJ2ZhaWxlZCdgKTogaXQgZGVjaWRlc1xuICogYCd0aW1lb3V0J2AgKHRoZSBhdHRlbXB0J3Mgb3duIHRpbWVyKSBhbmQgYCd1bmtub3duJ2AgKHRoZSBydW4ncyBzaWduYWwpIGJlZm9yZSB0aGUgZXJyb3IgaXMgcmVhZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVycm9yQ2F0ZWdvcnkoZXJyb3I6IHVua25vd24sIG91dGNvbWU6IEF0dGVtcHRPdXRjb21lID0gJ2ZhaWxlZCcpOiBBdHRlbXB0Q2F0ZWdvcnkge1xuICBpZiAob3V0Y29tZSA9PT0gJ3RpbWVvdXQnKSByZXR1cm4gJ3RpbWVvdXQnO1xuICBpZiAob3V0Y29tZSA9PT0gJ2Fib3J0ZWQnKSByZXR1cm4gJ3Vua25vd24nO1xuICB0cnkge1xuICAgIHJldHVybiBjYXRlZ29yeU9mKGVycm9yKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuICd1bmtub3duJztcbiAgfVxufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBUZXJtaW5hbCBvd25lcnNoaXAgcHJlc2VydmVzIGEgcHJvZHVjZXIncyBrbm93biBjYXRlZ29yeS4gQW5cbiAqIHVucmVzb2x2ZWQgZWZmZWN0IGlzIHVua25vd24sIG5ldmVyIHRoZSBjYXRlZ29yeSBvZiBpdHMgcGh5c2ljYWwgY2F1c2UuXG4gKiBUaGlzIGRvZXMgbm90IHJld3JpdGUgaGlzdG9yaWNhbCBhdHRlbXB0IGNhdGVnb3JpZXMgb3IgcmUtcmVhZCBhIGtub3duIG9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRlcm1pbmFsQ2F0ZWdvcnkoZXJyb3I6IHVua25vd24sIGtub3duPzogQXR0ZW1wdENhdGVnb3J5KTogQXR0ZW1wdENhdGVnb3J5IHtcbiAgdHJ5IHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBVbmtub3duRWZmZWN0RXJyb3IpIHJldHVybiAndW5rbm93bic7XG4gICAgLy8gQ0pTIGFuZCBFU00gaGF2ZSBkaXN0aW5jdCBjb25zdHJ1Y3RvcnMuIEEgZGVjbGFyZWQgb3duIERBVEEgbmFtZSBtYXlcbiAgICAvLyBvbmx5IHJlZHVjZSBjZXJ0YWludHkgdG8gdW5rbm93bjsgbmV2ZXIgZXhlY3V0ZSBhbiBlcnJvcidzIG5hbWUgZ2V0dGVyXG4gICAgLy8gb3IgcHJvbW90ZSBpdHMgcGh5c2ljYWwgY2F1c2UgdG8gYSBrbm93biBvdXRjb21lIGFjcm9zcyBtb2R1bGUgY29waWVzLlxuICAgIGlmIChlcnJvciAhPT0gbnVsbCAmJiAodHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyB8fCB0eXBlb2YgZXJyb3IgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgICBjb25zdCBuYW1lID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlcnJvciwgJ25hbWUnKTtcbiAgICAgIGlmIChuYW1lICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuYW1lLCAndmFsdWUnKSAmJiBuYW1lLnZhbHVlID09PSAnVW5rbm93bkVmZmVjdEVycm9yJykge1xuICAgICAgICByZXR1cm4gJ3Vua25vd24nO1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGtub3duID8/ICd1bmtub3duJztcbiAgfVxuICByZXR1cm4ga25vd24gPz8gZXJyb3JDYXRlZ29yeShlcnJvcik7XG59XG5cbmZ1bmN0aW9uIGNhdGVnb3J5T2YoZXJyb3I6IHVua25vd24pOiBBdHRlbXB0Q2F0ZWdvcnkge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBdHRlbXB0VGltZW91dEVycm9yKSByZXR1cm4gJ3RpbWVvdXQnO1xuICBpZiAoZXJyb3IgPT09IG51bGwgfHwgKHR5cGVvZiBlcnJvciAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIGVycm9yICE9PSAnZnVuY3Rpb24nKSkgcmV0dXJuICd1bmtub3duJztcbiAgY29uc3QgZmllbGRzID0gZXJyb3IgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgY29uc3Qgc3RhdHVzID0gbnVtYmVyRmllbGQoZmllbGRzLCAnc3RhdHVzJykgPz8gbnVtYmVyRmllbGQoZmllbGRzLCAnc3RhdHVzQ29kZScpO1xuICBjb25zdCBkZWNsYXJlc1JldHJ5QWZ0ZXIgPSBpc1dhaXQoZmllbGRzLnJldHJ5QWZ0ZXJNcykgfHwgaXNXYWl0KGZpZWxkcy5yZXRyeUFmdGVyU2Vjb25kcyk7XG4gIGlmIChzdGF0dXMgPT09IDQyOSB8fCBkZWNsYXJlc1JldHJ5QWZ0ZXIpIHJldHVybiAncmF0ZS1saW1pdGVkJztcbiAgaWYgKHN0YXR1cyAhPT0gdW5kZWZpbmVkICYmIHN0YXR1cyA+PSA1MDAgJiYgc3RhdHVzIDw9IDU5OSkgcmV0dXJuICdzZXJ2ZXInO1xuICBpZiAoc3RhdHVzID09PSA0MDEgfHwgc3RhdHVzID09PSA0MDMpIHJldHVybiAnYXV0aCc7XG4gIGlmIChzdGF0dXMgIT09IHVuZGVmaW5lZCAmJiBzdGF0dXMgPj0gNDAwICYmIHN0YXR1cyA8PSA0OTkpIHJldHVybiAncGVybWFuZW50JztcblxuICBpZiAoZmllbGRzLnJldHJ5YWJsZSA9PT0gZmFsc2UpIHJldHVybiAncGVybWFuZW50JztcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgSW5wdXRWYWxpZGF0aW9uRXJyb3IpIHJldHVybiAncGVybWFuZW50JztcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBmaWVsZHMubmFtZSA9PT0gJ3N0cmluZycgPyBmaWVsZHMubmFtZSA6IHVuZGVmaW5lZDtcbiAgaWYgKG5hbWUgIT09IHVuZGVmaW5lZCAmJiBWQUxJREFUSU9OX05BTUVTLmhhcyhuYW1lKSkgcmV0dXJuICdwZXJtYW5lbnQnO1xuXG4gIGlmIChzdGF0dXMgPT09IHVuZGVmaW5lZCAmJiBpc1RyYW5zcG9ydEZhaWx1cmUoZmllbGRzLCBuYW1lKSkgcmV0dXJuICduZXR3b3JrJztcbiAgcmV0dXJuICd1bmtub3duJztcbn1cblxuZnVuY3Rpb24gaXNUcmFuc3BvcnRGYWlsdXJlKGZpZWxkczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICBpZiAoaGFzTmV0d29ya0NvZGUoZmllbGRzLmNvZGUpKSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgY2F1c2UgPSBmaWVsZHMuY2F1c2U7XG4gIGlmIChjYXVzZSAhPT0gbnVsbCAmJiB0eXBlb2YgY2F1c2UgPT09ICdvYmplY3QnICYmIGhhc05ldHdvcmtDb2RlKChjYXVzZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuY29kZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAobmFtZSAhPT0gdW5kZWZpbmVkICYmIFRSQU5TUE9SVF9BQk9SVF9OQU1FUy5oYXMobmFtZSkpIHJldHVybiB0cnVlO1xuICByZXR1cm4gZmllbGRzIGluc3RhbmNlb2YgVHlwZUVycm9yICYmIHR5cGVvZiBmaWVsZHMubWVzc2FnZSA9PT0gJ3N0cmluZycgJiYgRkVUQ0hfRkFJTFVSRS50ZXN0KGZpZWxkcy5tZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gaGFzTmV0d29ya0NvZGUoY29kZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIGNvZGUgPT09ICdzdHJpbmcnICYmIE5FVFdPUktfQ09ERVMuaGFzKGNvZGUpO1xufVxuXG5mdW5jdGlvbiBudW1iZXJGaWVsZChmaWVsZHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBrZXk6ICdzdGF0dXMnIHwgJ3N0YXR1c0NvZGUnKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdmFsdWUgPSBmaWVsZHNba2V5XTtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc1dhaXQodmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAwO1xufVxuIl19
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* attempt/correlation.ts — the run's correlation: the W3C `traceparent` codec and the ONE resolution of the env
|
|
4
|
+
* into a `RunCorrelation` (design docs/design/2026-10-time-and-failure-evidence.md §3.4, packet P4).
|
|
5
|
+
*
|
|
6
|
+
* THREAT MODEL. A `traceparent` comes from whoever sent the request. So:
|
|
7
|
+
* - it is read STRICTLY to the W3C Trace Context grammar (`version-traceid-parentid-flags`, lowercase hex) and
|
|
8
|
+
* anything else is refused by a NAMED reason (`TraceparentError.reason`) — the message never repeats the
|
|
9
|
+
* header, and the error holds no copy of it;
|
|
10
|
+
* - what the run keeps is the canonical form of what was parsed (`formatTraceparent`), never the received
|
|
11
|
+
* bytes — a future version's tail is dropped;
|
|
12
|
+
* - it is correlation only: a name the record carries so a run can be found from a trace. Nothing in the
|
|
13
|
+
* library treats it as identity or authorisation.
|
|
14
|
+
*
|
|
15
|
+
* W3C forward compatibility: a version other than `00` (and never `ff`) is read by its first four fields; a
|
|
16
|
+
* longer header must continue with `-`. Version `00` is exactly 55 characters. A header longer than
|
|
17
|
+
* {@link MAX_HEADER_LENGTH} is refused before it is scanned.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.resolveCorrelation = exports.admitRunEnv = exports.formatTraceparent = exports.parseTraceparent = exports.TraceparentError = exports.MAX_HEADER_LENGTH = void 0;
|
|
21
|
+
/** The longest header read at all (a future version may append fields; nothing legitimate is near this). */
|
|
22
|
+
exports.MAX_HEADER_LENGTH = 256;
|
|
23
|
+
/** A version-00 header, exactly. */
|
|
24
|
+
const V00_LENGTH = 55;
|
|
25
|
+
const WHY = {
|
|
26
|
+
'not-a-string': 'it is not a string',
|
|
27
|
+
length: 'its length is not a W3C traceparent length (55 characters for version 00)',
|
|
28
|
+
version: 'its version is not two lowercase hex digits other than ff',
|
|
29
|
+
characters: 'it is not lowercase hex fields in the W3C layout version-traceid-parentid-flags',
|
|
30
|
+
'zero-trace-id': 'its trace-id is all zeros',
|
|
31
|
+
'zero-parent-id': 'its parent-id is all zeros',
|
|
32
|
+
};
|
|
33
|
+
/** A `traceparent` the library will not read. The header itself is never in the message or on the error. */
|
|
34
|
+
class TraceparentError extends Error {
|
|
35
|
+
reason;
|
|
36
|
+
constructor(reason) {
|
|
37
|
+
super(`traceparent refused (${reason}): ${WHY[reason]}`);
|
|
38
|
+
this.name = 'TraceparentError';
|
|
39
|
+
this.reason = reason;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.TraceparentError = TraceparentError;
|
|
43
|
+
const HEX2 = /^[0-9a-f]{2}$/;
|
|
44
|
+
const HEX16 = /^[0-9a-f]{16}$/;
|
|
45
|
+
const HEX32 = /^[0-9a-f]{32}$/;
|
|
46
|
+
const ZEROS = /^0+$/;
|
|
47
|
+
/**
|
|
48
|
+
* Parse a W3C `traceparent` header strictly. Returns a frozen {@link ParsedTraceparent}; throws a
|
|
49
|
+
* {@link TraceparentError} naming the first rule the header breaks.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* parseTraceparent('00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01');
|
|
53
|
+
* // { traceId: '4bf92f3577b34da6a3ce929d0e0e4736', operationId: '00f067aa0ba902b7', sampled: true, flags: '01' }
|
|
54
|
+
*/
|
|
55
|
+
function parseTraceparent(header) {
|
|
56
|
+
if (typeof header !== 'string')
|
|
57
|
+
throw new TraceparentError('not-a-string');
|
|
58
|
+
if (header.length < V00_LENGTH || header.length > exports.MAX_HEADER_LENGTH)
|
|
59
|
+
throw new TraceparentError('length');
|
|
60
|
+
const version = header.slice(0, 2);
|
|
61
|
+
if (!HEX2.test(version) || version === 'ff')
|
|
62
|
+
throw new TraceparentError('version');
|
|
63
|
+
if (version === '00' && header.length !== V00_LENGTH)
|
|
64
|
+
throw new TraceparentError('length');
|
|
65
|
+
const traceId = header.slice(3, 35);
|
|
66
|
+
const operationId = header.slice(36, 52);
|
|
67
|
+
const flags = header.slice(53, 55);
|
|
68
|
+
const laidOut = header[2] === '-' && header[35] === '-' && header[52] === '-';
|
|
69
|
+
const tailOk = header.length === V00_LENGTH || header[V00_LENGTH] === '-';
|
|
70
|
+
if (!laidOut || !tailOk || !HEX32.test(traceId) || !HEX16.test(operationId) || !HEX2.test(flags)) {
|
|
71
|
+
throw new TraceparentError('characters');
|
|
72
|
+
}
|
|
73
|
+
if (ZEROS.test(traceId))
|
|
74
|
+
throw new TraceparentError('zero-trace-id');
|
|
75
|
+
if (ZEROS.test(operationId))
|
|
76
|
+
throw new TraceparentError('zero-parent-id');
|
|
77
|
+
return Object.freeze({ traceId, operationId, sampled: (parseInt(flags, 16) & 1) === 1, flags });
|
|
78
|
+
}
|
|
79
|
+
exports.parseTraceparent = parseTraceparent;
|
|
80
|
+
/**
|
|
81
|
+
* Write a version-00 `traceparent` — for an outbound call that continues this run's trace. Both ids must be W3C
|
|
82
|
+
* ids and `flags` a byte of 2 lowercase hex (refused by name otherwise, like a parse); `sampled`, when given,
|
|
83
|
+
* sets or clears bit 0 of the flags. `formatTraceparent(parseTraceparent(h))` is `h` for any valid version-00 `h`.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* formatTraceparent({ traceId, operationId: mySpanId, sampled: true }); // '00-<traceId>-<mySpanId>-01'
|
|
87
|
+
*/
|
|
88
|
+
function formatTraceparent(fields) {
|
|
89
|
+
const { traceId, operationId } = fields;
|
|
90
|
+
if (typeof traceId !== 'string' || typeof operationId !== 'string')
|
|
91
|
+
throw new TraceparentError('not-a-string');
|
|
92
|
+
if (!HEX32.test(traceId) || !HEX16.test(operationId))
|
|
93
|
+
throw new TraceparentError('characters');
|
|
94
|
+
if (ZEROS.test(traceId))
|
|
95
|
+
throw new TraceparentError('zero-trace-id');
|
|
96
|
+
if (ZEROS.test(operationId))
|
|
97
|
+
throw new TraceparentError('zero-parent-id');
|
|
98
|
+
return `00-${traceId}-${operationId}-${flagsOf(fields)}`;
|
|
99
|
+
}
|
|
100
|
+
exports.formatTraceparent = formatTraceparent;
|
|
101
|
+
/** The trace-flags byte to write: the given one (or `00`), bit 0 set or cleared by `sampled` when it is given. */
|
|
102
|
+
function flagsOf(fields) {
|
|
103
|
+
const { flags = '00', sampled } = fields;
|
|
104
|
+
if (typeof flags !== 'string')
|
|
105
|
+
throw new TraceparentError('not-a-string');
|
|
106
|
+
if (!HEX2.test(flags))
|
|
107
|
+
throw new TraceparentError('characters');
|
|
108
|
+
if (sampled === undefined)
|
|
109
|
+
return flags;
|
|
110
|
+
const byte = sampled ? parseInt(flags, 16) | 1 : parseInt(flags, 16) & 0xfe;
|
|
111
|
+
return byte.toString(16).padStart(2, '0');
|
|
112
|
+
}
|
|
113
|
+
/** An explicit id: 1–256 printable ASCII characters, no space — a name a log line or an exporter can carry. */
|
|
114
|
+
const EXPLICIT_ID = /^[\x21-\x7e]{1,256}$/;
|
|
115
|
+
/**
|
|
116
|
+
* Admit a leg's env ONCE (called by `FlowChartExecutor · run` / `resume` before anything moves): a single
|
|
117
|
+
* own-property snapshot of it — every getter runs once, nothing is read off the prototype — and the correlation
|
|
118
|
+
* resolved from that snapshot. In the snapshot the stages see (`$getEnv()`), `traceparent` is exactly
|
|
119
|
+
* `correlation.traceparent` — the canonical header of the effective ids, or no key when the run's correlation has
|
|
120
|
+
* none — so stage code never holds the received bytes, nor a header naming another trace than the record.
|
|
121
|
+
* `env` is `undefined` exactly when none was given.
|
|
122
|
+
*/
|
|
123
|
+
function admitRunEnv(env) {
|
|
124
|
+
if (env === undefined || env === null)
|
|
125
|
+
return { env: undefined, correlation: undefined };
|
|
126
|
+
const snapshot = { ...env };
|
|
127
|
+
const correlation = resolveParsed(snapshot);
|
|
128
|
+
if (correlation?.traceparent !== undefined)
|
|
129
|
+
snapshot.traceparent = correlation.traceparent;
|
|
130
|
+
else if (snapshot.traceparent !== undefined)
|
|
131
|
+
delete snapshot.traceparent; // a header the record does not carry
|
|
132
|
+
return { env: snapshot, correlation };
|
|
133
|
+
}
|
|
134
|
+
exports.admitRunEnv = admitRunEnv;
|
|
135
|
+
/**
|
|
136
|
+
* The ONE resolution of a leg's correlation from its env. Only OWN fields count. `traceparent` is parsed once (a
|
|
137
|
+
* bad header refuses the leg — explicit ids do not rescue it); explicit `traceId` / `operationId` win over the
|
|
138
|
+
* header's and must be 1–256 printable ASCII characters (refused by field name, never echoed); an empty one is
|
|
139
|
+
* no id. Everything of the header — its parent-id as the operation, `sampled`, `traceparent` — rides only while
|
|
140
|
+
* the trace IS the header's, and `traceparent` is rebuilt from the EFFECTIVE ids with the header's flags
|
|
141
|
+
* (omitted when the operation is not a W3C parent-id), so the record never names one trace and files or
|
|
142
|
+
* propagates another's. Returns `undefined` when there is no trace id at all — and refuses
|
|
143
|
+
* an `operationId` with no trace to belong to.
|
|
144
|
+
*/
|
|
145
|
+
function resolveCorrelation(env) {
|
|
146
|
+
if (env === undefined || env === null)
|
|
147
|
+
return undefined;
|
|
148
|
+
return resolveParsed({ ...env });
|
|
149
|
+
}
|
|
150
|
+
exports.resolveCorrelation = resolveCorrelation;
|
|
151
|
+
/** {@link resolveCorrelation} over an env already snapshotted (each field read once). */
|
|
152
|
+
function resolveParsed(env) {
|
|
153
|
+
const raw = own(env, 'traceparent');
|
|
154
|
+
const header = raw === undefined ? undefined : parseTraceparent(raw);
|
|
155
|
+
const traceId = explicitId(own(env, 'traceId'), 'traceId') ?? header?.traceId;
|
|
156
|
+
const sameTrace = header !== undefined && traceId === header.traceId;
|
|
157
|
+
const operationId = explicitId(own(env, 'operationId'), 'operationId') ?? (sameTrace ? header.operationId : undefined);
|
|
158
|
+
if (traceId === undefined) {
|
|
159
|
+
if (operationId !== undefined) {
|
|
160
|
+
throw new TypeError('env.operationId needs a trace to belong to: give env.traceId or env.traceparent');
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
const propagable = sameTrace && operationId !== undefined && HEX16.test(operationId) && !ZEROS.test(operationId);
|
|
165
|
+
return Object.freeze({
|
|
166
|
+
traceId,
|
|
167
|
+
...(operationId !== undefined && { operationId }),
|
|
168
|
+
...(sameTrace && { sampled: header.sampled }),
|
|
169
|
+
...(propagable && { traceparent: formatTraceparent({ traceId, operationId, flags: header.flags }) }),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** An own field's value — a value inherited through the prototype is not the caller's. */
|
|
173
|
+
function own(env, field) {
|
|
174
|
+
return Object.prototype.hasOwnProperty.call(env, field) ? env[field] : undefined;
|
|
175
|
+
}
|
|
176
|
+
function explicitId(value, field) {
|
|
177
|
+
if (value === undefined || value === '')
|
|
178
|
+
return undefined;
|
|
179
|
+
if (typeof value !== 'string')
|
|
180
|
+
throw new TypeError(`env.${field} must be a string`);
|
|
181
|
+
if (!EXPLICIT_ID.test(value)) {
|
|
182
|
+
throw new TypeError(`env.${field} refused: an id is 1–256 printable ASCII characters with no space`);
|
|
183
|
+
}
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ycmVsYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2F0dGVtcHQvY29ycmVsYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHOzs7QUFvQ0gsNEdBQTRHO0FBQy9GLFFBQUEsaUJBQWlCLEdBQUcsR0FBRyxDQUFDO0FBQ3JDLG9DQUFvQztBQUNwQyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7QUFFdEIsTUFBTSxHQUFHLEdBQWlEO0lBQ3hELGNBQWMsRUFBRSxvQkFBb0I7SUFDcEMsTUFBTSxFQUFFLDJFQUEyRTtJQUNuRixPQUFPLEVBQUUsMkRBQTJEO0lBQ3BFLFVBQVUsRUFBRSxpRkFBaUY7SUFDN0YsZUFBZSxFQUFFLDJCQUEyQjtJQUM1QyxnQkFBZ0IsRUFBRSw0QkFBNEI7Q0FDL0MsQ0FBQztBQUVGLDRHQUE0RztBQUM1RyxNQUFhLGdCQUFpQixTQUFRLEtBQUs7SUFDaEMsTUFBTSxDQUFxQjtJQUVwQyxZQUFZLE1BQTBCO1FBQ3BDLEtBQUssQ0FBQyx3QkFBd0IsTUFBTSxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQztRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0NBQ0Y7QUFSRCw0Q0FRQztBQUVELE1BQU0sSUFBSSxHQUFHLGVBQWUsQ0FBQztBQUM3QixNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQztBQUMvQixNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQztBQUMvQixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUM7QUFFckI7Ozs7Ozs7R0FPRztBQUNILFNBQWdCLGdCQUFnQixDQUFDLE1BQWU7SUFDOUMsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRO1FBQUUsTUFBTSxJQUFJLGdCQUFnQixDQUFDLGNBQWMs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LFVBQVUsQ0FBQyxLQUFjLEVBQUUsS0FBZ0M7SUFDbEUsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxFQUFFO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDMUQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQyxPQUFPLEtBQUssbUJBQW1CLENBQUMsQ0FBQztJQUNwRixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sSUFBSSxTQUFTLENBQUMsT0FBTyxLQUFLLG1FQUFtRSxDQUFDLENBQUM7SUFDdkcsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYXR0ZW1wdC9jb3JyZWxhdGlvbi50cyDigJQgdGhlIHJ1bidzIGNvcnJlbGF0aW9uOiB0aGUgVzNDIGB0cmFjZXBhcmVudGAgY29kZWMgYW5kIHRoZSBPTkUgcmVzb2x1dGlvbiBvZiB0aGUgZW52XG4gKiBpbnRvIGEgYFJ1bkNvcnJlbGF0aW9uYCAoZGVzaWduIGRvY3MvZGVzaWduLzIwMjYtMTAtdGltZS1hbmQtZmFpbHVyZS1ldmlkZW5jZS5tZCDCpzMuNCwgcGFja2V0IFA0KS5cbiAqXG4gKiBUSFJFQVQgTU9ERUwuIEEgYHRyYWNlcGFyZW50YCBjb21lcyBmcm9tIHdob2V2ZXIgc2VudCB0aGUgcmVxdWVzdC4gU286XG4gKiAgIC0gaXQgaXMgcmVhZCBTVFJJQ1RMWSB0byB0aGUgVzNDIFRyYWNlIENvbnRleHQgZ3JhbW1hciAoYHZlcnNpb24tdHJhY2VpZC1wYXJlbnRpZC1mbGFnc2AsIGxvd2VyY2FzZSBoZXgpIGFuZFxuICogICAgIGFueXRoaW5nIGVsc2UgaXMgcmVmdXNlZCBieSBhIE5BTUVEIHJlYXNvbiAoYFRyYWNlcGFyZW50RXJyb3IucmVhc29uYCkg4oCUIHRoZSBtZXNzYWdlIG5ldmVyIHJlcGVhdHMgdGhlXG4gKiAgICAgaGVhZGVyLCBhbmQgdGhlIGVycm9yIGhvbGRzIG5vIGNvcHkgb2YgaXQ7XG4gKiAgIC0gd2hhdCB0aGUgcnVuIGtlZXBzIGlzIHRoZSBjYW5vbmljYWwgZm9ybSBvZiB3aGF0IHdhcyBwYXJzZWQgKGBmb3JtYXRUcmFjZXBhcmVudGApLCBuZXZlciB0aGUgcmVjZWl2ZWRcbiAqICAgICBieXRlcyDigJQgYSBmdXR1cmUgdmVyc2lvbidzIHRhaWwgaXMgZHJvcHBlZDtcbiAqICAgLSBpdCBpcyBjb3JyZWxhdGlvbiBvbmx5OiBhIG5hbWUgdGhlIHJlY29yZCBjYXJyaWVzIHNvIGEgcnVuIGNhbiBiZSBmb3VuZCBmcm9tIGEgdHJhY2UuIE5vdGhpbmcgaW4gdGhlXG4gKiAgICAgbGlicmFyeSB0cmVhdHMgaXQgYXMgaWRlbnRpdHkgb3IgYXV0aG9yaXNhdGlvbi5cbiAqXG4gKiBXM0MgZm9yd2FyZCBjb21wYXRpYmlsaXR5OiBhIHZlcnNpb24gb3RoZXIgdGhhbiBgMDBgIChhbmQgbmV2ZXIgYGZmYCkgaXMgcmVhZCBieSBpdHMgZmlyc3QgZm91ciBmaWVsZHM7IGFcbiAqIGxvbmdlciBoZWFkZXIgbXVzdCBjb250aW51ZSB3aXRoIGAtYC4gVmVyc2lvbiBgMDBgIGlzIGV4YWN0bHkgNTUgY2hhcmFjdGVycy4gQSBoZWFkZXIgbG9uZ2VyIHRoYW5cbiAqIHtAbGluayBNQVhfSEVBREVSX0xFTkdUSH0gaXMgcmVmdXNlZCBiZWZvcmUgaXQgaXMgc2Nhbm5lZC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFJ1bkNvcnJlbGF0aW9uIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKiBXaHkgYSBgdHJhY2VwYXJlbnRgIHdhcyByZWZ1c2VkIOKAlCBhIE5BTUUsIHNvIGEgY2FsbGVyIGNhbiBicmFuY2ggb24gaXQgd2l0aG91dCByZWFkaW5nIGEgbWVzc2FnZS4gKi9cbmV4cG9ydCB0eXBlIFRyYWNlcGFyZW50UmVmdXNhbCA9XG4gIHwgJ25vdC1hLXN0cmluZydcbiAgfCAnbGVuZ3RoJ1xuICB8ICd2ZXJzaW9uJ1xuICB8ICdjaGFyYWN0ZXJzJ1xuICB8ICd6ZXJvLXRyYWNlLWlkJ1xuICB8ICd6ZXJvLXBhcmVudC1pZCc7XG5cbi8qKiBBIHBhcnNlZCBgdHJhY2VwYXJlbnRgOiB0aGUgVzNDIHRyYWNlLWlkLCB0aGUgcGFyZW50LWlkICh0aGUgY2FsbGVyJ3MgdW5pdCBvZiB3b3JrKSwgYW5kIGl0cyB0cmFjZS1mbGFncy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VkVHJhY2VwYXJlbnQge1xuICAvKiogMzIgbG93ZXJjYXNlIGhleCwgbm90IGFsbCB6ZXJvcy4gKi9cbiAgcmVhZG9ubHkgdHJhY2VJZDogc3RyaW5nO1xuICAvKiogVGhlIFczQyBwYXJlbnQtaWQg4oCUIDE2IGxvd2VyY2FzZSBoZXgsIG5vdCBhbGwgemVyb3MuIFRoZSBsaWJyYXJ5J3Mgd29yZCBmb3IgaXQgaXMgXCJvcGVyYXRpb25cIi4gKi9cbiAgcmVhZG9ubHkgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgLyoqIEJpdCAwIG9mIGBmbGFnc2AuICovXG4gIHJlYWRvbmx5IHNhbXBsZWQ6IGJvb2xlYW47XG4gIC8qKiBUaGUgdHJhY2UtZmxhZ3MgYnl0ZSBhcyByZWNlaXZlZCDigJQgMiBsb3dlcmNhc2UgaGV4IOKAlCBzbyBhIHJlLWZvcm1hdCBrZWVwcyBldmVyeSBiaXQgKFczQyBsZXZlbCAyJ3MgcmFuZG9tKS4gKi9cbiAgcmVhZG9ubHkgZmxhZ3M6IHN0cmluZztcbn1cblxuLyoqXG4gKiBXaGF0IGBmb3JtYXRUcmFjZXBhcmVudGAgd3JpdGVzIGZyb20uIGBmbGFnc2AgKDIgbG93ZXJjYXNlIGhleCkgaXMgdGhlIHRyYWNlLWZsYWdzIGJ5dGUsIGAnMDAnYCB3aGVuIGFic2VudDtcbiAqIGBzYW1wbGVkYCwgd2hlbiBnaXZlbiwgc2V0cyBvciBjbGVhcnMgaXRzIGJpdCAwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRyYWNlcGFyZW50RmllbGRzIHtcbiAgcmVhZG9ubHkgdHJhY2VJZDogc3RyaW5nO1xuICByZWFkb25seSBvcGVyYXRpb25JZDogc3RyaW5nO1xuICByZWFkb25seSBzYW1wbGVkPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZmxhZ3M/OiBzdHJpbmc7XG59XG5cbi8qKiBUaGUgbG9uZ2VzdCBoZWFkZXIgcmVhZCBhdCBhbGwgKGEgZnV0dXJlIHZlcnNpb24gbWF5IGFwcGVuZCBmaWVsZHM7IG5vdGhpbmcgbGVnaXRpbWF0ZSBpcyBuZWFyIHRoaXMpLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9IRUFERVJfTEVOR1RIID0gMjU2O1xuLyoqIEEgdmVyc2lvbi0wMCBoZWFkZXIsIGV4YWN0bHkuICovXG5jb25zdCBWMDBfTEVOR1RIID0gNTU7XG5cbmNvbnN0IFdIWTogUmVhZG9ubHk8UmVjb3JkPFRyYWNlcGFyZW50UmVmdXNhbCwgc3RyaW5nPj4gPSB7XG4gICdub3QtYS1zdHJpbmcnOiAnaXQgaXMgbm90IGEgc3RyaW5nJyxcbiAgbGVuZ3RoOiAnaXRzIGxlbmd0aCBpcyBub3QgYSBXM0MgdHJhY2VwYXJlbnQgbGVuZ3RoICg1NSBjaGFyYWN0ZXJzIGZvciB2ZXJzaW9uIDAwKScsXG4gIHZlcnNpb246ICdpdHMgdmVyc2lvbiBpcyBub3QgdHdvIGxvd2VyY2FzZSBoZXggZGlnaXRzIG90aGVyIHRoYW4gZmYnLFxuICBjaGFyYWN0ZXJzOiAnaXQgaXMgbm90IGxvd2VyY2FzZSBoZXggZmllbGRzIGluIHRoZSBXM0MgbGF5b3V0IHZlcnNpb24tdHJhY2VpZC1wYXJlbnRpZC1mbGFncycsXG4gICd6ZXJvLXRyYWNlLWlkJzogJ2l0cyB0cmFjZS1pZCBpcyBhbGwgemVyb3MnLFxuICAnemVyby1wYXJlbnQtaWQnOiAnaXRzIHBhcmVudC1pZCBpcyBhbGwgemVyb3MnLFxufTtcblxuLyoqIEEgYHRyYWNlcGFyZW50YCB0aGUgbGlicmFyeSB3aWxsIG5vdCByZWFkLiBUaGUgaGVhZGVyIGl0c2VsZiBpcyBuZXZlciBpbiB0aGUgbWVzc2FnZSBvciBvbiB0aGUgZXJyb3IuICovXG5leHBvcnQgY2xhc3MgVHJhY2VwYXJlbnRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcmVhZG9ubHkgcmVhc29uOiBUcmFjZXBhcmVudFJlZnVzYWw7XG5cbiAgY29uc3RydWN0b3IocmVhc29uOiBUcmFjZXBhcmVudFJlZnVzYWwpIHtcbiAgICBzdXBlcihgdHJhY2VwYXJlbnQgcmVmdXNlZCAoJHtyZWFzb259KTogJHtXSFlbcmVhc29uXX1gKTtcbiAgICB0aGlzLm5hbWUgPSAnVHJhY2VwYXJlbnRFcnJvcic7XG4gICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gIH1cbn1cblxuY29uc3QgSEVYMiA9IC9eWzAtOWEtZl17Mn0kLztcbmNvbnN0IEhFWDE2ID0gL15bMC05YS1mXXsxNn0kLztcbmNvbnN0IEhFWDMyID0gL15bMC05YS1mXXszMn0kLztcbmNvbnN0IFpFUk9TID0gL14wKyQvO1xuXG4vKipcbiAqIFBhcnNlIGEgVzNDIGB0cmFjZXBhcmVudGAgaGVhZGVyIHN0cmljdGx5LiBSZXR1cm5zIGEgZnJvemVuIHtAbGluayBQYXJzZWRUcmFjZXBhcmVudH07IHRocm93cyBhXG4gKiB7QGxpbmsgVHJhY2VwYXJlbnRFcnJvcn0gbmFtaW5nIHRoZSBmaXJzdCBydWxlIHRoZSBoZWFkZXIgYnJlYWtzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBwYXJzZVRyYWNlcGFyZW50KCcwMC00YmY5MmYzNTc3YjM0ZGE2YTNjZTkyOWQwZTBlNDczNi0wMGYwNjdhYTBiYTkwMmI3LTAxJyk7XG4gKiAvLyB7IHRyYWNlSWQ6ICc0YmY5MmYzNTc3YjM0ZGE2YTNjZTkyOWQwZTBlNDczNicsIG9wZXJhdGlvbklkOiAnMDBmMDY3YWEwYmE5MDJiNycsIHNhbXBsZWQ6IHRydWUsIGZsYWdzOiAnMDEnIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVHJhY2VwYXJlbnQoaGVhZGVyOiB1bmtub3duKTogUGFyc2VkVHJhY2VwYXJlbnQge1xuICBpZiAodHlwZW9mIGhlYWRlciAhPT0gJ3N0cmluZycpIHRocm93IG5ldyBUcmFjZXBhcmVudEVycm9yKCdub3QtYS1zdHJpbmcnKTtcbiAgaWYgKGhlYWRlci5sZW5ndGggPCBWMDBfTEVOR1RIIHx8IGhlYWRlci5sZW5ndGggPiBNQVhfSEVBREVSX0xFTkdUSCkgdGhyb3cgbmV3IFRyYWNlcGFyZW50RXJyb3IoJ2xlbmd0aCcpO1xuICBjb25zdCB2ZXJzaW9uID0gaGVhZGVyLnNsaWNlKDAsIDIpO1xuICBpZiAoIUhFWDIudGVzdCh2ZXJzaW9uKSB8fCB2ZXJzaW9uID09PSAnZmYnKSB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcigndmVyc2lvbicpO1xuICBpZiAodmVyc2lvbiA9PT0gJzAwJyAmJiBoZWFkZXIubGVuZ3RoICE9PSBWMDBfTEVOR1RIKSB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcignbGVuZ3RoJyk7XG5cbiAgY29uc3QgdHJhY2VJZCA9IGhlYWRlci5zbGljZSgzLCAzNSk7XG4gIGNvbnN0IG9wZXJhdGlvbklkID0gaGVhZGVyLnNsaWNlKDM2LCA1Mik7XG4gIGNvbnN0IGZsYWdzID0gaGVhZGVyLnNsaWNlKDUzLCA1NSk7XG4gIGNvbnN0IGxhaWRPdXQgPSBoZWFkZXJbMl0gPT09ICctJyAmJiBoZWFkZXJbMzVdID09PSAnLScgJiYgaGVhZGVyWzUyXSA9PT0gJy0nO1xuICBjb25zdCB0YWlsT2sgPSBoZWFkZXIubGVuZ3RoID09PSBWMDBfTEVOR1RIIHx8IGhlYWRlcltWMDBfTEVOR1RIXSA9PT0gJy0nO1xuICBpZiAoIWxhaWRPdXQgfHwgIXRhaWxPayB8fCAhSEVYMzIudGVzdCh0cmFjZUlkKSB8fCAhSEVYMTYudGVzdChvcGVyYXRpb25JZCkgfHwgIUhFWDIudGVzdChmbGFncykpIHtcbiAgICB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcignY2hhcmFjdGVycycpO1xuICB9XG4gIGlmIChaRVJPUy50ZXN0KHRyYWNlSWQpKSB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcignemVyby10cmFjZS1pZCcpO1xuICBpZiAoWkVST1MudGVzdChvcGVyYXRpb25JZCkpIHRocm93IG5ldyBUcmFjZXBhcmVudEVycm9yKCd6ZXJvLXBhcmVudC1pZCcpO1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHsgdHJhY2VJZCwgb3BlcmF0aW9uSWQsIHNhbXBsZWQ6IChwYXJzZUludChmbGFncywgMTYpICYgMSkgPT09IDEsIGZsYWdzIH0pO1xufVxuXG4vKipcbiAqIFdyaXRlIGEgdmVyc2lvbi0wMCBgdHJhY2VwYXJlbnRgIOKAlCBmb3IgYW4gb3V0Ym91bmQgY2FsbCB0aGF0IGNvbnRpbnVlcyB0aGlzIHJ1bidzIHRyYWNlLiBCb3RoIGlkcyBtdXN0IGJlIFczQ1xuICogaWRzIGFuZCBgZmxhZ3NgIGEgYnl0ZSBvZiAyIGxvd2VyY2FzZSBoZXggKHJlZnVzZWQgYnkgbmFtZSBvdGhlcndpc2UsIGxpa2UgYSBwYXJzZSk7IGBzYW1wbGVkYCwgd2hlbiBnaXZlbixcbiAqIHNldHMgb3IgY2xlYXJzIGJpdCAwIG9mIHRoZSBmbGFncy4gYGZvcm1hdFRyYWNlcGFyZW50KHBhcnNlVHJhY2VwYXJlbnQoaCkpYCBpcyBgaGAgZm9yIGFueSB2YWxpZCB2ZXJzaW9uLTAwIGBoYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogZm9ybWF0VHJhY2VwYXJlbnQoeyB0cmFjZUlkLCBvcGVyYXRpb25JZDogbXlTcGFuSWQsIHNhbXBsZWQ6IHRydWUgfSk7IC8vICcwMC08dHJhY2VJZD4tPG15U3BhbklkPi0wMSdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFRyYWNlcGFyZW50KGZpZWxkczogVHJhY2VwYXJlbnRGaWVsZHMpOiBzdHJpbmcge1xuICBjb25zdCB7IHRyYWNlSWQsIG9wZXJhdGlvbklkIH0gPSBmaWVsZHM7XG4gIGlmICh0eXBlb2YgdHJhY2VJZCAhPT0gJ3N0cmluZycgfHwgdHlwZW9mIG9wZXJhdGlvbklkICE9PSAnc3RyaW5nJykgdGhyb3cgbmV3IFRyYWNlcGFyZW50RXJyb3IoJ25vdC1hLXN0cmluZycpO1xuICBpZiAoIUhFWDMyLnRlc3QodHJhY2VJZCkgfHwgIUhFWDE2LnRlc3Qob3BlcmF0aW9uSWQpKSB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcignY2hhcmFjdGVycycpO1xuICBpZiAoWkVST1MudGVzdCh0cmFjZUlkKSkgdGhyb3cgbmV3IFRyYWNlcGFyZW50RXJyb3IoJ3plcm8tdHJhY2UtaWQnKTtcbiAgaWYgKFpFUk9TLnRlc3Qob3BlcmF0aW9uSWQpKSB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcignemVyby1wYXJlbnQtaWQnKTtcbiAgcmV0dXJuIGAwMC0ke3RyYWNlSWR9LSR7b3BlcmF0aW9uSWR9LSR7ZmxhZ3NPZihmaWVsZHMpfWA7XG59XG5cbi8qKiBUaGUgdHJhY2UtZmxhZ3MgYnl0ZSB0byB3cml0ZTogdGhlIGdpdmVuIG9uZSAob3IgYDAwYCksIGJpdCAwIHNldCBvciBjbGVhcmVkIGJ5IGBzYW1wbGVkYCB3aGVuIGl0IGlzIGdpdmVuLiAqL1xuZnVuY3Rpb24gZmxhZ3NPZihmaWVsZHM6IFRyYWNlcGFyZW50RmllbGRzKTogc3RyaW5nIHtcbiAgY29uc3QgeyBmbGFncyA9ICcwMCcsIHNhbXBsZWQgfSA9IGZpZWxkcztcbiAgaWYgKHR5cGVvZiBmbGFncyAhPT0gJ3N0cmluZycpIHRocm93IG5ldyBUcmFjZXBhcmVudEVycm9yKCdub3QtYS1zdHJpbmcnKTtcbiAgaWYgKCFIRVgyLnRlc3QoZmxhZ3MpKSB0aHJvdyBuZXcgVHJhY2VwYXJlbnRFcnJvcignY2hhcmFjdGVycycpO1xuICBpZiAoc2FtcGxlZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmxhZ3M7XG4gIGNvbnN0IGJ5dGUgPSBzYW1wbGVkID8gcGFyc2VJbnQoZmxhZ3MsIDE2KSB8IDEgOiBwYXJzZUludChmbGFncywgMTYpICYgMHhmZTtcbiAgcmV0dXJuIGJ5dGUudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJyk7XG59XG5cbi8qKiBUaGUgZW52IGZpZWxkcyBjb3JyZWxhdGlvbiByZWFkcyDigJQgc3RydWN0dXJhbCwgc28gdGhpcyBMNSBmaWxlIG5hbWVzIG5vdGhpbmcgb2YgdGhlIGVuZ2luZSdzIGBFeGVjdXRpb25FbnZgLiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3JyZWxhdGlvbkVudiB7XG4gIHJlYWRvbmx5IHRyYWNlcGFyZW50PzogdW5rbm93bjtcbiAgcmVhZG9ubHkgdHJhY2VJZD86IHVua25vd247XG4gIHJlYWRvbmx5IG9wZXJhdGlvbklkPzogdW5rbm93bjtcbn1cblxuLyoqIEFuIGV4cGxpY2l0IGlkOiAx4oCTMjU2IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXJzLCBubyBzcGFjZSDigJQgYSBuYW1lIGEgbG9nIGxpbmUgb3IgYW4gZXhwb3J0ZXIgY2FuIGNhcnJ5LiAqL1xuY29uc3QgRVhQTElDSVRfSUQgPSAvXltcXHgyMS1cXHg3ZV17MSwyNTZ9JC87XG5cbi8qKlxuICogQWRtaXQgYSBsZWcncyBlbnYgT05DRSAoY2FsbGVkIGJ5IGBGbG93Q2hhcnRFeGVjdXRvciDCtyBydW5gIC8gYHJlc3VtZWAgYmVmb3JlIGFueXRoaW5nIG1vdmVzKTogYSBzaW5nbGVcbiAqIG93bi1wcm9wZXJ0eSBzbmFwc2hvdCBvZiBpdCDigJQgZXZlcnkgZ2V0dGVyIHJ1bnMgb25jZSwgbm90aGluZyBpcyByZWFkIG9mZiB0aGUgcHJvdG90eXBlIOKAlCBhbmQgdGhlIGNvcnJlbGF0aW9uXG4gKiByZXNvbHZlZCBmcm9tIHRoYXQgc25hcHNob3QuIEluIHRoZSBzbmFwc2hvdCB0aGUgc3RhZ2VzIHNlZSAoYCRnZXRFbnYoKWApLCBgdHJhY2VwYXJlbnRgIGlzIGV4YWN0bHlcbiAqIGBjb3JyZWxhdGlvbi50cmFjZXBhcmVudGAg4oCUIHRoZSBjYW5vbmljYWwgaGVhZGVyIG9mIHRoZSBlZmZlY3RpdmUgaWRzLCBvciBubyBrZXkgd2hlbiB0aGUgcnVuJ3MgY29ycmVsYXRpb24gaGFzXG4gKiBub25lIOKAlCBzbyBzdGFnZSBjb2RlIG5ldmVyIGhvbGRzIHRoZSByZWNlaXZlZCBieXRlcywgbm9yIGEgaGVhZGVyIG5hbWluZyBhbm90aGVyIHRyYWNlIHRoYW4gdGhlIHJlY29yZC5cbiAqIGBlbnZgIGlzIGB1bmRlZmluZWRgIGV4YWN0bHkgd2hlbiBub25lIHdhcyBnaXZlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkbWl0UnVuRW52PEUgZXh0ZW5kcyBvYmplY3Q+KFxuICBlbnY6IEUgfCB1bmRlZmluZWQsXG4pOiB7IHJlYWRvbmx5IGVudjogRSB8IHVuZGVmaW5lZDsgcmVhZG9ubHkgY29ycmVsYXRpb246IFJ1bkNvcnJlbGF0aW9uIHwgdW5kZWZpbmVkIH0ge1xuICBpZiAoZW52ID09PSB1bmRlZmluZWQgfHwgZW52ID09PSBudWxsKSByZXR1cm4geyBlbnY6IHVuZGVmaW5lZCwgY29ycmVsYXRpb246IHVuZGVmaW5lZCB9O1xuICBjb25zdCBzbmFwc2hvdCA9IHsgLi4uZW52IH0gYXMgRSAmIHsgdHJhY2VwYXJlbnQ/OiB1bmtub3duIH07XG4gIGNvbnN0IGNvcnJlbGF0aW9uID0gcmVzb2x2ZVBhcnNlZChzbmFwc2hvdCk7XG4gIGlmIChjb3JyZWxhdGlvbj8udHJhY2VwYXJlbnQgIT09IHVuZGVmaW5lZCkgc25hcHNob3QudHJhY2VwYXJlbnQgPSBjb3JyZWxhdGlvbi50cmFjZXBhcmVudDtcbiAgZWxzZSBpZiAoc25hcHNob3QudHJhY2VwYXJlbnQgIT09IHVuZGVmaW5lZCkgZGVsZXRlIHNuYXBzaG90LnRyYWNlcGFyZW50OyAvLyBhIGhlYWRlciB0aGUgcmVjb3JkIGRvZXMgbm90IGNhcnJ5XG4gIHJldHVybiB7IGVudjogc25hcHNob3QsIGNvcnJlbGF0aW9uIH07XG59XG5cbi8qKlxuICogVGhlIE9ORSByZXNvbHV0aW9uIG9mIGEgbGVnJ3MgY29ycmVsYXRpb24gZnJvbSBpdHMgZW52LiBPbmx5IE9XTiBmaWVsZHMgY291bnQuIGB0cmFjZXBhcmVudGAgaXMgcGFyc2VkIG9uY2UgKGFcbiAqIGJhZCBoZWFkZXIgcmVmdXNlcyB0aGUgbGVnIOKAlCBleHBsaWNpdCBpZHMgZG8gbm90IHJlc2N1ZSBpdCk7IGV4cGxpY2l0IGB0cmFjZUlkYCAvIGBvcGVyYXRpb25JZGAgd2luIG92ZXIgdGhlXG4gKiBoZWFkZXIncyBhbmQgbXVzdCBiZSAx4oCTMjU2IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXJzIChyZWZ1c2VkIGJ5IGZpZWxkIG5hbWUsIG5ldmVyIGVjaG9lZCk7IGFuIGVtcHR5IG9uZSBpc1xuICogbm8gaWQuIEV2ZXJ5dGhpbmcgb2YgdGhlIGhlYWRlciDigJQgaXRzIHBhcmVudC1pZCBhcyB0aGUgb3BlcmF0aW9uLCBgc2FtcGxlZGAsIGB0cmFjZXBhcmVudGAg4oCUIHJpZGVzIG9ubHkgd2hpbGVcbiAqIHRoZSB0cmFjZSBJUyB0aGUgaGVhZGVyJ3MsIGFuZCBgdHJhY2VwYXJlbnRgIGlzIHJlYnVpbHQgZnJvbSB0aGUgRUZGRUNUSVZFIGlkcyB3aXRoIHRoZSBoZWFkZXIncyBmbGFnc1xuICogKG9taXR0ZWQgd2hlbiB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhIFczQyBwYXJlbnQtaWQpLCBzbyB0aGUgcmVjb3JkIG5ldmVyIG5hbWVzIG9uZSB0cmFjZSBhbmQgZmlsZXMgb3JcbiAqIHByb3BhZ2F0ZXMgYW5vdGhlcidzLiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm8gdHJhY2UgaWQgYXQgYWxsIOKAlCBhbmQgcmVmdXNlc1xuICogYW4gYG9wZXJhdGlvbklkYCB3aXRoIG5vIHRyYWNlIHRvIGJlbG9uZyB0by5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVDb3JyZWxhdGlvbihlbnY6IENvcnJlbGF0aW9uRW52IHwgdW5kZWZpbmVkKTogUnVuQ29ycmVsYXRpb24gfCB1bmRlZmluZWQge1xuICBpZiAoZW52ID09PSB1bmRlZmluZWQgfHwgZW52ID09PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gcmVzb2x2ZVBhcnNlZCh7IC4uLmVudiB9KTtcbn1cblxuLyoqIHtAbGluayByZXNvbHZlQ29ycmVsYXRpb259IG92ZXIgYW4gZW52IGFscmVhZHkgc25hcHNob3R0ZWQgKGVhY2ggZmllbGQgcmVhZCBvbmNlKS4gKi9cbmZ1bmN0aW9uIHJlc29sdmVQYXJzZWQoZW52OiBDb3JyZWxhdGlvbkVudik6IFJ1bkNvcnJlbGF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmF3ID0gb3duKGVudiwgJ3RyYWNlcGFyZW50Jyk7XG4gIGNvbnN0IGhlYWRlciA9IHJhdyA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcGFyc2VUcmFjZXBhcmVudChyYXcpO1xuICBjb25zdCB0cmFjZUlkID0gZXhwbGljaXRJZChvd24oZW52LCAndHJhY2VJZCcpLCAndHJhY2VJZCcpID8/IGhlYWRlcj8udHJhY2VJZDtcbiAgY29uc3Qgc2FtZVRyYWNlID0gaGVhZGVyICE9PSB1bmRlZmluZWQgJiYgdHJhY2VJZCA9PT0gaGVhZGVyLnRyYWNlSWQ7XG4gIGNvbnN0IG9wZXJhdGlvbklkID1cbiAgICBleHBsaWNpdElkKG93bihlbnYsICdvcGVyYXRpb25JZCcpLCAnb3BlcmF0aW9uSWQnKSA/PyAoc2FtZVRyYWNlID8gaGVhZGVyLm9wZXJhdGlvbklkIDogdW5kZWZpbmVkKTtcbiAgaWYgKHRyYWNlSWQgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChvcGVyYXRpb25JZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbnYub3BlcmF0aW9uSWQgbmVlZHMgYSB0cmFjZSB0byBiZWxvbmcgdG86IGdpdmUgZW52LnRyYWNlSWQgb3IgZW52LnRyYWNlcGFyZW50Jyk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3QgcHJvcGFnYWJsZSA9IHNhbWVUcmFjZSAmJiBvcGVyYXRpb25JZCAhPT0gdW5kZWZpbmVkICYmIEhFWDE2LnRlc3Qob3BlcmF0aW9uSWQpICYmICFaRVJPUy50ZXN0KG9wZXJhdGlvbklkKTtcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIHRyYWNlSWQsXG4gICAgLi4uKG9wZXJhdGlvbklkICE9PSB1bmRlZmluZWQgJiYgeyBvcGVyYXRpb25JZCB9KSxcbiAgICAuLi4oc2FtZVRyYWNlICYmIHsgc2FtcGxlZDogaGVhZGVyLnNhbXBsZWQgfSksXG4gICAgLi4uKHByb3BhZ2FibGUgJiYgeyB0cmFjZXBhcmVudDogZm9ybWF0VHJhY2VwYXJlbnQoeyB0cmFjZUlkLCBvcGVyYXRpb25JZCwgZmxhZ3M6IGhlYWRlci5mbGFncyB9KSB9KSxcbiAgfSk7XG59XG5cbi8qKiBBbiBvd24gZmllbGQncyB2YWx1ZSDigJQgYSB2YWx1ZSBpbmhlcml0ZWQgdGhyb3VnaCB0aGUgcHJvdG90eXBlIGlzIG5vdCB0aGUgY2FsbGVyJ3MuICovXG5mdW5jdGlvbiBvd24oZW52OiBDb3JyZWxhdGlvbkVudiwgZmllbGQ6IGtleW9mIENvcnJlbGF0aW9uRW52KTogdW5rbm93biB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZW52LCBmaWVsZCkgPyBlbnZbZmllbGRdIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBleHBsaWNpdElkKHZhbHVlOiB1bmtub3duLCBmaWVsZDogJ3RyYWNlSWQnIHwgJ29wZXJhdGlvbklkJyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHRocm93IG5ldyBUeXBlRXJyb3IoYGVudi4ke2ZpZWxkfSBtdXN0IGJlIGEgc3RyaW5nYCk7XG4gIGlmICghRVhQTElDSVRfSUQudGVzdCh2YWx1ZSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBlbnYuJHtmaWVsZH0gcmVmdXNlZDogYW4gaWQgaXMgMeKAkzI1NiBwcmludGFibGUgQVNDSUkgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlYCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuIl19
|