@sunshaobei/dsh-workflow 0.0.0-stage → 2.1.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/README.md +43 -2
- package/cordis.patch.yml +17 -0
- package/lib/client.js +14708 -0
- package/lib/core.js +137 -0
- package/lib/engine-adapter.js +1387 -0
- package/lib/host-driver.js +298 -0
- package/lib/index.js +536 -0
- package/lib/projection.js +159 -0
- package/lib/registry.js +218 -0
- package/lib/session-records.js +54 -0
- package/lib/submission-commit.js +34 -0
- package/lib/world-driver.js +275 -0
- package/package.json +64 -4
- package/vendor/PROVENANCE.md +9 -0
- package/vendor/dynamic-workflow/analysis/actor-graph.d.ts +47 -0
- package/vendor/dynamic-workflow/analysis/actor-graph.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/actor-graph.js +95 -0
- package/vendor/dynamic-workflow/analysis/actor-models.d.ts +60 -0
- package/vendor/dynamic-workflow/analysis/actor-models.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/actor-models.js +208 -0
- package/vendor/dynamic-workflow/analysis/actor-names.d.ts +56 -0
- package/vendor/dynamic-workflow/analysis/actor-names.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/actor-names.js +155 -0
- package/vendor/dynamic-workflow/analysis/analyze.d.ts +63 -0
- package/vendor/dynamic-workflow/analysis/analyze.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/analyze.js +92 -0
- package/vendor/dynamic-workflow/analysis/array-methods.d.ts +21 -0
- package/vendor/dynamic-workflow/analysis/array-methods.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/array-methods.js +132 -0
- package/vendor/dynamic-workflow/analysis/artifact-types.d.ts +39 -0
- package/vendor/dynamic-workflow/analysis/artifact-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/artifact-types.js +114 -0
- package/vendor/dynamic-workflow/analysis/artifacts.d.ts +67 -0
- package/vendor/dynamic-workflow/analysis/artifacts.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/artifacts.js +263 -0
- package/vendor/dynamic-workflow/analysis/assign.d.ts +42 -0
- package/vendor/dynamic-workflow/analysis/assign.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/assign.js +287 -0
- package/vendor/dynamic-workflow/analysis/callbacks.d.ts +71 -0
- package/vendor/dynamic-workflow/analysis/callbacks.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/callbacks.js +133 -0
- package/vendor/dynamic-workflow/analysis/calls.d.ts +40 -0
- package/vendor/dynamic-workflow/analysis/calls.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/calls.js +495 -0
- package/vendor/dynamic-workflow/analysis/causality-graph-lanes.d.ts +25 -0
- package/vendor/dynamic-workflow/analysis/causality-graph-lanes.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-graph-lanes.js +161 -0
- package/vendor/dynamic-workflow/analysis/causality-graph-types.d.ts +163 -0
- package/vendor/dynamic-workflow/analysis/causality-graph-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-graph-types.js +8 -0
- package/vendor/dynamic-workflow/analysis/causality-graph.d.ts +39 -0
- package/vendor/dynamic-workflow/analysis/causality-graph.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-graph.js +530 -0
- package/vendor/dynamic-workflow/analysis/causality-order-calls.d.ts +29 -0
- package/vendor/dynamic-workflow/analysis/causality-order-calls.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-calls.js +266 -0
- package/vendor/dynamic-workflow/analysis/causality-order-functions.d.ts +26 -0
- package/vendor/dynamic-workflow/analysis/causality-order-functions.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-functions.js +116 -0
- package/vendor/dynamic-workflow/analysis/causality-order-loops.d.ts +5 -0
- package/vendor/dynamic-workflow/analysis/causality-order-loops.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-loops.js +148 -0
- package/vendor/dynamic-workflow/analysis/causality-order-settle.d.ts +39 -0
- package/vendor/dynamic-workflow/analysis/causality-order-settle.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-settle.js +263 -0
- package/vendor/dynamic-workflow/analysis/causality-order-state.d.ts +110 -0
- package/vendor/dynamic-workflow/analysis/causality-order-state.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-state.js +162 -0
- package/vendor/dynamic-workflow/analysis/causality-order-strands.d.ts +79 -0
- package/vendor/dynamic-workflow/analysis/causality-order-strands.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-strands.js +154 -0
- package/vendor/dynamic-workflow/analysis/causality-order-types.d.ts +174 -0
- package/vendor/dynamic-workflow/analysis/causality-order-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-types.js +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-walk.d.ts +17 -0
- package/vendor/dynamic-workflow/analysis/causality-order-walk.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order-walk.js +282 -0
- package/vendor/dynamic-workflow/analysis/causality-order.d.ts +60 -0
- package/vendor/dynamic-workflow/analysis/causality-order.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-order.js +110 -0
- package/vendor/dynamic-workflow/analysis/causality-reduce.d.ts +60 -0
- package/vendor/dynamic-workflow/analysis/causality-reduce.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/causality-reduce.js +198 -0
- package/vendor/dynamic-workflow/analysis/classes.d.ts +47 -0
- package/vendor/dynamic-workflow/analysis/classes.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/classes.js +264 -0
- package/vendor/dynamic-workflow/analysis/constants.d.ts +35 -0
- package/vendor/dynamic-workflow/analysis/constants.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/constants.js +23 -0
- package/vendor/dynamic-workflow/analysis/control-flow.d.ts +26 -0
- package/vendor/dynamic-workflow/analysis/control-flow.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/control-flow.js +132 -0
- package/vendor/dynamic-workflow/analysis/core-json.d.ts +45 -0
- package/vendor/dynamic-workflow/analysis/core-json.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/core-json.js +49 -0
- package/vendor/dynamic-workflow/analysis/core.d.ts +194 -0
- package/vendor/dynamic-workflow/analysis/core.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/core.js +204 -0
- package/vendor/dynamic-workflow/analysis/domain.d.ts +269 -0
- package/vendor/dynamic-workflow/analysis/domain.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/domain.js +523 -0
- package/vendor/dynamic-workflow/analysis/facade-misuse.d.ts +56 -0
- package/vendor/dynamic-workflow/analysis/facade-misuse.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/facade-misuse.js +350 -0
- package/vendor/dynamic-workflow/analysis/fanout-cardinality.d.ts +11 -0
- package/vendor/dynamic-workflow/analysis/fanout-cardinality.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/fanout-cardinality.js +121 -0
- package/vendor/dynamic-workflow/analysis/flow-graph.d.ts +113 -0
- package/vendor/dynamic-workflow/analysis/flow-graph.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/flow-graph.js +411 -0
- package/vendor/dynamic-workflow/analysis/flow-phase.d.ts +28 -0
- package/vendor/dynamic-workflow/analysis/flow-phase.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/flow-phase.js +104 -0
- package/vendor/dynamic-workflow/analysis/flow-strands.d.ts +39 -0
- package/vendor/dynamic-workflow/analysis/flow-strands.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/flow-strands.js +47 -0
- package/vendor/dynamic-workflow/analysis/flow-tree.d.ts +35 -0
- package/vendor/dynamic-workflow/analysis/flow-tree.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/flow-tree.js +33 -0
- package/vendor/dynamic-workflow/analysis/graph.d.ts +5 -0
- package/vendor/dynamic-workflow/analysis/graph.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/graph.js +199 -0
- package/vendor/dynamic-workflow/analysis/handoff-graph.d.ts +48 -0
- package/vendor/dynamic-workflow/analysis/handoff-graph.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/handoff-graph.js +0 -0
- package/vendor/dynamic-workflow/analysis/heap-ops.d.ts +14 -0
- package/vendor/dynamic-workflow/analysis/heap-ops.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/heap-ops.js +70 -0
- package/vendor/dynamic-workflow/analysis/hole-id.d.ts +28 -0
- package/vendor/dynamic-workflow/analysis/hole-id.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/hole-id.js +41 -0
- package/vendor/dynamic-workflow/analysis/hole-sites.d.ts +32 -0
- package/vendor/dynamic-workflow/analysis/hole-sites.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/hole-sites.js +215 -0
- package/vendor/dynamic-workflow/analysis/hole-splice.d.ts +45 -0
- package/vendor/dynamic-workflow/analysis/hole-splice.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/hole-splice.js +100 -0
- package/vendor/dynamic-workflow/analysis/interpret.d.ts +26 -0
- package/vendor/dynamic-workflow/analysis/interpret.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/interpret.js +200 -0
- package/vendor/dynamic-workflow/analysis/literals.d.ts +18 -0
- package/vendor/dynamic-workflow/analysis/literals.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/literals.js +125 -0
- package/vendor/dynamic-workflow/analysis/mermaid.d.ts +60 -0
- package/vendor/dynamic-workflow/analysis/mermaid.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/mermaid.js +477 -0
- package/vendor/dynamic-workflow/analysis/patterns.d.ts +31 -0
- package/vendor/dynamic-workflow/analysis/patterns.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/patterns.js +94 -0
- package/vendor/dynamic-workflow/analysis/phase-graph.d.ts +47 -0
- package/vendor/dynamic-workflow/analysis/phase-graph.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/phase-graph.js +334 -0
- package/vendor/dynamic-workflow/analysis/phases.d.ts +24 -0
- package/vendor/dynamic-workflow/analysis/phases.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/phases.js +54 -0
- package/vendor/dynamic-workflow/analysis/promise-ops.d.ts +52 -0
- package/vendor/dynamic-workflow/analysis/promise-ops.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/promise-ops.js +123 -0
- package/vendor/dynamic-workflow/analysis/relays.d.ts +12 -0
- package/vendor/dynamic-workflow/analysis/relays.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/relays.js +78 -0
- package/vendor/dynamic-workflow/analysis/serialize.d.ts +125 -0
- package/vendor/dynamic-workflow/analysis/serialize.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/serialize.js +321 -0
- package/vendor/dynamic-workflow/analysis/site-phases.d.ts +32 -0
- package/vendor/dynamic-workflow/analysis/site-phases.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/site-phases.js +69 -0
- package/vendor/dynamic-workflow/analysis/sites-labels.d.ts +71 -0
- package/vendor/dynamic-workflow/analysis/sites-labels.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/sites-labels.js +189 -0
- package/vendor/dynamic-workflow/analysis/sites.d.ts +267 -0
- package/vendor/dynamic-workflow/analysis/sites.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/sites.js +225 -0
- package/vendor/dynamic-workflow/analysis/state.d.ts +254 -0
- package/vendor/dynamic-workflow/analysis/state.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/state.js +569 -0
- package/vendor/dynamic-workflow/analysis/taint.d.ts +97 -0
- package/vendor/dynamic-workflow/analysis/taint.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/taint.js +649 -0
- package/vendor/dynamic-workflow/analysis/types.d.ts +100 -0
- package/vendor/dynamic-workflow/analysis/types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/types.js +1 -0
- package/vendor/dynamic-workflow/analysis/world-run.d.ts +27 -0
- package/vendor/dynamic-workflow/analysis/world-run.d.ts.map +1 -0
- package/vendor/dynamic-workflow/analysis/world-run.js +44 -0
- package/vendor/dynamic-workflow/compiler/compile.d.ts +59 -0
- package/vendor/dynamic-workflow/compiler/compile.d.ts.map +1 -0
- package/vendor/dynamic-workflow/compiler/compile.js +159 -0
- package/vendor/dynamic-workflow/compiler/libs.generated.d.ts +3 -0
- package/vendor/dynamic-workflow/compiler/libs.generated.d.ts.map +1 -0
- package/vendor/dynamic-workflow/compiler/libs.generated.js +64 -0
- package/vendor/dynamic-workflow/engine/artifact-spec.d.ts +26 -0
- package/vendor/dynamic-workflow/engine/artifact-spec.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/artifact-spec.js +173 -0
- package/vendor/dynamic-workflow/engine/ask-observation-types.d.ts +54 -0
- package/vendor/dynamic-workflow/engine/ask-observation-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/ask-observation-types.js +19 -0
- package/vendor/dynamic-workflow/engine/cached-ask-facts.d.ts +28 -0
- package/vendor/dynamic-workflow/engine/cached-ask-facts.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/cached-ask-facts.js +35 -0
- package/vendor/dynamic-workflow/engine/concurrency.d.ts +151 -0
- package/vendor/dynamic-workflow/engine/concurrency.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/concurrency.js +282 -0
- package/vendor/dynamic-workflow/engine/engine-artifacts-primary.d.ts +17 -0
- package/vendor/dynamic-workflow/engine/engine-artifacts-primary.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-artifacts-primary.js +29 -0
- package/vendor/dynamic-workflow/engine/engine-artifacts.d.ts +55 -0
- package/vendor/dynamic-workflow/engine/engine-artifacts.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-artifacts.js +367 -0
- package/vendor/dynamic-workflow/engine/engine-config.d.ts +90 -0
- package/vendor/dynamic-workflow/engine/engine-config.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-config.js +6 -0
- package/vendor/dynamic-workflow/engine/engine-holes.d.ts +116 -0
- package/vendor/dynamic-workflow/engine/engine-holes.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-holes.js +142 -0
- package/vendor/dynamic-workflow/engine/engine-launch.d.ts +34 -0
- package/vendor/dynamic-workflow/engine/engine-launch.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-launch.js +26 -0
- package/vendor/dynamic-workflow/engine/engine-phase-stamp.d.ts +35 -0
- package/vendor/dynamic-workflow/engine/engine-phase-stamp.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-phase-stamp.js +74 -0
- package/vendor/dynamic-workflow/engine/engine-report.d.ts +27 -0
- package/vendor/dynamic-workflow/engine/engine-report.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-report.js +151 -0
- package/vendor/dynamic-workflow/engine/engine-resume.d.ts +18 -0
- package/vendor/dynamic-workflow/engine/engine-resume.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-resume.js +38 -0
- package/vendor/dynamic-workflow/engine/engine-settlement.d.ts +30 -0
- package/vendor/dynamic-workflow/engine/engine-settlement.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-settlement.js +79 -0
- package/vendor/dynamic-workflow/engine/engine-state.d.ts +99 -0
- package/vendor/dynamic-workflow/engine/engine-state.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-state.js +13 -0
- package/vendor/dynamic-workflow/engine/engine-world.d.ts +36 -0
- package/vendor/dynamic-workflow/engine/engine-world.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine-world.js +189 -0
- package/vendor/dynamic-workflow/engine/engine.d.ts +263 -0
- package/vendor/dynamic-workflow/engine/engine.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/engine.js +602 -0
- package/vendor/dynamic-workflow/engine/errors.d.ts +87 -0
- package/vendor/dynamic-workflow/engine/errors.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/errors.js +56 -0
- package/vendor/dynamic-workflow/engine/hash-mismatch.d.ts +10 -0
- package/vendor/dynamic-workflow/engine/hash-mismatch.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/hash-mismatch.js +15 -0
- package/vendor/dynamic-workflow/engine/hash.d.ts +16 -0
- package/vendor/dynamic-workflow/engine/hash.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/hash.js +48 -0
- package/vendor/dynamic-workflow/engine/imported-cache-types.d.ts +96 -0
- package/vendor/dynamic-workflow/engine/imported-cache-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/imported-cache-types.js +6 -0
- package/vendor/dynamic-workflow/engine/imported-cache.d.ts +127 -0
- package/vendor/dynamic-workflow/engine/imported-cache.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/imported-cache.js +244 -0
- package/vendor/dynamic-workflow/engine/index.d.ts +11 -0
- package/vendor/dynamic-workflow/engine/index.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/index.js +10 -0
- package/vendor/dynamic-workflow/engine/journal-memory.d.ts +32 -0
- package/vendor/dynamic-workflow/engine/journal-memory.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/journal-memory.js +243 -0
- package/vendor/dynamic-workflow/engine/journal-read-types.d.ts +72 -0
- package/vendor/dynamic-workflow/engine/journal-read-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/journal-read-types.js +28 -0
- package/vendor/dynamic-workflow/engine/persona.d.ts +20 -0
- package/vendor/dynamic-workflow/engine/persona.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/persona.js +43 -0
- package/vendor/dynamic-workflow/engine/replay-order.d.ts +96 -0
- package/vendor/dynamic-workflow/engine/replay-order.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/replay-order.js +229 -0
- package/vendor/dynamic-workflow/engine/run-terminal.d.ts +35 -0
- package/vendor/dynamic-workflow/engine/run-terminal.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/run-terminal.js +7 -0
- package/vendor/dynamic-workflow/engine/scheduler-submit.d.ts +22 -0
- package/vendor/dynamic-workflow/engine/scheduler-submit.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/scheduler-submit.js +84 -0
- package/vendor/dynamic-workflow/engine/scheduler-types.d.ts +105 -0
- package/vendor/dynamic-workflow/engine/scheduler-types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/scheduler-types.js +17 -0
- package/vendor/dynamic-workflow/engine/scheduler.d.ts +113 -0
- package/vendor/dynamic-workflow/engine/scheduler.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/scheduler.js +484 -0
- package/vendor/dynamic-workflow/engine/types.d.ts +979 -0
- package/vendor/dynamic-workflow/engine/types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/types.js +26 -0
- package/vendor/dynamic-workflow/engine/world-read-input.d.ts +10 -0
- package/vendor/dynamic-workflow/engine/world-read-input.d.ts.map +1 -0
- package/vendor/dynamic-workflow/engine/world-read-input.js +55 -0
- package/vendor/dynamic-workflow/facade/artifact-caps.d.ts +48 -0
- package/vendor/dynamic-workflow/facade/artifact-caps.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/artifact-caps.js +47 -0
- package/vendor/dynamic-workflow/facade/dts-hole.d.ts +16 -0
- package/vendor/dynamic-workflow/facade/dts-hole.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/dts-hole.js +26 -0
- package/vendor/dynamic-workflow/facade/dts-model.d.ts +11 -0
- package/vendor/dynamic-workflow/facade/dts-model.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/dts-model.js +18 -0
- package/vendor/dynamic-workflow/facade/dts-stream.d.ts +15 -0
- package/vendor/dynamic-workflow/facade/dts-stream.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/dts-stream.js +41 -0
- package/vendor/dynamic-workflow/facade/dts.d.ts +29 -0
- package/vendor/dynamic-workflow/facade/dts.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/dts.js +324 -0
- package/vendor/dynamic-workflow/facade/registry.d.ts +218 -0
- package/vendor/dynamic-workflow/facade/registry.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/registry.js +203 -0
- package/vendor/dynamic-workflow/facade/report-caps.d.ts +40 -0
- package/vendor/dynamic-workflow/facade/report-caps.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/report-caps.js +39 -0
- package/vendor/dynamic-workflow/facade/world-read-caps.d.ts +37 -0
- package/vendor/dynamic-workflow/facade/world-read-caps.d.ts.map +1 -0
- package/vendor/dynamic-workflow/facade/world-read-caps.js +36 -0
- package/vendor/dynamic-workflow/index.d.ts +41 -0
- package/vendor/dynamic-workflow/index.d.ts.map +1 -0
- package/vendor/dynamic-workflow/index.js +51 -0
- package/vendor/dynamic-workflow/lowering/index.d.ts +2 -0
- package/vendor/dynamic-workflow/lowering/index.d.ts.map +1 -0
- package/vendor/dynamic-workflow/lowering/index.js +1 -0
- package/vendor/dynamic-workflow/lowering/lower-hole.d.ts +16 -0
- package/vendor/dynamic-workflow/lowering/lower-hole.d.ts.map +1 -0
- package/vendor/dynamic-workflow/lowering/lower-hole.js +63 -0
- package/vendor/dynamic-workflow/lowering/lower.d.ts +82 -0
- package/vendor/dynamic-workflow/lowering/lower.d.ts.map +1 -0
- package/vendor/dynamic-workflow/lowering/lower.js +333 -0
- package/vendor/dynamic-workflow/projections.d.ts +26 -0
- package/vendor/dynamic-workflow/projections.d.ts.map +1 -0
- package/vendor/dynamic-workflow/projections.js +23 -0
- package/vendor/dynamic-workflow/schema/actor-submit-profiles.d.ts +49 -0
- package/vendor/dynamic-workflow/schema/actor-submit-profiles.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/actor-submit-profiles.js +69 -0
- package/vendor/dynamic-workflow/schema/emit.d.ts +55 -0
- package/vendor/dynamic-workflow/schema/emit.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/emit.js +325 -0
- package/vendor/dynamic-workflow/schema/jsdoc.d.ts +10 -0
- package/vendor/dynamic-workflow/schema/jsdoc.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/jsdoc.js +83 -0
- package/vendor/dynamic-workflow/schema/serialize.d.ts +8 -0
- package/vendor/dynamic-workflow/schema/serialize.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/serialize.js +20 -0
- package/vendor/dynamic-workflow/schema/synthesize.d.ts +48 -0
- package/vendor/dynamic-workflow/schema/synthesize.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/synthesize.js +138 -0
- package/vendor/dynamic-workflow/schema/types.d.ts +67 -0
- package/vendor/dynamic-workflow/schema/types.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/types.js +18 -0
- package/vendor/dynamic-workflow/schema/validate.d.ts +15 -0
- package/vendor/dynamic-workflow/schema/validate.d.ts.map +1 -0
- package/vendor/dynamic-workflow/schema/validate.js +213 -0
- package/vendor/dynamic-workflow/testing/index.d.ts +6 -0
- package/vendor/dynamic-workflow/testing/index.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/index.js +5 -0
- package/vendor/dynamic-workflow/testing/journal-contract-artifacts.d.ts +9 -0
- package/vendor/dynamic-workflow/testing/journal-contract-artifacts.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-artifacts.js +195 -0
- package/vendor/dynamic-workflow/testing/journal-contract-events.d.ts +9 -0
- package/vendor/dynamic-workflow/testing/journal-contract-events.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-events.js +163 -0
- package/vendor/dynamic-workflow/testing/journal-contract-helpers.d.ts +9 -0
- package/vendor/dynamic-workflow/testing/journal-contract-helpers.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-helpers.js +12 -0
- package/vendor/dynamic-workflow/testing/journal-contract-isolation.d.ts +9 -0
- package/vendor/dynamic-workflow/testing/journal-contract-isolation.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-isolation.js +46 -0
- package/vendor/dynamic-workflow/testing/journal-contract-nodes.d.ts +9 -0
- package/vendor/dynamic-workflow/testing/journal-contract-nodes.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-nodes.js +234 -0
- package/vendor/dynamic-workflow/testing/journal-contract-reads.d.ts +11 -0
- package/vendor/dynamic-workflow/testing/journal-contract-reads.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-reads.js +281 -0
- package/vendor/dynamic-workflow/testing/journal-contract-runs.d.ts +9 -0
- package/vendor/dynamic-workflow/testing/journal-contract-runs.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-runs.js +396 -0
- package/vendor/dynamic-workflow/testing/journal-contract-script.d.ts +12 -0
- package/vendor/dynamic-workflow/testing/journal-contract-script.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract-script.js +82 -0
- package/vendor/dynamic-workflow/testing/journal-contract.d.ts +15 -0
- package/vendor/dynamic-workflow/testing/journal-contract.d.ts.map +1 -0
- package/vendor/dynamic-workflow/testing/journal-contract.js +31 -0
- package/vendor/dynamic-workflow-runtime/child-cell-streams.js +128 -0
- package/vendor/dynamic-workflow-runtime/child-entry-file.js +43 -0
- package/vendor/dynamic-workflow-runtime/child-source.js +299 -0
- package/vendor/dynamic-workflow-runtime/harness.js +302 -0
- package/vendor/dynamic-workflow-runtime/index.js +4 -0
- package/vendor/dynamic-workflow-runtime/protocol.js +2 -0
- package/vendor/mcode-host/dynamic-workflow-import.js +269 -0
- package/vendor/mcode-host/workflow-git-world-read.js +183 -0
- package/vendor/mcode-host/workflow-world-read.js +282 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { collectFlowHoles, collectFlowPhases, quotientFlow } from "./flow-phase.js";
|
|
2
|
+
import { createStrandPark } from "./flow-strands.js";
|
|
3
|
+
import { buildTree } from "./flow-tree.js";
|
|
4
|
+
/** Terminal node ids. `sink` is the causality graph's sink: the script completed normally. */
|
|
5
|
+
export const FLOW_ENTRY = "entry";
|
|
6
|
+
export const FLOW_SINK = "sink";
|
|
7
|
+
export const FLOW_ABORT = "abort";
|
|
8
|
+
/**
|
|
9
|
+
* One edge stands for the whole path from its source node to its target node, and that path
|
|
10
|
+
* may cross several boundaries (leave a choice arm, exit an inner loop, close the outer
|
|
11
|
+
* loop). The edge takes the MOST SIGNIFICANT transition on the path, by this rank: a plain
|
|
12
|
+
* successor < entering a branch or fan-out < leaving a loop / fan-out / call < closing a
|
|
13
|
+
* loop < an exception. `via` names the jump statement behind the kind and survives only
|
|
14
|
+
* while the kind does.
|
|
15
|
+
*/
|
|
16
|
+
const RANK = {
|
|
17
|
+
next: 0,
|
|
18
|
+
branch: 1,
|
|
19
|
+
fork: 1,
|
|
20
|
+
exit: 2,
|
|
21
|
+
join: 2,
|
|
22
|
+
jump: 2,
|
|
23
|
+
loop: 3,
|
|
24
|
+
throw: 4,
|
|
25
|
+
"may-throw": 4,
|
|
26
|
+
};
|
|
27
|
+
function retype(srcs, kind, via) {
|
|
28
|
+
return srcs.map((src) => RANK[kind] > RANK[src.kind] ? { from: src.from, kind, ...(via === undefined ? {} : { via }) } : src);
|
|
29
|
+
}
|
|
30
|
+
/** Force a kind regardless of rank: where a construct RESOLVES a jump (a `return` reaching its call). */
|
|
31
|
+
function settle(srcs, kind, via) {
|
|
32
|
+
return srcs.map((src) => ({ from: src.from, kind, ...(via === undefined ? {} : { via }) }));
|
|
33
|
+
}
|
|
34
|
+
function dedupeSrcs(srcs) {
|
|
35
|
+
const seen = new Set();
|
|
36
|
+
return srcs.filter((src) => {
|
|
37
|
+
const key = `${src.from}|${src.kind}|${src.via ?? ""}`;
|
|
38
|
+
if (seen.has(key))
|
|
39
|
+
return false;
|
|
40
|
+
seen.add(key);
|
|
41
|
+
return true;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** The edge a jump of `kind` makes at its target. `return` into a fan-out is decided there. */
|
|
45
|
+
function jumpEdge(kind) {
|
|
46
|
+
switch (kind) {
|
|
47
|
+
case "continue":
|
|
48
|
+
return { kind: "loop", via: "continue" };
|
|
49
|
+
case "recur":
|
|
50
|
+
return { kind: "loop", via: "recur" };
|
|
51
|
+
case "break":
|
|
52
|
+
return { kind: "exit", via: "break" };
|
|
53
|
+
case "return":
|
|
54
|
+
return { kind: "jump", via: "return" };
|
|
55
|
+
case "throw":
|
|
56
|
+
return { kind: "throw" };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function projectControlFlow(core) {
|
|
60
|
+
const trace = core.trace;
|
|
61
|
+
const { byId, root } = buildTree(trace);
|
|
62
|
+
const nodes = [];
|
|
63
|
+
const edges = [];
|
|
64
|
+
const edgeKeys = new Set();
|
|
65
|
+
const pending = [];
|
|
66
|
+
const occurrences = new Map();
|
|
67
|
+
const park = createStrandPark(trace.phases);
|
|
68
|
+
let placeholders = 0;
|
|
69
|
+
const emit = (from, to, kind, via) => {
|
|
70
|
+
const key = `${from}|${to}|${kind}|${via ?? ""}`;
|
|
71
|
+
if (edgeKeys.has(key))
|
|
72
|
+
return;
|
|
73
|
+
edgeKeys.add(key);
|
|
74
|
+
edges.push({ from, kind, to, ...(via === undefined ? {} : { via }) });
|
|
75
|
+
};
|
|
76
|
+
const connect = (srcs, to) => {
|
|
77
|
+
for (const src of srcs)
|
|
78
|
+
emit(src.from, to, src.kind, src.via);
|
|
79
|
+
};
|
|
80
|
+
/** Remove and return the registered jumps of these kinds aimed at `target`. */
|
|
81
|
+
const take = (target, kinds) => {
|
|
82
|
+
const out = [];
|
|
83
|
+
for (let i = pending.length - 1; i >= 0; i -= 1) {
|
|
84
|
+
const entry = pending[i];
|
|
85
|
+
if (entry.target !== target || !kinds.includes(entry.kind))
|
|
86
|
+
continue;
|
|
87
|
+
out.unshift(...entry.srcs);
|
|
88
|
+
pending.splice(i, 1);
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
};
|
|
92
|
+
/** The nearest enclosing `attempt` of a region: where an exception escaping it lands. */
|
|
93
|
+
const enclosingAttempt = (region) => {
|
|
94
|
+
let parent = region.parent === undefined ? undefined : byId.get(region.parent)?.region;
|
|
95
|
+
while (parent !== undefined) {
|
|
96
|
+
if (parent.kind === "attempt")
|
|
97
|
+
return parent.id;
|
|
98
|
+
parent = parent.parent === undefined ? undefined : byId.get(parent.parent)?.region;
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
};
|
|
102
|
+
const raiseOutward = (from, srcs) => {
|
|
103
|
+
if (srcs.length === 0)
|
|
104
|
+
return;
|
|
105
|
+
const attempt = enclosingAttempt(from);
|
|
106
|
+
if (attempt === undefined)
|
|
107
|
+
connect(srcs, FLOW_ABORT);
|
|
108
|
+
else
|
|
109
|
+
pending.push({ kind: "throw", srcs: [...srcs], target: attempt });
|
|
110
|
+
};
|
|
111
|
+
const subtreeIds = (node, into = new Set()) => {
|
|
112
|
+
into.add(node.region.id);
|
|
113
|
+
for (const child of node.children)
|
|
114
|
+
if (child.type === "region")
|
|
115
|
+
subtreeIds(child, into);
|
|
116
|
+
return into;
|
|
117
|
+
};
|
|
118
|
+
const leaf = (node, incoming) => {
|
|
119
|
+
const { event } = node;
|
|
120
|
+
if (event.at === "actor")
|
|
121
|
+
return [...incoming];
|
|
122
|
+
// A barrier is transparent to the main line and is where the strands it awaits rejoin
|
|
123
|
+
// it: their parked exits continue from here, beside the sources that arrived.
|
|
124
|
+
if (event.at === "settle")
|
|
125
|
+
return [...incoming, ...park.join(event.joins ?? [])];
|
|
126
|
+
if (event.at === "jump") {
|
|
127
|
+
const { kind, via } = jumpEdge(event.kind);
|
|
128
|
+
pending.push({ kind: event.kind, srcs: retype(incoming, kind, via), target: event.target });
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
const key = event.at === "issue" ? event.step : event.phase;
|
|
132
|
+
const k = (occurrences.get(key) ?? 0) + 1;
|
|
133
|
+
occurrences.set(key, k);
|
|
134
|
+
const id = `${key}@${k}`;
|
|
135
|
+
const alongside = event.at === "mark" ? park.alongside(event.phase, event.regions) : [];
|
|
136
|
+
nodes.push({
|
|
137
|
+
id,
|
|
138
|
+
kind: event.at,
|
|
139
|
+
...(event.at === "issue" ? { site: event.step } : {}),
|
|
140
|
+
phase: event.phase,
|
|
141
|
+
...(alongside.length === 0 ? {} : { alongside }),
|
|
142
|
+
});
|
|
143
|
+
connect(incoming, id);
|
|
144
|
+
return [{ from: id, kind: "next" }];
|
|
145
|
+
};
|
|
146
|
+
/** Flow children in order: a sequential container. */
|
|
147
|
+
const sequence = (children, incoming) => {
|
|
148
|
+
let cur = [...incoming];
|
|
149
|
+
for (const child of children)
|
|
150
|
+
cur = flow(child, cur);
|
|
151
|
+
return cur;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Flow a body while learning its ENTRY nodes: the body is fed a placeholder source, the
|
|
155
|
+
* nodes the placeholder reached are the entries, and the real incoming sources are then
|
|
156
|
+
* connected to them — each edge ranked between what the source already carried and what
|
|
157
|
+
* the body's first construct assigned. Incoming sources that came out the other end
|
|
158
|
+
* without meeting a node are returned separately as `passed`: a path through the body
|
|
159
|
+
* that touched nothing is not an iteration anyone can see, so it must not close a loop.
|
|
160
|
+
*/
|
|
161
|
+
const withEntries = (children, incoming) => {
|
|
162
|
+
placeholders += 1;
|
|
163
|
+
const ph = `$entry${placeholders}`;
|
|
164
|
+
const pendingMark = pending.length;
|
|
165
|
+
const exits = sequence(children, [{ from: ph, kind: "next" }]);
|
|
166
|
+
const entries = [];
|
|
167
|
+
for (let i = edges.length - 1; i >= 0; i -= 1) {
|
|
168
|
+
const edge = edges[i];
|
|
169
|
+
if (edge.from !== ph)
|
|
170
|
+
continue;
|
|
171
|
+
edges.splice(i, 1);
|
|
172
|
+
edgeKeys.delete(`${edge.from}|${edge.to}|${edge.kind}|${edge.via ?? ""}`);
|
|
173
|
+
if (!entries.includes(edge.to))
|
|
174
|
+
entries.unshift(edge.to);
|
|
175
|
+
connect(retype(incoming, edge.kind, edge.via), edge.to);
|
|
176
|
+
}
|
|
177
|
+
// A jump as the body's first leaf registered the placeholder as its source.
|
|
178
|
+
for (const entry of pending.slice(pendingMark)) {
|
|
179
|
+
entry.srcs = entry.srcs.flatMap((src) => src.from === ph ? incoming.map((real) => ({ ...src, from: real.from })) : [src]);
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
entries,
|
|
183
|
+
exits: exits.filter((src) => src.from !== ph),
|
|
184
|
+
passed: exits.some((src) => src.from === ph) ? [...incoming] : [],
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
const choice = (node, incoming) => {
|
|
188
|
+
const { region } = node;
|
|
189
|
+
let cur = [...incoming]; // a case-clause expression that issues runs before the arms
|
|
190
|
+
const exits = [];
|
|
191
|
+
let carried = []; // switch fallthrough: the previous arm's normal completion
|
|
192
|
+
let sawArm = false;
|
|
193
|
+
for (const child of node.children) {
|
|
194
|
+
if (child.type !== "region" || child.region.kind !== "branch") {
|
|
195
|
+
cur = flow(child, cur);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
sawArm = true;
|
|
199
|
+
const armExits = sequence(child.children, [...retype(cur, "branch"), ...carried]);
|
|
200
|
+
if (region.fallthrough)
|
|
201
|
+
carried = armExits;
|
|
202
|
+
else
|
|
203
|
+
exits.push(...armExits);
|
|
204
|
+
}
|
|
205
|
+
if (region.fallthrough)
|
|
206
|
+
exits.push(...carried);
|
|
207
|
+
if (!region.exhaustive || !sawArm)
|
|
208
|
+
exits.push(...retype(cur, "branch"));
|
|
209
|
+
// `break` out of a switch is just choosing the successor: a `branch`, not a loop exit.
|
|
210
|
+
exits.push(...settle(take(region.id, ["break"]), "branch"));
|
|
211
|
+
return exits;
|
|
212
|
+
};
|
|
213
|
+
const loop = (node, incoming) => {
|
|
214
|
+
const { region } = node;
|
|
215
|
+
const { entries, exits: bodyExits, passed } = withEntries(node.children, incoming);
|
|
216
|
+
const breaks = take(region.id, ["break"]);
|
|
217
|
+
const jumpsBack = take(region.id, ["continue", "recur"]);
|
|
218
|
+
if (region.recursive) {
|
|
219
|
+
// A recursion SCC: only the re-entrant calls close the loop. The body completing
|
|
220
|
+
// normally is the helper RETURNING — that is the exit, and nothing is skipped.
|
|
221
|
+
for (const src of jumpsBack)
|
|
222
|
+
for (const entry of entries)
|
|
223
|
+
emit(src.from, entry, src.kind, src.via);
|
|
224
|
+
return [...bodyExits, ...passed, ...breaks];
|
|
225
|
+
}
|
|
226
|
+
const back = [...retype(bodyExits, "loop"), ...jumpsBack];
|
|
227
|
+
for (const src of back)
|
|
228
|
+
for (const entry of entries)
|
|
229
|
+
emit(src.from, entry, src.kind, src.via);
|
|
230
|
+
if (entries.length === 0) {
|
|
231
|
+
// No node inside: the loop is invisible, except that a `break` may have consumed the
|
|
232
|
+
// incoming sources and a never-entered loop still lets them pass.
|
|
233
|
+
return dedupeSrcs([...bodyExits, ...passed, ...breaks, ...(region.entered ? [] : incoming)]);
|
|
234
|
+
}
|
|
235
|
+
const exits = [...retype(bodyExits, "exit"), ...retype(passed, "exit"), ...breaks];
|
|
236
|
+
if (!region.entered)
|
|
237
|
+
exits.push(...retype(incoming, "exit"));
|
|
238
|
+
return dedupeSrcs(exits);
|
|
239
|
+
};
|
|
240
|
+
const fanout = (node, incoming) => {
|
|
241
|
+
const { entries, exits: bodyExits, passed } = withEntries(node.children, retype(incoming, "fork"));
|
|
242
|
+
const returns = settle(take(node.region.id, ["return"]), "join", "return");
|
|
243
|
+
if (entries.length === 0)
|
|
244
|
+
return dedupeSrcs([...bodyExits, ...passed, ...returns]);
|
|
245
|
+
return dedupeSrcs([...retype(bodyExits, "join"), ...retype(passed, "join"), ...returns]);
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* A STRAND: one asynchronous activation that runs alongside the body that spawned it.
|
|
249
|
+
* Control forks into it here, where the trace records it, but leaves it at the barrier
|
|
250
|
+
* that awaits its promise — so its exits (the body's, and its `return`s, all `join`) are
|
|
251
|
+
* parked under its region id for that barrier to collect, and the spawner carries on
|
|
252
|
+
* with exactly the sources it arrived with.
|
|
253
|
+
*
|
|
254
|
+
* `passed` is dropped, and so is any exit still standing on one of the strand's own
|
|
255
|
+
* incoming sources: both are the spawner's control, not the strand's, and they leave
|
|
256
|
+
* with `incoming`. Parking one would draw a second, `join`-kinded copy of the
|
|
257
|
+
* pass-through edge the spawner already makes. A strand left with nothing to park is
|
|
258
|
+
* invisible and parks nothing.
|
|
259
|
+
*
|
|
260
|
+
* "Nothing" is judged on the EXITS, never on `entries`. Both corners that rule out the
|
|
261
|
+
* tempting `entries.length === 0` test are in the corpus, and both were measured:
|
|
262
|
+
* - a body that meets no node of its own can still have real exits. The `.finally` of
|
|
263
|
+
* `async-promise-then-both-callbacks` holds no call, but its barrier joins the two
|
|
264
|
+
* `.then` strands and their exits surface in `bodyExits`. `entries` is built from
|
|
265
|
+
* the edges leaving the entry PLACEHOLDER, which never reached a node here, so the
|
|
266
|
+
* entries test drops them and leaves two ask nodes with no outgoing edge at all.
|
|
267
|
+
* - a body full of nodes can still carry an exit that met none. A `return` whose path
|
|
268
|
+
* touched nothing stands on whatever `withEntries` rewrote the placeholder to; on
|
|
269
|
+
* `functions-summaries-mutual-recursion` that is an enclosing body's placeholder,
|
|
270
|
+
* and parking it emitted `$entry1 -> sink`, an edge out of a node that never was.
|
|
271
|
+
*/
|
|
272
|
+
const strandRegion = (node, incoming) => {
|
|
273
|
+
const nodeMark = nodes.length;
|
|
274
|
+
const spawner = new Set(incoming.map((src) => src.from));
|
|
275
|
+
const { exits: bodyExits } = withEntries(node.children, retype(incoming, "fork"));
|
|
276
|
+
const returns = settle(take(node.region.id, ["return"]), "join", "return");
|
|
277
|
+
const all = dedupeSrcs([...retype(bodyExits, "join"), ...returns]);
|
|
278
|
+
const exits = all.filter((src) => !spawner.has(src.from));
|
|
279
|
+
const phases = new Set(nodes.slice(nodeMark).map((inner) => inner.phase));
|
|
280
|
+
if (exits.length > 0 || phases.size > 0)
|
|
281
|
+
park.park(node.region.id, exits, [...phases]);
|
|
282
|
+
return [...incoming];
|
|
283
|
+
};
|
|
284
|
+
// A `return` reaching its call resumes at the call site: from the caller's point of view a
|
|
285
|
+
// plain successor. (`return` to the root is a `jump` to the sink; see the root below.)
|
|
286
|
+
const call = (node, incoming) => [
|
|
287
|
+
...sequence(node.children, incoming),
|
|
288
|
+
...settle(take(node.region.id, ["return"]), "next"),
|
|
289
|
+
];
|
|
290
|
+
const tryGroup = (node, incoming) => {
|
|
291
|
+
const part = (kind) => node.children.find((child) => child.type === "region" && child.region.kind === kind);
|
|
292
|
+
const attempt = part("attempt");
|
|
293
|
+
const handler = part("catch");
|
|
294
|
+
const finalizer = part("finally");
|
|
295
|
+
if (attempt === undefined)
|
|
296
|
+
return sequence(node.children, incoming);
|
|
297
|
+
const inside = subtreeIds(node);
|
|
298
|
+
const pendingMark = pending.length;
|
|
299
|
+
const nodeMark = nodes.length;
|
|
300
|
+
let normal = sequence(attempt.children, incoming);
|
|
301
|
+
// Every issue lexically inside the try body may reject there; explicit throws targeting
|
|
302
|
+
// this attempt join them. Nothing outside a try body gets an implicit exception edge.
|
|
303
|
+
// (An issue inside a NESTED try also lands here — its own catch may rethrow, so the
|
|
304
|
+
// outer handler stays reachable; over-approximating is the licensed direction.)
|
|
305
|
+
let raised = [
|
|
306
|
+
...nodes.slice(nodeMark).filter((n) => n.kind === "issue").map((n) => ({ from: n.id, kind: "may-throw" })),
|
|
307
|
+
...take(attempt.region.id, ["throw"]),
|
|
308
|
+
];
|
|
309
|
+
if (handler !== undefined) {
|
|
310
|
+
normal = [...normal, ...sequence(handler.children, raised)];
|
|
311
|
+
raised = [];
|
|
312
|
+
}
|
|
313
|
+
if (finalizer === undefined) {
|
|
314
|
+
raiseOutward(node.region, raised);
|
|
315
|
+
return normal;
|
|
316
|
+
}
|
|
317
|
+
// Jumps out of the try body / catch block pass through finally first: they are pulled
|
|
318
|
+
// off the pending list, fed into finally, and re-registered from finally's exits.
|
|
319
|
+
const escaping = [];
|
|
320
|
+
for (let i = pending.length - 1; i >= pendingMark; i -= 1) {
|
|
321
|
+
const entry = pending[i];
|
|
322
|
+
if (inside.has(entry.target))
|
|
323
|
+
continue;
|
|
324
|
+
escaping.unshift(entry);
|
|
325
|
+
pending.splice(i, 1);
|
|
326
|
+
}
|
|
327
|
+
const finallyExits = sequence(finalizer.children, [
|
|
328
|
+
...normal,
|
|
329
|
+
...raised,
|
|
330
|
+
...escaping.flatMap((entry) => entry.srcs),
|
|
331
|
+
]);
|
|
332
|
+
for (const entry of escaping) {
|
|
333
|
+
const { kind, via } = jumpEdge(entry.kind);
|
|
334
|
+
pending.push({ kind: entry.kind, srcs: retype(finallyExits, kind, via), target: entry.target });
|
|
335
|
+
}
|
|
336
|
+
if (raised.length > 0)
|
|
337
|
+
raiseOutward(node.region, retype(finallyExits, "throw"));
|
|
338
|
+
return normal.length > 0 ? finallyExits : [];
|
|
339
|
+
};
|
|
340
|
+
// A source list is a SET: `connect` dedups the edges it makes, so duplicates carry no
|
|
341
|
+
// information — but they multiply. A skippable choice with nothing inside returns its
|
|
342
|
+
// incoming sources twice (once through the arm, once past it), and a helper inlined a
|
|
343
|
+
// hundred times contributes thousands of such leafless regions in sequence: the multiset
|
|
344
|
+
// doubled at each one until `push(...exits)` overflowed the call stack with 135,200 copies
|
|
345
|
+
// of ONE source. Dedup at the one seam every construct flows through, so no list ever
|
|
346
|
+
// exceeds |nodes| × |kinds| entries whatever the shape.
|
|
347
|
+
const flow = (node, incoming) => dedupeSrcs(flowRaw(node, incoming));
|
|
348
|
+
const flowRaw = (node, incoming) => {
|
|
349
|
+
if (node.type === "leaf")
|
|
350
|
+
return leaf(node, incoming);
|
|
351
|
+
// `strand` rides on a `call` or a `fanout` and overrides both: what matters is that
|
|
352
|
+
// the body runs concurrently with its spawner, not how it was written.
|
|
353
|
+
if (node.region.strand === true)
|
|
354
|
+
return strandRegion(node, incoming);
|
|
355
|
+
switch (node.region.kind) {
|
|
356
|
+
case "choice":
|
|
357
|
+
return choice(node, incoming);
|
|
358
|
+
case "loop":
|
|
359
|
+
return loop(node, incoming);
|
|
360
|
+
case "fanout":
|
|
361
|
+
return fanout(node, incoming);
|
|
362
|
+
case "call":
|
|
363
|
+
return call(node, incoming);
|
|
364
|
+
case "try":
|
|
365
|
+
return tryGroup(node, incoming);
|
|
366
|
+
default:
|
|
367
|
+
return sequence(node.children, incoming);
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
// --- Root: entry, the main sequence, the terminals, then the detached bodies ------------
|
|
371
|
+
const detached = root.children.filter((child) => child.type === "region" && child.region.detached === true);
|
|
372
|
+
const main = root.children.filter((child) => !detached.includes(child));
|
|
373
|
+
const exits = sequence(main, [{ from: FLOW_ENTRY, kind: "next" }]);
|
|
374
|
+
connect(exits, FLOW_SINK);
|
|
375
|
+
connect(take(trace.root, ["return"]), FLOW_SINK);
|
|
376
|
+
connect(take(trace.root, ["throw"]), FLOW_ABORT);
|
|
377
|
+
// No barrier ever awaited these strands. All that is known is that the script did not
|
|
378
|
+
// outlive them, so they join the sink — the same terminal the main line reaches.
|
|
379
|
+
connect(park.drain(), FLOW_SINK);
|
|
380
|
+
for (const body of detached) {
|
|
381
|
+
const pendingMark = pending.length;
|
|
382
|
+
const nodeMark = nodes.length;
|
|
383
|
+
sequence(body.children, []);
|
|
384
|
+
for (const node of nodes.slice(nodeMark))
|
|
385
|
+
node.detached = true;
|
|
386
|
+
// A detached body has no position, so nothing it jumps to can be drawn — and neither
|
|
387
|
+
// can the strands it spawns, which go the same way as its pending jumps.
|
|
388
|
+
pending.splice(pendingMark);
|
|
389
|
+
park.discard();
|
|
390
|
+
}
|
|
391
|
+
sortEdges(nodes, edges);
|
|
392
|
+
const phases = collectFlowPhases(trace, nodes);
|
|
393
|
+
const holes = collectFlowHoles(core, nodes);
|
|
394
|
+
return {
|
|
395
|
+
edges,
|
|
396
|
+
nodes,
|
|
397
|
+
...(trace.phases.length === 0 ? {} : { phaseEdges: quotientFlow(nodes, edges, phases), phases }),
|
|
398
|
+
...(holes.length === 0 ? {} : { holes }),
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function sortEdges(nodes, edges) {
|
|
402
|
+
const rank = new Map(nodes.map((node, index) => [node.id, index]));
|
|
403
|
+
rank.set(FLOW_ENTRY, -1);
|
|
404
|
+
rank.set(FLOW_SINK, nodes.length);
|
|
405
|
+
rank.set(FLOW_ABORT, nodes.length + 1);
|
|
406
|
+
const at = (id) => rank.get(id) ?? nodes.length + 2;
|
|
407
|
+
edges.sort((a, b) => at(a.from) - at(b.from) ||
|
|
408
|
+
at(a.to) - at(b.to) ||
|
|
409
|
+
a.kind.localeCompare(b.kind) ||
|
|
410
|
+
(a.via ?? "").localeCompare(b.via ?? ""));
|
|
411
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { OrderTrace } from "./causality-order.js";
|
|
2
|
+
import type { AnalysisCore } from "./core.js";
|
|
3
|
+
import { type FlowEdge, type FlowHole, type FlowNode, type FlowPhase } from "./flow-graph.js";
|
|
4
|
+
/**
|
|
5
|
+
* The phase quotient of the control-flow graph — the control-flow counterpart of
|
|
6
|
+
* phase-graph.ts (which quotients the CAUSALITY graph). Same vocabulary, same all-or-nothing
|
|
7
|
+
* contract, different question: this one says where execution can go between phases.
|
|
8
|
+
*
|
|
9
|
+
* `alongside` is folded here too, but it is not an edge and so not part of the quotient:
|
|
10
|
+
* it is the union of the mark nodes' own `alongside` lists, because a phase entered twice
|
|
11
|
+
* with different strands running is entered alongside both.
|
|
12
|
+
*/
|
|
13
|
+
/** Phases some node carries, in first-reach order, {@link UNPHASED_ID} first when present. */
|
|
14
|
+
export declare function collectFlowPhases(trace: OrderTrace, nodes: readonly FlowNode[]): FlowPhase[];
|
|
15
|
+
/**
|
|
16
|
+
* The open holes for the display (docs/dynamic-workflow/presentation.md, `holes`), in source
|
|
17
|
+
* order. `phase` is the phase of the hole's FIRST issue node — where it stands; a hole the
|
|
18
|
+
* walk never reached (none in practice: the sweep issues every step) carries none.
|
|
19
|
+
*/
|
|
20
|
+
export declare function collectFlowHoles(core: AnalysisCore, nodes: readonly FlowNode[]): FlowHole[];
|
|
21
|
+
/**
|
|
22
|
+
* Each occurrence edge projected onto the phases of its endpoints. Same-phase edges dissolve
|
|
23
|
+
* unless they are `loop` back edges (a loop living inside one phase is a self-loop);
|
|
24
|
+
* terminals project to themselves. Kinds are kept apart — the renderer merges arrows, the
|
|
25
|
+
* model does not. No transitive reduction: a CFG never is.
|
|
26
|
+
*/
|
|
27
|
+
export declare function quotientFlow(nodes: readonly FlowNode[], edges: readonly FlowEdge[], phases: readonly FlowPhase[]): FlowEdge[];
|
|
28
|
+
//# sourceMappingURL=flow-phase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-phase.d.ts","sourceRoot":"","sources":["../../src/analysis/flow-phase.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;GAQG;AAEH,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,EAAE,CA8B5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAmB3F;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,MAAM,EAAE,SAAS,SAAS,EAAE,GAC3B,QAAQ,EAAE,CA0BZ"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { UNPHASED_ID } from "./constants.js";
|
|
2
|
+
import { FLOW_ABORT, FLOW_ENTRY, FLOW_SINK, } from "./flow-graph.js";
|
|
3
|
+
/**
|
|
4
|
+
* The phase quotient of the control-flow graph — the control-flow counterpart of
|
|
5
|
+
* phase-graph.ts (which quotients the CAUSALITY graph). Same vocabulary, same all-or-nothing
|
|
6
|
+
* contract, different question: this one says where execution can go between phases.
|
|
7
|
+
*
|
|
8
|
+
* `alongside` is folded here too, but it is not an edge and so not part of the quotient:
|
|
9
|
+
* it is the union of the mark nodes' own `alongside` lists, because a phase entered twice
|
|
10
|
+
* with different strands running is entered alongside both.
|
|
11
|
+
*/
|
|
12
|
+
/** Phases some node carries, in first-reach order, {@link UNPHASED_ID} first when present. */
|
|
13
|
+
export function collectFlowPhases(trace, nodes) {
|
|
14
|
+
const present = new Set(nodes.map((node) => node.phase));
|
|
15
|
+
const rank = new Map(trace.phases.map((phase, index) => [phase.id, index + 1]));
|
|
16
|
+
rank.set(UNPHASED_ID, 0);
|
|
17
|
+
const at = (id) => rank.get(id) ?? rank.size;
|
|
18
|
+
const running = new Map();
|
|
19
|
+
for (const node of nodes) {
|
|
20
|
+
if (node.alongside === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
const into = running.get(node.phase) ?? new Set();
|
|
23
|
+
for (const id of node.alongside)
|
|
24
|
+
if (id !== node.phase)
|
|
25
|
+
into.add(id);
|
|
26
|
+
running.set(node.phase, into);
|
|
27
|
+
}
|
|
28
|
+
const alongsideOf = (id) => {
|
|
29
|
+
const ids = [...(running.get(id) ?? [])].sort((a, b) => at(a) - at(b));
|
|
30
|
+
return ids.length === 0 ? {} : { alongside: ids };
|
|
31
|
+
};
|
|
32
|
+
const out = [];
|
|
33
|
+
if (present.has(UNPHASED_ID))
|
|
34
|
+
out.push({ id: UNPHASED_ID, ...alongsideOf(UNPHASED_ID) });
|
|
35
|
+
for (const phase of trace.phases) {
|
|
36
|
+
if (present.has(phase.id)) {
|
|
37
|
+
out.push({
|
|
38
|
+
id: phase.id,
|
|
39
|
+
loc: phase.loc,
|
|
40
|
+
name: phase.name,
|
|
41
|
+
...alongsideOf(phase.id),
|
|
42
|
+
...(phase.fill === undefined ? {} : { fill: phase.fill }),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The open holes for the display (docs/dynamic-workflow/presentation.md, `holes`), in source
|
|
50
|
+
* order. `phase` is the phase of the hole's FIRST issue node — where it stands; a hole the
|
|
51
|
+
* walk never reached (none in practice: the sweep issues every step) carries none.
|
|
52
|
+
*/
|
|
53
|
+
export function collectFlowHoles(core, nodes) {
|
|
54
|
+
const phaseOf = new Map();
|
|
55
|
+
for (const node of nodes) {
|
|
56
|
+
if (node.kind === "issue" && node.site !== undefined && !phaseOf.has(node.site)) {
|
|
57
|
+
phaseOf.set(node.site, node.phase);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return [...core.sites.holes]
|
|
61
|
+
.sort((a, b) => a.order - b.order)
|
|
62
|
+
.map((hole) => {
|
|
63
|
+
const phase = phaseOf.get(hole.id);
|
|
64
|
+
return {
|
|
65
|
+
siteId: hole.id,
|
|
66
|
+
name: hole.name,
|
|
67
|
+
type: hole.type,
|
|
68
|
+
...(phase === undefined ? {} : { phase }),
|
|
69
|
+
...(hole.tail ? { tail: true } : {}),
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Each occurrence edge projected onto the phases of its endpoints. Same-phase edges dissolve
|
|
75
|
+
* unless they are `loop` back edges (a loop living inside one phase is a self-loop);
|
|
76
|
+
* terminals project to themselves. Kinds are kept apart — the renderer merges arrows, the
|
|
77
|
+
* model does not. No transitive reduction: a CFG never is.
|
|
78
|
+
*/
|
|
79
|
+
export function quotientFlow(nodes, edges, phases) {
|
|
80
|
+
const phaseOf = new Map(nodes.map((node) => [node.id, node.phase]));
|
|
81
|
+
const rank = new Map(phases.map((phase, index) => [phase.id, index]));
|
|
82
|
+
rank.set(FLOW_ENTRY, -1);
|
|
83
|
+
rank.set(FLOW_SINK, phases.length);
|
|
84
|
+
rank.set(FLOW_ABORT, phases.length + 1);
|
|
85
|
+
const at = (id) => rank.get(id) ?? phases.length + 2;
|
|
86
|
+
const seen = new Set();
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const edge of edges) {
|
|
89
|
+
const from = phaseOf.get(edge.from) ?? edge.from;
|
|
90
|
+
const to = phaseOf.get(edge.to) ?? edge.to;
|
|
91
|
+
if (from === to && edge.kind !== "loop")
|
|
92
|
+
continue;
|
|
93
|
+
const key = `${from}|${to}|${edge.kind}|${edge.via ?? ""}`;
|
|
94
|
+
if (seen.has(key))
|
|
95
|
+
continue;
|
|
96
|
+
seen.add(key);
|
|
97
|
+
out.push({ from, kind: edge.kind, to, ...(edge.via === undefined ? {} : { via: edge.via }) });
|
|
98
|
+
}
|
|
99
|
+
out.sort((a, b) => at(a.from) - at(b.from) ||
|
|
100
|
+
at(a.to) - at(b.to) ||
|
|
101
|
+
a.kind.localeCompare(b.kind) ||
|
|
102
|
+
(a.via ?? "").localeCompare(b.via ?? ""));
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PhaseInfo } from "./causality-order.js";
|
|
2
|
+
import type { Src } from "./flow-graph.js";
|
|
3
|
+
/**
|
|
4
|
+
* Where a strand's exits wait between the `fork` that starts it and the `join` that
|
|
5
|
+
* collects it — the one piece of state the concurrent control-flow graph (flow-graph.ts)
|
|
6
|
+
* keeps outside its recursion over the control tree.
|
|
7
|
+
*
|
|
8
|
+
* A strand region is flowed at its SPAWN point, because that is where the trace records
|
|
9
|
+
* it, but its exits do not belong there: they belong at the barrier that awaits its
|
|
10
|
+
* promise, an arbitrary distance later in the leaf stream and possibly in another region.
|
|
11
|
+
* So a strand parks its exits under its own region id and the spawner carries on
|
|
12
|
+
* unchanged; the `settle` leaf whose `joins` names the region unparks them and merges them
|
|
13
|
+
* into its own outgoing sources. A strand is joined at most once, exactly as the walk's
|
|
14
|
+
* `joined` set says. Whatever is still parked when the root's sequence ends joins the
|
|
15
|
+
* sink: nothing awaited it, so all that is known is that the script did not outlive it.
|
|
16
|
+
*
|
|
17
|
+
* The park also answers `alongside` for a `mark` leaf — which phases are still running
|
|
18
|
+
* when this one is entered — which is why it carries each strand's phases and not only its
|
|
19
|
+
* exits. Like every other projection module it must not import `typescript`; it is a
|
|
20
|
+
* separate file only because flow-graph.ts sits at the 400-line cap.
|
|
21
|
+
*/
|
|
22
|
+
export interface StrandPark {
|
|
23
|
+
/** Phases running alongside a mark: everything parked, minus its own and its ancestors'. */
|
|
24
|
+
alongside: (phase: string, regions: readonly string[]) => string[];
|
|
25
|
+
/** Forget everything parked, connecting nothing: a detached body's strands have no position. */
|
|
26
|
+
discard: () => void;
|
|
27
|
+
/** Take every exit still parked (the sink's share), leaving the park empty. */
|
|
28
|
+
drain: () => Src[];
|
|
29
|
+
/** Take the exits of the named strands; a name that parked nothing contributes none. */
|
|
30
|
+
join: (regions: readonly string[]) => Src[];
|
|
31
|
+
/** Record one strand's exits and the phases of the nodes its body created. */
|
|
32
|
+
park: (region: string, exits: readonly Src[], phases: readonly string[]) => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `phases` is the trace's phase table, which orders every list this module returns:
|
|
36
|
+
* {@link UNPHASED_ID} first (as in `collectFlowPhases`), then first-reach order.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createStrandPark(phases: readonly PhaseInfo[]): StrandPark;
|
|
39
|
+
//# sourceMappingURL=flow-strands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-strands.d.ts","sourceRoot":"","sources":["../../src/analysis/flow-strands.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,UAAU;IACzB,4FAA4F;IAC5F,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACnE,gGAAgG;IAChG,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,+EAA+E;IAC/E,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC;IACnB,wFAAwF;IACxF,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,GAAG,EAAE,CAAC;IAC5C,8EAA8E;IAC9E,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CAClF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,UAAU,CAqCzE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { UNPHASED_ID } from "./constants.js";
|
|
2
|
+
/**
|
|
3
|
+
* `phases` is the trace's phase table, which orders every list this module returns:
|
|
4
|
+
* {@link UNPHASED_ID} first (as in `collectFlowPhases`), then first-reach order.
|
|
5
|
+
*/
|
|
6
|
+
export function createStrandPark(phases) {
|
|
7
|
+
const parked = new Map();
|
|
8
|
+
const rank = new Map(phases.map((phase, index) => [phase.id, index + 1]));
|
|
9
|
+
rank.set(UNPHASED_ID, 0);
|
|
10
|
+
const at = (id) => rank.get(id) ?? rank.size;
|
|
11
|
+
return {
|
|
12
|
+
alongside: (phase, regions) => {
|
|
13
|
+
// A mark inside a strand is not alongside it: the strand is where the mark IS. The
|
|
14
|
+
// whole enclosing chain is excluded, not just the innermost region.
|
|
15
|
+
const enclosing = new Set(regions);
|
|
16
|
+
const running = new Set();
|
|
17
|
+
for (const [region, strand] of parked) {
|
|
18
|
+
if (enclosing.has(region))
|
|
19
|
+
continue;
|
|
20
|
+
for (const id of strand.phases)
|
|
21
|
+
if (id !== phase)
|
|
22
|
+
running.add(id);
|
|
23
|
+
}
|
|
24
|
+
return [...running].sort((a, b) => at(a) - at(b));
|
|
25
|
+
},
|
|
26
|
+
discard: () => parked.clear(),
|
|
27
|
+
drain: () => {
|
|
28
|
+
const out = [...parked.values()].flatMap((strand) => strand.exits);
|
|
29
|
+
parked.clear();
|
|
30
|
+
return out;
|
|
31
|
+
},
|
|
32
|
+
join: (regions) => {
|
|
33
|
+
const out = [];
|
|
34
|
+
for (const region of regions) {
|
|
35
|
+
const strand = parked.get(region);
|
|
36
|
+
if (strand === undefined)
|
|
37
|
+
continue;
|
|
38
|
+
parked.delete(region);
|
|
39
|
+
out.push(...strand.exits);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
},
|
|
43
|
+
park: (region, exits, phaseIds) => {
|
|
44
|
+
parked.set(region, { exits: [...exits], phases: [...phaseIds] });
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { OrderEvent, OrderRegion, OrderTrace } from "./causality-order.js";
|
|
2
|
+
/**
|
|
3
|
+
* The trace's leaf stream re-read as the STRUCTURED CONTROL TREE that the control-flow
|
|
4
|
+
* projection (flow-graph.ts) recurses over: regions are the inner nodes, events the
|
|
5
|
+
* leaves, and every leaf sits in the innermost region of its own `regions` chain.
|
|
6
|
+
*
|
|
7
|
+
* Children are ordered by first leaf, which is the evaluation order the walk recorded. A
|
|
8
|
+
* region holding no leaf sorts last among its siblings: it cannot affect the flow (an
|
|
9
|
+
* empty region passes control straight through), only its EXISTENCE can (an empty `catch`
|
|
10
|
+
* still catches).
|
|
11
|
+
*
|
|
12
|
+
* Its own file because flow-graph.ts sits at the 400-line cap and the tree is the one part
|
|
13
|
+
* of it that owes nothing to the flow recursion. Like its siblings it must not import
|
|
14
|
+
* `typescript`, and nothing here reaches the package barrels — flow-graph.ts is the only
|
|
15
|
+
* consumer.
|
|
16
|
+
*/
|
|
17
|
+
export interface RegionNode {
|
|
18
|
+
type: "region";
|
|
19
|
+
region: OrderRegion;
|
|
20
|
+
children: TreeNode[];
|
|
21
|
+
/** Index of the first leaf in this subtree; Infinity when it holds none. */
|
|
22
|
+
first: number;
|
|
23
|
+
}
|
|
24
|
+
export interface LeafNode {
|
|
25
|
+
type: "leaf";
|
|
26
|
+
event: OrderEvent;
|
|
27
|
+
index: number;
|
|
28
|
+
}
|
|
29
|
+
export type TreeNode = RegionNode | LeafNode;
|
|
30
|
+
/** Rebuild the tree from the leaf stream, and index every region by id. */
|
|
31
|
+
export declare function buildTree(trace: OrderTrace): {
|
|
32
|
+
root: RegionNode;
|
|
33
|
+
byId: Map<string, RegionNode>;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=flow-tree.d.ts.map
|