|
| 1 | +# Task 144 - API Surface Tightening for 1.0 |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +The package currently exports 93 public types, of which only ~a dozen are the |
| 6 | +intended consumer API. The rest are engine internals that are public only |
| 7 | +because the Yoga port translated C++ file-by-file. 1.0.0 freezes the public |
| 8 | +surface under semver, so this must happen BEFORE the stable release — |
| 9 | +internalizing anything afterward is a breaking change. This is the only |
| 10 | +blocker for 1.0 (see task 147). |
| 11 | + |
| 12 | +## Intended public surface (keep public) |
| 13 | + |
| 14 | +`Node`, `Style`, `Config`, `CalculateLayout`, `LayoutResults`, |
| 15 | +`StyleLength`, `StyleSizeLength`, `YGValue`, `YGSize`, `FloatOptional`, |
| 16 | +`YogaAssertException`, the delegates (`MeasureFunc`, `BaselineFunc`, |
| 17 | +`DirtiedFunc`, `CloneNodeFunc`, `YogaLogHandler`), and the enums |
| 18 | +(`FlexDirection`, `Justify`, `Align`, `Wrap`, `Edge`, `Gutter`, `Dimension`, |
| 19 | +`PhysicalEdge`, `Direction`, `PositionType`, `Overflow`, `Display`, |
| 20 | +`BoxSizing`, `Unit`, `MeasureMode`, `NodeType`, `Errata`, |
| 21 | +`ExperimentalFeature`, `LogLevel`). Review each remaining public member on |
| 22 | +these types too (e.g. `Node.CloneChildrenIfNeeded`, layout setters) — some |
| 23 | +are engine plumbing. |
| 24 | + |
| 25 | +## Todo List |
| 26 | + |
| 27 | +- [x] Internalize the algorithm machinery: `AbsoluteLayout`, `AlignUtils`, |
| 28 | + `Baseline`, `BoundAxis`, `Cache`, `CalculateLayoutCore`, `FlexBasis`, |
| 29 | + `FlexDirectionUtils`, `FlexDistribution`, `FlexLine`, `JustifyContent`, |
| 30 | + `LayoutHelpers`, `MeasureNode`, `PixelGrid`, `TrailingPosition`, |
| 31 | + `SizingMode`(+extensions), `LayoutData`, `LayoutPassReason`(+extensions) |
| 32 | +- [x] Internalize storage/infra: `StyleValuePool`, `StyleValueHandle`, |
| 33 | + `SmallValueBuffer`(+generic), `LayoutableChildren`, `CachedMeasurement`, |
| 34 | + `Comparison`, `YogaEnums`(+extensions), `OrdinalCountAttribute`, |
| 35 | + `YogaEvent`/`LayoutData` event plumbing, `YogaLog`, `YogaAssert` |
| 36 | +- [x] **Eliminate the mutable public static wiring**: `FlexBasis.CalculateLayoutInternal` |
| 37 | + is a public static settable delegate — any consumer can reassign it and break |
| 38 | + the engine globally. Make the wiring internal (or replace the delegate |
| 39 | + indirection with a direct internal call; it exists only to break a |
| 40 | + circular file dependency from the C++ port) |
| 41 | +- [x] Add `[assembly: InternalsVisibleTo("TimeWarp.Flexbox.Tests")]` — the unit |
| 42 | + tests exercise the machinery directly (keep them; they're ported Yoga tests) |
| 43 | +- [x] Confirm naming decisions that 1.0 freezes: `YGValue`/`YGSize` Yoga-parity |
| 44 | + names (recommended: keep — they signal lineage), `CalculateLayout.Calculate` |
| 45 | + static entry point vs. a `Node.CalculateLayout()` instance convenience |
| 46 | + (consider adding the instance method; additive later, but nicer at 1.0) |
| 47 | +- [x] Rebuild + full suite (1335/0/3 pins behavior), AOT smoke, `dotnet pack` |
| 48 | + and inspect the package's public API (e.g. dotnet-inspect) to confirm the |
| 49 | + final surface |
| 50 | +- [x] Update the flexbox skill / readme if any referenced type changed visibility |
| 51 | + |
| 52 | +## Notes |
| 53 | + |
| 54 | +- The 530 generated conformance tests use only the consumer API — they are the |
| 55 | + guarantee that internalization broke nothing behavioral. |
| 56 | +- After this task, the public surface should be reviewable in one screenful. |
| 57 | + |
| 58 | +## Results (2026-07-04) |
| 59 | + |
| 60 | +Public surface reduced from 93 to 39 types: 19 enums, 6 value types |
| 61 | +(YGValue, YGSize, FloatOptional, StyleLength, StyleSizeLength, |
| 62 | +ExperimentalFeatureSet), 5 delegates, 9 classes (Node, Style, Config, |
| 63 | +CalculateLayout, LayoutResults, Comparison, StyleLength/StyleSizeLength |
| 64 | +extensions, YogaAssertException). All algorithm machinery, storage internals, |
| 65 | +event system, and debug utilities are now internal; the mutable |
| 66 | +FlexBasis.CalculateLayoutInternal delegate is internal with the type. |
| 67 | + |
| 68 | +Deviations from the plan, deliberate: |
| 69 | +- `Comparison` kept public: tiny, useful (IsUndefined/IsDefined for NaN |
| 70 | + semantics), documented in the flexbox skill. |
| 71 | +- `ExperimentalFeatureSet` kept public (readonly struct surfaced by |
| 72 | + Config.EnabledExperiments). |
| 73 | + |
| 74 | +API improvements while the surface was open: |
| 75 | +- `Node.GetChild(int)` now returns `Node` (was ILayoutableNode); the duplicate |
| 76 | + `GetChildNode` removed; ILayoutableNode members explicitly implemented. |
| 77 | +- Added `Node.CalculateLayout(availableWidth = NaN, availableHeight = NaN, |
| 78 | + ownerDirection = LTR)` instance convenience; docs/skill updated. |
| 79 | +- InternalsVisibleTo("timewarp-flexbox-tests") added; MockNode test helper |
| 80 | + internalized — which removed 5 phantom Fixie-discovered entries (suite is |
| 81 | + now a clean 1333 passed / 0 failed / 0 skipped; previously 1335+3 included |
| 82 | + MockNode's methods). |
| 83 | + |
| 84 | +Verified: gated Release build zero warnings, suite 1333/0/0, AOT smoke native |
| 85 | +binary PASS, layout demo runs, dotnet format stable, ganda audit 22/22. |
| 86 | +Naming frozen deliberately: YGValue/YGSize Yoga-parity names kept. |
0 commit comments