Dependencies
Two surfaces live on this ornament: a typed-shape layer (constructors + dispatcher + spec ctor) and a resolver eliminators layer (uniform resolution + the resolved-deps marker).
Typed-shape layer
A DependencyShape selects the resolution strategy by
constructor:
Uniform { langName }— single-typed, identical treatment across all packages.Partitioned { langName; pathField }— custom-vs-bundled split driven by a sentinel path field.MultiTyped { types : list DependencyType }— N-type mix; eachDependencyTypedeclares its own transitive / toposort flags.
matchShape { uniform = …; partitioned = …; multiTyped = …; }
shape is the typed dispatcher: constructor-driven pattern match
over the three modes.
define { dependencyShape; … } produces a DependenciesBuilder
spec; consumers fold the spec into the surrounding builder
pipeline downstream.
Resolver eliminators
resolveUniform { langName; deps } walks the transitive closure of
deps via the ${langName}Deps field on each package, then
toposorts so dependencies precede dependents. Throws on cycles.
markResolved deps wraps an already-resolved list in a
sentinel-tagged record. isResolved x answers the marker check;
unwrapDeps x extracts the list (or returns plain inputs as-is).
Together they centralise the inline if ? __resolvedDeps then
.deps else x pattern that legacy consumers spelled at every call
site.