footprintjs 5.0.0 → 6.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.
Files changed (78) hide show
  1. package/CLAUDE.md +32 -8
  2. package/dist/advanced.js +2 -3
  3. package/dist/esm/advanced.js +2 -2
  4. package/dist/esm/index.js +1 -1
  5. package/dist/esm/lib/builder/FlowChartBuilder.js +364 -100
  6. package/dist/esm/lib/builder/index.js +1 -1
  7. package/dist/esm/lib/builder/structure/StructureRecorder.js +158 -0
  8. package/dist/esm/lib/builder/structure/StructureRecorderDispatcher.js +171 -0
  9. package/dist/esm/lib/builder/types.js +1 -1
  10. package/dist/esm/lib/engine/errors/errorInfo.js +4 -3
  11. package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +11 -2
  12. package/dist/esm/lib/engine/handlers/DeciderHandler.js +5 -7
  13. package/dist/esm/lib/engine/handlers/RuntimeStructureManager.js +2 -2
  14. package/dist/esm/lib/engine/handlers/SelectorHandler.js +9 -7
  15. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +7 -1
  16. package/dist/esm/lib/engine/handlers/index.js +1 -3
  17. package/dist/esm/lib/engine/handlers/types.js +2 -2
  18. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +12 -2
  19. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +3 -3
  20. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +8 -1
  21. package/dist/esm/lib/engine/narrative/types.js +1 -1
  22. package/dist/esm/lib/engine/runtimeStageId.js +64 -2
  23. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +11 -54
  24. package/dist/esm/lib/engine/types.js +1 -1
  25. package/dist/esm/lib/engine/walkSubflowSpec.js +144 -0
  26. package/dist/esm/lib/runner/FlowChartExecutor.js +4 -17
  27. package/dist/esm/lib/runner/getSubtreeSnapshot.js +3 -2
  28. package/dist/esm/trace.js +3 -2
  29. package/dist/index.js +1 -1
  30. package/dist/lib/builder/FlowChartBuilder.js +364 -100
  31. package/dist/lib/builder/index.js +1 -1
  32. package/dist/lib/builder/structure/StructureRecorder.js +159 -0
  33. package/dist/lib/builder/structure/StructureRecorderDispatcher.js +175 -0
  34. package/dist/lib/builder/types.js +1 -1
  35. package/dist/lib/engine/errors/errorInfo.js +4 -3
  36. package/dist/lib/engine/handlers/ChildrenExecutor.js +11 -2
  37. package/dist/lib/engine/handlers/DeciderHandler.js +5 -7
  38. package/dist/lib/engine/handlers/RuntimeStructureManager.js +2 -2
  39. package/dist/lib/engine/handlers/SelectorHandler.js +9 -7
  40. package/dist/lib/engine/handlers/SubflowExecutor.js +7 -1
  41. package/dist/lib/engine/handlers/index.js +2 -5
  42. package/dist/lib/engine/handlers/types.js +2 -2
  43. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +12 -2
  44. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +3 -3
  45. package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +8 -1
  46. package/dist/lib/engine/narrative/types.js +1 -1
  47. package/dist/lib/engine/runtimeStageId.js +66 -3
  48. package/dist/lib/engine/traversal/FlowchartTraverser.js +11 -54
  49. package/dist/lib/engine/types.js +1 -1
  50. package/dist/lib/engine/walkSubflowSpec.js +148 -0
  51. package/dist/lib/runner/FlowChartExecutor.js +4 -17
  52. package/dist/lib/runner/getSubtreeSnapshot.js +3 -2
  53. package/dist/trace.js +5 -2
  54. package/dist/types/advanced.d.ts +4 -4
  55. package/dist/types/index.d.ts +2 -0
  56. package/dist/types/lib/builder/FlowChartBuilder.d.ts +110 -14
  57. package/dist/types/lib/builder/index.d.ts +2 -1
  58. package/dist/types/lib/builder/structure/StructureRecorder.d.ts +349 -0
  59. package/dist/types/lib/builder/structure/StructureRecorderDispatcher.d.ts +77 -0
  60. package/dist/types/lib/builder/types.d.ts +20 -6
  61. package/dist/types/lib/engine/errors/errorInfo.d.ts +3 -2
  62. package/dist/types/lib/engine/handlers/DeciderHandler.d.ts +3 -3
  63. package/dist/types/lib/engine/handlers/RuntimeStructureManager.d.ts +1 -1
  64. package/dist/types/lib/engine/handlers/SelectorHandler.d.ts +2 -2
  65. package/dist/types/lib/engine/handlers/index.d.ts +1 -2
  66. package/dist/types/lib/engine/handlers/types.d.ts +2 -9
  67. package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +2 -2
  68. package/dist/types/lib/engine/narrative/types.d.ts +24 -2
  69. package/dist/types/lib/engine/runtimeStageId.d.ts +57 -1
  70. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +1 -6
  71. package/dist/types/lib/engine/types.d.ts +0 -26
  72. package/dist/types/lib/engine/walkSubflowSpec.d.ts +95 -0
  73. package/dist/types/lib/runner/FlowChartExecutor.d.ts +4 -16
  74. package/dist/types/trace.d.ts +3 -1
  75. package/package.json +1 -1
  76. package/dist/esm/lib/engine/handlers/ExtractorRunner.js +0 -122
  77. package/dist/lib/engine/handlers/ExtractorRunner.js +0 -126
  78. package/dist/types/lib/engine/handlers/ExtractorRunner.d.ts +0 -41
package/dist/trace.js CHANGED
@@ -22,11 +22,14 @@
22
22
  * ```
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.qualityTrace = exports.formatQualityTrace = exports.QualityRecorder = exports.ROOT_SUBFLOW_ID = exports.ROOT_RUNTIME_STAGE_ID = exports.inOutRecorder = exports.InOutRecorder = exports.topologyRecorder = exports.TopologyRecorder = exports.BoundaryStateTracker = exports.SequenceRecorder = exports.KeyedRecorder = exports.CommitRangeIndex = exports.SequenceStore = exports.KeyedStore = exports.BoundaryStateStore = exports.formatCausalChain = exports.flattenCausalDAG = exports.causalChain = exports.findLastWriter = exports.findCommits = exports.findCommit = exports.parseRuntimeStageId = exports.createExecutionCounter = exports.buildRuntimeStageId = void 0;
25
+ exports.qualityTrace = exports.formatQualityTrace = exports.QualityRecorder = exports.ROOT_SUBFLOW_ID = exports.ROOT_RUNTIME_STAGE_ID = exports.inOutRecorder = exports.InOutRecorder = exports.topologyRecorder = exports.TopologyRecorder = exports.BoundaryStateTracker = exports.SequenceRecorder = exports.KeyedRecorder = exports.CommitRangeIndex = exports.SequenceStore = exports.KeyedStore = exports.BoundaryStateStore = exports.formatCausalChain = exports.flattenCausalDAG = exports.causalChain = exports.findLastWriter = exports.findCommits = exports.findCommit = exports.walkSubflowSpec = exports.splitStageId = exports.parseRuntimeStageId = exports.createExecutionCounter = exports.buildRuntimeStageId = void 0;
26
26
  var runtimeStageId_js_1 = require("./lib/engine/runtimeStageId.js");
27
27
  Object.defineProperty(exports, "buildRuntimeStageId", { enumerable: true, get: function () { return runtimeStageId_js_1.buildRuntimeStageId; } });
28
28
  Object.defineProperty(exports, "createExecutionCounter", { enumerable: true, get: function () { return runtimeStageId_js_1.createExecutionCounter; } });
29
29
  Object.defineProperty(exports, "parseRuntimeStageId", { enumerable: true, get: function () { return runtimeStageId_js_1.parseRuntimeStageId; } });
30
+ Object.defineProperty(exports, "splitStageId", { enumerable: true, get: function () { return runtimeStageId_js_1.splitStageId; } });
31
+ var walkSubflowSpec_js_1 = require("./lib/engine/walkSubflowSpec.js");
32
+ Object.defineProperty(exports, "walkSubflowSpec", { enumerable: true, get: function () { return walkSubflowSpec_js_1.walkSubflowSpec; } });
30
33
  // Commit log queries — typed utilities for backtracking
31
34
  var commitLogUtils_js_1 = require("./lib/memory/commitLogUtils.js");
32
35
  Object.defineProperty(exports, "findCommit", { enumerable: true, get: function () { return commitLogUtils_js_1.findCommit; } });
@@ -75,4 +78,4 @@ Object.defineProperty(exports, "QualityRecorder", { enumerable: true, get: funct
75
78
  var qualityTrace_js_1 = require("./lib/recorder/qualityTrace.js");
76
79
  Object.defineProperty(exports, "formatQualityTrace", { enumerable: true, get: function () { return qualityTrace_js_1.formatQualityTrace; } });
77
80
  Object.defineProperty(exports, "qualityTrace", { enumerable: true, get: function () { return qualityTrace_js_1.qualityTrace; } });
78
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7OztBQUlILG9FQUFrSDtBQUF6Ryx3SEFBQSxtQkFBbUIsT0FBQTtBQUFFLDJIQUFBLHNCQUFzQixPQUFBO0FBQUUsd0hBQUEsbUJBQW1CLE9BQUE7QUFFekUsd0RBQXdEO0FBQ3hELG9FQUF5RjtBQUFoRiwrR0FBQSxVQUFVLE9BQUE7QUFBRSxnSEFBQSxXQUFXLE9BQUE7QUFBRSxtSEFBQSxjQUFjLE9BQUE7QUFJaEQsMERBQTZGO0FBQXBGLDJHQUFBLFdBQVcsT0FBQTtBQUFFLGdIQUFBLGdCQUFnQixPQUFBO0FBQUUsaUhBQUEsaUJBQWlCLE9BQUE7QUFFekQsbUVBQW1FO0FBQ25FLGlFQUFpRTtBQUNqRSxpRUFBaUU7QUFDakUsNENBQTRDO0FBQzVDLDhFQUEwRTtBQUFqRSwySEFBQSxrQkFBa0IsT0FBQTtBQUMzQiw4REFBMEQ7QUFBakQsMkdBQUEsVUFBVSxPQUFBO0FBQ25CLG9FQUFnRTtBQUF2RCxpSEFBQSxhQUFhLE9BQUE7QUFTdEIsMEVBQXNFO0FBQTdELHVIQUFBLGdCQUFnQixPQUFBO0FBRXpCLG9FQUFvRTtBQUNwRSwrREFBK0Q7QUFDL0QsZ0VBQWdFO0FBQ2hFLHdEQUF3RDtBQUN4RCx5REFBeUQ7QUFDekQsb0VBQWdFO0FBQXZELGlIQUFBLGFBQWEsT0FBQTtBQUV0QixvRkFBb0Y7QUFDcEYsMEVBQXNFO0FBQTdELHVIQUFBLGdCQUFnQixPQUFBO0FBRXpCLHVFQUF1RTtBQUN2RSw2RUFBNkU7QUFDN0Usa0ZBQThFO0FBQXJFLCtIQUFBLG9CQUFvQixPQUFBO0FBVTdCLDBFQUF3RjtBQUEvRSx1SEFBQSxnQkFBZ0IsT0FBQTtBQUFFLHVIQUFBLGdCQUFnQixPQUFBO0FBSzNDLG9FQUF1SDtBQUE5RyxpSEFBQSxhQUFhLE9BQUE7QUFBRSxpSEFBQSxhQUFhLE9BQUE7QUFBRSx5SEFBQSxxQkFBcUIsT0FBQTtBQUFFLG1IQUFBLGVBQWUsT0FBQTtBQUk3RSx3RUFBb0U7QUFBM0QscUhBQUEsZUFBZSxPQUFBO0FBSXhCLGtFQUFrRjtBQUF6RSxxSEFBQSxrQkFBa0IsT0FBQTtBQUFFLCtHQUFBLFlBQVksT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZm9vdHByaW50anMvdHJhY2Ug4oCUIEV4ZWN1dGlvbiB0cmFjaW5nLCBkZWJ1Z2dpbmcsIGFuZCBiYWNrdHJhY2tpbmcgdXRpbGl0aWVzLlxuICpcbiAqIFJ1bnRpbWUgc3RhZ2UgSURzLCBjb21taXQgbG9nIHF1ZXJpZXMsIGFuZCByZWNvcmRlciBiYXNlIGNsYXNzZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IHBhcnNlUnVudGltZVN0YWdlSWQsIGZpbmRMYXN0V3JpdGVyLCBLZXllZFJlY29yZGVyLCBTZXF1ZW5jZVJlY29yZGVyIH0gZnJvbSAnZm9vdHByaW50anMvdHJhY2UnO1xuICpcbiAqIC8vIFBhcnNlIGEgcnVudGltZVN0YWdlSWRcbiAqIGNvbnN0IHsgc3RhZ2VJZCwgZXhlY3V0aW9uSW5kZXggfSA9IHBhcnNlUnVudGltZVN0YWdlSWQoJ2NhbGwtbGxtIzUnKTtcbiAqXG4gKiAvLyBCYWNrdHJhY2s6IHdobyB3cm90ZSAnc3lzdGVtUHJvbXB0JyBiZWZvcmUgc3RhZ2UgYXQgaWR4IDg/XG4gKiBjb25zdCB3cml0ZXIgPSBmaW5kTGFzdFdyaXRlcihjb21taXRMb2csICdzeXN0ZW1Qcm9tcHQnLCA4KTtcbiAqXG4gKiAvLyBCdWlsZCBhIGtleWVkIHJlY29yZGVyICgxOjEg4oCUIG9uZSBlbnRyeSBwZXIgc3RlcClcbiAqIGNsYXNzIE15UmVjb3JkZXIgZXh0ZW5kcyBLZXllZFJlY29yZGVyPE15RW50cnk+IHsgLi4uIH1cbiAqXG4gKiAvLyBCdWlsZCBhIHNlcXVlbmNlIHJlY29yZGVyICgxOk4g4oCUIG11bHRpcGxlIGVudHJpZXMgcGVyIHN0ZXAsIG9yZGVyaW5nIG1hdHRlcnMpXG4gKiBjbGFzcyBBdWRpdFJlY29yZGVyIGV4dGVuZHMgU2VxdWVuY2VSZWNvcmRlcjxBdWRpdEVudHJ5PiB7IC4uLiB9XG4gKiBgYGBcbiAqL1xuXG4vLyBSdW50aW1lIHN0YWdlIElEIOKAlCB1bmlxdWUgZXhlY3V0aW9uIHN0ZXAgaWRlbnRpZmllcnNcbmV4cG9ydCB0eXBlIHsgRXhlY3V0aW9uQ291bnRlciB9IGZyb20gJy4vbGliL2VuZ2luZS9ydW50aW1lU3RhZ2VJZC5qcyc7XG5leHBvcnQgeyBidWlsZFJ1bnRpbWVTdGFnZUlkLCBjcmVhdGVFeGVjdXRpb25Db3VudGVyLCBwYXJzZVJ1bnRpbWVTdGFnZUlkIH0gZnJvbSAnLi9saWIvZW5naW5lL3J1bnRpbWVTdGFnZUlkLmpzJztcblxuLy8gQ29tbWl0IGxvZyBxdWVyaWVzIOKAlCB0eXBlZCB1dGlsaXRpZXMgZm9yIGJhY2t0cmFja2luZ1xuZXhwb3J0IHsgZmluZENvbW1pdCwgZmluZENvbW1pdHMsIGZpbmRMYXN0V3JpdGVyIH0gZnJvbSAnLi9saWIvbWVtb3J5L2NvbW1pdExvZ1V0aWxzLmpzJztcblxuLy8gQ2F1c2FsIGNoYWluIOKAlCBiYWNrd2FyZCBwcm9ncmFtIHNsaWNpbmcgb24gY29tbWl0IGxvZyAoREFHKVxuZXhwb3J0IHR5cGUgeyBDYXVzYWxDaGFpbk9wdGlvbnMsIENhdXNhbE5vZGUsIEtleXNSZWFkTG9va3VwIH0gZnJvbSAnLi9saWIvbWVtb3J5L2JhY2t0cmFjay5qcyc7XG5leHBvcnQgeyBjYXVzYWxDaGFpbiwgZmxhdHRlbkNhdXNhbERBRywgZm9ybWF0Q2F1c2FsQ2hhaW4gfSBmcm9tICcuL2xpYi9tZW1vcnkvYmFja3RyYWNrLmpzJztcblxuLy8g4pSA4pSAIHY1IFN0b3JlcyAoY29uY3JldGUsIGNvbXBvc2FibGUg4oCUIHByaW1hcnkgcmVjb3JkZXIgQVBJKSDilIDilIDilIDilIDilIBcbi8vIENvbXBvc2UgdGhlc2UgdmlhIGBuZXcgU3RvcmU8VD4oKWAgYXMgYSBmaWVsZCBvbiB5b3VyIHJlY29yZGVyXG4vLyBjbGFzcy4gT25lIHB1cnBvc2UgcGVyIHJlY29yZGVyOiBzdG9yZXMgYXJlIHN0b3JhZ2U7IHJlY29yZGVyc1xuLy8gYXJlIGV2ZW50LWhvb2sgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9ucy5cbmV4cG9ydCB7IEJvdW5kYXJ5U3RhdGVTdG9yZSB9IGZyb20gJy4vbGliL3JlY29yZGVyL0JvdW5kYXJ5U3RhdGVTdG9yZS5qcyc7XG5leHBvcnQgeyBLZXllZFN0b3JlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvS2V5ZWRTdG9yZS5qcyc7XG5leHBvcnQgeyBTZXF1ZW5jZVN0b3JlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvU2VxdWVuY2VTdG9yZS5qcyc7XG5cbi8vIOKUgOKUgCB2NS4xIENvbW1pdCBncm91cGluZyBwcmltaXRpdmUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBJbnRlcnZhbCBpbmRleCBvdmVyIGNvbW1pdCBpbmRpY2VzLiBCdWlsdCBpbmNyZW1lbnRhbGx5IGR1cmluZ1xuLy8gdHJhdmVyc2FsOiBvcGVuKCkgb24gYm91bmRhcnkgZW50cnksIGNsb3NlKCkgb24gZXhpdC4gUXVlcnkgYXQgYW55XG4vLyBjb21taXQgcG9zaXRpb24gd2l0aCBlbmNsb3NpbmcoKS9vdmVybGFwcGluZygpLiBHZW5lcmljIG92ZXIgVExhYmVsXG4vLyDigJQgZm9vdHByaW50anMgb3ducyBaRVJPIGtub3dsZWRnZSBvZiB3aGF0IGNvbnN1bWVycyB1c2UgYXMgbGFiZWxzLlxuLy8gU2VlIGRvY3MvZGVzaWduL2NvbW1pdC1yYW5nZS1pbmRleC5tZCBmb3IgdGhlIGZ1bGwgY29udHJhY3QuXG5leHBvcnQgdHlwZSB7IFJhbmdlRW50cnksIFJhbmdlVG9rZW4gfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Db21taXRSYW5nZUluZGV4LmpzJztcbmV4cG9ydCB7IENvbW1pdFJhbmdlSW5kZXggfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Db21taXRSYW5nZUluZGV4LmpzJztcblxuLy8g4pSA4pSAIEFic3RyYWN0IGJhc2VzIChERVBSRUNBVEVEIGluIHY1IOKAlCBzbGF0ZWQgZm9yIHJlbW92YWwpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gS2VwdCBkdXJpbmcgdGhlIHY1IG1pZ3JhdGlvbiB3aW5kb3cgZm9yIGRvd25zdHJlYW0gY29uc3VtZXJzXG4vLyAoYWdlbnRmb290cHJpbnQsIGFnZW50Zm9vdHByaW50LWxlbnMsIGV0Yy4pIHRoYXQgc3RpbGwgZXh0ZW5kXG4vLyB0aGVtLiBNaWdyYXRlIHRvIHRoZSBjb3JyZXNwb25kaW5nIFN0b3JlIGNsYXNzIGFib3ZlLlxuLy8gS2V5ZWRSZWNvcmRlciDigJQgYmFzZSBjbGFzcyBmb3IgMToxIE1hcC1iYXNlZCByZWNvcmRlcnNcbmV4cG9ydCB7IEtleWVkUmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9LZXllZFJlY29yZGVyLmpzJztcblxuLy8gU2VxdWVuY2VSZWNvcmRlciDigJQgYmFzZSBjbGFzcyBmb3IgMTpOIG9yZGVyZWQgc2VxdWVuY2UgcmVjb3JkZXJzIHdpdGgga2V5ZWQgaW5kZXhcbmV4cG9ydCB7IFNlcXVlbmNlUmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9TZXF1ZW5jZVJlY29yZGVyLmpzJztcblxuLy8gQm91bmRhcnlTdGF0ZVRyYWNrZXIg4oCUIGJhc2UgY2xhc3MgZm9yIHRyYW5zaWVudCBicmFja2V0LXNjb3BlZCBzdGF0ZVxuLy8gKGxpdmUgc3RhdGUgRFVSSU5HIGEgbWF0Y2hlZCBbc3RhcnQsIHN0b3BdIGV2ZW50IGludGVydmFsOyBjbGVhcnMgb24gc3RvcClcbmV4cG9ydCB7IEJvdW5kYXJ5U3RhdGVUcmFja2VyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQm91bmRhcnlTdGF0ZVRyYWNrZXIuanMnO1xuXG4vLyBUb3BvbG9neVJlY29yZGVyIOKAlCBjb21wb3NpdGlvbiBncmFwaCBhY2N1bXVsYXRvciAoc3ViZmxvd3MgKyBjb250cm9sLWZsb3cgZWRnZXMpXG5leHBvcnQgdHlwZSB7XG4gIFRvcG9sb2d5LFxuICBUb3BvbG9neUVkZ2UsXG4gIFRvcG9sb2d5SW5jb21pbmdLaW5kLFxuICBUb3BvbG9neU5vZGUsXG4gIFRvcG9sb2d5UmVjb3JkZXJPcHRpb25zLFxufSBmcm9tICcuL2xpYi9yZWNvcmRlci9Ub3BvbG9neVJlY29yZGVyLmpzJztcbmV4cG9ydCB7IFRvcG9sb2d5UmVjb3JkZXIsIHRvcG9sb2d5UmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Ub3BvbG9neVJlY29yZGVyLmpzJztcblxuLy8gSW5PdXRSZWNvcmRlciDigJQgY2hhcnQgaW4vb3V0IHN0cmVhbSAoZW50cnkvZXhpdCBwYWlycyBhdCBldmVyeSBjaGFydCBib3VuZGFyeSxcbi8vIGluY2x1ZGluZyB0aGUgdG9wLWxldmVsIHJ1biBhbmQgZXZlcnkgc3ViZmxvdylcbmV4cG9ydCB0eXBlIHsgSW5PdXRFbnRyeSwgSW5PdXRQaGFzZSwgSW5PdXRSZWNvcmRlck9wdGlvbnMgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Jbk91dFJlY29yZGVyLmpzJztcbmV4cG9ydCB7IEluT3V0UmVjb3JkZXIsIGluT3V0UmVjb3JkZXIsIFJPT1RfUlVOVElNRV9TVEFHRV9JRCwgUk9PVF9TVUJGTE9XX0lEIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvSW5PdXRSZWNvcmRlci5qcyc7XG5cbi8vIFF1YWxpdHlSZWNvcmRlciDigJQgcGVyLXN0ZXAgcXVhbGl0eSBzY29yaW5nIHdpdGggYmFja3RyYWNraW5nXG5leHBvcnQgdHlwZSB7IFF1YWxpdHlFbnRyeSwgUXVhbGl0eVJlY29yZGVyT3B0aW9ucywgUXVhbGl0eVNjb3JpbmdGbiB9IGZyb20gJy4vbGliL3JlY29yZGVyL1F1YWxpdHlSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBRdWFsaXR5UmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9RdWFsaXR5UmVjb3JkZXIuanMnO1xuXG4vLyBxdWFsaXR5VHJhY2Ug4oCUIFF1YWxpdHkgU3RhY2sgVHJhY2UgKGJhY2t0cmFjayBmcm9tIGxvdy1zY29yaW5nIHN0ZXBzKVxuZXhwb3J0IHR5cGUgeyBRdWFsaXR5RnJhbWUsIFF1YWxpdHlTdGFja1RyYWNlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvcXVhbGl0eVRyYWNlLmpzJztcbmV4cG9ydCB7IGZvcm1hdFF1YWxpdHlUcmFjZSwgcXVhbGl0eVRyYWNlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvcXVhbGl0eVRyYWNlLmpzJztcbiJdfQ==
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7OztBQUlILG9FQUt3QztBQUp0Qyx3SEFBQSxtQkFBbUIsT0FBQTtBQUNuQiwySEFBQSxzQkFBc0IsT0FBQTtBQUN0Qix3SEFBQSxtQkFBbUIsT0FBQTtBQUNuQixpSEFBQSxZQUFZLE9BQUE7QUFNZCxzRUFBa0U7QUFBekQscUhBQUEsZUFBZSxPQUFBO0FBRXhCLHdEQUF3RDtBQUN4RCxvRUFBeUY7QUFBaEYsK0dBQUEsVUFBVSxPQUFBO0FBQUUsZ0hBQUEsV0FBVyxPQUFBO0FBQUUsbUhBQUEsY0FBYyxPQUFBO0FBSWhELDBEQUE2RjtBQUFwRiwyR0FBQSxXQUFXLE9BQUE7QUFBRSxnSEFBQSxnQkFBZ0IsT0FBQTtBQUFFLGlIQUFBLGlCQUFpQixPQUFBO0FBRXpELG1FQUFtRTtBQUNuRSxpRUFBaUU7QUFDakUsaUVBQWlFO0FBQ2pFLDRDQUE0QztBQUM1Qyw4RUFBMEU7QUFBakUsMkhBQUEsa0JBQWtCLE9BQUE7QUFDM0IsOERBQTBEO0FBQWpELDJHQUFBLFVBQVUsT0FBQTtBQUNuQixvRUFBZ0U7QUFBdkQsaUhBQUEsYUFBYSxPQUFBO0FBU3RCLDBFQUFzRTtBQUE3RCx1SEFBQSxnQkFBZ0IsT0FBQTtBQUV6QixvRUFBb0U7QUFDcEUsK0RBQStEO0FBQy9ELGdFQUFnRTtBQUNoRSx3REFBd0Q7QUFDeEQseURBQXlEO0FBQ3pELG9FQUFnRTtBQUF2RCxpSEFBQSxhQUFhLE9BQUE7QUFFdEIsb0ZBQW9GO0FBQ3BGLDBFQUFzRTtBQUE3RCx1SEFBQSxnQkFBZ0IsT0FBQTtBQUV6Qix1RUFBdUU7QUFDdkUsNkVBQTZFO0FBQzdFLGtGQUE4RTtBQUFyRSwrSEFBQSxvQkFBb0IsT0FBQTtBQVU3QiwwRUFBd0Y7QUFBL0UsdUhBQUEsZ0JBQWdCLE9BQUE7QUFBRSx1SEFBQSxnQkFBZ0IsT0FBQTtBQUszQyxvRUFBdUg7QUFBOUcsaUhBQUEsYUFBYSxPQUFBO0FBQUUsaUhBQUEsYUFBYSxPQUFBO0FBQUUseUhBQUEscUJBQXFCLE9BQUE7QUFBRSxtSEFBQSxlQUFlLE9BQUE7QUFJN0Usd0VBQW9FO0FBQTNELHFIQUFBLGVBQWUsT0FBQTtBQUl4QixrRUFBa0Y7QUFBekUscUhBQUEsa0JBQWtCLE9BQUE7QUFBRSwrR0FBQSxZQUFZLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGZvb3RwcmludGpzL3RyYWNlIOKAlCBFeGVjdXRpb24gdHJhY2luZywgZGVidWdnaW5nLCBhbmQgYmFja3RyYWNraW5nIHV0aWxpdGllcy5cbiAqXG4gKiBSdW50aW1lIHN0YWdlIElEcywgY29tbWl0IGxvZyBxdWVyaWVzLCBhbmQgcmVjb3JkZXIgYmFzZSBjbGFzc2VzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBwYXJzZVJ1bnRpbWVTdGFnZUlkLCBmaW5kTGFzdFdyaXRlciwgS2V5ZWRSZWNvcmRlciwgU2VxdWVuY2VSZWNvcmRlciB9IGZyb20gJ2Zvb3RwcmludGpzL3RyYWNlJztcbiAqXG4gKiAvLyBQYXJzZSBhIHJ1bnRpbWVTdGFnZUlkXG4gKiBjb25zdCB7IHN0YWdlSWQsIGV4ZWN1dGlvbkluZGV4IH0gPSBwYXJzZVJ1bnRpbWVTdGFnZUlkKCdjYWxsLWxsbSM1Jyk7XG4gKlxuICogLy8gQmFja3RyYWNrOiB3aG8gd3JvdGUgJ3N5c3RlbVByb21wdCcgYmVmb3JlIHN0YWdlIGF0IGlkeCA4P1xuICogY29uc3Qgd3JpdGVyID0gZmluZExhc3RXcml0ZXIoY29tbWl0TG9nLCAnc3lzdGVtUHJvbXB0JywgOCk7XG4gKlxuICogLy8gQnVpbGQgYSBrZXllZCByZWNvcmRlciAoMToxIOKAlCBvbmUgZW50cnkgcGVyIHN0ZXApXG4gKiBjbGFzcyBNeVJlY29yZGVyIGV4dGVuZHMgS2V5ZWRSZWNvcmRlcjxNeUVudHJ5PiB7IC4uLiB9XG4gKlxuICogLy8gQnVpbGQgYSBzZXF1ZW5jZSByZWNvcmRlciAoMTpOIOKAlCBtdWx0aXBsZSBlbnRyaWVzIHBlciBzdGVwLCBvcmRlcmluZyBtYXR0ZXJzKVxuICogY2xhc3MgQXVkaXRSZWNvcmRlciBleHRlbmRzIFNlcXVlbmNlUmVjb3JkZXI8QXVkaXRFbnRyeT4geyAuLi4gfVxuICogYGBgXG4gKi9cblxuLy8gUnVudGltZSBzdGFnZSBJRCDigJQgdW5pcXVlIGV4ZWN1dGlvbiBzdGVwIGlkZW50aWZpZXJzXG5leHBvcnQgdHlwZSB7IEV4ZWN1dGlvbkNvdW50ZXIgfSBmcm9tICcuL2xpYi9lbmdpbmUvcnVudGltZVN0YWdlSWQuanMnO1xuZXhwb3J0IHtcbiAgYnVpbGRSdW50aW1lU3RhZ2VJZCxcbiAgY3JlYXRlRXhlY3V0aW9uQ291bnRlcixcbiAgcGFyc2VSdW50aW1lU3RhZ2VJZCxcbiAgc3BsaXRTdGFnZUlkLFxufSBmcm9tICcuL2xpYi9lbmdpbmUvcnVudGltZVN0YWdlSWQuanMnO1xuXG4vLyB3YWxrU3ViZmxvd1NwZWMg4oCUIGZsYXQgb3JkZXJlZCB0cmF2ZXJzYWwgb2YgYSBzdWJmbG93J3Mgc3RydWN0dXJlXG4vLyAoY29uc3VtZSB2aWEgU3RydWN0dXJlUmVjb3JkZXIub25TdWJmbG93TW91bnRlZCdzIHN1YmZsb3dTcGVjIHBheWxvYWQpXG5leHBvcnQgdHlwZSB7IFdhbGtlckl0ZW0sIFdhbGtlck9wdGlvbnMgfSBmcm9tICcuL2xpYi9lbmdpbmUvd2Fsa1N1YmZsb3dTcGVjLmpzJztcbmV4cG9ydCB7IHdhbGtTdWJmbG93U3BlYyB9IGZyb20gJy4vbGliL2VuZ2luZS93YWxrU3ViZmxvd1NwZWMuanMnO1xuXG4vLyBDb21taXQgbG9nIHF1ZXJpZXMg4oCUIHR5cGVkIHV0aWxpdGllcyBmb3IgYmFja3RyYWNraW5nXG5leHBvcnQgeyBmaW5kQ29tbWl0LCBmaW5kQ29tbWl0cywgZmluZExhc3RXcml0ZXIgfSBmcm9tICcuL2xpYi9tZW1vcnkvY29tbWl0TG9nVXRpbHMuanMnO1xuXG4vLyBDYXVzYWwgY2hhaW4g4oCUIGJhY2t3YXJkIHByb2dyYW0gc2xpY2luZyBvbiBjb21taXQgbG9nIChEQUcpXG5leHBvcnQgdHlwZSB7IENhdXNhbENoYWluT3B0aW9ucywgQ2F1c2FsTm9kZSwgS2V5c1JlYWRMb29rdXAgfSBmcm9tICcuL2xpYi9tZW1vcnkvYmFja3RyYWNrLmpzJztcbmV4cG9ydCB7IGNhdXNhbENoYWluLCBmbGF0dGVuQ2F1c2FsREFHLCBmb3JtYXRDYXVzYWxDaGFpbiB9IGZyb20gJy4vbGliL21lbW9yeS9iYWNrdHJhY2suanMnO1xuXG4vLyDilIDilIAgdjUgU3RvcmVzIChjb25jcmV0ZSwgY29tcG9zYWJsZSDigJQgcHJpbWFyeSByZWNvcmRlciBBUEkpIOKUgOKUgOKUgOKUgOKUgFxuLy8gQ29tcG9zZSB0aGVzZSB2aWEgYG5ldyBTdG9yZTxUPigpYCBhcyBhIGZpZWxkIG9uIHlvdXIgcmVjb3JkZXJcbi8vIGNsYXNzLiBPbmUgcHVycG9zZSBwZXIgcmVjb3JkZXI6IHN0b3JlcyBhcmUgc3RvcmFnZTsgcmVjb3JkZXJzXG4vLyBhcmUgZXZlbnQtaG9vayBpbnRlcmZhY2UgaW1wbGVtZW50YXRpb25zLlxuZXhwb3J0IHsgQm91bmRhcnlTdGF0ZVN0b3JlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQm91bmRhcnlTdGF0ZVN0b3JlLmpzJztcbmV4cG9ydCB7IEtleWVkU3RvcmUgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9LZXllZFN0b3JlLmpzJztcbmV4cG9ydCB7IFNlcXVlbmNlU3RvcmUgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9TZXF1ZW5jZVN0b3JlLmpzJztcblxuLy8g4pSA4pSAIHY1LjEgQ29tbWl0IGdyb3VwaW5nIHByaW1pdGl2ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIEludGVydmFsIGluZGV4IG92ZXIgY29tbWl0IGluZGljZXMuIEJ1aWx0IGluY3JlbWVudGFsbHkgZHVyaW5nXG4vLyB0cmF2ZXJzYWw6IG9wZW4oKSBvbiBib3VuZGFyeSBlbnRyeSwgY2xvc2UoKSBvbiBleGl0LiBRdWVyeSBhdCBhbnlcbi8vIGNvbW1pdCBwb3NpdGlvbiB3aXRoIGVuY2xvc2luZygpL292ZXJsYXBwaW5nKCkuIEdlbmVyaWMgb3ZlciBUTGFiZWxcbi8vIOKAlCBmb290cHJpbnRqcyBvd25zIFpFUk8ga25vd2xlZGdlIG9mIHdoYXQgY29uc3VtZXJzIHVzZSBhcyBsYWJlbHMuXG4vLyBTZWUgZG9jcy9kZXNpZ24vY29tbWl0LXJhbmdlLWluZGV4Lm1kIGZvciB0aGUgZnVsbCBjb250cmFjdC5cbmV4cG9ydCB0eXBlIHsgUmFuZ2VFbnRyeSwgUmFuZ2VUb2tlbiB9IGZyb20gJy4vbGliL3JlY29yZGVyL0NvbW1pdFJhbmdlSW5kZXguanMnO1xuZXhwb3J0IHsgQ29tbWl0UmFuZ2VJbmRleCB9IGZyb20gJy4vbGliL3JlY29yZGVyL0NvbW1pdFJhbmdlSW5kZXguanMnO1xuXG4vLyDilIDilIAgQWJzdHJhY3QgYmFzZXMgKERFUFJFQ0FURUQgaW4gdjUg4oCUIHNsYXRlZCBmb3IgcmVtb3ZhbCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBLZXB0IGR1cmluZyB0aGUgdjUgbWlncmF0aW9uIHdpbmRvdyBmb3IgZG93bnN0cmVhbSBjb25zdW1lcnNcbi8vIChhZ2VudGZvb3RwcmludCwgYWdlbnRmb290cHJpbnQtbGVucywgZXRjLikgdGhhdCBzdGlsbCBleHRlbmRcbi8vIHRoZW0uIE1pZ3JhdGUgdG8gdGhlIGNvcnJlc3BvbmRpbmcgU3RvcmUgY2xhc3MgYWJvdmUuXG4vLyBLZXllZFJlY29yZGVyIOKAlCBiYXNlIGNsYXNzIGZvciAxOjEgTWFwLWJhc2VkIHJlY29yZGVyc1xuZXhwb3J0IHsgS2V5ZWRSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL0tleWVkUmVjb3JkZXIuanMnO1xuXG4vLyBTZXF1ZW5jZVJlY29yZGVyIOKAlCBiYXNlIGNsYXNzIGZvciAxOk4gb3JkZXJlZCBzZXF1ZW5jZSByZWNvcmRlcnMgd2l0aCBrZXllZCBpbmRleFxuZXhwb3J0IHsgU2VxdWVuY2VSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL1NlcXVlbmNlUmVjb3JkZXIuanMnO1xuXG4vLyBCb3VuZGFyeVN0YXRlVHJhY2tlciDigJQgYmFzZSBjbGFzcyBmb3IgdHJhbnNpZW50IGJyYWNrZXQtc2NvcGVkIHN0YXRlXG4vLyAobGl2ZSBzdGF0ZSBEVVJJTkcgYSBtYXRjaGVkIFtzdGFydCwgc3RvcF0gZXZlbnQgaW50ZXJ2YWw7IGNsZWFycyBvbiBzdG9wKVxuZXhwb3J0IHsgQm91bmRhcnlTdGF0ZVRyYWNrZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Cb3VuZGFyeVN0YXRlVHJhY2tlci5qcyc7XG5cbi8vIFRvcG9sb2d5UmVjb3JkZXIg4oCUIGNvbXBvc2l0aW9uIGdyYXBoIGFjY3VtdWxhdG9yIChzdWJmbG93cyArIGNvbnRyb2wtZmxvdyBlZGdlcylcbmV4cG9ydCB0eXBlIHtcbiAgVG9wb2xvZ3ksXG4gIFRvcG9sb2d5RWRnZSxcbiAgVG9wb2xvZ3lJbmNvbWluZ0tpbmQsXG4gIFRvcG9sb2d5Tm9kZSxcbiAgVG9wb2xvZ3lSZWNvcmRlck9wdGlvbnMsXG59IGZyb20gJy4vbGliL3JlY29yZGVyL1RvcG9sb2d5UmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgVG9wb2xvZ3lSZWNvcmRlciwgdG9wb2xvZ3lSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL1RvcG9sb2d5UmVjb3JkZXIuanMnO1xuXG4vLyBJbk91dFJlY29yZGVyIOKAlCBjaGFydCBpbi9vdXQgc3RyZWFtIChlbnRyeS9leGl0IHBhaXJzIGF0IGV2ZXJ5IGNoYXJ0IGJvdW5kYXJ5LFxuLy8gaW5jbHVkaW5nIHRoZSB0b3AtbGV2ZWwgcnVuIGFuZCBldmVyeSBzdWJmbG93KVxuZXhwb3J0IHR5cGUgeyBJbk91dEVudHJ5LCBJbk91dFBoYXNlLCBJbk91dFJlY29yZGVyT3B0aW9ucyB9IGZyb20gJy4vbGliL3JlY29yZGVyL0luT3V0UmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgSW5PdXRSZWNvcmRlciwgaW5PdXRSZWNvcmRlciwgUk9PVF9SVU5USU1FX1NUQUdFX0lELCBST09UX1NVQkZMT1dfSUQgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Jbk91dFJlY29yZGVyLmpzJztcblxuLy8gUXVhbGl0eVJlY29yZGVyIOKAlCBwZXItc3RlcCBxdWFsaXR5IHNjb3Jpbmcgd2l0aCBiYWNrdHJhY2tpbmdcbmV4cG9ydCB0eXBlIHsgUXVhbGl0eUVudHJ5LCBRdWFsaXR5UmVjb3JkZXJPcHRpb25zLCBRdWFsaXR5U2NvcmluZ0ZuIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvUXVhbGl0eVJlY29yZGVyLmpzJztcbmV4cG9ydCB7IFF1YWxpdHlSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL1F1YWxpdHlSZWNvcmRlci5qcyc7XG5cbi8vIHF1YWxpdHlUcmFjZSDigJQgUXVhbGl0eSBTdGFjayBUcmFjZSAoYmFja3RyYWNrIGZyb20gbG93LXNjb3Jpbmcgc3RlcHMpXG5leHBvcnQgdHlwZSB7IFF1YWxpdHlGcmFtZSwgUXVhbGl0eVN0YWNrVHJhY2UgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9xdWFsaXR5VHJhY2UuanMnO1xuZXhwb3J0IHsgZm9ybWF0UXVhbGl0eVRyYWNlLCBxdWFsaXR5VHJhY2UgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9xdWFsaXR5VHJhY2UuanMnO1xuIl19
@@ -26,7 +26,7 @@ export { EventLog } from './lib/memory/index.js';
26
26
  export { TransactionBuffer } from './lib/memory/index.js';
27
27
  export { DiagnosticCollector } from './lib/memory/index.js';
28
28
  export { applySmartMerge, deepSmartMerge, getNestedValue, getRunAndGlobalPaths, normalisePath, redactPatch, setNestedValue, updateNestedValue, updateValue, } from './lib/memory/index.js';
29
- export type { BuildTimeExtractor, BuildTimeNodeMetadata, ExecOptions, FlowChartSpec, ILogger, ScopeProtectionMode, SerializedPipelineStructure, SimplifiedParallelSpec, StageFn, StageNode, StreamCallback, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions, SubflowRef, } from './lib/builder/index.js';
29
+ export type { ExecOptions, FlowChartOptions, FlowChartSpec, ILogger, ScopeProtectionMode, SerializedPipelineStructure, SimplifiedParallelSpec, StageFn, StageNode, StreamCallback, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions, SubflowRef, } from './lib/builder/index.js';
30
30
  export { ArrayMergeMode, DeciderList, SelectorFnList, specToStageNode } from './lib/builder/index.js';
31
31
  export { createTypedScopeFactory } from './lib/builder/typedFlowChart.js';
32
32
  export type { ProviderResolver, ResolveOptions, ScopeProvider, StageContextLike, StrictMode, } from './lib/scope/index.js';
@@ -44,10 +44,10 @@ export { FlowchartTraverser } from './lib/engine/index.js';
44
44
  export { isStageNodeReturn } from './lib/engine/index.js';
45
45
  export type { IControlFlowNarrative } from './lib/engine/index.js';
46
46
  export type { CombinedNarrativeEntry, CombinedNarrativeOptions } from './lib/engine/index.js';
47
- export type { BranchResult, BranchResults, SerializedPipelineStructure as EngineSerializedPipelineStructure, StageSnapshot as EngineStageSnapshot, ExtractorError, HandlerDeps, IExecutionRuntime, NodeResultType, RuntimeStructureMetadata, ScopeFactory, SerializedPipelineNode, StageFunction, SubflowResult, TraversalExtractor, TraversalResult, } from './lib/engine/index.js';
47
+ export type { BranchResult, BranchResults, SerializedPipelineStructure as EngineSerializedPipelineStructure, HandlerDeps, IExecutionRuntime, NodeResultType, RuntimeStructureMetadata, ScopeFactory, SerializedPipelineNode, StageFunction, SubflowResult, TraversalResult, } from './lib/engine/index.js';
48
48
  export { NullControlFlowNarrativeGenerator } from './lib/engine/index.js';
49
- export type { CallExtractorFn, ExecuteNodeFn, GetStagePathFn, RunStageFn } from './lib/engine/index.js';
50
- export { applyOutputMapping, ChildrenExecutor, computeNodeType, ContinuationResolver, createSubflowHandlerDeps, DeciderHandler, DEFAULT_MAX_ITERATIONS, ExtractorRunner, extractParentScopeValues, getInitialScopeValues, NodeResolver, RuntimeStructureManager, seedSubflowGlobalStore, SelectorHandler, StageRunner, SubflowExecutor, } from './lib/engine/index.js';
49
+ export type { ExecuteNodeFn, RunStageFn } from './lib/engine/index.js';
50
+ export { applyOutputMapping, ChildrenExecutor, computeNodeType, ContinuationResolver, createSubflowHandlerDeps, DeciderHandler, DEFAULT_MAX_ITERATIONS, extractParentScopeValues, getInitialScopeValues, NodeResolver, RuntimeStructureManager, seedSubflowGlobalStore, SelectorHandler, StageRunner, SubflowExecutor, } from './lib/engine/index.js';
51
51
  export type { ExecutionCounter } from './lib/engine/runtimeStageId.js';
52
52
  export { buildRuntimeStageId, createExecutionCounter, parseRuntimeStageId } from './lib/engine/runtimeStageId.js';
53
53
  export { findCommit, findCommits, findLastWriter } from './lib/memory/commitLogUtils.js';
@@ -17,6 +17,8 @@
17
17
  export type { FlowChart, StageFunction as StageHandler, StreamHandlers } from './lib/builder/index.js';
18
18
  /** @category Quick Start */
19
19
  export { flowChart, FlowChartBuilder } from './lib/builder/index.js';
20
+ /** @category Quick Start — build-time observer (twin of FlowRecorder) */
21
+ export type { StructureDeciderCompleteEvent, StructureEdgeAddedEvent, StructureEdgeKind, StructureLoopEdgeAddedEvent, StructureRecorder, StructureStageAddedEvent, StructureSubflowMountedEvent, } from './lib/builder/index.js';
20
22
  /** @category Quick Start */
21
23
  export type { TypedStageFunction } from './lib/builder/typedFlowChart.js';
22
24
  /** @category Quick Start */
@@ -15,8 +15,10 @@ import type { ScopeFactory } from '../engine/types.js';
15
15
  import type { PausableHandler } from '../pause/types.js';
16
16
  import type { TypedScope } from '../reactive/types.js';
17
17
  import { type RunnableFlowChart } from '../runner/RunnableChart.js';
18
+ import type { StructureEdgeKind, StructureRecorder } from './structure/StructureRecorder.js';
19
+ import { StructureRecorderDispatcher } from './structure/StructureRecorderDispatcher.js';
18
20
  import { type TypedStageFunction } from './typedFlowChart.js';
19
- import type { BuildTimeExtractor, FlowChart, FlowChartSpec, ILogger, SerializedPipelineStructure, SimplifiedParallelSpec, StageFunction, StageNode, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions, TraversalExtractor } from './types.js';
21
+ import type { FlowChart, FlowChartOptions, FlowChartSpec, ILogger, SerializedPipelineStructure, SimplifiedParallelSpec, StageFunction, StageNode, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions } from './types.js';
20
22
  /**
21
23
  * Fluent helper returned by addDeciderFunction to add branches.
22
24
  * `end()` sets `deciderFn = true` — the fn IS the decider.
@@ -92,9 +94,22 @@ export declare class FlowChartBuilder<TOut = any, TScope = any> {
92
94
  root: StageNode<TOut, TScope>;
93
95
  }>;
94
96
  private _streamHandlers;
95
- private _extractor?;
96
- private _buildTimeExtractor?;
97
- private _buildTimeExtractorErrors;
97
+ /**
98
+ * L7.3 — Build-time observer fan-out. Owned by the builder so every
99
+ * `addX()` method can fire `StructureRecorder` events at the natural
100
+ * moment of the corresponding mutation. Dispatcher is allocated
101
+ * lazily on first attach to keep the zero-recorder path allocation-
102
+ * free.
103
+ */
104
+ private _structureDispatcher?;
105
+ /**
106
+ * L7.3 — Sealed-after-build flag (Panel 2 phase invariant). Flips
107
+ * to `true` when `.build()` returns; subsequent `attachStructureRecorder`
108
+ * throws. Prevents the footgun where a consumer attaches a recorder
109
+ * mid-execution and gets partial structure data (missed every event
110
+ * already fired during construction).
111
+ */
112
+ private _sealed;
98
113
  private _enableNarrative;
99
114
  private _logger?;
100
115
  private _descriptionParts;
@@ -106,7 +121,90 @@ export declare class FlowChartBuilder<TOut = any, TScope = any> {
106
121
  private _outputSchema?;
107
122
  private _outputMapper?;
108
123
  private _scopeFactory?;
109
- constructor(buildTimeExtractor?: BuildTimeExtractor<any>);
124
+ /**
125
+ * Attach a `StructureRecorder` for build-phase observation. Multiple
126
+ * recorders coexist (same id allowed; iteration order = attach
127
+ * order). Throws if called after `.build()` — the chart is sealed at
128
+ * that point and any recorder attached late would miss every event
129
+ * fired during construction.
130
+ *
131
+ * **Seed replay**: when this is called AFTER `start()` has already
132
+ * fired (i.e., after the `flowChart()` factory returns), the
133
+ * just-attached recorder receives a one-time `onStageAdded` for the
134
+ * root stage so it observes the seed. Only the new recorder sees
135
+ * the replay; already-attached recorders are not re-fired.
136
+ *
137
+ * **Mid-chain attach caveat**: a recorder attached AFTER one or more
138
+ * `addX()` calls receives the seed replay but MISSES every
139
+ * intermediate event. Attach BEFORE the first `addX()` for complete
140
+ * capture.
141
+ *
142
+ * Public for now to enable direct attach in tests + early consumers.
143
+ * L7.4 will wire `flowChart(..., { structureRecorders: [...] })` as
144
+ * an additional registration site; this method will remain.
145
+ */
146
+ attachStructureRecorder(recorder: StructureRecorder): this;
147
+ /**
148
+ * Inspect accumulated `StructureBuildError`s. Returns empty array
149
+ * when no recorders attached OR no errors occurred. Returns a
150
+ * defensive copy — caller mutations do not affect subsequent calls.
151
+ *
152
+ * **Call on the BUILDER, not the chart returned by `.build()`.**
153
+ * Capture the builder reference before `.build()` if you need
154
+ * post-build access:
155
+ * ```ts
156
+ * const builder = flowChart(...).attachStructureRecorder(rec);
157
+ * const chart = builder.build();
158
+ * const errors = builder.getStructureBuildErrors();
159
+ * ```
160
+ */
161
+ getStructureBuildErrors(): ReturnType<StructureRecorderDispatcher['getErrors']>;
162
+ private _fireStageAdded;
163
+ private _fireEdgeAdded;
164
+ private _fireLoopEdgeAdded;
165
+ /**
166
+ * Fire the `next` edge(s) from a parent spec to a freshly-added
167
+ * node — with convergence expansion when the parent is a
168
+ * fork / decider / selector with branches.
169
+ *
170
+ * A fork at `parent` is semantically `parent ──fork-branch──► child[i]`
171
+ * for each child, and the chained `.addFunction(X)` continues
172
+ * AFTER the fork converges. The runtime semantics are that each
173
+ * child INDEPENDENTLY feeds `X` (parallel completion → join). The
174
+ * literal "edge from parent to X" would misrepresent this —
175
+ * visualizers and topological algorithms would see one edge where
176
+ * there should be N convergence edges.
177
+ *
178
+ * Fix: when `parentSpec` has branch children (fork or branched
179
+ * decider/selector), fire one `next` edge from EACH child to the
180
+ * target. Otherwise fire the single edge from `parentSpec` itself.
181
+ *
182
+ * Loop-reference children (synthetic spec nodes created by
183
+ * `.loopTo()`) are excluded — they're back-edge markers, not
184
+ * convergence sources.
185
+ *
186
+ * Call ORDER constraint: must be called BEFORE the cursor advances
187
+ * to the new target. The caller passes the PRE-ADVANCE parent spec.
188
+ */
189
+ private _fireNextEdgeFromParent;
190
+ private _fireDeciderComplete;
191
+ private _fireSubflowMounted;
192
+ /** Sub-builder access (`.b._fireXxx`) is needed by DeciderList /
193
+ * SelectorFnList; expose the dispatcher through internal helpers
194
+ * that go through the same no-op-when-absent guard.
195
+ *
196
+ * @internal — these methods are exposed because TypeScript `private`
197
+ * doesn't traverse class boundaries. Consumer code MUST NOT call
198
+ * them; calling them post-construction lets a hostile caller
199
+ * fabricate structure events and corrupt downstream visualizations
200
+ * or audit trails. The `_` prefix is intentional convention. */
201
+ _fireEdgeAddedFromSubBuilder(from: string, to: string, kind: StructureEdgeKind, label?: string): void;
202
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. */
203
+ _fireStageAddedFromSubBuilder(spec: SerializedPipelineStructure): void;
204
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. */
205
+ _fireDeciderCompleteFromSubBuilder(decider: string, type: 'decider' | 'selector', branchIds: string[], defaultBranch?: string): void;
206
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. */
207
+ _fireSubflowMountedFromSubBuilder(subflowId: string, subflowName: string, rootStageId: string, isLazy?: boolean, subflowSpec?: SerializedPipelineStructure, subflowPath?: string): void;
110
208
  private _appendDescriptionLine;
111
209
  private _appendSubflowDescription;
112
210
  setLogger(logger: ILogger): this;
@@ -240,12 +338,6 @@ export declare class FlowChartBuilder<TOut = any, TScope = any> {
240
338
  onStream(handler: StreamTokenHandler): this;
241
339
  onStreamStart(handler: StreamLifecycleHandler): this;
242
340
  onStreamEnd(handler: StreamLifecycleHandler): this;
243
- addTraversalExtractor<TResult = unknown>(extractor: TraversalExtractor<TResult>): this;
244
- addBuildTimeExtractor<TResult = FlowChartSpec>(extractor: BuildTimeExtractor<TResult>): this;
245
- getBuildTimeExtractorErrors(): Array<{
246
- message: string;
247
- error: unknown;
248
- }>;
249
341
  build(): RunnableFlowChart<TOut, TScope>;
250
342
  /** Override the scope factory. Rarely needed — auto-embeds TypedScope by default. */
251
343
  setScopeFactory(factory: ScopeFactory<TScope>): this;
@@ -253,7 +345,11 @@ export declare class FlowChartBuilder<TOut = any, TScope = any> {
253
345
  toMermaid(): string;
254
346
  private _needCursor;
255
347
  private _needCursorSpec;
256
- _applyExtractorToNode(spec: SerializedPipelineStructure): SerializedPipelineStructure;
348
+ /**
349
+ * Advance the spec cursor. Retained as a method so call sites stay
350
+ * one-liners and future cursor-related side effects have a hook.
351
+ */
352
+ private _advanceCursorSpec;
257
353
  _stageMapHas(key: string): boolean;
258
354
  _addToMap(id: string, fn: StageFunction<TOut, TScope>): void;
259
355
  _mergeStageMap(other: Map<string, StageFunction<TOut, TScope>>, prefix?: string): void;
@@ -262,6 +358,6 @@ export declare class FlowChartBuilder<TOut = any, TScope = any> {
262
358
  root: StageNode<TOut, TScope>;
263
359
  }> | undefined, prefix: string): void;
264
360
  }
265
- export declare function flowChart<TState extends object>(name: string, fn: TypedStageFunction<TState> | PausableHandler<TypedScope<TState>>, id: string, buildTimeExtractor?: BuildTimeExtractor<any>, description?: string): FlowChartBuilder<any, TypedScope<TState>>;
266
- export declare function flowChart<TOut = any, TScope = any>(name: string, fn: StageFunction<TOut, TScope> | PausableHandler<TScope>, id: string, buildTimeExtractor?: BuildTimeExtractor<any>, description?: string): FlowChartBuilder<TOut, TScope>;
361
+ export declare function flowChart<TState extends object>(name: string, fn: TypedStageFunction<TState> | PausableHandler<TypedScope<TState>>, id: string, options?: FlowChartOptions): FlowChartBuilder<any, TypedScope<TState>>;
362
+ export declare function flowChart<TOut = any, TScope = any>(name: string, fn: StageFunction<TOut, TScope> | PausableHandler<TScope>, id: string, options?: FlowChartOptions): FlowChartBuilder<TOut, TScope>;
267
363
  export declare function specToStageNode(spec: FlowChartSpec): StageNode<any, any>;
@@ -6,5 +6,6 @@
6
6
  */
7
7
  export { DeciderList, FlowChartBuilder, SelectorFnList } from './FlowChartBuilder.js';
8
8
  export { flowChart, specToStageNode } from './FlowChartBuilder.js';
9
- export type { BuildTimeExtractor, BuildTimeNodeMetadata, ExecOptions, FlowChart, FlowChartSpec, ILogger, ScopeProtectionMode, SerializedPipelineStructure, SimplifiedParallelSpec, StageFn, StageFunction, StageNode, StreamCallback, StreamHandlers, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions, SubflowRef, TraversalExtractor, } from './types.js';
9
+ export type { ExecOptions, FlowChart, FlowChartOptions, FlowChartSpec, ILogger, ScopeProtectionMode, SerializedPipelineStructure, SimplifiedParallelSpec, StageFn, StageFunction, StageNode, StreamCallback, StreamHandlers, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions, SubflowRef, } from './types.js';
10
10
  export { ArrayMergeMode } from './types.js';
11
+ export type { StructureDeciderCompleteEvent, StructureEdgeAddedEvent, StructureEdgeKind, StructureLoopEdgeAddedEvent, StructureRecorder, StructureStageAddedEvent, StructureSubflowMountedEvent, } from './structure/StructureRecorder.js';
@@ -0,0 +1,349 @@
1
+ /**
2
+ * StructureRecorder — passive observer of BUILD-TIME chart construction events.
3
+ *
4
+ * The build-time twin of `FlowRecorder`. Where `FlowRecorder` observes
5
+ * RUNTIME control-flow transitions (per-execution `runtimeStageId`,
6
+ * iteration counts, errors, pauses), `StructureRecorder` observes
7
+ * STATIC chart shape as it's assembled by the builder — every spec
8
+ * node added, every outgoing edge wired, every decider closed.
9
+ *
10
+ * Why two interfaces, not one
11
+ * ───────────────────────────
12
+ * Build and runtime events have different INVARIANTS, not just
13
+ * different timing:
14
+ *
15
+ * - Runtime events carry `runtimeStageId` (`[subflowPath/]stageId#N`),
16
+ * `iteration`, `traversalContext` — load-bearing for time-travel
17
+ * UIs, commit-log indices, and `SequenceRecorder<T>` consumers.
18
+ * NONE of these exist at build time.
19
+ *
20
+ * - Build events carry only `stageId` + structural fields. No
21
+ * execution index, no iteration, no snapshot.
22
+ *
23
+ * - Some events have no analog across phases: `onPause` /
24
+ * `onResume` / `onError` / `onRunStart` are runtime-only;
25
+ * `onDeciderComplete` / `onStageAdded` are build-only.
26
+ *
27
+ * A single `FlowRecorder` with `phase: 'static' | 'dynamic'`
28
+ * discriminator would force every consumer to write
29
+ * `if (e.phase === 'static') ...` branches and would erase the
30
+ * least-privilege boundary (a static-only consumer should NOT
31
+ * accidentally observe runtime data — e.g., a public docs site
32
+ * rendering chart topology must not see scope values).
33
+ *
34
+ * Two interfaces, same mental model, clean separation. Two
35
+ * registration sites ship today (pick whichever fits your call
36
+ * site):
37
+ *
38
+ * 1. **Options-bag** (preferred when the recorder set is known
39
+ * at construction time — registers BEFORE `start()` so even
40
+ * the seed event fires through the normal dispatcher fan-out):
41
+ * ```ts
42
+ * flowChart('seed', fn, 'seed', { structureRecorders: [rec] })
43
+ * .addFunction('a', fnA, 'a').build();
44
+ * ```
45
+ *
46
+ * 2. **Fluent** (preferred when attach is conditional, late, or
47
+ * in a chain builder — the just-attached recorder gets a
48
+ * one-time seed replay so it observes the root stage):
49
+ * ```ts
50
+ * flowChart('seed', fn, 'seed')
51
+ * .attachStructureRecorder(rec)
52
+ * .addFunction('a', fnA, 'a').build();
53
+ * ```
54
+ *
55
+ * Both deliver the same event stream to the same recorder. See the
56
+ * `@example` block below for a fully-fleshed-out implementation.
57
+ *
58
+ * Lifecycle + ordering invariants
59
+ * ───────────────────────────────
60
+ * - Fires SYNCHRONOUSLY during builder chain calls (and during
61
+ * `.build()` for the terminal node) at the natural moment each
62
+ * spec mutation completes.
63
+ * - `onStageAdded(A)` and `onStageAdded(B)` fire BEFORE any
64
+ * `onEdgeAdded({from: A, to: B})` — endpoint registration
65
+ * happens before edge wiring.
66
+ * - `onDeciderComplete(D)` fires at sub-builder `.end()` time, AFTER
67
+ * every child's `onStageAdded` and every `onEdgeAdded({from: D,
68
+ * to: child})`. Marks the decider as no-further-mutation.
69
+ * - `onSubflowMounted({subflowId})` fires once per mount.
70
+ * **MOUNT-ONLY**: parent recorders do NOT receive a replay of
71
+ * the subflow's own internal structure events (those fired
72
+ * during the subflow's own `.build()`). Matches the runtime
73
+ * `onSubflowEntry` semantics — composition over replay.
74
+ *
75
+ * Error isolation (matches FlowRecorder contract)
76
+ * ───────────────────────────────────────────────
77
+ * - A throwing handler is caught, logged via `isDevMode()` warning,
78
+ * and accumulated on `builder.getStructureBuildErrors()` for
79
+ * post-hoc inspection.
80
+ * - Subsequent recorders + subsequent events fire normally; one
81
+ * misbehaving recorder cannot THROW its way into blocking
82
+ * construction.
83
+ * - The errors[] accumulator is soft-capped (~100 entries) with a
84
+ * `__truncated__` sentinel record once the cap is hit, to prevent
85
+ * unbounded growth on chatty broken recorders.
86
+ * - Note: throw isolation does NOT defend against a handler that
87
+ * succeeds at runtime but mutates `event.spec` to corrupt the
88
+ * chart. See "Spec mutation" below.
89
+ *
90
+ * Spec mutation — readonly-by-contract (NOT runtime-enforced)
91
+ * ────────────────────────────────────────────────────────────
92
+ * - Event payloads pass spec references where useful (e.g., `spec`
93
+ * on `onStageAdded`). Every field on every event payload is
94
+ * marked `readonly` in TypeScript — the type system signals
95
+ * consumer intent at author time.
96
+ * - There is NO runtime freeze. The builder fires `onStageAdded`
97
+ * IMMEDIATELY when a spec node is added, BEFORE the builder
98
+ * wires that node's `.next`/`.children`/`.loopTarget` in the
99
+ * subsequent `addX` call. Freezing here would break the
100
+ * builder's own subsequent mutation.
101
+ * - Handler mutation of `event.spec` is DOCUMENTED UNDEFINED
102
+ * BEHAVIOR — it will succeed at runtime, but is not supported
103
+ * and downstream consumers may break. Specifically, mutating
104
+ * `event.spec.fn`, `event.spec.id`, or `event.spec.children`
105
+ * can corrupt subsequent runtime behavior of the chart.
106
+ * - **Trust model**: attach ONLY recorders from trusted code paths.
107
+ * A hostile or buggy recorder can effectively substitute stage
108
+ * functions or rewire the chart structure. The `readonly`
109
+ * markers cannot defend against intentional mutation.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * class TraceStructureRecorder implements StructureRecorder {
114
+ * readonly id = 'trace-static';
115
+ * nodes: XyflowNode[] = [];
116
+ * edges: XyflowEdge[] = [];
117
+ *
118
+ * onStageAdded(e) {
119
+ * // Node role: 'stage' is the initial type. If outgoing edges
120
+ * // arrive with kind 'fork-branch' / 'decision-branch' the node
121
+ * // is functioning as a fork/decider — derive the visual style
122
+ * // from those edges, not from `e.type` alone.
123
+ * this.nodes.push({ id: e.stageId, type: 'lensStage', data: { label: e.name } });
124
+ * }
125
+ * onEdgeAdded(e) {
126
+ * this.edges.push({ id: `${e.from}->${e.to}`, source: e.from, target: e.to });
127
+ * }
128
+ * onSubflowMounted(e) {
129
+ * this.nodes.push({ id: e.subflowId, type: 'subflow', data: { label: e.subflowName } });
130
+ * }
131
+ * onDeciderComplete(e) {
132
+ * // Optional: finalize node styling now that branch list is sealed.
133
+ * }
134
+ * }
135
+ *
136
+ * // Registration option A — options-bag (preferred when recorders
137
+ * // are known up front; attaches BEFORE the seed event fires):
138
+ * const rec = new TraceStructureRecorder();
139
+ * const builder = flowChart('seed', fn, 'seed', {
140
+ * structureRecorders: [rec],
141
+ * }).addFunction('a', fnA, 'a');
142
+ * const chart = builder.build();
143
+ *
144
+ * // Registration option B — fluent chain (preferred for conditional
145
+ * // or late attach; the just-attached recorder gets a seed replay):
146
+ * const rec2 = new TraceStructureRecorder();
147
+ * const builder2 = flowChart('seed', fn, 'seed')
148
+ * .attachStructureRecorder(rec2)
149
+ * .addFunction('a', fnA, 'a');
150
+ *
151
+ * // Inspect any recorder errors (call on the BUILDER, not the chart):
152
+ * const errors = builder.getStructureBuildErrors();
153
+ *
154
+ * <ReactFlow nodes={rec.nodes} edges={rec.edges} />
155
+ * ```
156
+ */
157
+ import type { FlowChartSpec, SerializedPipelineStructure } from '../types.js';
158
+ /**
159
+ * Event payload for `StructureRecorder.onStageAdded`. Fires for every
160
+ * spec node added to the chart, including the seed (added via
161
+ * `flowChart()` factory) and subflow mount nodes. Excludes synthetic
162
+ * loop-reference nodes (those carry `isLoopReference: true` on the
163
+ * spec; consumers see them via the separate `onLoopEdgeAdded` event
164
+ * instead of as fresh stages).
165
+ */
166
+ export interface StructureStageAddedEvent {
167
+ /**
168
+ * Stable identifier for this node. AT EVENT FIRE TIME this is the
169
+ * builder's LOCAL form (no subflow prefix — the prefix is applied
170
+ * later by `_prefixNodeTree` when this builder is mounted as a
171
+ * subflow into a parent).
172
+ *
173
+ * Note: `spec.id` is a LIVE reference. If you read it AFTER this
174
+ * chart has been mounted as a subflow, it may have been rewritten
175
+ * to the FULL prefixed form. Use `splitStageId(spec.id)` from
176
+ * `footprintjs/trace` to decompose it back into local + subflowPath.
177
+ *
178
+ * Correlating with runtime events:
179
+ * - Same builder (no mount) →
180
+ * `event.stageId === parseRuntimeStageId(runtime).stageId`
181
+ * - This builder mounted as subflow → use `splitStageId` on the
182
+ * prefixed form (or `parseRuntimeStageId` on the full
183
+ * runtimeStageId) before comparing.
184
+ */
185
+ readonly stageId: string;
186
+ /** Human-readable label for the node. */
187
+ readonly name: string;
188
+ /** Spec node `type`. Lets recorders branch on stage vs decider vs
189
+ * fork vs subflow without re-deriving from other fields. */
190
+ readonly type: NonNullable<FlowChartSpec['type']>;
191
+ /** True for nodes added via `addPausableFunction()` — useful for
192
+ * visualisers that want to mark stages that can pause execution. */
193
+ readonly isPausable?: boolean;
194
+ /** Live reference to the full spec node, for handlers that want
195
+ * details beyond the discriminator fields above. MUST NOT be
196
+ * mutated by the handler — readonly is type-level intent; no
197
+ * runtime freeze. See "Spec mutation" in the file header for the
198
+ * trust-model caveats. */
199
+ readonly spec: FlowChartSpec;
200
+ }
201
+ /** Edge kinds the builder produces at structural time. Matches the
202
+ * footprintjs control-flow vocabulary used at runtime.
203
+ *
204
+ * Why no `subflow-entry` here: subflow mounts use the lifecycle
205
+ * event `onSubflowMounted` (not an edge event). If a future use case
206
+ * needs the parent→subflow-root edge as a distinct kind, it'll be
207
+ * added then — YAGNI now (Panel 3, L7.2 review). */
208
+ export type StructureEdgeKind = 'next' | 'fork-branch' | 'decision-branch';
209
+ /**
210
+ * Event payload for `StructureRecorder.onEdgeAdded`. Fires whenever
211
+ * the builder wires an outgoing edge from one node to another. Both
212
+ * endpoints have already been announced via `onStageAdded` by the
213
+ * time this fires.
214
+ *
215
+ * Loop back-edges have their OWN event (`onLoopEdgeAdded`) so
216
+ * consumers can theme them distinctly and so build-time events stay
217
+ * free of the runtime-only `iteration` field.
218
+ */
219
+ export interface StructureEdgeAddedEvent {
220
+ readonly from: string;
221
+ readonly to: string;
222
+ readonly kind: StructureEdgeKind;
223
+ /** Optional human-readable label — used today for decider branch
224
+ * keys (e.g., `'low'`, `'high'`, `'high (default)'`) and parallel
225
+ * branch ids. */
226
+ readonly label?: string;
227
+ }
228
+ /**
229
+ * Event payload for `StructureRecorder.onLoopEdgeAdded`. Fires when
230
+ * `.loopTo(target)` installs a back-edge. Distinct from
231
+ * `onEdgeAdded` so consumers can theme back-edges differently and
232
+ * because runtime `onLoop` carries `iteration: number` which has no
233
+ * build-time meaning — keeping the events separated avoids forcing
234
+ * an `iteration?: number` lie into the structural shape.
235
+ */
236
+ export interface StructureLoopEdgeAddedEvent {
237
+ readonly from: string;
238
+ readonly to: string;
239
+ }
240
+ /**
241
+ * Event payload for `StructureRecorder.onDeciderComplete`. Fires
242
+ * when a decider / selector sub-builder closes via `.end()`. By the
243
+ * time this fires every branch has been announced and the
244
+ * `defaultBranch` (if set via `.setDefault()`) is final. Lets
245
+ * recorders treat the decider as no-further-mutation and snapshot
246
+ * its branch list as final.
247
+ */
248
+ export interface StructureDeciderCompleteEvent {
249
+ /** Decider / selector stage id. */
250
+ readonly decider: string;
251
+ /** Spec type (`'decider'` vs `'selector'`) — exposed so consumers
252
+ * don't need to look up the original `onStageAdded` event. */
253
+ readonly type: 'decider' | 'selector';
254
+ /** Branch member ids in declaration order. */
255
+ readonly branchIds: readonly string[];
256
+ /** Default branch id when set via `.setDefault()`; undefined when
257
+ * no default is configured (e.g., selectors). */
258
+ readonly defaultBranch?: string;
259
+ }
260
+ /**
261
+ * Event payload for `StructureRecorder.onSubflowMounted`. Fires once
262
+ * per subflow mount (`addSubFlowChart` / `addSubFlowChartNext` and
263
+ * their lazy variants).
264
+ *
265
+ * **MOUNT-ONLY semantics** — the subflow's OWN structure events
266
+ * (every `onStageAdded` / `onEdgeAdded` inside the subflow) fired
267
+ * during the subflow's own `.build()`, before the mount. Parent
268
+ * recorders do NOT receive a replay. Instead, this event delivers
269
+ * the subflow's full structure via `subflowSpec`, and consumers can
270
+ * walk it via `walkSubflowSpec` from `footprintjs/trace`.
271
+ *
272
+ * This matches `FlowRecorder.onSubflowEntry` semantics at runtime
273
+ * (parents see the boundary, not a replay of internals) and
274
+ * preserves the "one purpose per recorder" convention.
275
+ */
276
+ export interface StructureSubflowMountedEvent {
277
+ /** Subflow identifier the parent assigned at mount. */
278
+ readonly subflowId: string;
279
+ /** Human-readable subflow name. */
280
+ readonly subflowName: string;
281
+ /** Mount node id in the parent's chart. */
282
+ readonly rootStageId: string;
283
+ /** True when the mount uses lazy resolution (deferred subflow
284
+ * resolution until execution). */
285
+ readonly isLazy?: boolean;
286
+ /**
287
+ * The mounted subflow's complete spec — the SAME OBJECT
288
+ * (=== reference equality) reachable via `subflow.buildTimeStructure`
289
+ * for the FlowChart the consumer passed to `addSubFlowChartBranch` /
290
+ * `addSubFlowChart` / `addSubFlowChartNext`.
291
+ *
292
+ * UNDEFINED for lazy mounts at build time (`isLazy: true`) — the
293
+ * subflow's structure hasn't been resolved yet. Consumers waiting on
294
+ * lazy subflows handle the runtime `onSubflowEntry` event instead.
295
+ *
296
+ * Immutable post-build; consumers MUST NOT mutate.
297
+ *
298
+ * @internal `SerializedPipelineStructure` is library-internal.
299
+ * Use `walkSubflowSpec` from `footprintjs/trace` for the
300
+ * stable public contract.
301
+ */
302
+ readonly subflowSpec?: SerializedPipelineStructure;
303
+ /**
304
+ * Local mount id of this subflow within its parent — equal to
305
+ * `subflowId` for top-level mounts (e.g. `'auth'`), composed
306
+ * (`'auth/verify'`) for nested mounts whose recorder is attached
307
+ * to the grandparent. Matches runtime `traversalContext.subflowPath`
308
+ * semantics — NEVER prefixed with `__root__/`.
309
+ */
310
+ readonly subflowPath: string;
311
+ }
312
+ /**
313
+ * Pluggable observer for BUILD-TIME chart construction events.
314
+ *
315
+ * All methods are optional — implement only the hooks you need.
316
+ * Handlers fire SYNCHRONOUSLY during builder operations and `.build()`.
317
+ * A throwing handler is caught (see "Error isolation" in the file
318
+ * header); subsequent dispatch continues.
319
+ *
320
+ * Lifecycle: each `StructureRecorder` instance is registered via
321
+ * EITHER the `flowChart()` options bag (`{ structureRecorders: [rec] }`)
322
+ * OR the fluent `.attachStructureRecorder(rec)` chain — see the file
323
+ * header for the trade-offs. Registration after `.build()` is
324
+ * rejected (chart is sealed).
325
+ */
326
+ export interface StructureRecorder {
327
+ /**
328
+ * Stable identifier — used by the dispatcher to scope error
329
+ * messages and to support `detach(id)` lookup.
330
+ *
331
+ * Convention (matches `FlowRecorder.id` from CLAUDE.md):
332
+ * - domain-prefixed kebab-case (`'lens-structure'`,
333
+ * `'agentfootprint-composition'`, `'trace-explainable'`)
334
+ * - same id → multiple recorders coexist (NOT deduplicated by
335
+ * id; the dispatcher fires every attached recorder regardless)
336
+ * - `detach(id)` removes EVERY recorder with that id — be
337
+ * intentional about reuse if you rely on selective detach
338
+ *
339
+ * Choose a stable id at module load and don't randomise it across
340
+ * runs — it lands in `StructureBuildError.recorderId` so debug
341
+ * output is greppable.
342
+ */
343
+ readonly id: string;
344
+ onStageAdded?(event: StructureStageAddedEvent): void;
345
+ onEdgeAdded?(event: StructureEdgeAddedEvent): void;
346
+ onLoopEdgeAdded?(event: StructureLoopEdgeAddedEvent): void;
347
+ onDeciderComplete?(event: StructureDeciderCompleteEvent): void;
348
+ onSubflowMounted?(event: StructureSubflowMountedEvent): void;
349
+ }