flexily 0.5.1 → 0.6.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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-CBBoxR_p.mjs +26 -0
  3. package/dist/constants-BNURa6H7.mjs +65 -0
  4. package/dist/constants-BNURa6H7.mjs.map +1 -0
  5. package/dist/constants-D7ythAJC.d.mts +64 -0
  6. package/dist/constants-D7ythAJC.d.mts.map +1 -0
  7. package/{src/classic/node.ts → dist/index-classic.d.mts} +118 -619
  8. package/dist/index-classic.d.mts.map +1 -0
  9. package/dist/index-classic.mjs +1909 -0
  10. package/dist/index-classic.mjs.map +1 -0
  11. package/dist/index.d.mts +195 -0
  12. package/dist/index.d.mts.map +1 -0
  13. package/dist/index.mjs +3279 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/dist/node-zero-75maLs2s.d.mts +762 -0
  16. package/dist/node-zero-75maLs2s.d.mts.map +1 -0
  17. package/dist/src-BWyhokNZ.mjs +692 -0
  18. package/dist/src-BWyhokNZ.mjs.map +1 -0
  19. package/dist/src-DdSLylRA.mjs +816 -0
  20. package/dist/src-DdSLylRA.mjs.map +1 -0
  21. package/dist/testing.d.mts +55 -0
  22. package/dist/testing.d.mts.map +1 -0
  23. package/dist/testing.mjs +154 -0
  24. package/dist/testing.mjs.map +1 -0
  25. package/dist/types--IozHd4V.mjs +283 -0
  26. package/dist/types--IozHd4V.mjs.map +1 -0
  27. package/dist/types-DG1H4DVR.d.mts +157 -0
  28. package/dist/types-DG1H4DVR.d.mts.map +1 -0
  29. package/package.json +34 -24
  30. package/src/CLAUDE.md +0 -527
  31. package/src/classic/layout.ts +0 -1843
  32. package/src/constants.ts +0 -82
  33. package/src/create-flexily.ts +0 -153
  34. package/src/index-classic.ts +0 -110
  35. package/src/index.ts +0 -133
  36. package/src/layout-flex-lines.ts +0 -413
  37. package/src/layout-helpers.ts +0 -160
  38. package/src/layout-measure.ts +0 -259
  39. package/src/layout-stats.ts +0 -41
  40. package/src/layout-traversal.ts +0 -70
  41. package/src/layout-zero.ts +0 -2219
  42. package/src/logger.ts +0 -67
  43. package/src/monospace-measurer.ts +0 -68
  44. package/src/node-zero.ts +0 -1508
  45. package/src/pretext-measurer.ts +0 -86
  46. package/src/test-measurer.ts +0 -219
  47. package/src/testing.ts +0 -215
  48. package/src/text-layout.ts +0 -75
  49. package/src/trace.ts +0 -252
  50. package/src/types.ts +0 -236
  51. package/src/utils.ts +0 -243
package/src/constants.ts DELETED
@@ -1,82 +0,0 @@
1
- /**
2
- * Flexily Constants
3
- *
4
- * Yoga-compatible constants for flexbox layout.
5
- * These match Yoga's enum values exactly for drop-in compatibility.
6
- */
7
-
8
- // Flex Direction
9
- export const FLEX_DIRECTION_COLUMN = 0
10
- export const FLEX_DIRECTION_COLUMN_REVERSE = 1
11
- export const FLEX_DIRECTION_ROW = 2
12
- export const FLEX_DIRECTION_ROW_REVERSE = 3
13
-
14
- // Wrap
15
- export const WRAP_NO_WRAP = 0
16
- export const WRAP_WRAP = 1
17
- export const WRAP_WRAP_REVERSE = 2
18
-
19
- // Align
20
- export const ALIGN_AUTO = 0
21
- export const ALIGN_FLEX_START = 1
22
- export const ALIGN_CENTER = 2
23
- export const ALIGN_FLEX_END = 3
24
- export const ALIGN_STRETCH = 4
25
- export const ALIGN_BASELINE = 5
26
- export const ALIGN_SPACE_BETWEEN = 6
27
- export const ALIGN_SPACE_AROUND = 7
28
- export const ALIGN_SPACE_EVENLY = 8
29
-
30
- // Justify
31
- export const JUSTIFY_FLEX_START = 0
32
- export const JUSTIFY_CENTER = 1
33
- export const JUSTIFY_FLEX_END = 2
34
- export const JUSTIFY_SPACE_BETWEEN = 3
35
- export const JUSTIFY_SPACE_AROUND = 4
36
- export const JUSTIFY_SPACE_EVENLY = 5
37
-
38
- // Edge
39
- export const EDGE_LEFT = 0
40
- export const EDGE_TOP = 1
41
- export const EDGE_RIGHT = 2
42
- export const EDGE_BOTTOM = 3
43
- export const EDGE_START = 4
44
- export const EDGE_END = 5
45
- export const EDGE_HORIZONTAL = 6
46
- export const EDGE_VERTICAL = 7
47
- export const EDGE_ALL = 8
48
-
49
- // Gutter
50
- export const GUTTER_COLUMN = 0
51
- export const GUTTER_ROW = 1
52
- export const GUTTER_ALL = 2
53
-
54
- // Display
55
- export const DISPLAY_FLEX = 0
56
- export const DISPLAY_NONE = 1
57
-
58
- // Position Type
59
- export const POSITION_TYPE_STATIC = 0
60
- export const POSITION_TYPE_RELATIVE = 1
61
- export const POSITION_TYPE_ABSOLUTE = 2
62
-
63
- // Overflow
64
- export const OVERFLOW_VISIBLE = 0
65
- export const OVERFLOW_HIDDEN = 1
66
- export const OVERFLOW_SCROLL = 2
67
-
68
- // Direction (LTR and RTL are both supported)
69
- export const DIRECTION_INHERIT = 0
70
- export const DIRECTION_LTR = 1
71
- export const DIRECTION_RTL = 2
72
-
73
- // Measure Mode (for measureFunc)
74
- export const MEASURE_MODE_UNDEFINED = 0
75
- export const MEASURE_MODE_EXACTLY = 1
76
- export const MEASURE_MODE_AT_MOST = 2
77
-
78
- // Unit (for internal use)
79
- export const UNIT_UNDEFINED = 0
80
- export const UNIT_POINT = 1
81
- export const UNIT_PERCENT = 2
82
- export const UNIT_AUTO = 3
@@ -1,153 +0,0 @@
1
- /**
2
- * Composable Flexily engine — createFlexily, createBareFlexily, pipe.
3
- *
4
- * FlexilyNode = Node + { setTextContent, getTextContent }.
5
- * No wrapper — text methods are mixed directly onto the Node instance.
6
- */
7
-
8
- import { Node } from "./node-zero.js"
9
- import { DIRECTION_LTR, MEASURE_MODE_UNDEFINED, MEASURE_MODE_AT_MOST } from "./constants.js"
10
- import type { TextLayoutService, ResolvedTextStyle, PreparedText } from "./text-layout.js"
11
- import { createMonospaceMeasurer } from "./monospace-measurer.js"
12
-
13
- // ============================================================================
14
- // FlexilyNode — Node + text content mixin
15
- // ============================================================================
16
-
17
- /** A Node with text content methods. */
18
- export interface FlexilyNode extends Node {
19
- setTextContent(text: string, style?: Partial<ResolvedTextStyle>): void
20
- getTextContent(): string | null
21
- }
22
-
23
- const DEFAULT_TEXT_STYLE: ResolvedTextStyle = {
24
- fontShorthand: "1ch monospace",
25
- fontFamily: "monospace",
26
- fontSize: 1,
27
- fontWeight: 400,
28
- fontStyle: "normal",
29
- lineHeight: 1,
30
- }
31
-
32
- /** Mix text content methods onto a Node. Returns the same node typed as FlexilyNode. */
33
- function mixTextContent(node: Node, engine: FlexilyEngine): FlexilyNode {
34
- let textContent: string | null = null
35
- let prepared: PreparedText | null = null
36
-
37
- // Save originals before overriding — setTextContent needs to call the
38
- // original setMeasureFunc without triggering text state clearing.
39
- const origSetMeasure = node.setMeasureFunc.bind(node)
40
- const origUnsetMeasure = node.unsetMeasureFunc.bind(node)
41
-
42
- const flexNode = node as FlexilyNode
43
-
44
- flexNode.setTextContent = function (text: string, style?: Partial<ResolvedTextStyle>): void {
45
- if (!engine.textLayout) {
46
- throw new Error("No TextLayoutService. Add a text plugin (withMonospace, withPretext, withTestMeasurer).")
47
- }
48
-
49
- textContent = text
50
- const resolved: ResolvedTextStyle = { ...DEFAULT_TEXT_STYLE, ...style }
51
- prepared = engine.textLayout.prepare({ text, style: resolved })
52
-
53
- // Install a MeasureFunc via original (bypasses text-clearing override)
54
- const p = prepared
55
- origSetMeasure((width, widthMode) => {
56
- if (widthMode === MEASURE_MODE_UNDEFINED) {
57
- const sizes = p.intrinsicSizes()
58
- const result = p.layout({ maxWidth: sizes.maxContentWidth })
59
- return { width: result.width, height: result.height }
60
- }
61
- const result = p.layout({ maxWidth: width })
62
- const usedWidth = widthMode === MEASURE_MODE_AT_MOST ? Math.min(width, result.width) : width
63
- return { width: usedWidth, height: result.height }
64
- })
65
- }
66
-
67
- flexNode.getTextContent = function (): string | null {
68
- return textContent
69
- }
70
-
71
- // Override setMeasureFunc/unsetMeasureFunc to clear text state when
72
- // the user explicitly sets a custom measure function.
73
- flexNode.setMeasureFunc = function (fn) {
74
- textContent = null
75
- prepared = null
76
- origSetMeasure(fn)
77
- }
78
-
79
- flexNode.unsetMeasureFunc = function () {
80
- textContent = null
81
- prepared = null
82
- origUnsetMeasure()
83
- }
84
-
85
- return flexNode
86
- }
87
-
88
- // ============================================================================
89
- // Engine
90
- // ============================================================================
91
-
92
- /** The composable Flexily engine. */
93
- export interface FlexilyEngine {
94
- createNode(): FlexilyNode
95
- calculateLayout(root: FlexilyNode, width?: number, height?: number, direction?: number): void
96
- textLayout?: TextLayoutService
97
- }
98
-
99
- /** A plugin that extends or configures the engine. */
100
- export type FlexilyPlugin = (engine: FlexilyEngine) => FlexilyEngine
101
-
102
- /**
103
- * Create a bare Flexily engine — no plugins, just nodes and layout.
104
- * Add plugins via pipe() for text measurement.
105
- */
106
- export function createBareFlexily(): FlexilyEngine {
107
- const engine: FlexilyEngine = {
108
- createNode(): FlexilyNode {
109
- return mixTextContent(Node.create(), engine)
110
- },
111
- calculateLayout(root: FlexilyNode, width?: number, height?: number, direction?: number): void {
112
- root.calculateLayout(width, height, direction ?? DIRECTION_LTR)
113
- },
114
- }
115
- return engine
116
- }
117
-
118
- /**
119
- * Apply plugins to an engine, left to right.
120
- *
121
- * @example
122
- * ```typescript
123
- * const flex = pipe(createBareFlexily(), withMonospace(), withTestMeasurer())
124
- * ```
125
- */
126
- export function pipe(engine: FlexilyEngine, ...plugins: FlexilyPlugin[]): FlexilyEngine {
127
- let result = engine
128
- for (const plugin of plugins) {
129
- result = plugin(result)
130
- }
131
- return result
132
- }
133
-
134
- /**
135
- * Create a batteries-included Flexily engine.
136
- *
137
- * Includes monospace text measurement (1 char = charWidth units).
138
- * For terminal UIs, the default charWidth/charHeight of 1 maps to terminal cells.
139
- *
140
- * @example
141
- * ```typescript
142
- * import { createFlexily } from "flexily"
143
- * const flex = createFlexily()
144
- * const node = flex.createNode()
145
- * node.setTextContent("Hello world")
146
- * flex.calculateLayout(node, 80, 24)
147
- * ```
148
- */
149
- export function createFlexily(options?: { charWidth?: number; charHeight?: number }): FlexilyEngine {
150
- const engine = createBareFlexily()
151
- engine.textLayout = createMonospaceMeasurer(options?.charWidth ?? 1, options?.charHeight ?? 1)
152
- return engine
153
- }
@@ -1,110 +0,0 @@
1
- /**
2
- * Flexily Classic - Allocating Layout Engine
3
- *
4
- * The classic (allocating) variant of Flexily. Use for debugging, comparison,
5
- * or when you need reentrancy (concurrent layouts).
6
- *
7
- * The main export 'flexily' uses the faster zero-allocation algorithm.
8
- *
9
- * @example
10
- * ```typescript
11
- * import { Node, FLEX_DIRECTION_ROW, DIRECTION_LTR } from 'flexily/classic';
12
- *
13
- * const root = Node.create();
14
- * root.setWidth(80);
15
- * root.setFlexDirection(FLEX_DIRECTION_ROW);
16
- *
17
- * const child = Node.create();
18
- * child.setFlexGrow(1);
19
- * root.insertChild(child, 0);
20
- *
21
- * root.calculateLayout(80, 24, DIRECTION_LTR);
22
- * console.log(child.getComputedWidth()); // 80
23
- * ```
24
- */
25
-
26
- // Node class (classic allocating variant)
27
- export { Node } from "./classic/node.js"
28
-
29
- // All constants (Yoga-compatible)
30
- export {
31
- // Flex Direction
32
- FLEX_DIRECTION_COLUMN,
33
- FLEX_DIRECTION_COLUMN_REVERSE,
34
- FLEX_DIRECTION_ROW,
35
- FLEX_DIRECTION_ROW_REVERSE,
36
- // Wrap
37
- WRAP_NO_WRAP,
38
- WRAP_WRAP,
39
- WRAP_WRAP_REVERSE,
40
- // Align
41
- ALIGN_AUTO,
42
- ALIGN_FLEX_START,
43
- ALIGN_CENTER,
44
- ALIGN_FLEX_END,
45
- ALIGN_STRETCH,
46
- ALIGN_BASELINE,
47
- ALIGN_SPACE_BETWEEN,
48
- ALIGN_SPACE_AROUND,
49
- ALIGN_SPACE_EVENLY,
50
- // Justify
51
- JUSTIFY_FLEX_START,
52
- JUSTIFY_CENTER,
53
- JUSTIFY_FLEX_END,
54
- JUSTIFY_SPACE_BETWEEN,
55
- JUSTIFY_SPACE_AROUND,
56
- JUSTIFY_SPACE_EVENLY,
57
- // Edge
58
- EDGE_LEFT,
59
- EDGE_TOP,
60
- EDGE_RIGHT,
61
- EDGE_BOTTOM,
62
- EDGE_START,
63
- EDGE_END,
64
- EDGE_HORIZONTAL,
65
- EDGE_VERTICAL,
66
- EDGE_ALL,
67
- // Gutter
68
- GUTTER_COLUMN,
69
- GUTTER_ROW,
70
- GUTTER_ALL,
71
- // Display
72
- DISPLAY_FLEX,
73
- DISPLAY_NONE,
74
- // Position Type
75
- POSITION_TYPE_STATIC,
76
- POSITION_TYPE_RELATIVE,
77
- POSITION_TYPE_ABSOLUTE,
78
- // Overflow
79
- OVERFLOW_VISIBLE,
80
- OVERFLOW_HIDDEN,
81
- OVERFLOW_SCROLL,
82
- // Direction
83
- DIRECTION_INHERIT,
84
- DIRECTION_LTR,
85
- DIRECTION_RTL,
86
- // Measure Mode
87
- MEASURE_MODE_UNDEFINED,
88
- MEASURE_MODE_EXACTLY,
89
- MEASURE_MODE_AT_MOST,
90
- // Unit (internal, but exported for advanced use)
91
- UNIT_UNDEFINED,
92
- UNIT_POINT,
93
- UNIT_PERCENT,
94
- UNIT_AUTO,
95
- } from "./constants.js"
96
-
97
- // Types
98
- export type { BaselineFunc, Layout, MeasureFunc, Style, Value } from "./types.js"
99
-
100
- // Utility functions
101
- export { createDefaultStyle, createValue } from "./types.js"
102
-
103
- // Layout stats (for debugging/benchmarking)
104
- export {
105
- layoutNodeCalls,
106
- layoutSizingCalls,
107
- layoutPositioningCalls,
108
- layoutCacheHits,
109
- resetLayoutStats,
110
- } from "./classic/layout.js"
package/src/index.ts DELETED
@@ -1,133 +0,0 @@
1
- /**
2
- * Flexily - Pure JavaScript Flexbox Layout Engine
3
- *
4
- * A Yoga-compatible layout engine for terminal UIs and other environments
5
- * where WebAssembly is not available or desirable.
6
- *
7
- * Two API levels:
8
- *
9
- * 1. Composable (recommended):
10
- * ```typescript
11
- * import { createFlexily } from "flexily"
12
- * const flex = createFlexily()
13
- * const node = flex.createNode()
14
- * node.setTextContent("Hello world")
15
- * flex.calculateLayout(node, 80, 24)
16
- * ```
17
- *
18
- * 2. Low-level (Yoga-compatible):
19
- * ```typescript
20
- * import { Node, DIRECTION_LTR } from "flexily"
21
- * const root = Node.create()
22
- * root.setWidth(80)
23
- * root.calculateLayout(80, 24, DIRECTION_LTR)
24
- * ```
25
- */
26
-
27
- // Composable API
28
- export { createFlexily, createBareFlexily, pipe } from "./create-flexily.js"
29
- export type { FlexilyEngine, FlexilyNode, FlexilyPlugin } from "./create-flexily.js"
30
-
31
- // Text measurement plugins
32
- export { createMonospaceMeasurer, withMonospace } from "./monospace-measurer.js"
33
- export { createTestMeasurer, withTestMeasurer } from "./test-measurer.js"
34
- export { createPretextMeasurer, withPretext } from "./pretext-measurer.js"
35
- export type { PretextAPI, PretextPrepared, PretextLayout } from "./pretext-measurer.js"
36
-
37
- // Text layout service types
38
- export type {
39
- TextLayoutService,
40
- PreparedText,
41
- TextLayout,
42
- TextLine,
43
- TextConstraints,
44
- IntrinsicSizes,
45
- ResolvedTextStyle,
46
- TextPrepareInput,
47
- } from "./text-layout.js"
48
-
49
- // Node class (zero-alloc version) — low-level Yoga-compatible API
50
- export { Node } from "./node-zero.js"
51
-
52
- // All constants (Yoga-compatible)
53
- export {
54
- // Flex Direction
55
- FLEX_DIRECTION_COLUMN,
56
- FLEX_DIRECTION_COLUMN_REVERSE,
57
- FLEX_DIRECTION_ROW,
58
- FLEX_DIRECTION_ROW_REVERSE,
59
- // Wrap
60
- WRAP_NO_WRAP,
61
- WRAP_WRAP,
62
- WRAP_WRAP_REVERSE,
63
- // Align
64
- ALIGN_AUTO,
65
- ALIGN_FLEX_START,
66
- ALIGN_CENTER,
67
- ALIGN_FLEX_END,
68
- ALIGN_STRETCH,
69
- ALIGN_BASELINE,
70
- ALIGN_SPACE_BETWEEN,
71
- ALIGN_SPACE_AROUND,
72
- ALIGN_SPACE_EVENLY,
73
- // Justify
74
- JUSTIFY_FLEX_START,
75
- JUSTIFY_CENTER,
76
- JUSTIFY_FLEX_END,
77
- JUSTIFY_SPACE_BETWEEN,
78
- JUSTIFY_SPACE_AROUND,
79
- JUSTIFY_SPACE_EVENLY,
80
- // Edge
81
- EDGE_LEFT,
82
- EDGE_TOP,
83
- EDGE_RIGHT,
84
- EDGE_BOTTOM,
85
- EDGE_START,
86
- EDGE_END,
87
- EDGE_HORIZONTAL,
88
- EDGE_VERTICAL,
89
- EDGE_ALL,
90
- // Gutter
91
- GUTTER_COLUMN,
92
- GUTTER_ROW,
93
- GUTTER_ALL,
94
- // Display
95
- DISPLAY_FLEX,
96
- DISPLAY_NONE,
97
- // Position Type
98
- POSITION_TYPE_STATIC,
99
- POSITION_TYPE_RELATIVE,
100
- POSITION_TYPE_ABSOLUTE,
101
- // Overflow
102
- OVERFLOW_VISIBLE,
103
- OVERFLOW_HIDDEN,
104
- OVERFLOW_SCROLL,
105
- // Direction
106
- DIRECTION_INHERIT,
107
- DIRECTION_LTR,
108
- DIRECTION_RTL,
109
- // Measure Mode
110
- MEASURE_MODE_UNDEFINED,
111
- MEASURE_MODE_EXACTLY,
112
- MEASURE_MODE_AT_MOST,
113
- // Unit (internal, but exported for advanced use)
114
- UNIT_UNDEFINED,
115
- UNIT_POINT,
116
- UNIT_PERCENT,
117
- UNIT_AUTO,
118
- } from "./constants.js"
119
-
120
- // Types
121
- export type { BaselineFunc, Layout, MeasureFunc, Style, Value } from "./types.js"
122
-
123
- // Utility functions
124
- export { createDefaultStyle, createValue } from "./types.js"
125
-
126
- // Layout stats (for debugging/benchmarking)
127
- export {
128
- layoutNodeCalls,
129
- layoutSizingCalls,
130
- layoutPositioningCalls,
131
- layoutCacheHits,
132
- resetLayoutStats,
133
- } from "./layout-zero.js"