1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! # Exponential UI core (VAPP-86)
//!
//! The engine every native Exponential UI painter (gpui, SwiftUI, Compose)
//! runs on: an [A2UI](https://a2ui.org) surface comes in as messages, the
//! **reducer** turns the flat component list into ONE normalized tree in the
//! core vocabulary (the A2UI basic catalog mapped onto it, macros expanded
//! through the generated table, extension catalogs validated and their
//! natives passed through as `Extension` nodes), the **theme** resolves every
//! `$token` reference and per-part recipe into concrete visuals, **taffy**
//! lays the tree out against the surface width with a batched two-phase text
//! measurement that crosses the FFI at most three times per pass (sizes AND
//! first baselines), **overlay layers** (dialogs, drawers, popovers,
//! tooltips, menus and submenus, the Select / picker popups, the toast band)
//! get their own roots placed against the viewport, an anchor or a point,
//! and windowed `List`s / `Table`s lay out only the visible rows. Nodes live
//! in stable slots reconciled by id, so a data write, a tab switch or a
//! scroll touches only what changed (`NodeDelta`). The painter receives flat
//! `PlacedNode`s with RESOLVED visuals and paints; it never reads the
//! catalog or the theme.
//!
//! Round 1 (`packages/exponential-ui/docs/round-1-contract.md`): bound macro
//! inputs evaluate at bind time (`data::bind_tree`, `data::run_action`),
//! style conditions (`conditions`), the new style keys, responsive props,
//! the locale / strings / code / chart / a11y contracts (`locale`,
//! `strings`, `code`, `chart`, `a11y`), surface settings (mode incl.
//! `system`, density, contrast, font scale, safe-area insets).
//!
//! Round 2 (`docs/round-2-contract.md`): templates LIFTED out of the tree
//! (`ReduceResult::templates`), `#<index>` keys and accumulated instance
//! suffixes, a host [`format::Formatter`] (default: the English fallback),
//! display strings, per-node direction and physical text alignment
//! (`direction`), keyframe animations (`animation`), the Resizable
//! arithmetic (`resizable`) and native, one-axis windowing with sections,
//! sticky headers, unbounded lists and `scrollToIndex` (`list`),
//! `position: sticky`, `backdropBlur` and the shared layout numbers
//! (`layout`).
//!
//! The TypeScript reference implementation lives in `packages/exponential-ui`
//! (`@exponential_app/eui`); both replay the same fixtures byte for byte, and
//! the catalog, macro table and built-in themes are embedded here from the
//! same generator (`src/generated`).
//!
//! The coarse mobile facade is the sibling crate `exponential-ui-ffi`.
/// VAPP-103: run one step of a recursive pass with at least 64 KB of stack
/// left, else on a fresh 1 MB segment: the recursion never ends in the
/// guard page, however the tree nests.
pub
/// VAPP-103: run a whole pass (a reduce, a rebuild, a layout) with at
/// least [`PASS_STACK`] of stack, else on a fresh 8 MB segment (mapped
/// lazily). A `maxDepth`-deep pass takes ~400 KB in a release build, so a
/// host thread of 1 MB (the Linux JVM's and ART's default) never switches:
/// a host callback (the formatter, the measurer, the shaper) must run on
/// the host's OWN stack. The JVM refuses an upcall whose stack pointer lies
/// below its thread's stack (Linux maps a new segment there) with a
/// StackOverflowError that JNA swallows into an empty answer: every
/// formatted number was blank on Linux. Smaller threads (an iOS secondary
/// thread has 512 KB) still get the segment. One check per pass, so the
/// per-level [`deep`] rarely switches.
pub
/// The stack a pass asks for before it runs on its own segment ([`roomy`]).
pub const PASS_STACK: usize = 512 * 1024;
pub
pub use ;
pub use taffy;
pub use *;