footprintjs 9.48.2 → 10.0.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 +12 -10
- package/CLAUDE.md +21 -23
- package/README.md +1 -1
- package/dist/advanced.js +71 -128
- package/dist/esm/advanced.d.ts +24 -58
- package/dist/esm/advanced.js +13 -51
- package/dist/esm/index.d.ts +5 -8
- package/dist/esm/index.js +3 -3
- package/dist/esm/lib/builder/FlowChartBuilder.d.ts +1 -1
- package/dist/esm/lib/builder/FlowChartBuilder.js +3 -3
- package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +1 -1
- package/dist/esm/lib/builder/structure/StructureRecorder.js +1 -1
- package/dist/esm/lib/capture/index.d.ts +0 -1
- package/dist/esm/lib/capture/index.js +1 -2
- package/dist/esm/lib/engine/graph/prefixNodeTree.js +2 -2
- package/dist/esm/lib/engine/handlers/ResumeEntry.d.ts +3 -3
- package/dist/esm/lib/engine/handlers/ResumeEntry.js +4 -4
- package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +4 -8
- package/dist/esm/lib/engine/index.d.ts +1 -1
- package/dist/esm/lib/engine/index.js +1 -1
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
- package/dist/esm/lib/engine/narrative/index.d.ts +1 -1
- package/dist/esm/lib/engine/narrative/index.js +1 -1
- package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +1 -11
- package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +4 -6
- package/dist/esm/lib/engine/traversalContext.d.ts +1 -1
- package/dist/esm/lib/engine/traversalContext.js +2 -2
- package/dist/esm/lib/engine/types.d.ts +2 -10
- package/dist/esm/lib/engine/types.js +1 -1
- package/dist/esm/lib/engine/walkSubflowSpec.js +2 -2
- package/dist/esm/lib/ids/reservedIds.js +2 -2
- package/dist/esm/lib/memory/DiagnosticCollector.js +2 -2
- package/dist/esm/lib/memory/StageContext.d.ts +2 -4
- package/dist/esm/lib/memory/StageContext.js +2 -2
- package/dist/esm/lib/memory/borrowedMutation.js +2 -2
- package/dist/esm/lib/memory/index.d.ts +6 -21
- package/dist/esm/lib/memory/index.js +4 -22
- package/dist/esm/lib/memory/redaction.d.ts +1 -1
- package/dist/esm/lib/memory/redaction.js +2 -2
- package/dist/esm/lib/memory/runPolicy.d.ts +3 -2
- package/dist/esm/lib/memory/runPolicy.js +1 -1
- package/dist/esm/lib/reactive/createTypedScope.js +2 -2
- package/dist/esm/lib/reactive/writeTraps.js +2 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +3 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.js +3 -2
- package/dist/esm/lib/recorder/EmitRecorder.d.ts +1 -1
- package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
- package/dist/esm/lib/recorder/InOutRecorder.js +2 -2
- package/dist/esm/lib/recorder/qualityTrace.d.ts +1 -1
- package/dist/esm/lib/recorder/qualityTrace.js +2 -2
- package/dist/esm/lib/runner/DeferredObserverTier.js +2 -2
- package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -5
- package/dist/esm/lib/runner/ExecutionRuntime.js +2 -5
- package/dist/esm/lib/runner/FlowChartExecutor.d.ts +1 -1
- package/dist/esm/lib/runner/FlowChartExecutor.js +1 -1
- package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +1 -1
- package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -4
- package/dist/esm/lib/runner/resume.js +2 -2
- package/dist/esm/lib/runner/snapshot.js +3 -2
- package/dist/esm/lib/scope/ScopeFacade.js +2 -2
- package/dist/esm/lib/scope/state/zod/scopeFactory.js +2 -2
- package/dist/esm/recorders.d.ts +2 -3
- package/dist/esm/recorders.js +1 -1
- package/dist/esm/trace.d.ts +11 -57
- package/dist/esm/trace.js +10 -68
- package/dist/index.js +3 -3
- package/dist/lib/builder/FlowChartBuilder.js +5 -5
- package/dist/lib/builder/structure/StructureRecorder.js +1 -1
- package/dist/lib/capture/index.js +2 -4
- package/dist/lib/engine/graph/prefixNodeTree.js +5 -5
- package/dist/lib/engine/handlers/ResumeEntry.js +4 -4
- package/dist/lib/engine/handlers/SubflowExecutor.js +5 -9
- package/dist/lib/engine/index.js +1 -1
- package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
- package/dist/lib/engine/narrative/index.js +1 -1
- package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -10
- package/dist/lib/engine/traversalContext.js +4 -4
- package/dist/lib/engine/types.js +1 -1
- package/dist/lib/engine/walkSubflowSpec.js +3 -3
- package/dist/lib/ids/reservedIds.js +5 -5
- package/dist/lib/memory/DiagnosticCollector.js +3 -3
- package/dist/lib/memory/StageContext.js +3 -3
- package/dist/lib/memory/borrowedMutation.js +3 -3
- package/dist/lib/memory/index.js +7 -42
- package/dist/lib/memory/redaction.js +3 -3
- package/dist/lib/memory/runPolicy.js +1 -1
- package/dist/lib/reactive/createTypedScope.js +3 -3
- package/dist/lib/reactive/writeTraps.js +4 -4
- package/dist/lib/recorder/ControlDepRecorder.js +3 -2
- package/dist/lib/recorder/EmitRecorder.js +1 -1
- package/dist/lib/recorder/InOutRecorder.js +3 -3
- package/dist/lib/recorder/qualityTrace.js +4 -4
- package/dist/lib/runner/DeferredObserverTier.js +3 -3
- package/dist/lib/runner/ExecutionRuntime.js +6 -9
- package/dist/lib/runner/FlowChartExecutor.js +1 -1
- package/dist/lib/runner/getSubtreeSnapshot.js +6 -6
- package/dist/lib/runner/resume.js +3 -3
- package/dist/lib/runner/snapshot.js +6 -5
- package/dist/lib/scope/ScopeFacade.js +3 -3
- package/dist/lib/scope/state/zod/scopeFactory.js +4 -4
- package/dist/recorders.js +1 -1
- package/dist/trace.js +18 -120
- package/dist/types/advanced.d.ts +24 -58
- package/dist/types/index.d.ts +5 -8
- package/dist/types/lib/builder/FlowChartBuilder.d.ts +1 -1
- package/dist/types/lib/builder/structure/StructureRecorder.d.ts +1 -1
- package/dist/types/lib/capture/index.d.ts +0 -1
- package/dist/types/lib/engine/handlers/ResumeEntry.d.ts +3 -3
- package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
- package/dist/types/lib/engine/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
- package/dist/types/lib/engine/narrative/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +1 -11
- package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
- package/dist/types/lib/engine/traversalContext.d.ts +1 -1
- package/dist/types/lib/engine/types.d.ts +2 -10
- package/dist/types/lib/memory/StageContext.d.ts +2 -4
- package/dist/types/lib/memory/index.d.ts +6 -21
- package/dist/types/lib/memory/redaction.d.ts +1 -1
- package/dist/types/lib/memory/runPolicy.d.ts +3 -2
- package/dist/types/lib/recorder/ControlDepRecorder.d.ts +3 -2
- package/dist/types/lib/recorder/EmitRecorder.d.ts +1 -1
- package/dist/types/lib/recorder/qualityTrace.d.ts +1 -1
- package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -5
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +1 -1
- package/dist/types/lib/runner/getSubtreeSnapshot.d.ts +1 -1
- package/dist/types/recorders.d.ts +2 -3
- package/dist/types/trace.d.ts +11 -57
- package/package.json +6 -15
- package/dist/esm/lib/capture/freeze.d.ts +0 -91
- package/dist/esm/lib/capture/freeze.js +0 -314
- package/dist/esm/lib/capture/ownData.d.ts +0 -7
- package/dist/esm/lib/capture/ownData.js +0 -15
- package/dist/esm/lib/capture/valueKinds.d.ts +0 -57
- package/dist/esm/lib/capture/valueKinds.js +0 -142
- package/dist/esm/lib/ids/runtimeStageId.d.ts +0 -173
- package/dist/esm/lib/ids/runtimeStageId.js +0 -194
- package/dist/esm/lib/memory/EventLog.d.ts +0 -105
- package/dist/esm/lib/memory/EventLog.js +0 -148
- package/dist/esm/lib/memory/RecordFrame.d.ts +0 -232
- package/dist/esm/lib/memory/RecordFrame.js +0 -296
- package/dist/esm/lib/memory/SharedMemory.d.ts +0 -46
- package/dist/esm/lib/memory/SharedMemory.js +0 -88
- package/dist/esm/lib/memory/TransactionBuffer.d.ts +0 -521
- package/dist/esm/lib/memory/TransactionBuffer.js +0 -946
- package/dist/esm/lib/memory/admission.d.ts +0 -81
- package/dist/esm/lib/memory/admission.js +0 -153
- package/dist/esm/lib/memory/backtrack.d.ts +0 -286
- package/dist/esm/lib/memory/backtrack.js +0 -457
- package/dist/esm/lib/memory/commitLogUtils.d.ts +0 -217
- package/dist/esm/lib/memory/commitLogUtils.js +0 -384
- package/dist/esm/lib/memory/deltaEncoding.d.ts +0 -66
- package/dist/esm/lib/memory/deltaEncoding.js +0 -122
- package/dist/esm/lib/memory/equality.d.ts +0 -93
- package/dist/esm/lib/memory/equality.js +0 -262
- package/dist/esm/lib/memory/eventPosition.d.ts +0 -18
- package/dist/esm/lib/memory/eventPosition.js +0 -2
- package/dist/esm/lib/memory/honesty.d.ts +0 -93
- package/dist/esm/lib/memory/honesty.js +0 -92
- package/dist/esm/lib/memory/keyPaths.d.ts +0 -125
- package/dist/esm/lib/memory/keyPaths.js +0 -227
- package/dist/esm/lib/memory/logModel.d.ts +0 -76
- package/dist/esm/lib/memory/logModel.js +0 -364
- package/dist/esm/lib/memory/merge.d.ts +0 -26
- package/dist/esm/lib/memory/merge.js +0 -60
- package/dist/esm/lib/memory/pathOps.d.ts +0 -115
- package/dist/esm/lib/memory/pathOps.js +0 -290
- package/dist/esm/lib/memory/paths.d.ts +0 -52
- package/dist/esm/lib/memory/paths.js +0 -57
- package/dist/esm/lib/memory/placeholders.d.ts +0 -39
- package/dist/esm/lib/memory/placeholders.js +0 -40
- package/dist/esm/lib/memory/recordCommit.d.ts +0 -45
- package/dist/esm/lib/memory/recordCommit.js +0 -61
- package/dist/esm/lib/memory/scrub.d.ts +0 -53
- package/dist/esm/lib/memory/scrub.js +0 -74
- package/dist/esm/lib/memory/types.d.ts +0 -209
- package/dist/esm/lib/memory/types.js +0 -10
- package/dist/esm/lib/memory/utils.d.ts +0 -73
- package/dist/esm/lib/memory/utils.js +0 -159
- package/dist/esm/lib/memory/verbs.d.ts +0 -333
- package/dist/esm/lib/memory/verbs.js +0 -427
- package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +0 -147
- package/dist/esm/lib/recorder/CommitRangeIndex.js +0 -207
- package/dist/esm/lib/scope/detectCircular.d.ts +0 -13
- package/dist/esm/lib/scope/detectCircular.js +0 -14
- package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +0 -5
- package/dist/esm/lib/scope/recorders/summarizeValue.js +0 -6
- package/dist/esm/lib/slice/elementProvenance.d.ts +0 -81
- package/dist/esm/lib/slice/elementProvenance.js +0 -190
- package/dist/esm/lib/slice/forwardSliceForKey.d.ts +0 -88
- package/dist/esm/lib/slice/forwardSliceForKey.js +0 -243
- package/dist/esm/lib/slice/index.d.ts +0 -25
- package/dist/esm/lib/slice/index.js +0 -25
- package/dist/esm/lib/slice/keyIndex.d.ts +0 -137
- package/dist/esm/lib/slice/keyIndex.js +0 -293
- package/dist/esm/lib/slice/keyTimeline.d.ts +0 -49
- package/dist/esm/lib/slice/keyTimeline.js +0 -113
- package/dist/esm/lib/slice/keysReadSources.d.ts +0 -51
- package/dist/esm/lib/slice/keysReadSources.js +0 -95
- package/dist/esm/lib/slice/serialize.d.ts +0 -78
- package/dist/esm/lib/slice/serialize.js +0 -278
- package/dist/esm/lib/slice/sliceForKey.d.ts +0 -47
- package/dist/esm/lib/slice/sliceForKey.js +0 -88
- package/dist/esm/lib/slice/types.d.ts +0 -567
- package/dist/esm/lib/slice/types.js +0 -25
- package/dist/esm/lib/time-travel/axis.d.ts +0 -119
- package/dist/esm/lib/time-travel/axis.js +0 -179
- package/dist/esm/lib/time-travel/bundles.d.ts +0 -77
- package/dist/esm/lib/time-travel/bundles.js +0 -136
- package/dist/esm/lib/time-travel/chain.d.ts +0 -93
- package/dist/esm/lib/time-travel/chain.js +0 -188
- package/dist/esm/lib/time-travel/commitStops.d.ts +0 -55
- package/dist/esm/lib/time-travel/commitStops.js +0 -202
- package/dist/esm/lib/time-travel/index.d.ts +0 -22
- package/dist/esm/lib/time-travel/index.js +0 -21
- package/dist/esm/lib/time-travel/stateAt.d.ts +0 -102
- package/dist/esm/lib/time-travel/stateAt.js +0 -153
- package/dist/esm/lib/time-travel/tagStops.d.ts +0 -72
- package/dist/esm/lib/time-travel/tagStops.js +0 -102
- package/dist/esm/lib/time-travel/timeTravel.d.ts +0 -70
- package/dist/esm/lib/time-travel/timeTravel.js +0 -360
- package/dist/esm/lib/time-travel/types.d.ts +0 -470
- package/dist/esm/lib/time-travel/types.js +0 -23
- package/dist/esm/write.d.ts +0 -47
- package/dist/esm/write.js +0 -46
- package/dist/lib/capture/freeze.js +0 -320
- package/dist/lib/capture/ownData.js +0 -19
- package/dist/lib/capture/valueKinds.js +0 -146
- package/dist/lib/ids/runtimeStageId.js +0 -210
- package/dist/lib/memory/EventLog.js +0 -152
- package/dist/lib/memory/RecordFrame.js +0 -300
- package/dist/lib/memory/SharedMemory.js +0 -92
- package/dist/lib/memory/TransactionBuffer.js +0 -950
- package/dist/lib/memory/admission.js +0 -159
- package/dist/lib/memory/backtrack.js +0 -463
- package/dist/lib/memory/commitLogUtils.js +0 -399
- package/dist/lib/memory/deltaEncoding.js +0 -128
- package/dist/lib/memory/equality.js +0 -266
- package/dist/lib/memory/eventPosition.js +0 -3
- package/dist/lib/memory/honesty.js +0 -95
- package/dist/lib/memory/keyPaths.js +0 -243
- package/dist/lib/memory/logModel.js +0 -372
- package/dist/lib/memory/merge.js +0 -64
- package/dist/lib/memory/pathOps.js +0 -306
- package/dist/lib/memory/paths.js +0 -62
- package/dist/lib/memory/placeholders.js +0 -43
- package/dist/lib/memory/recordCommit.js +0 -65
- package/dist/lib/memory/scrub.js +0 -79
- package/dist/lib/memory/types.js +0 -11
- package/dist/lib/memory/utils.js +0 -178
- package/dist/lib/memory/verbs.js +0 -444
- package/dist/lib/recorder/CommitRangeIndex.js +0 -211
- package/dist/lib/scope/detectCircular.js +0 -21
- package/dist/lib/scope/recorders/summarizeValue.js +0 -10
- package/dist/lib/slice/elementProvenance.js +0 -195
- package/dist/lib/slice/forwardSliceForKey.js +0 -247
- package/dist/lib/slice/index.js +0 -42
- package/dist/lib/slice/keyIndex.js +0 -313
- package/dist/lib/slice/keyTimeline.js +0 -117
- package/dist/lib/slice/keysReadSources.js +0 -101
- package/dist/lib/slice/serialize.js +0 -286
- package/dist/lib/slice/sliceForKey.js +0 -93
- package/dist/lib/slice/types.js +0 -26
- package/dist/lib/time-travel/axis.js +0 -184
- package/dist/lib/time-travel/bundles.js +0 -144
- package/dist/lib/time-travel/chain.js +0 -193
- package/dist/lib/time-travel/commitStops.js +0 -206
- package/dist/lib/time-travel/index.js +0 -32
- package/dist/lib/time-travel/stateAt.js +0 -160
- package/dist/lib/time-travel/tagStops.js +0 -106
- package/dist/lib/time-travel/timeTravel.js +0 -364
- package/dist/lib/time-travel/types.js +0 -24
- package/dist/types/lib/capture/freeze.d.ts +0 -91
- package/dist/types/lib/capture/ownData.d.ts +0 -7
- package/dist/types/lib/capture/valueKinds.d.ts +0 -57
- package/dist/types/lib/ids/runtimeStageId.d.ts +0 -173
- package/dist/types/lib/memory/EventLog.d.ts +0 -105
- package/dist/types/lib/memory/RecordFrame.d.ts +0 -232
- package/dist/types/lib/memory/SharedMemory.d.ts +0 -46
- package/dist/types/lib/memory/TransactionBuffer.d.ts +0 -521
- package/dist/types/lib/memory/admission.d.ts +0 -81
- package/dist/types/lib/memory/backtrack.d.ts +0 -286
- package/dist/types/lib/memory/commitLogUtils.d.ts +0 -217
- package/dist/types/lib/memory/deltaEncoding.d.ts +0 -66
- package/dist/types/lib/memory/equality.d.ts +0 -93
- package/dist/types/lib/memory/eventPosition.d.ts +0 -18
- package/dist/types/lib/memory/honesty.d.ts +0 -93
- package/dist/types/lib/memory/keyPaths.d.ts +0 -125
- package/dist/types/lib/memory/logModel.d.ts +0 -76
- package/dist/types/lib/memory/merge.d.ts +0 -26
- package/dist/types/lib/memory/pathOps.d.ts +0 -115
- package/dist/types/lib/memory/paths.d.ts +0 -52
- package/dist/types/lib/memory/placeholders.d.ts +0 -39
- package/dist/types/lib/memory/recordCommit.d.ts +0 -45
- package/dist/types/lib/memory/scrub.d.ts +0 -53
- package/dist/types/lib/memory/types.d.ts +0 -209
- package/dist/types/lib/memory/utils.d.ts +0 -73
- package/dist/types/lib/memory/verbs.d.ts +0 -333
- package/dist/types/lib/recorder/CommitRangeIndex.d.ts +0 -147
- package/dist/types/lib/scope/detectCircular.d.ts +0 -13
- package/dist/types/lib/scope/recorders/summarizeValue.d.ts +0 -5
- package/dist/types/lib/slice/elementProvenance.d.ts +0 -81
- package/dist/types/lib/slice/forwardSliceForKey.d.ts +0 -88
- package/dist/types/lib/slice/index.d.ts +0 -25
- package/dist/types/lib/slice/keyIndex.d.ts +0 -137
- package/dist/types/lib/slice/keyTimeline.d.ts +0 -49
- package/dist/types/lib/slice/keysReadSources.d.ts +0 -51
- package/dist/types/lib/slice/serialize.d.ts +0 -78
- package/dist/types/lib/slice/sliceForKey.d.ts +0 -47
- package/dist/types/lib/slice/types.d.ts +0 -567
- package/dist/types/lib/time-travel/axis.d.ts +0 -119
- package/dist/types/lib/time-travel/bundles.d.ts +0 -77
- package/dist/types/lib/time-travel/chain.d.ts +0 -93
- package/dist/types/lib/time-travel/commitStops.d.ts +0 -55
- package/dist/types/lib/time-travel/index.d.ts +0 -22
- package/dist/types/lib/time-travel/stateAt.d.ts +0 -102
- package/dist/types/lib/time-travel/tagStops.d.ts +0 -72
- package/dist/types/lib/time-travel/timeTravel.d.ts +0 -70
- package/dist/types/lib/time-travel/types.d.ts +0 -470
- package/dist/types/write.d.ts +0 -47
- package/dist/write.js +0 -52
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/keyTimeline.ts — the whole life of ONE key, in commit order.
|
|
3
|
-
*
|
|
4
|
-
* The flat companion to {@link forwardSliceForKey}: no graph, no budgets,
|
|
5
|
-
* no anchor — every write of the key and every recorded read of it, as one
|
|
6
|
-
* chronological list. This is what a UI timeline row and an LLM's "walk me
|
|
7
|
-
* through what happened to `total`" both want, and what makes a forward
|
|
8
|
-
* slice checkable: the same facts, unfolded instead of walked.
|
|
9
|
-
*
|
|
10
|
-
* Every moment carries BOTH universal join keys — `runtimeStageId` (to
|
|
11
|
-
* recorders, execution trees, UIs) and `commitIdx` (to the commit log).
|
|
12
|
-
*
|
|
13
|
-
* ### LAW — read attribution is the walk's, exactly
|
|
14
|
-
*
|
|
15
|
-
* A read moment's `fromWriteIdx` is the write whose live range it sits in:
|
|
16
|
-
* the last write at a STRICTLY earlier commit index. That is the same
|
|
17
|
-
* `(writeIdx, nextWriteIdx]` rule `forwardSliceForKey` walks (reads fire
|
|
18
|
-
* PRE-commit), so the two doors can never disagree about which value a read
|
|
19
|
-
* saw — pinned by a cross-door property test. A read before ANY write has no
|
|
20
|
-
* `fromWriteIdx` and raises the `'pre-run-origin'` note: it saw initial
|
|
21
|
-
* state, frozen run `input`, or a closure.
|
|
22
|
-
*
|
|
23
|
-
* DAG position: memory ← slice. Imports memory/ only (see README.md).
|
|
24
|
-
*/
|
|
25
|
-
import { buildKeyIndex, hasRecordedReads, lastIndexBefore, nestedOnlyWrites, nestedRowsNote, preRunOriginNote, readsNotRecordedNote, unknownKeyNote, writeEntry, } from './keyIndex.js';
|
|
26
|
-
import { resolveKeysReadSource } from './keysReadSources.js';
|
|
27
|
-
import { normaliseStateKey } from './sliceForKey.js';
|
|
28
|
-
/**
|
|
29
|
-
* The life of one key as a chronological list of writes and reads.
|
|
30
|
-
*
|
|
31
|
-
* @param commitLog Ordered commit bundles — `getSnapshot().commitLog`.
|
|
32
|
-
* @param key A {@link StateKey} — normalised through the same
|
|
33
|
-
* `normaliseStateKey` both slice doors use.
|
|
34
|
-
* @param keysRead A {@link KeysReadSource} or bare lookup (reads are not in
|
|
35
|
-
* the commit log).
|
|
36
|
-
* @returns Always a {@link KeyTimeline}; absence carries its reason, and an
|
|
37
|
-
* unknown key is NAMED as unknown with a bounded list of known keys.
|
|
38
|
-
*/
|
|
39
|
-
export function keyTimeline(commitLog, key, keysRead, options) {
|
|
40
|
-
const source = resolveKeysReadSource(keysRead);
|
|
41
|
-
const normalisedKey = normaliseStateKey(key);
|
|
42
|
-
const base = {
|
|
43
|
-
key: normalisedKey,
|
|
44
|
-
...(options?.before !== undefined && { before: options.before }),
|
|
45
|
-
keysReadKind: source.kind,
|
|
46
|
-
...(source.coverage !== undefined && { readsCoverage: source.coverage }),
|
|
47
|
-
};
|
|
48
|
-
if (commitLog.length === 0)
|
|
49
|
-
return { ...base, missing: 'empty-log', notes: [] };
|
|
50
|
-
const index = buildKeyIndex(commitLog, source.lookup);
|
|
51
|
-
const readsRecorded = hasRecordedReads(index);
|
|
52
|
-
const notes = [];
|
|
53
|
-
// Same typo guard as the forward walk — one rule, both doors.
|
|
54
|
-
if (!index.isKnown(normalisedKey)) {
|
|
55
|
-
notes.push(unknownKeyNote(index, normalisedKey));
|
|
56
|
-
if (readsRecorded)
|
|
57
|
-
return { ...base, missing: 'never-written', notes };
|
|
58
|
-
}
|
|
59
|
-
if (!readsRecorded)
|
|
60
|
-
notes.push(readsNotRecordedNote());
|
|
61
|
-
const limit = options?.before ?? commitLog.length;
|
|
62
|
-
// Writes under the writer rule (on the key, inside it, or around it and
|
|
63
|
-
// changing it); reads on the key, inside it or around it (keyIndex.ts).
|
|
64
|
-
const allWrites = index.writesOf(normalisedKey);
|
|
65
|
-
const writes = allWrites.filter((i) => i < limit);
|
|
66
|
-
const reads = index.readsOf(normalisedKey).filter((i) => i < limit);
|
|
67
|
-
// Merge two ascending index lists. At the SAME commit index a read comes
|
|
68
|
-
// first: reads fire before their stage's commit (the engine's event order,
|
|
69
|
-
// and the reason the live range is closed at the next write).
|
|
70
|
-
const moments = [];
|
|
71
|
-
let w = 0;
|
|
72
|
-
let r = 0;
|
|
73
|
-
let sawPreRunRead = false;
|
|
74
|
-
while (w < writes.length || r < reads.length) {
|
|
75
|
-
const takeRead = r < reads.length && (w >= writes.length || reads[r] <= writes[w]);
|
|
76
|
-
if (takeRead) {
|
|
77
|
-
const idx = reads[r++];
|
|
78
|
-
const bundle = commitLog[idx];
|
|
79
|
-
// The live range this read sits in: the last write STRICTLY earlier.
|
|
80
|
-
const fromWriteIdx = lastIndexBefore(allWrites, idx);
|
|
81
|
-
if (fromWriteIdx === undefined)
|
|
82
|
-
sawPreRunRead = true;
|
|
83
|
-
moments.push({
|
|
84
|
-
kind: 'read',
|
|
85
|
-
commitIdx: idx,
|
|
86
|
-
runtimeStageId: bundle.runtimeStageId,
|
|
87
|
-
stageId: bundle.stageId,
|
|
88
|
-
stageName: bundle.stage,
|
|
89
|
-
...(fromWriteIdx !== undefined && { fromWriteIdx }),
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
const idx = writes[w++];
|
|
94
|
-
const bundle = commitLog[idx];
|
|
95
|
-
const entry = writeEntry(bundle, normalisedKey);
|
|
96
|
-
moments.push({
|
|
97
|
-
kind: 'write',
|
|
98
|
-
commitIdx: idx,
|
|
99
|
-
runtimeStageId: bundle.runtimeStageId,
|
|
100
|
-
stageId: bundle.stageId,
|
|
101
|
-
stageName: bundle.stage,
|
|
102
|
-
...(entry !== undefined && { verb: entry.verb }),
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (sawPreRunRead)
|
|
107
|
-
notes.push(preRunOriginNote(normalisedKey));
|
|
108
|
-
const nested = nestedOnlyWrites(commitLog, normalisedKey, writes);
|
|
109
|
-
if (nested.length > 0)
|
|
110
|
-
notes.push(nestedRowsNote(normalisedKey, nested));
|
|
111
|
-
return { ...base, moments, notes };
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5VGltZWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NsaWNlL2tleVRpbWVsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUlILE9BQU8sRUFDTCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLFVBQVUsR0FDWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQWNyRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FDekIsU0FBeUIsRUFDekIsR0FBYSxFQUNiLFFBQXlDLEVBQ3pDLE9BQTRCO0lBRTVCLE1BQU0sTUFBTSxHQUFHLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sYUFBYSxHQUFHLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sSUFBSSxHQUEyRTtRQUNuRixHQUFHLEVBQUUsYUFBYTtRQUNsQixHQUFHLENBQUMsT0FBTyxFQUFFLE1BQU0sS0FBSyxTQUFTLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hFLFlBQVksRUFBRSxNQUFNLENBQUMsSUFBSTtRQUN6QixHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ3pFLENBQUM7SUFFRixJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxPQUFPLEVBQUUs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QUM5QixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQ2hELE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQ1gsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsU0FBUyxFQUFFLEdBQUc7Z0JBQ2QsY0FBYyxFQUFFLE1BQU0sQ0FBQyxjQUFjO2dCQUNyQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87Z0JBQ3ZCLFNBQVMsRUFBRSxNQUFNLENBQUMsS0FBSztnQkFDdkIsR0FBRyxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO2FBQ2pELENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQy9ELE1BQU0sTUFBTSxHQUFHLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDbEUsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN6RSxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQ3JDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHNsaWNlL2tleVRpbWVsaW5lLnRzIOKAlCB0aGUgd2hvbGUgbGlmZSBvZiBPTkUga2V5LCBpbiBjb21taXQgb3JkZXIuXG4gKlxuICogVGhlIGZsYXQgY29tcGFuaW9uIHRvIHtAbGluayBmb3J3YXJkU2xpY2VGb3JLZXl9OiBubyBncmFwaCwgbm8gYnVkZ2V0cyxcbiAqIG5vIGFuY2hvciDigJQgZXZlcnkgd3JpdGUgb2YgdGhlIGtleSBhbmQgZXZlcnkgcmVjb3JkZWQgcmVhZCBvZiBpdCwgYXMgb25lXG4gKiBjaHJvbm9sb2dpY2FsIGxpc3QuIFRoaXMgaXMgd2hhdCBhIFVJIHRpbWVsaW5lIHJvdyBhbmQgYW4gTExNJ3MgXCJ3YWxrIG1lXG4gKiB0aHJvdWdoIHdoYXQgaGFwcGVuZWQgdG8gYHRvdGFsYFwiIGJvdGggd2FudCwgYW5kIHdoYXQgbWFrZXMgYSBmb3J3YXJkXG4gKiBzbGljZSBjaGVja2FibGU6IHRoZSBzYW1lIGZhY3RzLCB1bmZvbGRlZCBpbnN0ZWFkIG9mIHdhbGtlZC5cbiAqXG4gKiBFdmVyeSBtb21lbnQgY2FycmllcyBCT1RIIHVuaXZlcnNhbCBqb2luIGtleXMg4oCUIGBydW50aW1lU3RhZ2VJZGAgKHRvXG4gKiByZWNvcmRlcnMsIGV4ZWN1dGlvbiB0cmVlcywgVUlzKSBhbmQgYGNvbW1pdElkeGAgKHRvIHRoZSBjb21taXQgbG9nKS5cbiAqXG4gKiAjIyMgTEFXIOKAlCByZWFkIGF0dHJpYnV0aW9uIGlzIHRoZSB3YWxrJ3MsIGV4YWN0bHlcbiAqXG4gKiBBIHJlYWQgbW9tZW50J3MgYGZyb21Xcml0ZUlkeGAgaXMgdGhlIHdyaXRlIHdob3NlIGxpdmUgcmFuZ2UgaXQgc2l0cyBpbjpcbiAqIHRoZSBsYXN0IHdyaXRlIGF0IGEgU1RSSUNUTFkgZWFybGllciBjb21taXQgaW5kZXguIFRoYXQgaXMgdGhlIHNhbWVcbiAqIGAod3JpdGVJZHgsIG5leHRXcml0ZUlkeF1gIHJ1bGUgYGZvcndhcmRTbGljZUZvcktleWAgd2Fsa3MgKHJlYWRzIGZpcmVcbiAqIFBSRS1jb21taXQpLCBzbyB0aGUgdHdvIGRvb3JzIGNhbiBuZXZlciBkaXNhZ3JlZSBhYm91dCB3aGljaCB2YWx1ZSBhIHJlYWRcbiAqIHNhdyDigJQgcGlubmVkIGJ5IGEgY3Jvc3MtZG9vciBwcm9wZXJ0eSB0ZXN0LiBBIHJlYWQgYmVmb3JlIEFOWSB3cml0ZSBoYXMgbm9cbiAqIGBmcm9tV3JpdGVJZHhgIGFuZCByYWlzZXMgdGhlIGAncHJlLXJ1bi1vcmlnaW4nYCBub3RlOiBpdCBzYXcgaW5pdGlhbFxuICogc3RhdGUsIGZyb3plbiBydW4gYGlucHV0YCwgb3IgYSBjbG9zdXJlLlxuICpcbiAqIERBRyBwb3NpdGlvbjogbWVtb3J5IOKGkCBzbGljZS4gSW1wb3J0cyBtZW1vcnkvIG9ubHkgKHNlZSBSRUFETUUubWQpLlxuICovXG5cbmltcG9ydCB0eXBlIHsgS2V5c1JlYWRMb29rdXAgfSBmcm9tICcuLi9tZW1vcnkvYmFja3RyYWNrLmpzJztcbmltcG9ydCB0eXBlIHsgQ29tbWl0QnVuZGxlIH0gZnJvbSAnLi4vbWVtb3J5L3R5cGVzLmpzJztcbmltcG9ydCB7XG4gIGJ1aWxkS2V5SW5kZXgsXG4gIGhhc1JlY29yZGVkUmVhZHMsXG4gIGxhc3RJbmRleEJlZm9yZSxcbiAgbmVzdGVkT25seVdyaXRlcyxcbiAgbmVzdGVkUm93c05vdGUsXG4gIHByZVJ1bk9yaWdpbk5vdGUsXG4gIHJlYWRzTm90UmVjb3JkZWROb3RlLFxuICB1bmtub3duS2V5Tm90ZSxcbiAgd3JpdGVFbnRyeSxcbn0gZnJvbSAnLi9rZXlJbmRleC5qcyc7XG5pbXBvcnQgeyByZXNvbHZlS2V5c1JlYWRTb3VyY2UgfSBmcm9tICcuL2tleXNSZWFkU291cmNlcy5qcyc7XG5pbXBvcnQgeyBub3JtYWxpc2VTdGF0ZUtleSB9IGZyb20gJy4vc2xpY2VGb3JLZXkuanMnO1xuaW1wb3J0IHR5cGUgeyBIb25lc3R5Tm90ZSwgS2V5TW9tZW50LCBLZXlzUmVhZFNvdXJjZSwgS2V5VGltZWxpbmUsIFN0YXRlS2V5IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsga2V5VGltZWxpbmV9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBLZXlUaW1lbGluZU9wdGlvbnMge1xuICAvKipcbiAgICogRXhjbHVzaXZlIGNvbW1pdC1hcnJheS1pbmRleCB1cHBlciBib3VuZDogb25seSBtb21lbnRzIEJFRk9SRSB0aGlzIGlkeC5cbiAgICogU2FtZSB3b3JkIGFuZCBzZW1hbnRpY3MgYXMgYHNsaWNlRm9yS2V5YCdzIGBiZWZvcmVgIChub3RlIHRoZSBzaWJsaW5nXG4gICAqIGBhcnJheVByb3ZlbmFuY2VgIHVzZXMgYW4gSU5DTFVTSVZFIGBhdElkeGAg4oCUIHRoaXMgZmFtaWx5IGZvbGxvd3MgdGhlXG4gICAqIHNsaWNlIGRvb3JzKS5cbiAgICovXG4gIGJlZm9yZT86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgbGlmZSBvZiBvbmUga2V5IGFzIGEgY2hyb25vbG9naWNhbCBsaXN0IG9mIHdyaXRlcyBhbmQgcmVhZHMuXG4gKlxuICogQHBhcmFtIGNvbW1pdExvZyBPcmRlcmVkIGNvbW1pdCBidW5kbGVzIOKAlCBgZ2V0U25hcHNob3QoKS5jb21taXRMb2dgLlxuICogQHBhcmFtIGtleSBBIHtAbGluayBTdGF0ZUtleX0g4oCUIG5vcm1hbGlzZWQgdGhyb3VnaCB0aGUgc2FtZVxuICogICBgbm9ybWFsaXNlU3RhdGVLZXlgIGJvdGggc2xpY2UgZG9vcnMgdXNlLlxuICogQHBhcmFtIGtleXNSZWFkIEEge0BsaW5rIEtleXNSZWFkU291cmNlfSBvciBiYXJlIGxvb2t1cCAocmVhZHMgYXJlIG5vdCBpblxuICogICB0aGUgY29tbWl0IGxvZykuXG4gKiBAcmV0dXJucyBBbHdheXMgYSB7QGxpbmsgS2V5VGltZWxpbmV9OyBhYnNlbmNlIGNhcnJpZXMgaXRzIHJlYXNvbiwgYW5kIGFuXG4gKiAgIHVua25vd24ga2V5IGlzIE5BTUVEIGFzIHVua25vd24gd2l0aCBhIGJvdW5kZWQgbGlzdCBvZiBrbm93biBrZXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24ga2V5VGltZWxpbmUoXG4gIGNvbW1pdExvZzogQ29tbWl0QnVuZGxlW10sXG4gIGtleTogU3RhdGVLZXksXG4gIGtleXNSZWFkOiBLZXlzUmVhZFNvdXJjZSB8IEtleXNSZWFkTG9va3VwLFxuICBvcHRpb25zPzogS2V5VGltZWxpbmVPcHRpb25zLFxuKTogS2V5VGltZWxpbmUge1xuICBjb25zdCBzb3VyY2UgPSByZXNvbHZlS2V5c1JlYWRTb3VyY2Uoa2V5c1JlYWQpO1xuICBjb25zdCBub3JtYWxpc2VkS2V5ID0gbm9ybWFsaXNlU3RhdGVLZXkoa2V5KTtcbiAgY29uc3QgYmFzZTogUGljazxLZXlUaW1lbGluZSwgJ2tleScgfCAnYmVmb3JlJyB8ICdrZXlzUmVhZEtpbmQnIHwgJ3JlYWRzQ292ZXJhZ2UnPiA9IHtcbiAgICBrZXk6IG5vcm1hbGlzZWRLZXksXG4gICAgLi4uKG9wdGlvbnM/LmJlZm9yZSAhPT0gdW5kZWZpbmVkICYmIHsgYmVmb3JlOiBvcHRpb25zLmJlZm9yZSB9KSxcbiAgICBrZXlzUmVhZEtpbmQ6IHNvdXJjZS5raW5kLFxuICAgIC4uLihzb3VyY2UuY292ZXJhZ2UgIT09IHVuZGVmaW5lZCAmJiB7IHJlYWRzQ292ZXJhZ2U6IHNvdXJjZS5jb3ZlcmFnZSB9KSxcbiAgfTtcblxuICBpZiAoY29tbWl0TG9nLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgLi4uYmFzZSwgbWlzc2luZzogJ2VtcHR5LWxvZycsIG5vdGVzOiBbXSB9O1xuXG4gIGNvbnN0IGluZGV4ID0gYnVpbGRLZXlJbmRleChjb21taXRMb2csIHNvdXJjZS5sb29rdXApO1xuICBjb25zdCByZWFkc1JlY29yZGVkID0gaGFzUmVjb3JkZWRSZWFkcyhpbmRleCk7XG4gIGNvbnN0IG5vdGVzOiBIb25lc3R5Tm90ZVtdID0gW107XG5cbiAgLy8gU2FtZSB0eXBvIGd1YXJkIGFzIHRoZSBmb3J3YXJkIHdhbGsg4oCUIG9uZSBydWxlLCBib3RoIGRvb3JzLlxuICBpZiAoIWluZGV4LmlzS25vd24obm9ybWFsaXNlZEtleSkpIHtcbiAgICBub3Rlcy5wdXNoKHVua25vd25LZXlOb3RlKGluZGV4LCBub3JtYWxpc2VkS2V5KSk7XG4gICAgaWYgKHJlYWRzUmVjb3JkZWQpIHJldHVybiB7IC4uLmJhc2UsIG1pc3Npbmc6ICduZXZlci13cml0dGVuJywgbm90ZXMgfTtcbiAgfVxuICBpZiAoIXJlYWRzUmVjb3JkZWQpIG5vdGVzLnB1c2gocmVhZHNOb3RSZWNvcmRlZE5vdGUoKSk7XG5cbiAgY29uc3QgbGltaXQgPSBvcHRpb25zPy5iZWZvcmUgPz8gY29tbWl0TG9nLmxlbmd0aDtcbiAgLy8gV3JpdGVzIHVuZGVyIHRoZSB3cml0ZXIgcnVsZSAob24gdGhlIGtleSwgaW5zaWRlIGl0LCBvciBhcm91bmQgaXQgYW5kXG4gIC8vIGNoYW5naW5nIGl0KTsgcmVhZHMgb24gdGhlIGtleSwgaW5zaWRlIGl0IG9yIGFyb3VuZCBpdCAoa2V5SW5kZXgudHMpLlxuICBjb25zdCBhbGxXcml0ZXMgPSBpbmRleC53cml0ZXNPZihub3JtYWxpc2VkS2V5KTtcbiAgY29uc3Qgd3JpdGVzID0gYWxsV3JpdGVzLmZpbHRlcigoaSkgPT4gaSA8IGxpbWl0KTtcbiAgY29uc3QgcmVhZHMgPSBpbmRleC5yZWFkc09mKG5vcm1hbGlzZWRLZXkpLmZpbHRlcigoaSkgPT4gaSA8IGxpbWl0KTtcblxuICAvLyBNZXJnZSB0d28gYXNjZW5kaW5nIGluZGV4IGxpc3RzLiBBdCB0aGUgU0FNRSBjb21taXQgaW5kZXggYSByZWFkIGNvbWVzXG4gIC8vIGZpcnN0OiByZWFkcyBmaXJlIGJlZm9yZSB0aGVpciBzdGFnZSdzIGNvbW1pdCAodGhlIGVuZ2luZSdzIGV2ZW50IG9yZGVyLFxuICAvLyBhbmQgdGhlIHJlYXNvbiB0aGUgbGl2ZSByYW5nZSBpcyBjbG9zZWQgYXQgdGhlIG5leHQgd3JpdGUpLlxuICBjb25zdCBtb21lbnRzOiBLZXlNb21lbnRbXSA9IFtdO1xuICBsZXQgdyA9IDA7XG4gIGxldCByID0gMDtcbiAgbGV0IHNhd1ByZVJ1blJlYWQgPSBmYWxzZTtcbiAgd2hpbGUgKHcgPCB3cml0ZXMubGVuZ3RoIHx8IHIgPCByZWFkcy5sZW5ndGgpIHtcbiAgICBjb25zdCB0YWtlUmVhZCA9IHIgPCByZWFkcy5sZW5ndGggJiYgKHcgPj0gd3JpdGVzLmxlbmd0aCB8fCByZWFkc1tyXSA8PSB3cml0ZXNbd10pO1xuICAgIGlmICh0YWtlUmVhZCkge1xuICAgICAgY29uc3QgaWR4ID0gcmVhZHNbcisrXTtcbiAgICAgIGNvbnN0IGJ1bmRsZSA9IGNvbW1pdExvZ1tpZHhdO1xuICAgICAgLy8gVGhlIGxpdmUgcmFuZ2UgdGhpcyByZWFkIHNpdHMgaW46IHRoZSBsYXN0IHdyaXRlIFNUUklDVExZIGVhcmxpZXIuXG4gICAgICBjb25zdCBmcm9tV3JpdGVJZHggPSBsYXN0SW5kZXhCZWZvcmUoYWxsV3JpdGVzLCBpZHgpO1xuICAgICAgaWYgKGZyb21Xcml0ZUlkeCA9PT0gdW5kZWZpbmVkKSBzYXdQcmVSdW5SZWFkID0gdHJ1ZTtcbiAgICAgIG1vbWVudHMucHVzaCh7XG4gICAgICAgIGtpbmQ6ICdyZWFkJyxcbiAgICAgICAgY29tbWl0SWR4OiBpZHgsXG4gICAgICAgIHJ1bnRpbWVTdGFnZUlkOiBidW5kbGUucnVudGltZVN0YWdlSWQsXG4gICAgICAgIHN0YWdlSWQ6IGJ1bmRsZS5zdGFnZUlkLFxuICAgICAgICBzdGFnZU5hbWU6IGJ1bmRsZS5zdGFnZSxcbiAgICAgICAgLi4uKGZyb21Xcml0ZUlkeCAhPT0gdW5kZWZpbmVkICYmIHsgZnJvbVdyaXRlSWR4IH0pLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlkeCA9IHdyaXRlc1t3KytdO1xuICAgICAgY29uc3QgYnVuZGxlID0gY29tbWl0TG9nW2lkeF07XG4gICAgICBjb25zdCBlbnRyeSA9IHdyaXRlRW50cnkoYnVuZGxlLCBub3JtYWxpc2VkS2V5KTtcbiAgICAgIG1vbWVudHMucHVzaCh7XG4gICAgICAgIGtpbmQ6ICd3cml0ZScsXG4gICAgICAgIGNvbW1pdElkeDogaWR4LFxuICAgICAgICBydW50aW1lU3RhZ2VJZDogYnVuZGxlLnJ1bnRpbWVTdGFnZUlkLFxuICAgICAgICBzdGFnZUlkOiBidW5kbGUuc3RhZ2VJZCxcbiAgICAgICAgc3RhZ2VOYW1lOiBidW5kbGUuc3RhZ2UsXG4gICAgICAgIC4uLihlbnRyeSAhPT0gdW5kZWZpbmVkICYmIHsgdmVyYjogZW50cnkudmVyYiB9KSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzYXdQcmVSdW5SZWFkKSBub3Rlcy5wdXNoKHByZVJ1bk9yaWdpbk5vdGUobm9ybWFsaXNlZEtleSkpO1xuICBjb25zdCBuZXN0ZWQgPSBuZXN0ZWRPbmx5V3JpdGVzKGNvbW1pdExvZywgbm9ybWFsaXNlZEtleSwgd3JpdGVzKTtcbiAgaWYgKG5lc3RlZC5sZW5ndGggPiAwKSBub3Rlcy5wdXNoKG5lc3RlZFJvd3NOb3RlKG5vcm1hbGlzZWRLZXksIG5lc3RlZCkpO1xuICByZXR1cm4geyAuLi5iYXNlLCBtb21lbnRzLCBub3RlcyB9O1xufVxuIl19
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/keysReadSources.ts — the shipped {@link KeysReadSource} strategies.
|
|
3
|
-
*
|
|
4
|
-
* The canonical strategy list and rationale live on the KeysReadSource type
|
|
5
|
-
* (types.ts) — the doc consumers hover. This file holds the implementations.
|
|
6
|
-
*
|
|
7
|
-
* Deliberately NOT here: a QualityRecorder adapter. Importing recorder/ would
|
|
8
|
-
* drag this leaf library up the dependency DAG. The adapter is a one-liner at
|
|
9
|
-
* the call site instead: `(id) => recorder.getByKey(id)?.keysRead ?? []`.
|
|
10
|
-
*/
|
|
11
|
-
import type { KeysReadLookup } from '../memory/backtrack.js';
|
|
12
|
-
import type { ExecutionTree } from '../memory/types.js';
|
|
13
|
-
import type { KeysReadSource } from './types.js';
|
|
14
|
-
/**
|
|
15
|
-
* Post-hoc reads from a finished run's execution tree — ZERO setup.
|
|
16
|
-
*
|
|
17
|
-
* WHY this works: a stage's `stageReads` records the keys it
|
|
18
|
-
* tracked-read whenever the `readTracking` dial ≠ 'off' ('full' is the
|
|
19
|
-
* engine default; 'summary' replaces VALUES with markers but keeps the
|
|
20
|
-
* KEYS — and keys are all a slice needs). Under 'off' this source returns
|
|
21
|
-
* empty read-sets — detectable via `coverage.stepsWithReads === 0`, which
|
|
22
|
-
* `sliceForKey` copies onto the slice so tools can say "reads were not
|
|
23
|
-
* recorded" instead of the lie "no dependencies".
|
|
24
|
-
*
|
|
25
|
-
* SUBFLOW PAIRING (important): a subflow runs in an ISOLATED runtime — its
|
|
26
|
-
* commits live in `snapshot.subflowResults[sfId].commitLog`, its reads in
|
|
27
|
-
* `snapshot.subflowResults[sfId].executionTree`. Trees and logs must be
|
|
28
|
-
* paired from the SAME scope: to slice a key inside a subflow, re-anchor
|
|
29
|
-
* there —
|
|
30
|
-
*
|
|
31
|
-
* ```ts
|
|
32
|
-
* const sf = snapshot.subflowResults['sf-tools'];
|
|
33
|
-
* sliceForKey(sf.commitLog, key, keysReadFromExecutionTree(sf.executionTree));
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* Passing multiple trees widens READ resolution only (useful when one log
|
|
37
|
-
* genuinely spans them); it does not let a root-log slice cross a subflow
|
|
38
|
-
* mount — see README.md § Subflow boundaries.
|
|
39
|
-
*/
|
|
40
|
-
export declare function keysReadFromExecutionTree(tree: ExecutionTree | readonly ExecutionTree[]): KeysReadSource;
|
|
41
|
-
/**
|
|
42
|
-
* Reads from a prebuilt map — e.g. collected live from
|
|
43
|
-
* `ScopeRecorder.onRead` events, or deserialized from a stored trace.
|
|
44
|
-
*/
|
|
45
|
-
export declare function keysReadFromMap(map: ReadonlyMap<string, readonly string[]> | Readonly<Record<string, readonly string[]>>): KeysReadSource;
|
|
46
|
-
/**
|
|
47
|
-
* Normalize the ergonomic union: callers may pass a full strategy object or
|
|
48
|
-
* a bare lookup function (wrapped as kind 'custom-fn' so the honesty
|
|
49
|
-
* breadcrumb still says where reads came from).
|
|
50
|
-
*/
|
|
51
|
-
export declare function resolveKeysReadSource(src: KeysReadSource | KeysReadLookup): KeysReadSource;
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/keysReadSources.ts — the shipped {@link KeysReadSource} strategies.
|
|
3
|
-
*
|
|
4
|
-
* The canonical strategy list and rationale live on the KeysReadSource type
|
|
5
|
-
* (types.ts) — the doc consumers hover. This file holds the implementations.
|
|
6
|
-
*
|
|
7
|
-
* Deliberately NOT here: a QualityRecorder adapter. Importing recorder/ would
|
|
8
|
-
* drag this leaf library up the dependency DAG. The adapter is a one-liner at
|
|
9
|
-
* the call site instead: `(id) => recorder.getByKey(id)?.keysRead ?? []`.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Post-hoc reads from a finished run's execution tree — ZERO setup.
|
|
13
|
-
*
|
|
14
|
-
* WHY this works: a stage's `stageReads` records the keys it
|
|
15
|
-
* tracked-read whenever the `readTracking` dial ≠ 'off' ('full' is the
|
|
16
|
-
* engine default; 'summary' replaces VALUES with markers but keeps the
|
|
17
|
-
* KEYS — and keys are all a slice needs). Under 'off' this source returns
|
|
18
|
-
* empty read-sets — detectable via `coverage.stepsWithReads === 0`, which
|
|
19
|
-
* `sliceForKey` copies onto the slice so tools can say "reads were not
|
|
20
|
-
* recorded" instead of the lie "no dependencies".
|
|
21
|
-
*
|
|
22
|
-
* SUBFLOW PAIRING (important): a subflow runs in an ISOLATED runtime — its
|
|
23
|
-
* commits live in `snapshot.subflowResults[sfId].commitLog`, its reads in
|
|
24
|
-
* `snapshot.subflowResults[sfId].executionTree`. Trees and logs must be
|
|
25
|
-
* paired from the SAME scope: to slice a key inside a subflow, re-anchor
|
|
26
|
-
* there —
|
|
27
|
-
*
|
|
28
|
-
* ```ts
|
|
29
|
-
* const sf = snapshot.subflowResults['sf-tools'];
|
|
30
|
-
* sliceForKey(sf.commitLog, key, keysReadFromExecutionTree(sf.executionTree));
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* Passing multiple trees widens READ resolution only (useful when one log
|
|
34
|
-
* genuinely spans them); it does not let a root-log slice cross a subflow
|
|
35
|
-
* mount — see README.md § Subflow boundaries.
|
|
36
|
-
*/
|
|
37
|
-
export function keysReadFromExecutionTree(tree) {
|
|
38
|
-
const byStep = new Map();
|
|
39
|
-
let steps = 0;
|
|
40
|
-
// The tree is acyclic by construction (next/children), but this walker is
|
|
41
|
-
// also handed CONSUMER-provided data — a visited set makes a malformed or
|
|
42
|
-
// hand-built tree a non-event instead of an infinite loop.
|
|
43
|
-
const visited = new Set();
|
|
44
|
-
const stack = [tree].flat(); // one root, or several (subflow trees); a hole is skipped
|
|
45
|
-
while (stack.length > 0) {
|
|
46
|
-
const node = stack.pop();
|
|
47
|
-
if (visited.has(node))
|
|
48
|
-
continue;
|
|
49
|
-
visited.add(node);
|
|
50
|
-
if (node.runtimeStageId) {
|
|
51
|
-
steps++;
|
|
52
|
-
if (node.stageReads) {
|
|
53
|
-
const keys = Object.keys(node.stageReads);
|
|
54
|
-
if (keys.length > 0)
|
|
55
|
-
byStep.set(node.runtimeStageId, keys);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (node.next)
|
|
59
|
-
stack.push(node.next);
|
|
60
|
-
if (node.children)
|
|
61
|
-
for (const c of node.children)
|
|
62
|
-
stack.push(c);
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
kind: 'execution-tree',
|
|
66
|
-
lookup: (runtimeStageId) => byStep.get(runtimeStageId) ?? [],
|
|
67
|
-
coverage: { steps, stepsWithReads: byStep.size },
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Reads from a prebuilt map — e.g. collected live from
|
|
72
|
-
* `ScopeRecorder.onRead` events, or deserialized from a stored trace.
|
|
73
|
-
*/
|
|
74
|
-
export function keysReadFromMap(map) {
|
|
75
|
-
// Own-property guard on the object form: runtimeStageIds are consumer-
|
|
76
|
-
// influenced strings; without it, an id like 'constructor' would read
|
|
77
|
-
// through the prototype chain (the same hardening posture as the engine's
|
|
78
|
-
// nativeGet/prototype-pollution guards).
|
|
79
|
-
const get = map instanceof Map
|
|
80
|
-
? (id) => map.get(id)
|
|
81
|
-
: (id) => Object.prototype.hasOwnProperty.call(map, id) ? map[id] : undefined;
|
|
82
|
-
return {
|
|
83
|
-
kind: 'map',
|
|
84
|
-
lookup: (runtimeStageId) => [...(get(runtimeStageId) ?? [])],
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Normalize the ergonomic union: callers may pass a full strategy object or
|
|
89
|
-
* a bare lookup function (wrapped as kind 'custom-fn' so the honesty
|
|
90
|
-
* breadcrumb still says where reads came from).
|
|
91
|
-
*/
|
|
92
|
-
export function resolveKeysReadSource(src) {
|
|
93
|
-
return typeof src === 'function' ? { kind: 'custom-fn', lookup: src } : src;
|
|
94
|
-
}
|
|
95
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5c1JlYWRTb3VyY2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9zbGljZS9rZXlzUmVhZFNvdXJjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBTUg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFDSCxNQUFNLFVBQVUseUJBQXlCLENBQUMsSUFBOEM7SUFDdEYsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7SUFDM0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsMEVBQTBFO0lBQzFFLDBFQUEwRTtJQUMxRSwyREFBMkQ7SUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQWlCLENBQUM7SUFDekMsTUFBTSxLQUFLLEdBQW9CLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQywwREFBMEQ7SUFDeEcsT0FBTyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUcsQ0FBQztRQUMxQixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQUUsU0FBUztRQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xCLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQztvQkFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJO1lBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVE7Z0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBQ0QsT0FBTztRQUNMLElBQUksRUFBRSxnQkFBZ0I7UUFDdEIsTUFBTSxFQUFFLENBQUMsY0FBc0IsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFO1FBQ3BFLFFBQVEsRUFBRSxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRTtLQUNqRCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQzdCLEdBQXlGO0lBRXpGLHVFQUF1RTtJQUN2RSxzRUFBc0U7SUFDdEUsMEVBQTBFO0lBQzFFLHlDQUF5QztJQUN6QyxNQUFNLEdBQUcsR0FDUCxHQUFHLFlBQVksR0FBRztRQUNoQixDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQ0wsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUUsR0FBeUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ25ILE9BQU87UUFDTCxJQUFJLEVBQUUsS0FBSztRQUNYLE1BQU0sRUFBRSxDQUFDLGNBQXNCLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztLQUNyRSxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsR0FBb0M7SUFDeEUsT0FBTyxPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztBQUM5RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBzbGljZS9rZXlzUmVhZFNvdXJjZXMudHMg4oCUIHRoZSBzaGlwcGVkIHtAbGluayBLZXlzUmVhZFNvdXJjZX0gc3RyYXRlZ2llcy5cbiAqXG4gKiBUaGUgY2Fub25pY2FsIHN0cmF0ZWd5IGxpc3QgYW5kIHJhdGlvbmFsZSBsaXZlIG9uIHRoZSBLZXlzUmVhZFNvdXJjZSB0eXBlXG4gKiAodHlwZXMudHMpIOKAlCB0aGUgZG9jIGNvbnN1bWVycyBob3Zlci4gVGhpcyBmaWxlIGhvbGRzIHRoZSBpbXBsZW1lbnRhdGlvbnMuXG4gKlxuICogRGVsaWJlcmF0ZWx5IE5PVCBoZXJlOiBhIFF1YWxpdHlSZWNvcmRlciBhZGFwdGVyLiBJbXBvcnRpbmcgcmVjb3JkZXIvIHdvdWxkXG4gKiBkcmFnIHRoaXMgbGVhZiBsaWJyYXJ5IHVwIHRoZSBkZXBlbmRlbmN5IERBRy4gVGhlIGFkYXB0ZXIgaXMgYSBvbmUtbGluZXIgYXRcbiAqIHRoZSBjYWxsIHNpdGUgaW5zdGVhZDogYChpZCkgPT4gcmVjb3JkZXIuZ2V0QnlLZXkoaWQpPy5rZXlzUmVhZCA/PyBbXWAuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBLZXlzUmVhZExvb2t1cCB9IGZyb20gJy4uL21lbW9yeS9iYWNrdHJhY2suanMnO1xuaW1wb3J0IHR5cGUgeyBFeGVjdXRpb25UcmVlIH0gZnJvbSAnLi4vbWVtb3J5L3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgS2V5c1JlYWRTb3VyY2UgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBQb3N0LWhvYyByZWFkcyBmcm9tIGEgZmluaXNoZWQgcnVuJ3MgZXhlY3V0aW9uIHRyZWUg4oCUIFpFUk8gc2V0dXAuXG4gKlxuICogV0hZIHRoaXMgd29ya3M6IGEgc3RhZ2UncyBgc3RhZ2VSZWFkc2AgcmVjb3JkcyB0aGUga2V5cyBpdFxuICogdHJhY2tlZC1yZWFkIHdoZW5ldmVyIHRoZSBgcmVhZFRyYWNraW5nYCBkaWFsIOKJoCAnb2ZmJyAoJ2Z1bGwnIGlzIHRoZVxuICogZW5naW5lIGRlZmF1bHQ7ICdzdW1tYXJ5JyByZXBsYWNlcyBWQUxVRVMgd2l0aCBtYXJrZXJzIGJ1dCBrZWVwcyB0aGVcbiAqIEtFWVMg4oCUIGFuZCBrZXlzIGFyZSBhbGwgYSBzbGljZSBuZWVkcykuIFVuZGVyICdvZmYnIHRoaXMgc291cmNlIHJldHVybnNcbiAqIGVtcHR5IHJlYWQtc2V0cyDigJQgZGV0ZWN0YWJsZSB2aWEgYGNvdmVyYWdlLnN0ZXBzV2l0aFJlYWRzID09PSAwYCwgd2hpY2hcbiAqIGBzbGljZUZvcktleWAgY29waWVzIG9udG8gdGhlIHNsaWNlIHNvIHRvb2xzIGNhbiBzYXkgXCJyZWFkcyB3ZXJlIG5vdFxuICogcmVjb3JkZWRcIiBpbnN0ZWFkIG9mIHRoZSBsaWUgXCJubyBkZXBlbmRlbmNpZXNcIi5cbiAqXG4gKiBTVUJGTE9XIFBBSVJJTkcgKGltcG9ydGFudCk6IGEgc3ViZmxvdyBydW5zIGluIGFuIElTT0xBVEVEIHJ1bnRpbWUg4oCUIGl0c1xuICogY29tbWl0cyBsaXZlIGluIGBzbmFwc2hvdC5zdWJmbG93UmVzdWx0c1tzZklkXS5jb21taXRMb2dgLCBpdHMgcmVhZHMgaW5cbiAqIGBzbmFwc2hvdC5zdWJmbG93UmVzdWx0c1tzZklkXS5leGVjdXRpb25UcmVlYC4gVHJlZXMgYW5kIGxvZ3MgbXVzdCBiZVxuICogcGFpcmVkIGZyb20gdGhlIFNBTUUgc2NvcGU6IHRvIHNsaWNlIGEga2V5IGluc2lkZSBhIHN1YmZsb3csIHJlLWFuY2hvclxuICogdGhlcmUg4oCUXG4gKlxuICogYGBgdHNcbiAqIGNvbnN0IHNmID0gc25hcHNob3Quc3ViZmxvd1Jlc3VsdHNbJ3NmLXRvb2xzJ107XG4gKiBzbGljZUZvcktleShzZi5jb21taXRMb2csIGtleSwga2V5c1JlYWRGcm9tRXhlY3V0aW9uVHJlZShzZi5leGVjdXRpb25UcmVlKSk7XG4gKiBgYGBcbiAqXG4gKiBQYXNzaW5nIG11bHRpcGxlIHRyZWVzIHdpZGVucyBSRUFEIHJlc29sdXRpb24gb25seSAodXNlZnVsIHdoZW4gb25lIGxvZ1xuICogZ2VudWluZWx5IHNwYW5zIHRoZW0pOyBpdCBkb2VzIG5vdCBsZXQgYSByb290LWxvZyBzbGljZSBjcm9zcyBhIHN1YmZsb3dcbiAqIG1vdW50IOKAlCBzZWUgUkVBRE1FLm1kIMKnIFN1YmZsb3cgYm91bmRhcmllcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGtleXNSZWFkRnJvbUV4ZWN1dGlvblRyZWUodHJlZTogRXhlY3V0aW9uVHJlZSB8IHJlYWRvbmx5IEV4ZWN1dGlvblRyZWVbXSk6IEtleXNSZWFkU291cmNlIHtcbiAgY29uc3QgYnlTdGVwID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpO1xuICBsZXQgc3RlcHMgPSAwO1xuICAvLyBUaGUgdHJlZSBpcyBhY3ljbGljIGJ5IGNvbnN0cnVjdGlvbiAobmV4dC9jaGlsZHJlbiksIGJ1dCB0aGlzIHdhbGtlciBpc1xuICAvLyBhbHNvIGhhbmRlZCBDT05TVU1FUi1wcm92aWRlZCBkYXRhIOKAlCBhIHZpc2l0ZWQgc2V0IG1ha2VzIGEgbWFsZm9ybWVkIG9yXG4gIC8vIGhhbmQtYnVpbHQgdHJlZSBhIG5vbi1ldmVudCBpbnN0ZWFkIG9mIGFuIGluZmluaXRlIGxvb3AuXG4gIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PEV4ZWN1dGlvblRyZWU+KCk7XG4gIGNvbnN0IHN0YWNrOiBFeGVjdXRpb25UcmVlW10gPSBbdHJlZV0uZmxhdCgpOyAvLyBvbmUgcm9vdCwgb3Igc2V2ZXJhbCAoc3ViZmxvdyB0cmVlcyk7IGEgaG9sZSBpcyBza2lwcGVkXG4gIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgbm9kZSA9IHN0YWNrLnBvcCgpITtcbiAgICBpZiAodmlzaXRlZC5oYXMobm9kZSkpIGNvbnRpbnVlO1xuICAgIHZpc2l0ZWQuYWRkKG5vZGUpO1xuICAgIGlmIChub2RlLnJ1bnRpbWVTdGFnZUlkKSB7XG4gICAgICBzdGVwcysrO1xuICAgICAgaWYgKG5vZGUuc3RhZ2VSZWFkcykge1xuICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMobm9kZS5zdGFnZVJlYWRzKTtcbiAgICAgICAgaWYgKGtleXMubGVuZ3RoID4gMCkgYnlTdGVwLnNldChub2RlLnJ1bnRpbWVTdGFnZUlkLCBrZXlzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vZGUubmV4dCkgc3RhY2sucHVzaChub2RlLm5leHQpO1xuICAgIGlmIChub2RlLmNoaWxkcmVuKSBmb3IgKGNvbnN0IGMgb2Ygbm9kZS5jaGlsZHJlbikgc3RhY2sucHVzaChjKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGtpbmQ6ICdleGVjdXRpb24tdHJlZScsXG4gICAgbG9va3VwOiAocnVudGltZVN0YWdlSWQ6IHN0cmluZykgPT4gYnlTdGVwLmdldChydW50aW1lU3RhZ2VJZCkgPz8gW10sXG4gICAgY292ZXJhZ2U6IHsgc3RlcHMsIHN0ZXBzV2l0aFJlYWRzOiBieVN0ZXAuc2l6ZSB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJlYWRzIGZyb20gYSBwcmVidWlsdCBtYXAg4oCUIGUuZy4gY29sbGVjdGVkIGxpdmUgZnJvbVxuICogYFNjb3BlUmVjb3JkZXIub25SZWFkYCBldmVudHMsIG9yIGRlc2VyaWFsaXplZCBmcm9tIGEgc3RvcmVkIHRyYWNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24ga2V5c1JlYWRGcm9tTWFwKFxuICBtYXA6IFJlYWRvbmx5TWFwPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+IHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+Pixcbik6IEtleXNSZWFkU291cmNlIHtcbiAgLy8gT3duLXByb3BlcnR5IGd1YXJkIG9uIHRoZSBvYmplY3QgZm9ybTogcnVudGltZVN0YWdlSWRzIGFyZSBjb25zdW1lci1cbiAgLy8gaW5mbHVlbmNlZCBzdHJpbmdzOyB3aXRob3V0IGl0LCBhbiBpZCBsaWtlICdjb25zdHJ1Y3Rvcicgd291bGQgcmVhZFxuICAvLyB0aHJvdWdoIHRoZSBwcm90b3R5cGUgY2hhaW4gKHRoZSBzYW1lIGhhcmRlbmluZyBwb3N0dXJlIGFzIHRoZSBlbmdpbmUnc1xuICAvLyBuYXRpdmVHZXQvcHJvdG90eXBlLXBvbGx1dGlvbiBndWFyZHMpLlxuICBjb25zdCBnZXQ6IChpZDogc3RyaW5nKSA9PiByZWFkb25seSBzdHJpbmdbXSB8IHVuZGVmaW5lZCA9XG4gICAgbWFwIGluc3RhbmNlb2YgTWFwXG4gICAgICA/IChpZCkgPT4gbWFwLmdldChpZClcbiAgICAgIDogKGlkKSA9PlxuICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtYXAsIGlkKSA/IChtYXAgYXMgUmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+KVtpZF0gOiB1bmRlZmluZWQ7XG4gIHJldHVybiB7XG4gICAga2luZDogJ21hcCcsXG4gICAgbG9va3VwOiAocnVudGltZVN0YWdlSWQ6IHN0cmluZykgPT4gWy4uLihnZXQocnVudGltZVN0YWdlSWQpID8/IFtdKV0sXG4gIH07XG59XG5cbi8qKlxuICogTm9ybWFsaXplIHRoZSBlcmdvbm9taWMgdW5pb246IGNhbGxlcnMgbWF5IHBhc3MgYSBmdWxsIHN0cmF0ZWd5IG9iamVjdCBvclxuICogYSBiYXJlIGxvb2t1cCBmdW5jdGlvbiAod3JhcHBlZCBhcyBraW5kICdjdXN0b20tZm4nIHNvIHRoZSBob25lc3R5XG4gKiBicmVhZGNydW1iIHN0aWxsIHNheXMgd2hlcmUgcmVhZHMgY2FtZSBmcm9tKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVLZXlzUmVhZFNvdXJjZShzcmM6IEtleXNSZWFkU291cmNlIHwgS2V5c1JlYWRMb29rdXApOiBLZXlzUmVhZFNvdXJjZSB7XG4gIHJldHVybiB0eXBlb2Ygc3JjID09PSAnZnVuY3Rpb24nID8geyBraW5kOiAnY3VzdG9tLWZuJywgbG9va3VwOiBzcmMgfSA6IHNyYztcbn1cbiJdfQ==
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* slice/serialize.ts — JSON-safe and LLM-safe projections of a slice.
|
|
3
|
-
*
|
|
4
|
-
* WHY (the failure this prevents): `VariableSlice.root` is an in-memory DAG.
|
|
5
|
-
* Nodes are SHARED — a diamond ancestor is one object reached through many
|
|
6
|
-
* paths, and each node appears in both `parents` and `parentEdges[].parent`.
|
|
7
|
-
* `JSON.stringify` knows nothing about sharing: it re-serializes every shared
|
|
8
|
-
* subtree per path, which explodes combinatorially on diamond-heavy slices.
|
|
9
|
-
* The two consumers that would naively stringify are exactly the ones this
|
|
10
|
-
* library exists for — wire transfer (persist / send a slice) and LLM tools
|
|
11
|
-
* (bounded context). Each gets a purpose-built projection:
|
|
12
|
-
*
|
|
13
|
-
* - {@link sliceToJSON} — flat, id-referenced, LINEAR in node count.
|
|
14
|
-
* - {@link formatSlice} — one bounded human/LLM-readable string that also
|
|
15
|
-
* renders the honesty envelope (missing reason, reads coverage, truncation)
|
|
16
|
-
* a raw `formatCausalChain` doesn't know about.
|
|
17
|
-
*
|
|
18
|
-
* The FORWARD half has exactly the same hazard and the same two projections:
|
|
19
|
-
* {@link forwardSliceToJSON} / {@link formatForwardSlice}. A forward DAG
|
|
20
|
-
* shares nodes just as readily — two values read by one stage feed the same
|
|
21
|
-
* child write — so a forward root must never be stringified either.
|
|
22
|
-
*
|
|
23
|
-
* {@link KeyTimeline} is the deliberate exception, stated so nobody adds a
|
|
24
|
-
* pointless twin: it is a FLAT list of plain fields holding no live
|
|
25
|
-
* references and no sharing, so `JSON.stringify(timeline)` is already
|
|
26
|
-
* correct and linear. What it still needs is the bounded LLM projection —
|
|
27
|
-
* {@link formatTimeline} — because "the whole life of a key" is unbounded in
|
|
28
|
-
* a long run.
|
|
29
|
-
*/
|
|
30
|
-
import type { ForwardSlice, ForwardSliceJSON, KeyTimeline, SliceJSON, VariableSlice } from './types.js';
|
|
31
|
-
/**
|
|
32
|
-
* Flat, JSON-safe projection: every DAG node exactly once (keyed by
|
|
33
|
-
* runtimeStageId), edges as id references. Linear in node count — safe to
|
|
34
|
-
* persist, send, or feed to structured consumers. Lossless for everything
|
|
35
|
-
* except the in-memory object graph itself (rebuild adjacency from `edges`).
|
|
36
|
-
*/
|
|
37
|
-
export declare function sliceToJSON(slice: VariableSlice): SliceJSON;
|
|
38
|
-
/**
|
|
39
|
-
* One bounded string for LLM triage tools (the `traceToolpack` consumption
|
|
40
|
-
* pattern: tools return plain strings, never recursive objects). Wraps
|
|
41
|
-
* `formatCausalChain` (which is budget-bounded by causalChain's
|
|
42
|
-
* maxDepth/maxNodes and renders shared nodes once as `↳ … (see above)`),
|
|
43
|
-
* and adds the honesty envelope the raw chain doesn't carry:
|
|
44
|
-
*
|
|
45
|
-
* - missing slices render their reason ("value came from initial state /
|
|
46
|
-
* frozen args / a closure — the commit log cannot see those"),
|
|
47
|
-
* - a reads-less provider (`readTracking: 'off'` signature) renders an
|
|
48
|
-
* explicit "⚠ reads were not recorded" instead of silently showing an
|
|
49
|
-
* anchor with no dependencies,
|
|
50
|
-
* - truncation footers pass through from formatCausalChain.
|
|
51
|
-
*/
|
|
52
|
-
export declare function formatSlice(slice: VariableSlice): string;
|
|
53
|
-
/**
|
|
54
|
-
* Flat, JSON-safe projection of a {@link ForwardSlice} — the forward twin of
|
|
55
|
-
* {@link sliceToJSON}, linear in node count.
|
|
56
|
-
*
|
|
57
|
-
* Node ids are OPAQUE (`n0`, `n1`, … in BFS order) rather than
|
|
58
|
-
* `runtimeStageId` as in `SliceJSON`, for a structural reason: a forward
|
|
59
|
-
* node is a (key, write) pair, so ONE stage that wrote two keys owns two
|
|
60
|
-
* nodes and a runtimeStageId cannot key the map. Never parse the ids — join
|
|
61
|
-
* on `runtimeStageId` / `commitIdx` / `key`, which every node carries.
|
|
62
|
-
*/
|
|
63
|
-
export declare function forwardSliceToJSON(slice: ForwardSlice): ForwardSliceJSON;
|
|
64
|
-
/**
|
|
65
|
-
* One bounded string for LLM triage tools — the forward twin of
|
|
66
|
-
* {@link formatSlice}. Shared nodes render once (`↳ … (see above)`, the same
|
|
67
|
-
* convention `formatCausalChain` uses), read lists are capped, and every
|
|
68
|
-
* honesty note renders as a `⚠` line — including the one that says a `fed`
|
|
69
|
-
* edge is conservative, which is why edges print `[exact]` / `[conservative]`
|
|
70
|
-
* rather than looking alike.
|
|
71
|
-
*/
|
|
72
|
-
export declare function formatForwardSlice(slice: ForwardSlice): string;
|
|
73
|
-
/**
|
|
74
|
-
* One bounded string for a {@link KeyTimeline} — the LLM/human projection.
|
|
75
|
-
* (The timeline's JSON needs no helper: it is already flat and JSON-safe —
|
|
76
|
-
* see the file header.) Truncation is stated, never silent.
|
|
77
|
-
*/
|
|
78
|
-
export declare function formatTimeline(timeline: KeyTimeline): string;
|