@pilates/core 1.0.1 → 2.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 (77) hide show
  1. package/dist/algorithm/cache.d.ts +7 -19
  2. package/dist/algorithm/cache.d.ts.map +1 -1
  3. package/dist/algorithm/cache.js +31 -27
  4. package/dist/algorithm/cache.js.map +1 -1
  5. package/dist/algorithm/index.d.ts +31 -0
  6. package/dist/algorithm/index.d.ts.map +1 -1
  7. package/dist/algorithm/index.js +105 -13
  8. package/dist/algorithm/index.js.map +1 -1
  9. package/dist/algorithm/round.d.ts +13 -0
  10. package/dist/algorithm/round.d.ts.map +1 -1
  11. package/dist/algorithm/round.js +33 -16
  12. package/dist/algorithm/round.js.map +1 -1
  13. package/dist/algorithm/spineless/classify.d.ts +47 -0
  14. package/dist/algorithm/spineless/classify.d.ts.map +1 -0
  15. package/dist/algorithm/spineless/classify.js +109 -0
  16. package/dist/algorithm/spineless/classify.js.map +1 -0
  17. package/dist/algorithm/spineless/field-id-pool.d.ts +28 -0
  18. package/dist/algorithm/spineless/field-id-pool.d.ts.map +1 -0
  19. package/dist/algorithm/spineless/field-id-pool.js +35 -0
  20. package/dist/algorithm/spineless/field-id-pool.js.map +1 -0
  21. package/dist/algorithm/spineless/flex-grammar.d.ts +394 -0
  22. package/dist/algorithm/spineless/flex-grammar.d.ts.map +1 -0
  23. package/dist/algorithm/spineless/flex-grammar.js +2509 -0
  24. package/dist/algorithm/spineless/flex-grammar.js.map +1 -0
  25. package/dist/algorithm/spineless/grammar.d.ts +156 -0
  26. package/dist/algorithm/spineless/grammar.d.ts.map +1 -0
  27. package/dist/algorithm/spineless/grammar.js +145 -0
  28. package/dist/algorithm/spineless/grammar.js.map +1 -0
  29. package/dist/algorithm/spineless/layout.d.ts +167 -0
  30. package/dist/algorithm/spineless/layout.d.ts.map +1 -0
  31. package/dist/algorithm/spineless/layout.js +893 -0
  32. package/dist/algorithm/spineless/layout.js.map +1 -0
  33. package/dist/algorithm/spineless/order-maintenance.bench.d.ts +25 -0
  34. package/dist/algorithm/spineless/order-maintenance.bench.d.ts.map +1 -0
  35. package/dist/algorithm/spineless/order-maintenance.bench.js +78 -0
  36. package/dist/algorithm/spineless/order-maintenance.bench.js.map +1 -0
  37. package/dist/algorithm/spineless/order-maintenance.d.ts +201 -0
  38. package/dist/algorithm/spineless/order-maintenance.d.ts.map +1 -0
  39. package/dist/algorithm/spineless/order-maintenance.js +300 -0
  40. package/dist/algorithm/spineless/order-maintenance.js.map +1 -0
  41. package/dist/algorithm/spineless/priority-queue.bench.d.ts +17 -0
  42. package/dist/algorithm/spineless/priority-queue.bench.d.ts.map +1 -0
  43. package/dist/algorithm/spineless/priority-queue.bench.js +57 -0
  44. package/dist/algorithm/spineless/priority-queue.bench.js.map +1 -0
  45. package/dist/algorithm/spineless/priority-queue.d.ts +73 -0
  46. package/dist/algorithm/spineless/priority-queue.d.ts.map +1 -0
  47. package/dist/algorithm/spineless/priority-queue.js +149 -0
  48. package/dist/algorithm/spineless/priority-queue.js.map +1 -0
  49. package/dist/algorithm/spineless/runtime.d.ts +292 -0
  50. package/dist/algorithm/spineless/runtime.d.ts.map +1 -0
  51. package/dist/algorithm/spineless/runtime.js +609 -0
  52. package/dist/algorithm/spineless/runtime.js.map +1 -0
  53. package/dist/algorithm/spineless/style-dirty.d.ts +65 -0
  54. package/dist/algorithm/spineless/style-dirty.d.ts.map +1 -0
  55. package/dist/algorithm/spineless/style-dirty.js +75 -0
  56. package/dist/algorithm/spineless/style-dirty.js.map +1 -0
  57. package/dist/dirty-flags.d.ts +30 -0
  58. package/dist/dirty-flags.d.ts.map +1 -0
  59. package/dist/dirty-flags.js +35 -0
  60. package/dist/dirty-flags.js.map +1 -0
  61. package/dist/index.d.ts +4 -1
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +9 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/inspect.d.ts +27 -0
  66. package/dist/inspect.d.ts.map +1 -0
  67. package/dist/inspect.js +61 -0
  68. package/dist/inspect.js.map +1 -0
  69. package/dist/layout-pool.d.ts +49 -0
  70. package/dist/layout-pool.d.ts.map +1 -0
  71. package/dist/layout-pool.js +75 -0
  72. package/dist/layout-pool.js.map +1 -0
  73. package/dist/node.d.ts +20 -3
  74. package/dist/node.d.ts.map +1 -1
  75. package/dist/node.js +63 -42
  76. package/dist/node.js.map +1 -1
  77. package/package.json +1 -1
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Dirty-region classifier for the `calculateLayout` router (phase 14).
3
+ *
4
+ * Examines the dirty region of `root` against a snapshot map of the
5
+ * pre-mutation tree state. Returns a discriminated union telling the
6
+ * router which engine to use:
7
+ *
8
+ * - `value` — only value mutations on snapped nodes; Spineless wins
9
+ * - `structural` — one pivot node had its child list change; route to imperative
10
+ * - `multi-pivot` — two or more parents had children change; imperative for safety
11
+ * - `sig-change` — a snapped node had its signature or measure func change; imperative
12
+ * - `no-snap` — no snap map available (driver is cold or just invalidated)
13
+ *
14
+ * Pure function over `Node` reads + the snap map. No I/O, no
15
+ * side effects.
16
+ *
17
+ * @internal
18
+ */
19
+ /**
20
+ * Build a structural signature for one node. Two nodes' sigs are equal
21
+ * iff their style-affecting-layout-shape fields are equal — see
22
+ * `SpinelessLayout`'s `nodeSig` for the inspiration.
23
+ */
24
+ function nodeSig(node) {
25
+ const s = node.style;
26
+ return [
27
+ s.flexDirection,
28
+ s.flexWrap,
29
+ s.justifyContent,
30
+ s.alignItems,
31
+ s.alignContent,
32
+ s.alignSelf,
33
+ s.positionType,
34
+ s.display,
35
+ typeof s.width,
36
+ typeof s.height,
37
+ typeof s.flexBasis,
38
+ s.flexGrow > 0 ? 'g' : '_',
39
+ s.flexShrink > 0 ? 's' : '_',
40
+ s.aspectRatio === undefined ? 'n' : String(s.aspectRatio),
41
+ s.position.map((p) => (p === undefined ? '_' : String(p))).join(','),
42
+ ].join('|');
43
+ }
44
+ /** Snapshot one node's structural shape for later comparison. */
45
+ export function snapNode(node) {
46
+ const children = [];
47
+ for (let i = 0; i < node.getChildCount(); i++)
48
+ children.push(node.getChild(i));
49
+ return { sig: nodeSig(node), measure: node.getMeasureFunc(), children };
50
+ }
51
+ /** True iff `node`'s current child list still matches `snap.children`. */
52
+ function childrenUnchanged(snap, node) {
53
+ if (node.getChildCount() !== snap.children.length)
54
+ return false;
55
+ for (let i = 0; i < snap.children.length; i++) {
56
+ if (node.getChild(i) !== snap.children[i])
57
+ return false;
58
+ }
59
+ return true;
60
+ }
61
+ /** Walk dirty region, classify against the snap map. */
62
+ export function classifyDirty(root, snaps) {
63
+ if (snaps === null)
64
+ return { kind: 'no-snap' };
65
+ let structuralPivot = null;
66
+ let multiPivot = false;
67
+ let sigChanged = false;
68
+ function visit(n) {
69
+ if (sigChanged || multiPivot)
70
+ return;
71
+ const dirty = n.isDirty();
72
+ const hasDirtyDescendant = n
73
+ ._hasDirtyDescendant;
74
+ const snap = snaps.get(n);
75
+ if (snap === undefined) {
76
+ // A node with no snap that's part of the dirty walk = newly
77
+ // introduced node (e.g. an appended child). Its parent's child-list
78
+ // change is already tracked via childrenUnchanged(); don't escalate
79
+ // to multi-pivot just because the new subtree contains unseen nodes.
80
+ return;
81
+ }
82
+ if (dirty) {
83
+ if (snap.sig !== nodeSig(n) || snap.measure !== n.getMeasureFunc()) {
84
+ sigChanged = true;
85
+ return;
86
+ }
87
+ if (!childrenUnchanged(snap, n)) {
88
+ if (structuralPivot !== null && structuralPivot !== n) {
89
+ multiPivot = true;
90
+ return;
91
+ }
92
+ structuralPivot = n;
93
+ }
94
+ }
95
+ if (dirty || hasDirtyDescendant) {
96
+ for (let i = 0; i < n.getChildCount(); i++)
97
+ visit(n.getChild(i));
98
+ }
99
+ }
100
+ visit(root);
101
+ if (sigChanged)
102
+ return { kind: 'sig-change' };
103
+ if (multiPivot)
104
+ return { kind: 'multi-pivot' };
105
+ if (structuralPivot !== null)
106
+ return { kind: 'structural', pivot: structuralPivot };
107
+ return { kind: 'value' };
108
+ }
109
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../src/algorithm/spineless/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Monotonic integer ID allocator for Spineless `Field` objects.
3
+ * Phase 15I indexes the runtime's typed-array storage by field.id.
4
+ *
5
+ * IDs are never recycled — Fields are interned per (node, name) and
6
+ * live as long as their node. The max id is the live-field high-water
7
+ * mark, matching LayoutPool's accepted tradeoff.
8
+ *
9
+ * @internal
10
+ */
11
+ /** Allocate a fresh unique integer id for a Field. */
12
+ export declare function allocateFieldId(): number;
13
+ /** Current id count — the exclusive upper bound of allocated ids.
14
+ * Runtime typed arrays size to at least this. @internal */
15
+ export declare function fieldIdCount(): number;
16
+ /** Reset for tests. @internal
17
+ *
18
+ * WARNING: Only safe to call when no live `Field` objects exist
19
+ * anywhere — the `FIELD_REGISTRY` WeakMap in `grammar.ts` is NOT
20
+ * cleared, so any `Field` retained across this call still holds
21
+ * its old id. Newly-allocated fields will then collide with retained
22
+ * ids, aliasing entries in the runtime's typed-array storage. The
23
+ * standard test harness creates fresh `Node`s per test, so retained
24
+ * cross-test references are the only way to hit this; don't introduce
25
+ * them.
26
+ */
27
+ export declare function _resetFieldIdsForTesting(): void;
28
+ //# sourceMappingURL=field-id-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-id-pool.d.ts","sourceRoot":"","sources":["../../../src/algorithm/spineless/field-id-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,sDAAsD;AACtD,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;4DAC4D;AAC5D,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Monotonic integer ID allocator for Spineless `Field` objects.
3
+ * Phase 15I indexes the runtime's typed-array storage by field.id.
4
+ *
5
+ * IDs are never recycled — Fields are interned per (node, name) and
6
+ * live as long as their node. The max id is the live-field high-water
7
+ * mark, matching LayoutPool's accepted tradeoff.
8
+ *
9
+ * @internal
10
+ */
11
+ let _nextFieldId = 0;
12
+ /** Allocate a fresh unique integer id for a Field. */
13
+ export function allocateFieldId() {
14
+ return _nextFieldId++;
15
+ }
16
+ /** Current id count — the exclusive upper bound of allocated ids.
17
+ * Runtime typed arrays size to at least this. @internal */
18
+ export function fieldIdCount() {
19
+ return _nextFieldId;
20
+ }
21
+ /** Reset for tests. @internal
22
+ *
23
+ * WARNING: Only safe to call when no live `Field` objects exist
24
+ * anywhere — the `FIELD_REGISTRY` WeakMap in `grammar.ts` is NOT
25
+ * cleared, so any `Field` retained across this call still holds
26
+ * its old id. Newly-allocated fields will then collide with retained
27
+ * ids, aliasing entries in the runtime's typed-array storage. The
28
+ * standard test harness creates fresh `Node`s per test, so retained
29
+ * cross-test references are the only way to hit this; don't introduce
30
+ * them.
31
+ */
32
+ export function _resetFieldIdsForTesting() {
33
+ _nextFieldId = 0;
34
+ }
35
+ //# sourceMappingURL=field-id-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-id-pool.js","sourceRoot":"","sources":["../../../src/algorithm/spineless/field-id-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,IAAI,YAAY,GAAG,CAAC,CAAC;AAErB,sDAAsD;AACtD,MAAM,UAAU,eAAe;IAC7B,OAAO,YAAY,EAAE,CAAC;AACxB,CAAC;AAED;4DAC4D;AAC5D,MAAM,UAAU,YAAY;IAC1B,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB;IACtC,YAAY,GAAG,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Flexbox layout expressed as an attribute grammar.
3
+ *
4
+ * Current slice (v16b) covers:
5
+ *
6
+ * - flex-direction: `row`, `column`, `row-reverse`, `column-reverse`
7
+ * - flex-grow / flex-shrink / flex-basis (v3-v4)
8
+ * - padding / margin / gap (v5)
9
+ * - justify-content + align-items / align-self (v6)
10
+ * - flex-wrap (v7) — single-line wrap and multi-line packing,
11
+ * each line independently distributed / justified / aligned
12
+ * - positionType: `'absolute'` (v8) — out-of-flow children
13
+ * positioned against the parent's OUTER box via `style.position`
14
+ * and `style.margin`. Width / height resolve from explicit
15
+ * style, from opposing edges (`left`+`right` or `top`+`bottom`),
16
+ * or fall back to 0. Absolute children are filtered out of every
17
+ * in-flow computation (flex distribution, justify leftover,
18
+ * wrap line packing).
19
+ * - align-content (v9) — for multi-line wrap containers, the cross-
20
+ * axis leftover is distributed among / around the lines per
21
+ * `flex-start` / `flex-end` / `center` / `space-between` /
22
+ * `space-around` / `stretch`
23
+ * - flex-wrap: `wrap-reverse` (v10) — the line stack is mirrored
24
+ * on the cross axis
25
+ * - flex-direction: `row-reverse` / `column-reverse` (v11) — the
26
+ * main axis runs from the container's main END; each in-flow
27
+ * child's main position is reflected across the inner-main box,
28
+ * mirroring the imperative `flipMainAxis`
29
+ * - min / max size clamping (v12) — every node's main size, cross
30
+ * size, and an absolute child's width / height are clamped to
31
+ * the node's own `[minWidth/Height, maxWidth/Height]`. v12a
32
+ * covered the single-shot sites (non-distributed main size,
33
+ * cross size, absolute children); v12b folds min/max into the
34
+ * flex-distribution freeze loop and the wrap line packer — an
35
+ * item whose proportional grow / shrink target breaches a clamp
36
+ * is frozen at its bound and its share redistributed, iterating
37
+ * to a fixpoint, exactly as the imperative `distributeGrow` /
38
+ * `distributeShrink`.
39
+ * - `'auto'` main size (v13) — a non-measured `'auto'` main-axis
40
+ * size resolves to 0 (mirroring `resolveHypotheticalMainSize`);
41
+ * the root's `'auto'` axis resolves from the caller-supplied
42
+ * `available` size, modelled as a root input Field so a terminal
43
+ * resize is incremental.
44
+ * - `'auto'` cross size + `align-items: stretch` (v14) — an
45
+ * `'auto'` cross-axis size is 0 under a non-stretch align, but
46
+ * `stretch` (the default) resizes it to fill the line's inner
47
+ * cross, mirroring the imperative `crossAlignItemsInLine`
48
+ * stretch branch.
49
+ * - `aspectRatio` (v15) — an `'auto'` axis whose perpendicular
50
+ * axis is an explicit number derives `width = height × ratio` /
51
+ * `height = width ÷ ratio`, mirroring `effectivePreferredSize`.
52
+ * A derived axis is definite (not content-sized) — so it is not
53
+ * stretched.
54
+ * - measure-func leaves (v16) — a childless node with a measure
55
+ * function resolves its `'auto'` axes by calling the measurer.
56
+ * v16a covers the MAIN axis (main free, cross constrained,
57
+ * mirroring `resolveHypotheticalMainSize`); v16b the CROSS axis
58
+ * (cross constrained `AtMost` the parent inner cross, main free
59
+ * with a hint, mirroring `naturalCrossSize`). A measured cross
60
+ * feeds the wrap line cross-size aggregation and the non-stretch
61
+ * cross size; `align-items: stretch` still overrides it.
62
+ *
63
+ * With v16 the grammar covers the full imperative `'auto'` /
64
+ * measure / `aspectRatio` resolution: the Spineless engine is a
65
+ * drop-in for `calculateLayout` on real content-sized trees.
66
+ *
67
+ * Fields emitted per node:
68
+ *
69
+ * - `width` — main-axis size when parent is `row`, cross-axis size
70
+ * when parent is `column`. Cross axis reads
71
+ * `style.width` verbatim. Main axis is the result of
72
+ * flex distribution when the parent has any child with
73
+ * grow > 0, shrink > 0, or numeric `flexBasis`;
74
+ * otherwise it equals the basis.
75
+ * - `height` — symmetric to `width`.
76
+ * - `left` — position relative to parent. For row-parent children
77
+ * this is the main-axis cursor: `padLeft + myMarginLeft
78
+ * + sum_priors(marginLeft + width + marginRight) +
79
+ * i*gapColumn`. For column-parent children it's the
80
+ * cross-axis position: `padLeft + myMarginLeft`. Root
81
+ * is at 0.
82
+ * - `top` — symmetric to `left`.
83
+ *
84
+ * @internal
85
+ */
86
+ import type { Node } from '../../node.js';
87
+ import { type Field, type FieldRule, type Grammar } from './grammar.js';
88
+ /**
89
+ * Per-node input Fields for the style props the grammar reads. Each
90
+ * is present only if the grammar actually reads that prop for the
91
+ * node — every in-flow node has all three sizes; a container that
92
+ * lays children out along an axis has the matching `gap*`; an
93
+ * absolute child has `width` / `height` only when its size is
94
+ * explicit.
95
+ *
96
+ * @internal
97
+ */
98
+ export interface StyleInputs {
99
+ width?: Field<number>;
100
+ height?: Field<number>;
101
+ flexBasis?: Field<number>;
102
+ flexGrow?: Field<number>;
103
+ flexShrink?: Field<number>;
104
+ gapRow?: Field<number>;
105
+ gapColumn?: Field<number>;
106
+ /**
107
+ * Min / max size clamps. `min*` default to 0; `max*` carry
108
+ * `Infinity` when `style.max{Width,Height}` is `undefined` ("no
109
+ * upper bound"), so a single `clampMinMax` covers both.
110
+ */
111
+ minWidth?: Field<number>;
112
+ minHeight?: Field<number>;
113
+ maxWidth?: Field<number>;
114
+ maxHeight?: Field<number>;
115
+ /**
116
+ * Per-edge `padding` input Fields, indexed `[top, right, bottom,
117
+ * left]`. Entries are present only for edges the grammar reads
118
+ * (a container reads all four of its own padding edges).
119
+ */
120
+ padding?: Array<Field<number> | undefined>;
121
+ /**
122
+ * Per-edge `margin` input Fields, indexed `[top, right, bottom,
123
+ * left]`. Present for every non-root in-flow node and every
124
+ * absolute child (the grammar reads all four edges).
125
+ */
126
+ margin?: Array<Field<number> | undefined>;
127
+ }
128
+ /**
129
+ * Roots used by `buildFlexGrammar` to identify which (Node, name) pair
130
+ * is the canonical entry point. The Spineless runtime / interpreter
131
+ * starts evaluation from this set of fields and walks deps.
132
+ *
133
+ * @internal
134
+ */
135
+ export interface FlexGrammarOutput {
136
+ grammar: Grammar;
137
+ /** Fields the caller typically wants computed on the root. */
138
+ rootFields: {
139
+ width: Field<number>;
140
+ height: Field<number>;
141
+ left: Field<number>;
142
+ top: Field<number>;
143
+ };
144
+ /** All emitted fields, in pre-order. Useful for differential tests. */
145
+ allFields: Array<{
146
+ node: Node;
147
+ width: Field<number>;
148
+ height: Field<number>;
149
+ left: Field<number>;
150
+ top: Field<number>;
151
+ }>;
152
+ /**
153
+ * Per-node input Fields for the style props the grammar models as
154
+ * graph inputs — currently the SIZE props (`width` / `height` /
155
+ * `flexBasis`), `gap` (`gapRow` / `gapColumn`), `padding` and
156
+ * `margin` (per-edge). Each is a leaf field whose value is the live
157
+ * `node.style` value; every layout field that reads one declares
158
+ * the matching input as a dependency. To drive a precise
159
+ * incremental relayout after a `setWidth` / `setHeight` /
160
+ * `setFlexBasis` / `setFlexGrow` / `setFlexShrink` / `setGap` /
161
+ * `setPadding` / `setMargin`, `markDirty` the input Field for the
162
+ * mutated `(node, prop)` and call `recompute()` — propagation then
163
+ * reaches exactly the affected layout fields, with no
164
+ * `markAllDirty`.
165
+ *
166
+ * Every numeric style prop the grammar reads is now an input
167
+ * field. What still needs a fresh `buildFlexGrammar()` is
168
+ * STRUCTURAL mutation — flex-direction, flex-wrap on/off, the
169
+ * justify / align category, `positionType`, and toggling a flex
170
+ * weight or `flexBasis` across the zero / numeric boundary (which
171
+ * flips whether the parent flex-distributes).
172
+ */
173
+ styleInputs: Map<Node, StyleInputs>;
174
+ /**
175
+ * Input Fields for the root's caller-supplied `available` size,
176
+ * present only for an axis where the root's style is `'auto'`
177
+ * (v13). `markDirty` one and `recompute()` to re-lay the tree
178
+ * after a terminal resize.
179
+ */
180
+ availableInputs: {
181
+ width?: Field<number>;
182
+ height?: Field<number>;
183
+ };
184
+ /**
185
+ * Per-parent intermediate Fields for the phase-12 flex-distribution
186
+ * grammar. Keyed by each flex-distributing single-line parent; value
187
+ * is the `mainDistribution` Field emitted for that parent. Fragment
188
+ * builders (append / remove / reorder) consult this to perform
189
+ * precise rebinds without a full grammar rebuild.
190
+ */
191
+ mainDistributionByParent: Map<Node, Field<MainAxisDistribution>>;
192
+ }
193
+ /** Caller-supplied availability for an `'auto'`-sized root. */
194
+ export interface AvailableSize {
195
+ width?: number;
196
+ height?: number;
197
+ }
198
+ /**
199
+ * Walk the tree rooted at `root` and emit a `Grammar` that computes
200
+ * each node's `{width, height, left, top}`. See the module header
201
+ * for the field rules. A whole-tree build — `boundary` is `null`.
202
+ *
203
+ * `'auto'` width / height are supported (v13): a non-measured
204
+ * `'auto'` axis resolves to 0; the root's `'auto'` axis resolves
205
+ * from `available` (matching `calculateLayout`'s availability args).
206
+ *
207
+ * @internal
208
+ */
209
+ export declare function buildFlexGrammar(root: Node, available?: AvailableSize): FlexGrammarOutput;
210
+ /**
211
+ * The patch inputs for a fast-pathed child append — see
212
+ * `buildAppendFragment`.
213
+ *
214
+ * @internal
215
+ */
216
+ export interface AppendFragment {
217
+ /** Rules for the newly-added subtree's fields, for `graft`. */
218
+ additions: Grammar;
219
+ /** The new fields to start `SpinelessRuntime.graft`'s DFS from. */
220
+ newRoots: Array<Field<unknown>>;
221
+ /**
222
+ * Existing fields whose rule the append rewrote, paired with the
223
+ * new rule — for `SpinelessRuntime.rebindRule`. Empty for a
224
+ * simple-regime append (`graft` alone suffices); non-empty when
225
+ * the parent flex-distributes / justifies / wraps, where appending
226
+ * a child also grows every existing sibling's dependency set.
227
+ * Apply these AFTER `graft` (the new rules reference the grafted
228
+ * fields), then call `recompute()`.
229
+ */
230
+ rebinds: Array<[Field<unknown>, FieldRule<unknown>]>;
231
+ /**
232
+ * A fresh full `FlexGrammarOutput` for the post-append tree. The
233
+ * caller should adopt it for subsequent operations — its
234
+ * `allFields` / `styleInputs` cover the new subtree (the runtime's
235
+ * own grammar is patched in place by `graft` + `rebindRule`).
236
+ */
237
+ next: FlexGrammarOutput;
238
+ }
239
+ /**
240
+ * Fast-path a child INSERT for the Spineless runtime. If adding
241
+ * `child` under `parent` can be absorbed without a fresh runtime,
242
+ * return the patch inputs; return `null` when a full rebuild is
243
+ * required — `child` is not a child of `parent`, or `parent` uses a
244
+ * reverse `flex-direction` (supported by the grammar since v11, but
245
+ * not by this structural fast-path — reflecting every sibling's
246
+ * position is a whole-subtree rewrite).
247
+ *
248
+ * The new subtree's fields are always topological-tail additions
249
+ * handled by `graft` (`additions` / `newRoots`). When `parent` is in
250
+ * the "simple" regime (no flex distribution, default `flex-start`
251
+ * justify, no wrap) AND `child` is its LAST child — or `child` is
252
+ * absolute — that is the whole patch and `rebinds` is empty, and the
253
+ * fragment is built in **O(subtree)**: `makeEmitter` emits just the
254
+ * appended subtree against the runtime's grammar as a boundary, no
255
+ * whole-tree rebuild. Otherwise the insert also rewrites existing
256
+ * in-flow siblings' rules — a flex-distributing / justified /
257
+ * wrapping parent reads every sibling, and a MID-LIST insert (v32)
258
+ * shifts every later in-flow sibling's main position — so the
259
+ * grammar is rebuilt O(tree) and `rebinds` carries those siblings'
260
+ * rewritten rules.
261
+ *
262
+ * `next.grammar` is always `prev.grammar` — the runtime's own Map,
263
+ * which `graft` / `rebindRule` patch in place; `next.allFields` /
264
+ * `next.styleInputs` are refreshed lookup tables the caller adopts.
265
+ *
266
+ * @internal
267
+ */
268
+ export declare function buildAppendFragment(prev: FlexGrammarOutput, root: Node, parent: Node, child: Node, available?: AvailableSize): AppendFragment | null;
269
+ /**
270
+ * The patch inputs for a fast-pathed child removal — see
271
+ * `buildRemoveFragment`.
272
+ *
273
+ * @internal
274
+ */
275
+ export interface RemoveFragment {
276
+ /**
277
+ * Every field belonging to the removed subtree, for
278
+ * `SpinelessRuntime.detach`. Apply this AFTER the `rebinds` — a
279
+ * surviving sibling rebound off the removed child must drop its
280
+ * dependency on the child's fields before they can be detached.
281
+ */
282
+ removed: Array<Field<unknown>>;
283
+ /**
284
+ * Existing fields whose rule the removal rewrote, paired with the
285
+ * new rule — for `SpinelessRuntime.rebindRule`. Empty when removing
286
+ * a last child from a simple-regime parent (`detach` alone
287
+ * suffices); non-empty when the parent flex-distributes /
288
+ * justifies / wraps, or the child is interior — where removing it
289
+ * shrinks every surviving sibling's dependency set.
290
+ */
291
+ rebinds: Array<[Field<unknown>, FieldRule<unknown>]>;
292
+ /**
293
+ * A fresh full `FlexGrammarOutput` for the post-removal tree. The
294
+ * caller adopts it for subsequent operations.
295
+ */
296
+ next: FlexGrammarOutput;
297
+ }
298
+ /**
299
+ * Fast-path a child REMOVAL for the Spineless runtime — the mirror
300
+ * of `buildAppendFragment`. Call this **before** detaching `child`
301
+ * from `parent`: the simple-regime check needs `child` still in
302
+ * place. Returns the patch inputs, or `null` when a full rebuild is
303
+ * required (`child` is not `parent`'s child, or `parent` uses a
304
+ * reverse `flex-direction` — supported by the grammar since v11 but
305
+ * not by this fast-path).
306
+ *
307
+ * In the "simple" regime (no flex distribution, default `flex-start`
308
+ * justify, no wrap — or `child` is absolute) the patch is built in
309
+ * **O(subtree)**: `removed` is collected directly from `prev` by
310
+ * walking the removed subtree, with no whole-tree rebuild, and
311
+ * `rebinds` is empty. `SpinelessRuntime.detach` then drops those
312
+ * fields and auto-cleans any input field they orphaned (e.g. the new
313
+ * last child's now-unread main-end margin). Otherwise the removal
314
+ * shrinks every surviving in-flow sibling's dependency set, so the
315
+ * grammar is rebuilt O(tree) and `rebinds` carries those siblings'
316
+ * rewritten rules. The caller applies `rebindRule` for each rebind
317
+ * FIRST (so survivors stop depending on the removed fields), then
318
+ * `detach`, then `recompute()`.
319
+ *
320
+ * Does not mutate the tree. `next.grammar` is `prev.grammar` — the
321
+ * runtime's own Map, patched in place by `detach` / `rebindRule`.
322
+ *
323
+ * @internal
324
+ */
325
+ export declare function buildRemoveFragment(prev: FlexGrammarOutput, root: Node, parent: Node, child: Node, available?: AvailableSize): RemoveFragment | null;
326
+ /**
327
+ * The patch inputs for a fast-pathed child reorder — see
328
+ * `buildReorderFragment`.
329
+ *
330
+ * @internal
331
+ */
332
+ export interface ReorderFragment {
333
+ /**
334
+ * Input fields the reorder newly needs — for `SpinelessRuntime.graft`.
335
+ * A reorder adds no node, but it can give a node a follower (or
336
+ * take one away), and a node's main-END margin is read only when it
337
+ * has a follower. So a node that gained a follower contributes a
338
+ * newly-read margin input.
339
+ */
340
+ additions: Grammar;
341
+ /** The new fields to start `graft`'s DFS from (every addition). */
342
+ newRoots: Array<Field<unknown>>;
343
+ /**
344
+ * Input fields the reorder no longer needs — for
345
+ * `SpinelessRuntime.detach`. The mirror of `additions`: a node that
346
+ * lost its follower (became the last child) no longer has its
347
+ * main-end margin read.
348
+ */
349
+ removed: Array<Field<unknown>>;
350
+ /**
351
+ * Existing fields whose rule the reorder rewrote, paired with the
352
+ * new rule — for `SpinelessRuntime.rebindRule`.
353
+ */
354
+ rebinds: Array<[Field<unknown>, FieldRule<unknown>]>;
355
+ /** A fresh full `FlexGrammarOutput` for the reordered tree. */
356
+ next: FlexGrammarOutput;
357
+ }
358
+ /**
359
+ * Fast-path a child REORDER for the Spineless runtime — `parent`'s
360
+ * children are a permutation of their former order (no node added or
361
+ * removed). The grammar is rebuilt O(tree) and the patch applied to
362
+ * the existing runtime without a fresh `init`.
363
+ *
364
+ * Reordering `parent`'s children can only change the rules of
365
+ * `parent` itself (its `'auto'` / wrap content size now packs the
366
+ * children in a new order) and of its in-flow children (their main
367
+ * positions, and — under wrap — their line-dependent sizes), so the
368
+ * rebind set is `parent` + its in-flow children's
369
+ * `width / height / left / top`. Descendants and ancestors recompute
370
+ * from the changed VALUES; their rules are untouched.
371
+ *
372
+ * A reorder also shifts the "has a follower" boundary, so a node's
373
+ * main-end margin input can become newly read (`additions`) or
374
+ * newly unread (`removed`) — the same diff `buildAppendFragment`'s
375
+ * non-simple branch takes. The caller applies `graft` then
376
+ * `rebindRule` then `detach`.
377
+ *
378
+ * `next.grammar` is `prev.grammar` — the runtime's own Map, patched
379
+ * in place.
380
+ *
381
+ * @internal
382
+ */
383
+ export declare function buildReorderFragment(prev: FlexGrammarOutput, root: Node, parent: Node, available?: AvailableSize): ReorderFragment;
384
+ /**
385
+ * The materialised result of a flex-distributing parent's main-axis
386
+ * pass — sizes plus folded positions. One per qualifying parent.
387
+ * Cells index into this instead of redoing the distribution each.
388
+ * @internal
389
+ */
390
+ export interface MainAxisDistribution {
391
+ readonly sizes: readonly number[];
392
+ readonly positions: readonly number[];
393
+ }
394
+ //# sourceMappingURL=flex-grammar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flex-grammar.d.ts","sourceRoot":"","sources":["../../../src/algorithm/spineless/flex-grammar.ts"],"names":[],"mappings":"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"}