@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,65 @@
1
+ /**
2
+ * `markStyleDirty` — convenience for driving a precise incremental
3
+ * relayout after a style mutation.
4
+ *
5
+ * Every numeric style prop the flex grammar reads is modelled as a
6
+ * leaf input `Field` (see `buildFlexGrammar` / `StyleInputs`). After
7
+ * a `Node` setter call, the runtime needs the matching input Field
8
+ * marked dirty before `recompute()`. Looking that Field up through
9
+ * the `styleInputs` map by hand is repetitive and easy to get wrong;
10
+ * `createStyleDirtier` binds a runtime + its `styleInputs` into a
11
+ * single `(node, prop[, edge])` call that mirrors the `Node`
12
+ * setters:
13
+ *
14
+ * ```ts
15
+ * const { grammar, rootFields, styleInputs } = buildFlexGrammar(root);
16
+ * const rt = new SpinelessRuntime(grammar, [...rootFields...]);
17
+ * rt.init();
18
+ * const markStyleDirty = createStyleDirtier(rt, styleInputs);
19
+ *
20
+ * node.setWidth(50);
21
+ * markStyleDirty(node, 'width');
22
+ * rt.recompute();
23
+ * ```
24
+ *
25
+ * Value mutations only — a structural mutation (flex-direction,
26
+ * flex-wrap on/off, the justify / align category, `positionType`, a
27
+ * flex weight / `flexBasis` crossing the zero / numeric boundary)
28
+ * reshapes the dependency graph and still needs a fresh
29
+ * `buildFlexGrammar()`.
30
+ *
31
+ * @internal
32
+ */
33
+ import type { Node } from '../../node.js';
34
+ import type { StyleInputs } from './flex-grammar.js';
35
+ import type { SpinelessRuntime } from './runtime.js';
36
+ /** Style props addressed by a single input Field. */
37
+ export type ScalarStyleProp = 'width' | 'height' | 'flexBasis' | 'flexGrow' | 'flexShrink' | 'gapRow' | 'gapColumn' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight';
38
+ /** Style props addressed per `[top, right, bottom, left]` edge. */
39
+ export type EdgeStyleProp = 'padding' | 'margin';
40
+ /**
41
+ * A bound `(node, prop[, edge])` callback that marks the input
42
+ * Field(s) for a mutated style prop dirty on its runtime.
43
+ *
44
+ * @internal
45
+ */
46
+ export interface StyleDirtier {
47
+ (node: Node, prop: ScalarStyleProp): void;
48
+ (node: Node, prop: EdgeStyleProp, edge: number): void;
49
+ }
50
+ /**
51
+ * Bind a `SpinelessRuntime` and the `styleInputs` map from the
52
+ * `buildFlexGrammar` output that produced its grammar into a
53
+ * `StyleDirtier`.
54
+ *
55
+ * The returned callback throws if `node` is not part of the
56
+ * grammar's `styleInputs` (a node from a different / stale build),
57
+ * or if an edge prop is called without an edge index. It is a no-op
58
+ * when the grammar emits no input Field for the `(node, prop)` —
59
+ * which happens precisely when that prop can't affect layout (e.g.
60
+ * `padding` on a childless leaf), so marking nothing is correct.
61
+ *
62
+ * @internal
63
+ */
64
+ export declare function createStyleDirtier(runtime: SpinelessRuntime, styleInputs: ReadonlyMap<Node, StyleInputs>): StyleDirtier;
65
+ //# sourceMappingURL=style-dirty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-dirty.d.ts","sourceRoot":"","sources":["../../../src/algorithm/spineless/style-dirty.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,qDAAqD;AACrD,MAAM,MAAM,eAAe,GACvB,OAAO,GACP,QAAQ,GACR,WAAW,GACX,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,CAAC;AAEhB,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,EACzB,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,GAC1C,YAAY,CA8Bd"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `markStyleDirty` — convenience for driving a precise incremental
3
+ * relayout after a style mutation.
4
+ *
5
+ * Every numeric style prop the flex grammar reads is modelled as a
6
+ * leaf input `Field` (see `buildFlexGrammar` / `StyleInputs`). After
7
+ * a `Node` setter call, the runtime needs the matching input Field
8
+ * marked dirty before `recompute()`. Looking that Field up through
9
+ * the `styleInputs` map by hand is repetitive and easy to get wrong;
10
+ * `createStyleDirtier` binds a runtime + its `styleInputs` into a
11
+ * single `(node, prop[, edge])` call that mirrors the `Node`
12
+ * setters:
13
+ *
14
+ * ```ts
15
+ * const { grammar, rootFields, styleInputs } = buildFlexGrammar(root);
16
+ * const rt = new SpinelessRuntime(grammar, [...rootFields...]);
17
+ * rt.init();
18
+ * const markStyleDirty = createStyleDirtier(rt, styleInputs);
19
+ *
20
+ * node.setWidth(50);
21
+ * markStyleDirty(node, 'width');
22
+ * rt.recompute();
23
+ * ```
24
+ *
25
+ * Value mutations only — a structural mutation (flex-direction,
26
+ * flex-wrap on/off, the justify / align category, `positionType`, a
27
+ * flex weight / `flexBasis` crossing the zero / numeric boundary)
28
+ * reshapes the dependency graph and still needs a fresh
29
+ * `buildFlexGrammar()`.
30
+ *
31
+ * @internal
32
+ */
33
+ /**
34
+ * Bind a `SpinelessRuntime` and the `styleInputs` map from the
35
+ * `buildFlexGrammar` output that produced its grammar into a
36
+ * `StyleDirtier`.
37
+ *
38
+ * The returned callback throws if `node` is not part of the
39
+ * grammar's `styleInputs` (a node from a different / stale build),
40
+ * or if an edge prop is called without an edge index. It is a no-op
41
+ * when the grammar emits no input Field for the `(node, prop)` —
42
+ * which happens precisely when that prop can't affect layout (e.g.
43
+ * `padding` on a childless leaf), so marking nothing is correct.
44
+ *
45
+ * @internal
46
+ */
47
+ export function createStyleDirtier(runtime, styleInputs) {
48
+ return (node, prop, edge) => {
49
+ const entry = styleInputs.get(node);
50
+ if (entry === undefined) {
51
+ throw new Error('[spineless] markStyleDirty: node has no style inputs in this grammar — pass a node from the same buildFlexGrammar() tree');
52
+ }
53
+ let f;
54
+ if (prop === 'padding' || prop === 'margin') {
55
+ if (edge === undefined) {
56
+ throw new Error(`[spineless] markStyleDirty: '${prop}' requires an edge index`);
57
+ }
58
+ f = entry[prop]?.[edge];
59
+ }
60
+ else {
61
+ f = entry[prop];
62
+ }
63
+ // Marking nothing is the correct, precise behaviour when the
64
+ // mutation cannot move any layout field. That is the case both
65
+ // when no input Field exists for the prop, and when one exists
66
+ // but has been orphaned by a `detach` — e.g. the previous last
67
+ // child's main-end margin after its follower was removed. An
68
+ // orphaned input is no longer tracked by the runtime; a stale
69
+ // reference to it may linger in a `styleInputs` map.
70
+ if (f !== undefined && runtime.isTracked(f)) {
71
+ runtime.markDirty(f);
72
+ }
73
+ };
74
+ }
75
+ //# sourceMappingURL=style-dirty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-dirty.js","sourceRoot":"","sources":["../../../src/algorithm/spineless/style-dirty.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAmCH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAyB,EACzB,WAA2C;IAE3C,OAAO,CAAC,IAAU,EAAE,IAAqC,EAAE,IAAa,EAAQ,EAAE;QAChF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,0HAA0H,CAC3H,CAAC;QACJ,CAAC;QAED,IAAI,CAA4B,CAAC;QACjC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,0BAA0B,CAAC,CAAC;YAClF,CAAC;YACD,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,6DAA6D;QAC7D,+DAA+D;QAC/D,+DAA+D;QAC/D,+DAA+D;QAC/D,6DAA6D;QAC7D,8DAA8D;QAC9D,qDAAqD;QACrD,IAAI,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,CAAmB,CAAC,EAAE,CAAC;YAC9D,OAAO,CAAC,SAAS,CAAC,CAAmB,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Per-property dirty bits. Each mutation on a `Node` marks specific
3
+ * flags rather than a generic boolean. Cache layers and incremental
4
+ * engines consume these to skip invalidation when their inputs
5
+ * didn't actually change.
6
+ *
7
+ * The flag set is intentionally small (one word fits in V8's SMI
8
+ * representation); broad enough to cover every public Node setter
9
+ * but no broader.
10
+ *
11
+ * Used by `Node._dirtyFlags`, `Node.markDirtyFlag()`, and the cache
12
+ * + incremental layers consuming these flags in subsequent phases.
13
+ *
14
+ * @internal
15
+ */
16
+ /** Layout-shape mutations (flexDirection, wrap, justify, align, display, ...). */
17
+ export declare const DIRTY_STYLE_SIG: number;
18
+ /** Explicit-dimension values (width, height, margin, padding, border, position). */
19
+ export declare const DIRTY_STYLE_VALUE: number;
20
+ /** Flex-distribution parameters (flexGrow, flexShrink, flexBasis). */
21
+ export declare const DIRTY_FLEX_DISTRIBUTION: number;
22
+ /** Measure function attached or detached. */
23
+ export declare const DIRTY_MEASURE: number;
24
+ /** Manual measure-cache invalidation (consumer-driven). */
25
+ export declare const DIRTY_MEASURE_CONTENT: number;
26
+ /** Children list mutation (insert / remove / reorder). */
27
+ export declare const DIRTY_CHILDREN: number;
28
+ /** All flags ORed together. Used by back-compat `markDirty()`. */
29
+ export declare const DIRTY_ANY: number;
30
+ //# sourceMappingURL=dirty-flags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dirty-flags.d.ts","sourceRoot":"","sources":["../src/dirty-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,kFAAkF;AAClF,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,6CAA6C;AAC7C,eAAO,MAAM,aAAa,QAAS,CAAC;AAEpC,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,0DAA0D;AAC1D,eAAO,MAAM,cAAc,QAAS,CAAC;AAErC,kEAAkE;AAClE,eAAO,MAAM,SAAS,QAMN,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Per-property dirty bits. Each mutation on a `Node` marks specific
3
+ * flags rather than a generic boolean. Cache layers and incremental
4
+ * engines consume these to skip invalidation when their inputs
5
+ * didn't actually change.
6
+ *
7
+ * The flag set is intentionally small (one word fits in V8's SMI
8
+ * representation); broad enough to cover every public Node setter
9
+ * but no broader.
10
+ *
11
+ * Used by `Node._dirtyFlags`, `Node.markDirtyFlag()`, and the cache
12
+ * + incremental layers consuming these flags in subsequent phases.
13
+ *
14
+ * @internal
15
+ */
16
+ /** Layout-shape mutations (flexDirection, wrap, justify, align, display, ...). */
17
+ export const DIRTY_STYLE_SIG = 1 << 0;
18
+ /** Explicit-dimension values (width, height, margin, padding, border, position). */
19
+ export const DIRTY_STYLE_VALUE = 1 << 1;
20
+ /** Flex-distribution parameters (flexGrow, flexShrink, flexBasis). */
21
+ export const DIRTY_FLEX_DISTRIBUTION = 1 << 2;
22
+ /** Measure function attached or detached. */
23
+ export const DIRTY_MEASURE = 1 << 3;
24
+ /** Manual measure-cache invalidation (consumer-driven). */
25
+ export const DIRTY_MEASURE_CONTENT = 1 << 4;
26
+ /** Children list mutation (insert / remove / reorder). */
27
+ export const DIRTY_CHILDREN = 1 << 5;
28
+ /** All flags ORed together. Used by back-compat `markDirty()`. */
29
+ export const DIRTY_ANY = DIRTY_STYLE_SIG |
30
+ DIRTY_STYLE_VALUE |
31
+ DIRTY_FLEX_DISTRIBUTION |
32
+ DIRTY_MEASURE |
33
+ DIRTY_MEASURE_CONTENT |
34
+ DIRTY_CHILDREN;
35
+ //# sourceMappingURL=dirty-flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dirty-flags.js","sourceRoot":"","sources":["../src/dirty-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,kFAAkF;AAClF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAI,CAAC,CAAC;AAEtC,oFAAoF;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAI,CAAC,CAAC;AAExC,sEAAsE;AACtE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAI,CAAC,CAAC;AAE9C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,CAAC;AAEpC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAI,CAAC,CAAC;AAE5C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAI,CAAC,CAAC;AAErC,kEAAkE;AAClE,MAAM,CAAC,MAAM,SAAS,GACpB,eAAe;IACf,iBAAiB;IACjB,uBAAuB;IACvB,aAAa;IACb,qBAAqB;IACrB,cAAc,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,12 @@
1
- export declare const VERSION = "1.0.1";
1
+ export declare const VERSION = "2.0.0";
2
2
  export { Node } from './node.js';
3
3
  export { Edge } from './edge.js';
4
4
  export type { Align, Display, FlexDirection, FlexWrap, Justify, Length, Overflow, PositionType, Style, } from './style.js';
5
5
  export { MeasureMode } from './measure-func.js';
6
6
  export type { MeasureFunc, MeasureSize } from './measure-func.js';
7
7
  export type { ComputedLayout } from './layout.js';
8
+ export { setLayoutProfiler, type LayoutProfiler, type LayoutTrace } from './algorithm/index.js';
9
+ export { DIRTY_ANY, DIRTY_CHILDREN, DIRTY_FLEX_DISTRIBUTION, DIRTY_MEASURE, DIRTY_MEASURE_CONTENT, DIRTY_STYLE_SIG, DIRTY_STYLE_VALUE, } from './dirty-flags.js';
10
+ export { inspectLayout } from './inspect.js';
8
11
  export { cellWidth, graphemes, stringWidth, stripAnsi, type Grapheme } from './measure/index.js';
9
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EACV,KAAK,EACL,OAAO,EACP,aAAa,EACb,QAAQ,EACR,OAAO,EACP,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,KAAK,GACN,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EACV,KAAK,EACL,OAAO,EACP,aAAa,EACb,QAAQ,EACR,OAAO,EACP,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,KAAK,GACN,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIhG,OAAO,EACL,SAAS,EACT,cAAc,EACd,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,10 +1,18 @@
1
- export const VERSION = '1.0.1';
1
+ export const VERSION = '2.0.0';
2
2
  // Tree
3
3
  export { Node } from './node.js';
4
4
  // Style values
5
5
  export { Edge } from './edge.js';
6
6
  // Measure callback
7
7
  export { MeasureMode } from './measure-func.js';
8
+ // Layout profiling — observe what the incremental engine did per
9
+ // `calculateLayout` call (phase 9).
10
+ export { setLayoutProfiler } from './algorithm/index.js';
11
+ // Per-property dirty flags (phase 15B). @internal — consumed by the
12
+ // algorithm + spineless layers; not part of the public API surface.
13
+ export { DIRTY_ANY, DIRTY_CHILDREN, DIRTY_FLEX_DISTRIBUTION, DIRTY_MEASURE, DIRTY_MEASURE_CONTENT, DIRTY_STYLE_SIG, DIRTY_STYLE_VALUE, } from './dirty-flags.js';
14
+ // Layout inspection — a console dump of a computed-layout subtree.
15
+ export { inspectLayout } from './inspect.js';
8
16
  // Text measurement (re-exported from the measure module so consumers can
9
17
  // build measure functions on top of our width tables).
10
18
  export { cellWidth, graphemes, stringWidth, stripAnsi } from './measure/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO;AACP,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,eAAe;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAajC,mBAAmB;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD,yEAAyE;AACzE,uDAAuD;AACvD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO;AACP,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,eAAe;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAajC,mBAAmB;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMhD,iEAAiE;AACjE,oCAAoC;AACpC,OAAO,EAAE,iBAAiB,EAAyC,MAAM,sBAAsB,CAAC;AAEhG,oEAAoE;AACpE,oEAAoE;AACpE,OAAO,EACL,SAAS,EACT,cAAc,EACd,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,mEAAmE;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,yEAAyE;AACzE,uDAAuD;AACvD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `inspectLayout` — a devtools / console dump of a computed-layout
3
+ * subtree (phase 9). Pairs with `setLayoutProfiler`: the profiler
4
+ * tells you *what the engine did*, this tells you *what it produced*.
5
+ */
6
+ import type { Node } from './node.js';
7
+ /**
8
+ * A human-readable, indented dump of `node`'s computed-layout
9
+ * subtree — one line per node, two spaces of indent per depth:
10
+ *
11
+ * ```
12
+ * incremental 0,0 100x40
13
+ * 0,0 30x40
14
+ * 30,0 30x40 dirty
15
+ * ```
16
+ *
17
+ * Each line is `left,top WxH` followed by any flags (`scroll=WxH`
18
+ * when the content extent overflows the box; `dirty` / `dirty-desc`
19
+ * for pending-relayout state). The root line is prefixed with the
20
+ * engine path its most recent `calculateLayout` took (`imperative` /
21
+ * `build` / `graft` / `incremental`), when known.
22
+ *
23
+ * Pure — allocates only the returned string; for devtools and
24
+ * console debugging, not a hot path.
25
+ */
26
+ export declare function inspectLayout(node: Node): string;
27
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAuBtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAYhD"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * `inspectLayout` — a devtools / console dump of a computed-layout
3
+ * subtree (phase 9). Pairs with `setLayoutProfiler`: the profiler
4
+ * tells you *what the engine did*, this tells you *what it produced*.
5
+ */
6
+ import { lastLayoutPath } from './algorithm/index.js';
7
+ /** `left,top widthxheight` from a node's computed (rounded) layout. */
8
+ function boxOf(node) {
9
+ const l = node.layout;
10
+ return `${l.left},${l.top} ${l.width}x${l.height}`;
11
+ }
12
+ /**
13
+ * Space-joined flags for one node: `scroll=WxH` when the content
14
+ * extent overflows the box, and the node's dirty state.
15
+ */
16
+ function flagsOf(node) {
17
+ const l = node.layout;
18
+ const flags = [];
19
+ if (l.scrollWidth > l.width || l.scrollHeight > l.height) {
20
+ flags.push(`scroll=${l.scrollWidth}x${l.scrollHeight}`);
21
+ }
22
+ if (node.isDirty())
23
+ flags.push('dirty');
24
+ else if (node._hasDirtyDescendant)
25
+ flags.push('dirty-desc');
26
+ return flags.join(' ');
27
+ }
28
+ /**
29
+ * A human-readable, indented dump of `node`'s computed-layout
30
+ * subtree — one line per node, two spaces of indent per depth:
31
+ *
32
+ * ```
33
+ * incremental 0,0 100x40
34
+ * 0,0 30x40
35
+ * 30,0 30x40 dirty
36
+ * ```
37
+ *
38
+ * Each line is `left,top WxH` followed by any flags (`scroll=WxH`
39
+ * when the content extent overflows the box; `dirty` / `dirty-desc`
40
+ * for pending-relayout state). The root line is prefixed with the
41
+ * engine path its most recent `calculateLayout` took (`imperative` /
42
+ * `build` / `graft` / `incremental`), when known.
43
+ *
44
+ * Pure — allocates only the returned string; for devtools and
45
+ * console debugging, not a hot path.
46
+ */
47
+ export function inspectLayout(node) {
48
+ const lines = [];
49
+ const visit = (n, depth) => {
50
+ const flags = flagsOf(n);
51
+ lines.push(`${' '.repeat(depth)}${boxOf(n)}${flags === '' ? '' : ` ${flags}`}`);
52
+ for (let i = 0; i < n.getChildCount(); i++)
53
+ visit(n.getChild(i), depth + 1);
54
+ };
55
+ visit(node, 0);
56
+ const path = lastLayoutPath(node);
57
+ if (path !== undefined)
58
+ lines[0] = `${path} ${lines[0]}`;
59
+ return lines.join('\n');
60
+ }
61
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,uEAAuE;AACvE,SAAS,KAAK,CAAC,IAAU;IACvB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,IAAU;IACzB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACnC,IAAI,IAAI,CAAC,mBAAmB;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,CAAC,CAAO,EAAE,KAAa,EAAQ,EAAE;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC,CAAC;QAClF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE;YAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC/E,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEf,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * LayoutPool — typed-array storage indexed by Node._id.
3
+ *
4
+ * Manages Float64Arrays for absolute corner coordinates used by
5
+ * roundLayout. IDs are allocated at Node construction and recycled
6
+ * via FinalizationRegistry when the Node is garbage-collected.
7
+ *
8
+ * @internal
9
+ */
10
+ /**
11
+ * Mutable pool object. Properties are reassigned during growth so that
12
+ * consumers reading `Pool.absCornersX[id]` always see the latest array.
13
+ */
14
+ export declare const Pool: {
15
+ absCornersX: Float64Array;
16
+ absCornersY: Float64Array;
17
+ };
18
+ /**
19
+ * Allocate a unique integer ID for `node`. Phase 15C defers
20
+ * recycling: the FinalizationRegistry pattern showed ~2× regression
21
+ * on cold-build scenarios (huge/big) because per-Node registration
22
+ * cost dominated. Without recycling, the pool grows to peak-live-
23
+ * node count; for long-running TUIs this is bounded by the app's
24
+ * actual node footprint. A future sub-phase can add manual
25
+ * compactPool() if a real consumer reports memory pressure.
26
+ *
27
+ * The `node` parameter is unused for now; preserving the signature
28
+ * for API compatibility when recycling returns.
29
+ *
30
+ * @internal
31
+ */
32
+ export declare function allocateNodeId(_node: object): number;
33
+ /**
34
+ * Returns diagnostic stats about the pool. Intended for tests only.
35
+ *
36
+ * @internal
37
+ */
38
+ export declare function _poolStats(): {
39
+ capacity: number;
40
+ nextId: number;
41
+ freeCount: number;
42
+ };
43
+ /**
44
+ * Reset pool to initial state. Call in `beforeEach` in tests only.
45
+ *
46
+ * @internal
47
+ */
48
+ export declare function _resetPoolForTesting(): void;
49
+ //# sourceMappingURL=layout-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-pool.d.ts","sourceRoot":"","sources":["../src/layout-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE;IACjB,WAAW,EAAE,YAAY,CAAC;IAC1B,WAAW,EAAE,YAAY,CAAC;CAI3B,CAAC;AAiBF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAEpF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAM3C"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * LayoutPool — typed-array storage indexed by Node._id.
3
+ *
4
+ * Manages Float64Arrays for absolute corner coordinates used by
5
+ * roundLayout. IDs are allocated at Node construction and recycled
6
+ * via FinalizationRegistry when the Node is garbage-collected.
7
+ *
8
+ * @internal
9
+ */
10
+ const INITIAL_CAPACITY = 1024;
11
+ /**
12
+ * Mutable pool object. Properties are reassigned during growth so that
13
+ * consumers reading `Pool.absCornersX[id]` always see the latest array.
14
+ */
15
+ export const Pool = {
16
+ absCornersX: new Float64Array(INITIAL_CAPACITY),
17
+ absCornersY: new Float64Array(INITIAL_CAPACITY),
18
+ };
19
+ let _nextId = 0;
20
+ let _capacity = INITIAL_CAPACITY;
21
+ const _freeIds = [];
22
+ function growPool() {
23
+ const newCapacity = _capacity * 2;
24
+ const newX = new Float64Array(newCapacity);
25
+ const newY = new Float64Array(newCapacity);
26
+ newX.set(Pool.absCornersX);
27
+ newY.set(Pool.absCornersY);
28
+ Pool.absCornersX = newX;
29
+ Pool.absCornersY = newY;
30
+ _capacity = newCapacity;
31
+ }
32
+ /**
33
+ * Allocate a unique integer ID for `node`. Phase 15C defers
34
+ * recycling: the FinalizationRegistry pattern showed ~2× regression
35
+ * on cold-build scenarios (huge/big) because per-Node registration
36
+ * cost dominated. Without recycling, the pool grows to peak-live-
37
+ * node count; for long-running TUIs this is bounded by the app's
38
+ * actual node footprint. A future sub-phase can add manual
39
+ * compactPool() if a real consumer reports memory pressure.
40
+ *
41
+ * The `node` parameter is unused for now; preserving the signature
42
+ * for API compatibility when recycling returns.
43
+ *
44
+ * @internal
45
+ */
46
+ export function allocateNodeId(_node) {
47
+ if (_freeIds.length > 0) {
48
+ return _freeIds.pop();
49
+ }
50
+ if (_nextId >= _capacity) {
51
+ growPool();
52
+ }
53
+ return _nextId++;
54
+ }
55
+ /**
56
+ * Returns diagnostic stats about the pool. Intended for tests only.
57
+ *
58
+ * @internal
59
+ */
60
+ export function _poolStats() {
61
+ return { capacity: _capacity, nextId: _nextId, freeCount: _freeIds.length };
62
+ }
63
+ /**
64
+ * Reset pool to initial state. Call in `beforeEach` in tests only.
65
+ *
66
+ * @internal
67
+ */
68
+ export function _resetPoolForTesting() {
69
+ Pool.absCornersX = new Float64Array(INITIAL_CAPACITY);
70
+ Pool.absCornersY = new Float64Array(INITIAL_CAPACITY);
71
+ _nextId = 0;
72
+ _capacity = INITIAL_CAPACITY;
73
+ _freeIds.length = 0;
74
+ }
75
+ //# sourceMappingURL=layout-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-pool.js","sourceRoot":"","sources":["../src/layout-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAGb;IACF,WAAW,EAAE,IAAI,YAAY,CAAC,gBAAgB,CAAC;IAC/C,WAAW,EAAE,IAAI,YAAY,CAAC,gBAAgB,CAAC;CAChD,CAAC;AAEF,IAAI,OAAO,GAAG,CAAC,CAAC;AAChB,IAAI,SAAS,GAAG,gBAAgB,CAAC;AACjC,MAAM,QAAQ,GAAa,EAAE,CAAC;AAE9B,SAAS,QAAQ;IACf,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACxB,SAAS,GAAG,WAAW,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAC,GAAG,EAAG,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,QAAQ,EAAE,CAAC;IACb,CAAC;IACD,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC;IACtD,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,CAAC;IACZ,SAAS,GAAG,gBAAgB,CAAC;IAC7B,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;AACtB,CAAC"}
package/dist/node.d.ts CHANGED
@@ -29,6 +29,14 @@ export declare class Node {
29
29
  *
30
30
  * @internal
31
31
  */
32
+ /**
33
+ * Unique integer ID for typed-array indexing in the LayoutPool.
34
+ * Assigned at construction; recycled via FinalizationRegistry when
35
+ * this Node is garbage-collected.
36
+ *
37
+ * @internal
38
+ */
39
+ readonly _id: number;
32
40
  readonly _style: Style;
33
41
  /**
34
42
  * Backing storage for `layout`. Written by the algorithm in this package
@@ -68,15 +76,15 @@ export declare class Node {
68
76
  private readonly _children;
69
77
  private _parent;
70
78
  private _measure;
71
- /** True if style or tree has changed since the last `calculateLayout()`. */
72
- private _dirty;
79
+ /** Bitmask of `DIRTY_*` flags. Non-zero means this node is dirty. */
80
+ private _dirtyFlags;
73
81
  /**
74
82
  * True if any descendant has been marked dirty (even if dirty propagation
75
83
  * was stopped by a relayout boundary before reaching this node). Used by
76
84
  * the root cache-hit path to skip `layoutChildren` for subtrees that have
77
85
  * no mutations at all — not just subtrees where this node itself is clean.
78
86
  *
79
- * Invariant: `_dirty` implies `_hasDirtyDescendant` on the parent (if any).
87
+ * Invariant: `_dirtyFlags !== 0` implies `_hasDirtyDescendant` on the parent (if any).
80
88
  * Cleared by `clearDirty()` after each `calculateLayout()`.
81
89
  */
82
90
  _hasDirtyDescendant: boolean;
@@ -226,6 +234,15 @@ export declare class Node {
226
234
  * Walk up the tree marking every ancestor dirty too. The algorithm uses
227
235
  * this hint to short-circuit work in subtrees that did not change.
228
236
  */
237
+ /**
238
+ * Set specific dirty flag(s) on this node. Propagates upward
239
+ * through ancestors. Used by individual setters to indicate the
240
+ * granular nature of the change; cache layers consume the flag
241
+ * to decide whether to invalidate.
242
+ *
243
+ * @internal
244
+ */
245
+ markDirtyFlag(flag: number): void;
229
246
  markDirty(): void;
230
247
  /**
231
248
  * Called when a child (or descendant via recursion) is mutated. Marks
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAUtE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,KAAK,cAAc,EAAiB,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,KAAK,EAEX,MAAM,YAAY,CAAC;AAkBpB,qBAAa,IAAI;IACf;;;;;;;OAOG;IACH;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAwB;IAE5C,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAkB;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAmB;IAEnD;;;;;;;OAOG;IACH,UAAU,SAAK;IAEf,8BAA8B;IAC9B,SAAS,SAAK;IAEd,uEAAuE;IACvE,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,gDAAgD;IAChD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAE3B;IAED;;;;OAIG;IACH,IAAI,MAAM,IAAI,QAAQ,CAAC,cAAc,CAAC,CAErC;IAED,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAA4B;IAC5C,qEAAqE;IACrE,OAAO,CAAC,WAAW,CAAqB;IACxC;;;;;;;;OAQG;IACH,mBAAmB,UAAS;IAE5B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAE3B;;;;;;;;;;;;;;;OAeG;IACH,UAAU,SAAK;IACf,wCAAwC;IACxC,SAAS,SAAK;IAEd,oEAAoE;IACpE,MAAM,CAAC,MAAM,IAAI,IAAI;IAMrB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAc7C,WAAW,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAQ9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIzC,aAAa,IAAI,MAAM;IAIvB,mFAAmF;IACnF,WAAW,IAAI,IAAI,EAAE;IAIrB,SAAS,IAAI,IAAI,GAAG,IAAI;IAIxB,MAAM,IAAI,OAAO;IAMjB,cAAc,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI;IAiB5C,cAAc,IAAI,WAAW,GAAG,IAAI;IAMpC,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAK5C,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAKlC;;;;;;;;;OASG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB5B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM7B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKjC,iDAAiD;IACjD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAM5C,iDAAiD;IACjD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAM7C;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAY/C,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM3C,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM1C,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IASnD,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKvC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKjC,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKnC,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAOhC,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAK1C,yDAAyD;IACzD,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAUxD,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAOhC,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAOrC,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAKtC,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAOtC;;;;;;;;;OASG;IACH,eAAe,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI;IAIxE;;;;;OAKG;IACH,iBAAiB,IAAI,cAAc;IAMnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;OAGG;IACH;;;;;;;OAOG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAYjC,SAAS,IAAI,IAAI;IAIjB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;;;;;;;OAQG;IACH,WAAW,IAAI,IAAI;IAOnB,OAAO,IAAI,OAAO;IAIlB;;;;;;OAMG;IACH,UAAU,IAAI,IAAI;CAInB"}